summaryrefslogtreecommitdiffstats
path: root/lib/puppet/ssl/host.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/ssl/host.rb')
-rw-r--r--lib/puppet/ssl/host.rb460
1 files changed, 230 insertions, 230 deletions
diff --git a/lib/puppet/ssl/host.rb b/lib/puppet/ssl/host.rb
index 9aaff8ad2..8a6f0aa6d 100644
--- a/lib/puppet/ssl/host.rb
+++ b/lib/puppet/ssl/host.rb
@@ -8,255 +8,255 @@ require 'puppet/util/cacher'
# The class that manages all aspects of our SSL certificates --
# private keys, public keys, requests, etc.
class Puppet::SSL::Host
- # Yay, ruby's strange constant lookups.
- Key = Puppet::SSL::Key
- CA_NAME = Puppet::SSL::CA_NAME
- Certificate = Puppet::SSL::Certificate
- CertificateRequest = Puppet::SSL::CertificateRequest
- CertificateRevocationList = Puppet::SSL::CertificateRevocationList
-
- attr_reader :name
- attr_accessor :ca
-
- attr_writer :key, :certificate, :certificate_request
-
- class << self
- include Puppet::Util::Cacher
-
- cached_attr(:localhost) do
- result = new
- result.generate unless result.certificate
- result.key # Make sure it's read in
- result
- end
+ # Yay, ruby's strange constant lookups.
+ Key = Puppet::SSL::Key
+ CA_NAME = Puppet::SSL::CA_NAME
+ Certificate = Puppet::SSL::Certificate
+ CertificateRequest = Puppet::SSL::CertificateRequest
+ CertificateRevocationList = Puppet::SSL::CertificateRevocationList
+
+ attr_reader :name
+ attr_accessor :ca
+
+ attr_writer :key, :certificate, :certificate_request
+
+ class << self
+ include Puppet::Util::Cacher
+
+ cached_attr(:localhost) do
+ result = new
+ result.generate unless result.certificate
+ result.key # Make sure it's read in
+ result
end
-
- # This is the constant that people will use to mark that a given host is
- # a certificate authority.
- def self.ca_name
- CA_NAME
+ end
+
+ # This is the constant that people will use to mark that a given host is
+ # a certificate authority.
+ def self.ca_name
+ CA_NAME
+ end
+
+ class << self
+ attr_reader :ca_location
+ end
+
+ # Configure how our various classes interact with their various terminuses.
+ def self.configure_indirection(terminus, cache = nil)
+ Certificate.terminus_class = terminus
+ CertificateRequest.terminus_class = terminus
+ CertificateRevocationList.terminus_class = terminus
+
+ if cache
+ # This is weird; we don't actually cache our keys, we
+ # use what would otherwise be the cache as our normal
+ # terminus.
+ Key.terminus_class = cache
+ else
+ Key.terminus_class = terminus
end
- class << self
- attr_reader :ca_location
+ if cache
+ Certificate.cache_class = cache
+ CertificateRequest.cache_class = cache
+ CertificateRevocationList.cache_class = cache
+ else
+ # Make sure we have no cache configured. puppet master
+ # switches the configurations around a bit, so it's important
+ # that we specify the configs for absolutely everything, every
+ # time.
+ Certificate.cache_class = nil
+ CertificateRequest.cache_class = nil
+ CertificateRevocationList.cache_class = nil
end
-
- # Configure how our various classes interact with their various terminuses.
- def self.configure_indirection(terminus, cache = nil)
- Certificate.terminus_class = terminus
- CertificateRequest.terminus_class = terminus
- CertificateRevocationList.terminus_class = terminus
-
- if cache
- # This is weird; we don't actually cache our keys, we
- # use what would otherwise be the cache as our normal
- # terminus.
- Key.terminus_class = cache
- else
- Key.terminus_class = terminus
- end
-
- if cache
- Certificate.cache_class = cache
- CertificateRequest.cache_class = cache
- CertificateRevocationList.cache_class = cache
- else
- # Make sure we have no cache configured. puppet master
- # switches the configurations around a bit, so it's important
- # that we specify the configs for absolutely everything, every
- # time.
- Certificate.cache_class = nil
- CertificateRequest.cache_class = nil
- CertificateRevocationList.cache_class = nil
- end
+ end
+
+ CA_MODES = {
+ # Our ca is local, so we use it as the ultimate source of information
+ # And we cache files locally.
+ :local => [:ca, :file],
+ # We're a remote CA client.
+ :remote => [:rest, :file],
+ # We are the CA, so we don't have read/write access to the normal certificates.
+ :only => [:ca],
+ # We have no CA, so we just look in the local file store.
+ :none => [:file]
+ }
+
+ # Specify how we expect to interact with our certificate authority.
+ def self.ca_location=(mode)
+ raise ArgumentError, "CA Mode can only be #{CA_MODES.collect { |m| m.to_s }.join(", ")}" unless CA_MODES.include?(mode)
+
+ @ca_location = mode
+
+ configure_indirection(*CA_MODES[@ca_location])
+ end
+
+ # Remove all traces of a given host
+ def self.destroy(name)
+ [Key, Certificate, CertificateRequest].collect { |part| part.destroy(name) }.any? { |x| x }
+ end
+
+ # Search for more than one host, optionally only specifying
+ # an interest in hosts with a given file type.
+ # This just allows our non-indirected class to have one of
+ # indirection methods.
+ def self.search(options = {})
+ classlist = [options[:for] || [Key, CertificateRequest, Certificate]].flatten
+
+ # Collect the results from each class, flatten them, collect all of the names, make the name list unique,
+ # then create a Host instance for each one.
+ classlist.collect { |klass| klass.search }.flatten.collect { |r| r.name }.uniq.collect do |name|
+ new(name)
end
-
- CA_MODES = {
- # Our ca is local, so we use it as the ultimate source of information
- # And we cache files locally.
- :local => [:ca, :file],
- # We're a remote CA client.
- :remote => [:rest, :file],
- # We are the CA, so we don't have read/write access to the normal certificates.
- :only => [:ca],
- # We have no CA, so we just look in the local file store.
- :none => [:file]
- }
-
- # Specify how we expect to interact with our certificate authority.
- def self.ca_location=(mode)
- raise ArgumentError, "CA Mode can only be #{CA_MODES.collect { |m| m.to_s }.join(", ")}" unless CA_MODES.include?(mode)
-
- @ca_location = mode
-
- configure_indirection(*CA_MODES[@ca_location])
+ end
+
+ # Is this a ca host, meaning that all of its files go in the CA location?
+ def ca?
+ ca
+ end
+
+ def key
+ @key ||= Key.find(name)
+ end
+
+ # This is the private key; we can create it from scratch
+ # with no inputs.
+ def generate_key
+ @key = Key.new(name)
+ @key.generate
+ begin
+ @key.save
+ rescue
+ @key = nil
+ raise
end
-
- # Remove all traces of a given host
- def self.destroy(name)
- [Key, Certificate, CertificateRequest].collect { |part| part.destroy(name) }.any? { |x| x }
+ true
+ end
+
+ def certificate_request
+ @certificate_request ||= CertificateRequest.find(name)
+ end
+
+ # Our certificate request requires the key but that's all.
+ def generate_certificate_request
+ generate_key unless key
+ @certificate_request = CertificateRequest.new(name)
+ @certificate_request.generate(key.content)
+ begin
+ @certificate_request.save
+ rescue
+ @certificate_request = nil
+ raise
end
- # Search for more than one host, optionally only specifying
- # an interest in hosts with a given file type.
- # This just allows our non-indirected class to have one of
- # indirection methods.
- def self.search(options = {})
- classlist = [options[:for] || [Key, CertificateRequest, Certificate]].flatten
-
- # Collect the results from each class, flatten them, collect all of the names, make the name list unique,
- # then create a Host instance for each one.
- classlist.collect { |klass| klass.search }.flatten.collect { |r| r.name }.uniq.collect do |name|
- new(name)
- end
- end
+ true
+ end
- # Is this a ca host, meaning that all of its files go in the CA location?
- def ca?
- ca
- end
+ def certificate
+ unless @certificate
+ generate_key unless key
- def key
- @key ||= Key.find(name)
- end
+ # get the CA cert first, since it's required for the normal cert
+ # to be of any use.
+ return nil unless Certificate.find("ca") unless ca?
+ return nil unless @certificate = Certificate.find(name)
- # This is the private key; we can create it from scratch
- # with no inputs.
- def generate_key
- @key = Key.new(name)
- @key.generate
- begin
- @key.save
- rescue
- @key = nil
- raise
- end
- true
+ unless certificate_matches_key?
+ raise Puppet::Error, "Retrieved certificate does not match private key; please remove certificate from server and regenerate it with the current key"
+ end
end
-
- def certificate_request
- @certificate_request ||= CertificateRequest.find(name)
+ @certificate
+ end
+
+ def certificate_matches_key?
+ return false unless key
+ return false unless certificate
+
+ certificate.content.check_private_key(key.content)
+ end
+
+ # Generate all necessary parts of our ssl host.
+ def generate
+ generate_key unless key
+ generate_certificate_request unless certificate_request
+
+ # If we can get a CA instance, then we're a valid CA, and we
+ # should use it to sign our request; else, just try to read
+ # the cert.
+ if ! certificate and ca = Puppet::SSL::CertificateAuthority.instance
+ ca.sign(self.name)
end
-
- # Our certificate request requires the key but that's all.
- def generate_certificate_request
- generate_key unless key
- @certificate_request = CertificateRequest.new(name)
- @certificate_request.generate(key.content)
- begin
- @certificate_request.save
- rescue
- @certificate_request = nil
- raise
- end
-
- true
+ end
+
+ def initialize(name = nil)
+ @name = (name || Puppet[:certname]).downcase
+ @key = @certificate = @certificate_request = nil
+ @ca = (name == self.class.ca_name)
+ end
+
+ # Extract the public key from the private key.
+ def public_key
+ key.content.public_key
+ end
+
+ # Create/return a store that uses our SSL info to validate
+ # connections.
+ def ssl_store(purpose = OpenSSL::X509::PURPOSE_ANY)
+ unless @ssl_store
+ @ssl_store = OpenSSL::X509::Store.new
+ @ssl_store.purpose = purpose
+
+ # Use the file path here, because we don't want to cause
+ # a lookup in the middle of setting our ssl connection.
+ @ssl_store.add_file(Puppet[:localcacert])
+
+ # If there's a CRL, add it to our store.
+ if crl = Puppet::SSL::CertificateRevocationList.find(CA_NAME)
+ @ssl_store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK if Puppet.settings[:certificate_revocation]
+ @ssl_store.add_crl(crl.content)
+ end
+ return @ssl_store
end
-
- def certificate
- unless @certificate
- generate_key unless key
-
- # get the CA cert first, since it's required for the normal cert
- # to be of any use.
- return nil unless Certificate.find("ca") unless ca?
- return nil unless @certificate = Certificate.find(name)
-
- unless certificate_matches_key?
- raise Puppet::Error, "Retrieved certificate does not match private key; please remove certificate from server and regenerate it with the current key"
- end
- end
- @certificate
- end
-
- def certificate_matches_key?
- return false unless key
- return false unless certificate
-
- certificate.content.check_private_key(key.content)
- end
-
- # Generate all necessary parts of our ssl host.
- def generate
- generate_key unless key
- generate_certificate_request unless certificate_request
-
- # If we can get a CA instance, then we're a valid CA, and we
- # should use it to sign our request; else, just try to read
- # the cert.
- if ! certificate and ca = Puppet::SSL::CertificateAuthority.instance
- ca.sign(self.name)
- end
- end
-
- def initialize(name = nil)
- @name = (name || Puppet[:certname]).downcase
- @key = @certificate = @certificate_request = nil
- @ca = (name == self.class.ca_name)
- end
-
- # Extract the public key from the private key.
- def public_key
- key.content.public_key
+ @ssl_store
+ end
+
+ # Attempt to retrieve a cert, if we don't already have one.
+ def wait_for_cert(time)
+ begin
+ return if certificate
+ generate
+ return if certificate
+ rescue SystemExit,NoMemoryError
+ raise
+ rescue Exception => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not request certificate: #{detail}"
+ if time < 1
+ puts "Exiting; failed to retrieve certificate and waitforcert is disabled"
+ exit(1)
+ else
+ sleep(time)
+ end
+ retry
end
- # Create/return a store that uses our SSL info to validate
- # connections.
- def ssl_store(purpose = OpenSSL::X509::PURPOSE_ANY)
- unless @ssl_store
- @ssl_store = OpenSSL::X509::Store.new
- @ssl_store.purpose = purpose
-
- # Use the file path here, because we don't want to cause
- # a lookup in the middle of setting our ssl connection.
- @ssl_store.add_file(Puppet[:localcacert])
-
- # If there's a CRL, add it to our store.
- if crl = Puppet::SSL::CertificateRevocationList.find(CA_NAME)
- @ssl_store.flags = OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK if Puppet.settings[:certificate_revocation]
- @ssl_store.add_crl(crl.content)
- end
- return @ssl_store
- end
- @ssl_store
+ if time < 1
+ puts "Exiting; no certificate found and waitforcert is disabled"
+ exit(1)
end
- # Attempt to retrieve a cert, if we don't already have one.
- def wait_for_cert(time)
- begin
- return if certificate
- generate
- return if certificate
- rescue SystemExit,NoMemoryError
- raise
- rescue Exception => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not request certificate: #{detail}"
- if time < 1
- puts "Exiting; failed to retrieve certificate and waitforcert is disabled"
- exit(1)
- else
- sleep(time)
- end
- retry
- end
-
- if time < 1
- puts "Exiting; no certificate found and waitforcert is disabled"
- exit(1)
- end
-
- while true
- sleep time
- begin
- break if certificate
- Puppet.notice "Did not receive certificate"
- rescue StandardError => detail
- puts detail.backtrace if Puppet[:trace]
- Puppet.err "Could not request certificate: #{detail}"
- end
- end
+ while true
+ sleep time
+ begin
+ break if certificate
+ Puppet.notice "Did not receive certificate"
+ rescue StandardError => detail
+ puts detail.backtrace if Puppet[:trace]
+ Puppet.err "Could not request certificate: #{detail}"
+ end
end
+ end
end
require 'puppet/ssl/certificate_authority'