diff options
| author | Luke Kanies <luke@madstop.com> | 2008-03-11 19:27:32 -0500 |
|---|---|---|
| committer | Luke Kanies <luke@madstop.com> | 2008-04-15 21:34:04 -0500 |
| commit | 0f46815b4e7b7970e9516166f47c0ec074bf0fa2 (patch) | |
| tree | e1a237066f5216496cf9393f37d945985a99a7e2 /lib/puppet | |
| parent | 00e35bce4e8b7f4e0e4ee039a1d82ad9d08a6b96 (diff) | |
| download | puppet-0f46815b4e7b7970e9516166f47c0ec074bf0fa2.tar.gz puppet-0f46815b4e7b7970e9516166f47c0ec074bf0fa2.tar.xz puppet-0f46815b4e7b7970e9516166f47c0ec074bf0fa2.zip | |
It looks like all of the new ssl classes for managing
keys, certificates, and requests now work, including
talking to the certificate authority. Now we just
need the authority itself, along with the necessary
REST terminii.
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 |
