diff options
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/indirector/certificate_request/file.rb | 4 | ||||
-rw-r--r-- | lib/puppet/indirector/ssl_file.rb | 6 | ||||
-rw-r--r-- | lib/puppet/ssl/base.rb | 1 | ||||
-rw-r--r-- | lib/puppet/ssl/certificate.rb | 37 | ||||
-rw-r--r-- | lib/puppet/ssl/certificate_request.rb | 4 | ||||
-rw-r--r-- | lib/puppet/ssl/host.rb | 56 | ||||
-rw-r--r-- | lib/puppet/ssl/indirection_hooks.rb | 17 |
7 files changed, 105 insertions, 20 deletions
diff --git a/lib/puppet/indirector/certificate_request/file.rb b/lib/puppet/indirector/certificate_request/file.rb index 5eb6745fd..274311e2c 100644 --- a/lib/puppet/indirector/certificate_request/file.rb +++ b/lib/puppet/indirector/certificate_request/file.rb @@ -1,8 +1,8 @@ require 'puppet/indirector/ssl_file' require 'puppet/ssl/certificate_request' -class Puppet::SSL::CertificateRequest::CaFile < Puppet::Indirector::SslFile - desc "Manage the CA collection of certificate requests on disk." +class Puppet::SSL::CertificateRequest::File < Puppet::Indirector::SslFile + desc "Manage the collection of certificate requests on disk." store_in :requestdir end diff --git a/lib/puppet/indirector/ssl_file.rb b/lib/puppet/indirector/ssl_file.rb index 6125d46e4..7a1501dbf 100644 --- a/lib/puppet/indirector/ssl_file.rb +++ b/lib/puppet/indirector/ssl_file.rb @@ -25,7 +25,7 @@ class Puppet::Indirector::SslFile < Puppet::Indirector::Terminus end # Remove our file. - def destroy(file) + def destroy(file, options = {}) path = path(file.name) raise Puppet::Error.new("File %s does not exist; cannot destroy" % [file]) unless FileTest.exist?(path) @@ -37,7 +37,7 @@ class Puppet::Indirector::SslFile < Puppet::Indirector::Terminus end # Find the file on disk, returning an instance of the model. - def find(name) + def find(name, options = {}) path = path(name) return nil unless FileTest.exist?(path) @@ -48,7 +48,7 @@ class Puppet::Indirector::SslFile < Puppet::Indirector::Terminus end # Save our file to disk. - def save(file) + def save(file, options = {}) path = path(file.name) dir = File.dirname(path) diff --git a/lib/puppet/ssl/base.rb b/lib/puppet/ssl/base.rb index 87cbea4b5..781ccb805 100644 --- a/lib/puppet/ssl/base.rb +++ b/lib/puppet/ssl/base.rb @@ -1,4 +1,5 @@ require 'puppet/ssl' +require 'puppet/ssl/indirection_hooks' # The base class for wrapping SSL instances. class Puppet::SSL::Base diff --git a/lib/puppet/ssl/certificate.rb b/lib/puppet/ssl/certificate.rb index d1687e6f0..697b2e785 100644 --- a/lib/puppet/ssl/certificate.rb +++ b/lib/puppet/ssl/certificate.rb @@ -6,9 +6,40 @@ class Puppet::SSL::Certificate < Puppet::SSL::Base wraps OpenSSL::X509::Certificate extend Puppet::Indirector - indirects :certificate, :terminus_class => :file + indirects :certificate, :extend => Puppet::SSL::IndirectionHooks - def generate - raise Puppet::DevError, "Cannot generate certificates directly; they must be generated during signing" + # Indicate where we should get our signed certs from. + def self.ca_is(dest) + raise(ArgumentError, "Invalid location '%s' for ca; valid values are :local and :remote" % dest) unless [:local, :remote].include?(dest) + @ca_location = dest + end + + # Default to :local for the ca location. + def self.ca_location + if defined?(@ca_location) and @ca_location + @ca_location + else + :local + end + end + + # Request a certificate from our CA. + def generate(request) + if self.class.ca_location == :local + terminus = :ca_file + else + terminus = :rest + end + + # Save our certificate request. + request.save :in => terminus + + # And see if we can retrieve the certificate. + if cert = self.class.find(name, :in => terminus) + @content = cert.content + return true + else + return false + end end end diff --git a/lib/puppet/ssl/certificate_request.rb b/lib/puppet/ssl/certificate_request.rb index fec9e1733..e8cbbbade 100644 --- a/lib/puppet/ssl/certificate_request.rb +++ b/lib/puppet/ssl/certificate_request.rb @@ -5,7 +5,7 @@ class Puppet::SSL::CertificateRequest < Puppet::SSL::Base wraps OpenSSL::X509::Request extend Puppet::Indirector - indirects :certificate_request #, :terminus_class => :file + indirects :certificate_request, :extend => Puppet::SSL::IndirectionHooks # How to create a certificate request with our system defaults. def generate(key) @@ -17,6 +17,8 @@ class Puppet::SSL::CertificateRequest < Puppet::SSL::Base csr.public_key = key.public_key csr.sign(key, OpenSSL::Digest::MD5.new) + raise Puppet::Error, "CSR sign verification failed; you need to clean the certificate request for %s on the server" % name unless csr.verify(key.public_key) + @content = csr end end diff --git a/lib/puppet/ssl/host.rb b/lib/puppet/ssl/host.rb index 8df9ef385..bae33b23e 100644 --- a/lib/puppet/ssl/host.rb +++ b/lib/puppet/ssl/host.rb @@ -13,23 +13,28 @@ class Puppet::SSL::Host attr_reader :name + attr_accessor :ca + + # Is this a ca host, meaning that all of its files go in the CA collections? + def ca? + ca + end + # Read our cert if necessary, fail if we can't find it (since it should # be created by someone else and returned through 'find'). def certificate unless @certificate ||= Certificate.find(name) - Certificate.new(name).generate # throws an exception + return nil end - @certificate + @certificate.content end # Read or create, then return, our certificate request. def certificate_request unless @certificate_request ||= CertificateRequest.find(name) - @certificate_request = CertificateRequest.new(name) - @certificate_request.generate(key) - @certificate_request.save + return nil end - @certificate_request + @certificate_request.content end # Remove all traces of this ssl host @@ -39,20 +44,49 @@ class Puppet::SSL::Host end end + # Request a signed certificate from a ca, if we can find one. + def generate_certificate + generate_certificate_request unless certificate_request + + @certificate = Certificate.new(name) + if @certificate.generate(certificate_request) + @certificate.save + return true + else + return false + end + end + + # Generate and save a new certificate request. + def generate_certificate_request + generate_key unless key + @certificate_request = CertificateRequest.new(name) + @certificate_request.generate(key) + @certificate_request.save + return true + end + + # Generate and save a new key. + def generate_key + @key = Key.new(name) + @key.generate + @key.save + return true + end + # Read or create, then return, our key. The public key is part - # of the private key. + # of the private key. We def key unless @key ||= Key.find(name) - @key = Key.new(name) - @key.generate - @key.save + return nil end - @key + @key.content end def initialize(name) @name = name @key = @certificate = @certificate_request = nil + @ca = false end # Extract the public key from the private key. diff --git a/lib/puppet/ssl/indirection_hooks.rb b/lib/puppet/ssl/indirection_hooks.rb new file mode 100644 index 000000000..c2a3442c0 --- /dev/null +++ b/lib/puppet/ssl/indirection_hooks.rb @@ -0,0 +1,17 @@ +# +# Created by Luke Kanies on 2008-3-10. +# Copyright (c) 2008. All rights reserved. + +require 'uri' +require 'puppet/ssl' + +# This module is used to pick the appropriate terminus +# in certificate indirections. This is necessary because +# we need the ability to choose between interacting with the CA +# or the local certs. +module Puppet::SSL::IndirectionHooks + # Pick an appropriate terminus based on what's specified, defaulting to :file. + def select_terminus(full_uri, options = {}) + return options[:to] || options[:in] || :file + end +end |