summaryrefslogtreecommitdiffstats
path: root/lib/puppet
diff options
context:
space:
mode:
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