summaryrefslogtreecommitdiffstats
path: root/lib/puppet
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-03-11 19:27:32 -0500
committerLuke Kanies <luke@madstop.com>2008-04-15 21:34:04 -0500
commit0f46815b4e7b7970e9516166f47c0ec074bf0fa2 (patch)
treee1a237066f5216496cf9393f37d945985a99a7e2 /lib/puppet
parent00e35bce4e8b7f4e0e4ee039a1d82ad9d08a6b96 (diff)
downloadpuppet-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.rb4
-rw-r--r--lib/puppet/indirector/ssl_file.rb6
-rw-r--r--lib/puppet/ssl/base.rb1
-rw-r--r--lib/puppet/ssl/certificate.rb37
-rw-r--r--lib/puppet/ssl/certificate_request.rb4
-rw-r--r--lib/puppet/ssl/host.rb56
-rw-r--r--lib/puppet/ssl/indirection_hooks.rb17
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