summaryrefslogtreecommitdiffstats
path: root/lib/puppet/sslcertificates
diff options
context:
space:
mode:
authorMarkus Roberts <Markus@reality.com>2010-07-09 18:12:17 -0700
committerMarkus Roberts <Markus@reality.com>2010-07-09 18:12:17 -0700
commit3180b9d9b2c844dade1d361326600f7001ec66dd (patch)
tree98fe7c5ac7eb942aac9c39f019a17b0b3f5a57f4 /lib/puppet/sslcertificates
parent543225970225de5697734bfaf0a6eee996802c04 (diff)
downloadpuppet-3180b9d9b2c844dade1d361326600f7001ec66dd.tar.gz
puppet-3180b9d9b2c844dade1d361326600f7001ec66dd.tar.xz
puppet-3180b9d9b2c844dade1d361326600f7001ec66dd.zip
Code smell: Two space indentation
Replaced 106806 occurances of ^( +)(.*$) with The ruby community almost universally (i.e. everyone but Luke, Markus, and the other eleven people who learned ruby in the 1900s) uses two-space indentation. 3 Examples: The code: end # Tell getopt which arguments are valid def test_get_getopt_args element = Setting.new :name => "foo", :desc => "anything", :settings => Puppet::Util::Settings.new assert_equal([["--foo", GetoptLong::REQUIRED_ARGUMENT]], element.getopt_args, "Did not produce appropriate getopt args") becomes: end # Tell getopt which arguments are valid def test_get_getopt_args element = Setting.new :name => "foo", :desc => "anything", :settings => Puppet::Util::Settings.new assert_equal([["--foo", GetoptLong::REQUIRED_ARGUMENT]], element.getopt_args, "Did not produce appropriate getopt args") The code: assert_equal(str, val) assert_instance_of(Float, result) end # Now test it with a passed object becomes: assert_equal(str, val) assert_instance_of(Float, result) end # Now test it with a passed object The code: end assert_nothing_raised do klass[:Yay] = "boo" klass["Cool"] = :yayness end becomes: end assert_nothing_raised do klass[:Yay] = "boo" klass["Cool"] = :yayness end
Diffstat (limited to 'lib/puppet/sslcertificates')
-rw-r--r--lib/puppet/sslcertificates/ca.rb646
-rw-r--r--lib/puppet/sslcertificates/certificate.rb376
-rw-r--r--lib/puppet/sslcertificates/inventory.rb54
-rw-r--r--lib/puppet/sslcertificates/support.rb226
4 files changed, 651 insertions, 651 deletions
diff --git a/lib/puppet/sslcertificates/ca.rb b/lib/puppet/sslcertificates/ca.rb
index e9e66bc61..63e6b922a 100644
--- a/lib/puppet/sslcertificates/ca.rb
+++ b/lib/puppet/sslcertificates/ca.rb
@@ -1,381 +1,381 @@
require 'sync'
class Puppet::SSLCertificates::CA
- include Puppet::Util::Warnings
+ include Puppet::Util::Warnings
- Certificate = Puppet::SSLCertificates::Certificate
- attr_accessor :keyfile, :file, :config, :dir, :cert, :crl
+ Certificate = Puppet::SSLCertificates::Certificate
+ attr_accessor :keyfile, :file, :config, :dir, :cert, :crl
- def certfile
- @config[:cacert]
- end
-
- # Remove all traces of a given host. This is kind of hackish, but, eh.
- def clean(host)
- host = host.downcase
- [:csrdir, :signeddir, :publickeydir, :privatekeydir, :certdir].each do |name|
- dir = Puppet[name]
-
- file = File.join(dir, host + ".pem")
-
- if FileTest.exists?(file)
- begin
- if Puppet[:name] == "cert"
- puts "Removing #{file}"
- else
- Puppet.info "Removing #{file}"
- end
- File.unlink(file)
- rescue => detail
- raise Puppet::Error, "Could not delete #{file}: #{detail}"
- end
- end
-
- end
- end
-
- def host2csrfile(hostname)
- File.join(Puppet[:csrdir], [hostname.downcase, "pem"].join("."))
- end
+ def certfile
+ @config[:cacert]
+ end
- # this stores signed certs in a directory unrelated to
- # normal client certs
- def host2certfile(hostname)
- File.join(Puppet[:signeddir], [hostname.downcase, "pem"].join("."))
- end
-
- # Turn our hostname into a Name object
- def thing2name(thing)
- thing.subject.to_a.find { |ary|
- ary[0] == "CN"
- }[1]
- end
-
- def initialize(hash = {})
- Puppet.settings.use(:main, :ca, :ssl)
- self.setconfig(hash)
-
- if Puppet[:capass]
- if FileTest.exists?(Puppet[:capass])
- #puts "Reading #{Puppet[:capass]}"
- #system "ls -al #{Puppet[:capass]}"
- #File.read Puppet[:capass]
- @config[:password] = self.getpass
- else
- # Don't create a password if the cert already exists
- @config[:password] = self.genpass unless FileTest.exists?(@config[:cacert])
- end
- end
-
- self.getcert
- init_crl
- unless FileTest.exists?(@config[:serial])
- Puppet.settings.write(:serial) do |f|
- f << "%04X" % 1
- end
- end
- end
+ # Remove all traces of a given host. This is kind of hackish, but, eh.
+ def clean(host)
+ host = host.downcase
+ [:csrdir, :signeddir, :publickeydir, :privatekeydir, :certdir].each do |name|
+ dir = Puppet[name]
- # Generate a new password for the CA.
- def genpass
- pass = ""
- 20.times { pass += (rand(74) + 48).chr }
+ file = File.join(dir, host + ".pem")
+ if FileTest.exists?(file)
begin
- Puppet.settings.write(:capass) { |f| f.print pass }
- rescue Errno::EACCES => detail
- raise Puppet::Error, detail.to_s
+ if Puppet[:name] == "cert"
+ puts "Removing #{file}"
+ else
+ Puppet.info "Removing #{file}"
+ end
+ File.unlink(file)
+ rescue => detail
+ raise Puppet::Error, "Could not delete #{file}: #{detail}"
end
- pass
- end
+ end
- # Get the CA password.
- def getpass
- if @config[:capass] and File.readable?(@config[:capass])
- return File.read(@config[:capass])
- else
- raise Puppet::Error, "Could not decrypt CA key with password: #{detail}"
- end
end
-
- # Get the CA cert.
- def getcert
- if FileTest.exists?(@config[:cacert])
- @cert = OpenSSL::X509::Certificate.new(
- File.read(@config[:cacert])
- )
- else
- self.mkrootcert
- end
+ end
+
+ def host2csrfile(hostname)
+ File.join(Puppet[:csrdir], [hostname.downcase, "pem"].join("."))
+ end
+
+ # this stores signed certs in a directory unrelated to
+ # normal client certs
+ def host2certfile(hostname)
+ File.join(Puppet[:signeddir], [hostname.downcase, "pem"].join("."))
+ end
+
+ # Turn our hostname into a Name object
+ def thing2name(thing)
+ thing.subject.to_a.find { |ary|
+ ary[0] == "CN"
+ }[1]
+ end
+
+ def initialize(hash = {})
+ Puppet.settings.use(:main, :ca, :ssl)
+ self.setconfig(hash)
+
+ if Puppet[:capass]
+ if FileTest.exists?(Puppet[:capass])
+ #puts "Reading #{Puppet[:capass]}"
+ #system "ls -al #{Puppet[:capass]}"
+ #File.read Puppet[:capass]
+ @config[:password] = self.getpass
+ else
+ # Don't create a password if the cert already exists
+ @config[:password] = self.genpass unless FileTest.exists?(@config[:cacert])
+ end
end
- # Retrieve a client's CSR.
- def getclientcsr(host)
- csrfile = host2csrfile(host)
- return nil unless File.exists?(csrfile)
-
- OpenSSL::X509::Request.new(File.read(csrfile))
+ self.getcert
+ init_crl
+ unless FileTest.exists?(@config[:serial])
+ Puppet.settings.write(:serial) do |f|
+ f << "%04X" % 1
+ end
end
+ end
- # Retrieve a client's certificate.
- def getclientcert(host)
- certfile = host2certfile(host)
- return [nil, nil] unless File.exists?(certfile)
+ # Generate a new password for the CA.
+ def genpass
+ pass = ""
+ 20.times { pass += (rand(74) + 48).chr }
- [OpenSSL::X509::Certificate.new(File.read(certfile)), @cert]
+ begin
+ Puppet.settings.write(:capass) { |f| f.print pass }
+ rescue Errno::EACCES => detail
+ raise Puppet::Error, detail.to_s
end
-
- # List certificates waiting to be signed. This returns a list of hostnames, not actual
- # files -- the names can be converted to full paths with host2csrfile.
- def list(dummy_argument=:work_arround_for_ruby_GC_bug)
- return Dir.entries(Puppet[:csrdir]).find_all { |file|
- file =~ /\.pem$/
- }.collect { |file|
- file.sub(/\.pem$/, '')
- }
+ pass
+ end
+
+ # Get the CA password.
+ def getpass
+ if @config[:capass] and File.readable?(@config[:capass])
+ return File.read(@config[:capass])
+ else
+ raise Puppet::Error, "Could not decrypt CA key with password: #{detail}"
end
-
- # List signed certificates. This returns a list of hostnames, not actual
- # files -- the names can be converted to full paths with host2csrfile.
- def list_signed(dummy_argument=:work_arround_for_ruby_GC_bug)
- return Dir.entries(Puppet[:signeddir]).find_all { |file|
- file =~ /\.pem$/
- }.collect { |file|
- file.sub(/\.pem$/, '')
- }
+ end
+
+ # Get the CA cert.
+ def getcert
+ if FileTest.exists?(@config[:cacert])
+ @cert = OpenSSL::X509::Certificate.new(
+ File.read(@config[:cacert])
+ )
+ else
+ self.mkrootcert
+ end
+ end
+
+ # Retrieve a client's CSR.
+ def getclientcsr(host)
+ csrfile = host2csrfile(host)
+ return nil unless File.exists?(csrfile)
+
+ OpenSSL::X509::Request.new(File.read(csrfile))
+ end
+
+ # Retrieve a client's certificate.
+ def getclientcert(host)
+ certfile = host2certfile(host)
+ return [nil, nil] unless File.exists?(certfile)
+
+ [OpenSSL::X509::Certificate.new(File.read(certfile)), @cert]
+ end
+
+ # List certificates waiting to be signed. This returns a list of hostnames, not actual
+ # files -- the names can be converted to full paths with host2csrfile.
+ def list(dummy_argument=:work_arround_for_ruby_GC_bug)
+ return Dir.entries(Puppet[:csrdir]).find_all { |file|
+ file =~ /\.pem$/
+ }.collect { |file|
+ file.sub(/\.pem$/, '')
+ }
+ end
+
+ # List signed certificates. This returns a list of hostnames, not actual
+ # files -- the names can be converted to full paths with host2csrfile.
+ def list_signed(dummy_argument=:work_arround_for_ruby_GC_bug)
+ return Dir.entries(Puppet[:signeddir]).find_all { |file|
+ file =~ /\.pem$/
+ }.collect { |file|
+ file.sub(/\.pem$/, '')
+ }
+ end
+
+ # Create the root certificate.
+ def mkrootcert
+ # Make the root cert's name the FQDN of the host running the CA.
+ name = Facter["hostname"].value
+ if domain = Facter["domain"].value
+ name += ".#{domain}"
end
- # Create the root certificate.
- def mkrootcert
- # Make the root cert's name the FQDN of the host running the CA.
- name = Facter["hostname"].value
- if domain = Facter["domain"].value
- name += ".#{domain}"
- end
-
- cert = Certificate.new(
+ cert = Certificate.new(
- :name => name,
- :cert => @config[:cacert],
- :encrypt => @config[:capass],
- :key => @config[:cakey],
- :selfsign => true,
- :ttl => ttl,
+ :name => name,
+ :cert => @config[:cacert],
+ :encrypt => @config[:capass],
+ :key => @config[:cakey],
+ :selfsign => true,
+ :ttl => ttl,
- :type => :ca
- )
+ :type => :ca
+ )
- # This creates the cakey file
- Puppet::Util::SUIDManager.asuser(Puppet[:user], Puppet[:group]) do
- @cert = cert.mkselfsigned
- end
- Puppet.settings.write(:cacert) do |f|
- f.puts @cert.to_pem
- end
- Puppet.settings.write(:capub) do |f|
- f.puts @cert.public_key
- end
- cert
+ # This creates the cakey file
+ Puppet::Util::SUIDManager.asuser(Puppet[:user], Puppet[:group]) do
+ @cert = cert.mkselfsigned
end
-
- def removeclientcsr(host)
- csrfile = host2csrfile(host)
- raise Puppet::Error, "No certificate request for #{host}" unless File.exists?(csrfile)
-
- File.unlink(csrfile)
+ Puppet.settings.write(:cacert) do |f|
+ f.puts @cert.to_pem
end
-
- # Revoke the certificate with serial number SERIAL issued by this
- # CA. The REASON must be one of the OpenSSL::OCSP::REVOKED_* reasons
- def revoke(serial, reason = OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE)
- time = Time.now
- revoked = OpenSSL::X509::Revoked.new
- revoked.serial = serial
- revoked.time = time
- enum = OpenSSL::ASN1::Enumerated(reason)
- ext = OpenSSL::X509::Extension.new("CRLReason", enum)
- revoked.add_extension(ext)
- @crl.add_revoked(revoked)
- store_crl
+ Puppet.settings.write(:capub) do |f|
+ f.puts @cert.public_key
+ end
+ cert
+ end
+
+ def removeclientcsr(host)
+ csrfile = host2csrfile(host)
+ raise Puppet::Error, "No certificate request for #{host}" unless File.exists?(csrfile)
+
+ File.unlink(csrfile)
+ end
+
+ # Revoke the certificate with serial number SERIAL issued by this
+ # CA. The REASON must be one of the OpenSSL::OCSP::REVOKED_* reasons
+ def revoke(serial, reason = OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE)
+ time = Time.now
+ revoked = OpenSSL::X509::Revoked.new
+ revoked.serial = serial
+ revoked.time = time
+ enum = OpenSSL::ASN1::Enumerated(reason)
+ ext = OpenSSL::X509::Extension.new("CRLReason", enum)
+ revoked.add_extension(ext)
+ @crl.add_revoked(revoked)
+ store_crl
+ end
+
+ # Take the Puppet config and store it locally.
+ def setconfig(hash)
+ @config = {}
+ Puppet.settings.params("ca").each { |param|
+ param = param.intern if param.is_a? String
+ if hash.include?(param)
+ @config[param] = hash[param]
+ Puppet[param] = hash[param]
+ hash.delete(param)
+ else
+ @config[param] = Puppet[param]
+ end
+ }
+
+ if hash.include?(:password)
+ @config[:password] = hash[:password]
+ hash.delete(:password)
end
- # Take the Puppet config and store it locally.
- def setconfig(hash)
- @config = {}
- Puppet.settings.params("ca").each { |param|
- param = param.intern if param.is_a? String
- if hash.include?(param)
- @config[param] = hash[param]
- Puppet[param] = hash[param]
- hash.delete(param)
- else
- @config[param] = Puppet[param]
- end
- }
-
- if hash.include?(:password)
- @config[:password] = hash[:password]
- hash.delete(:password)
- end
+ raise ArgumentError, "Unknown parameters #{hash.keys.join(",")}" if hash.length > 0
- raise ArgumentError, "Unknown parameters #{hash.keys.join(",")}" if hash.length > 0
+ [:cadir, :csrdir, :signeddir].each { |dir|
+ raise Puppet::DevError, "#{dir} is undefined" unless @config[dir]
+ }
+ end
- [:cadir, :csrdir, :signeddir].each { |dir|
- raise Puppet::DevError, "#{dir} is undefined" unless @config[dir]
- }
+ # Sign a given certificate request.
+ def sign(csr)
+ unless csr.is_a?(OpenSSL::X509::Request)
+ raise Puppet::Error,
+ "CA#sign only accepts OpenSSL::X509::Request objects, not #{csr.class}"
end
- # Sign a given certificate request.
- def sign(csr)
- unless csr.is_a?(OpenSSL::X509::Request)
- raise Puppet::Error,
- "CA#sign only accepts OpenSSL::X509::Request objects, not #{csr.class}"
- end
-
- raise Puppet::Error, "CSR sign verification failed" unless csr.verify(csr.public_key)
+ raise Puppet::Error, "CSR sign verification failed" unless csr.verify(csr.public_key)
- serial = nil
- Puppet.settings.readwritelock(:serial) { |f|
- serial = File.read(@config[:serial]).chomp.hex
- # increment the serial
- f << "%04X" % (serial + 1)
- }
+ serial = nil
+ Puppet.settings.readwritelock(:serial) { |f|
+ serial = File.read(@config[:serial]).chomp.hex
+ # increment the serial
+ f << "%04X" % (serial + 1)
+ }
- newcert = Puppet::SSLCertificates.mkcert(
+ newcert = Puppet::SSLCertificates.mkcert(
- :type => :server,
- :name => csr.subject,
- :ttl => ttl,
- :issuer => @cert,
- :serial => serial,
+ :type => :server,
+ :name => csr.subject,
+ :ttl => ttl,
+ :issuer => @cert,
+ :serial => serial,
- :publickey => csr.public_key
- )
+ :publickey => csr.public_key
+ )
- sign_with_key(newcert)
+ sign_with_key(newcert)
- self.storeclientcert(newcert)
+ self.storeclientcert(newcert)
- [newcert, @cert]
- end
+ [newcert, @cert]
+ end
- # Store the client's CSR for later signing. This is called from
- # server/ca.rb, and the CSRs are deleted once the certificate is actually
- # signed.
- def storeclientcsr(csr)
- host = thing2name(csr)
+ # Store the client's CSR for later signing. This is called from
+ # server/ca.rb, and the CSRs are deleted once the certificate is actually
+ # signed.
+ def storeclientcsr(csr)
+ host = thing2name(csr)
- csrfile = host2csrfile(host)
- raise Puppet::Error, "Certificate request for #{host} already exists" if File.exists?(csrfile)
+ csrfile = host2csrfile(host)
+ raise Puppet::Error, "Certificate request for #{host} already exists" if File.exists?(csrfile)
- Puppet.settings.writesub(:csrdir, csrfile) do |f|
- f.print csr.to_pem
- end
+ Puppet.settings.writesub(:csrdir, csrfile) do |f|
+ f.print csr.to_pem
end
+ end
- # Store the certificate that we generate.
- def storeclientcert(cert)
- host = thing2name(cert)
+ # Store the certificate that we generate.
+ def storeclientcert(cert)
+ host = thing2name(cert)
- certfile = host2certfile(host)
- Puppet.notice "Overwriting signed certificate #{certfile} for #{host}" if File.exists?(certfile)
+ certfile = host2certfile(host)
+ Puppet.notice "Overwriting signed certificate #{certfile} for #{host}" if File.exists?(certfile)
- Puppet::SSLCertificates::Inventory::add(cert)
- Puppet.settings.writesub(:signeddir, certfile) do |f|
- f.print cert.to_pem
- end
+ Puppet::SSLCertificates::Inventory::add(cert)
+ Puppet.settings.writesub(:signeddir, certfile) do |f|
+ f.print cert.to_pem
end
-
- # TTL for new certificates in seconds. If config param :ca_ttl is set,
- # use that, otherwise use :ca_days for backwards compatibility
- def ttl
- days = @config[:ca_days]
- if days && days.size > 0
- warnonce "Parameter ca_ttl is not set. Using depecated ca_days instead."
- return @config[:ca_days] * 24 * 60 * 60
- else
- ttl = @config[:ca_ttl]
- if ttl.is_a?(String)
- unless ttl =~ /^(\d+)(y|d|h|s)$/
- raise ArgumentError, "Invalid ca_ttl #{ttl}"
- end
- case $2
- when 'y'
- unit = 365 * 24 * 60 * 60
- when 'd'
- unit = 24 * 60 * 60
- when 'h'
- unit = 60 * 60
- when 's'
- unit = 1
- else
- raise ArgumentError, "Invalid unit for ca_ttl #{ttl}"
- end
- return $1.to_i * unit
- else
- return ttl
- end
+ end
+
+ # TTL for new certificates in seconds. If config param :ca_ttl is set,
+ # use that, otherwise use :ca_days for backwards compatibility
+ def ttl
+ days = @config[:ca_days]
+ if days && days.size > 0
+ warnonce "Parameter ca_ttl is not set. Using depecated ca_days instead."
+ return @config[:ca_days] * 24 * 60 * 60
+ else
+ ttl = @config[:ca_ttl]
+ if ttl.is_a?(String)
+ unless ttl =~ /^(\d+)(y|d|h|s)$/
+ raise ArgumentError, "Invalid ca_ttl #{ttl}"
end
- end
-
- private
- def init_crl
- if FileTest.exists?(@config[:cacrl])
- @crl = OpenSSL::X509::CRL.new(
- File.read(@config[:cacrl])
- )
+ case $2
+ when 'y'
+ unit = 365 * 24 * 60 * 60
+ when 'd'
+ unit = 24 * 60 * 60
+ when 'h'
+ unit = 60 * 60
+ when 's'
+ unit = 1
else
- # Create new CRL
- @crl = OpenSSL::X509::CRL.new
- @crl.issuer = @cert.subject
- @crl.version = 1
- store_crl
- @crl
+ raise ArgumentError, "Invalid unit for ca_ttl #{ttl}"
end
+ return $1.to_i * unit
+ else
+ return ttl
+ end
end
-
- def store_crl
- # Increment the crlNumber
- e = @crl.extensions.find { |e| e.oid == 'crlNumber' }
- ext = @crl.extensions.reject { |e| e.oid == 'crlNumber' }
- crlNum = OpenSSL::ASN1::Integer(e ? e.value.to_i + 1 : 0)
- ext << OpenSSL::X509::Extension.new("crlNumber", crlNum)
- @crl.extensions = ext
-
- # Set last/next update
- now = Time.now
- @crl.last_update = now
- # Keep CRL valid for 5 years
- @crl.next_update = now + 5 * 365*24*60*60
-
- sign_with_key(@crl)
- Puppet.settings.write(:cacrl) do |f|
- f.puts @crl.to_pem
- end
+ end
+
+ private
+ def init_crl
+ if FileTest.exists?(@config[:cacrl])
+ @crl = OpenSSL::X509::CRL.new(
+ File.read(@config[:cacrl])
+ )
+ else
+ # Create new CRL
+ @crl = OpenSSL::X509::CRL.new
+ @crl.issuer = @cert.subject
+ @crl.version = 1
+ store_crl
+ @crl
+ end
+ end
+
+ def store_crl
+ # Increment the crlNumber
+ e = @crl.extensions.find { |e| e.oid == 'crlNumber' }
+ ext = @crl.extensions.reject { |e| e.oid == 'crlNumber' }
+ crlNum = OpenSSL::ASN1::Integer(e ? e.value.to_i + 1 : 0)
+ ext << OpenSSL::X509::Extension.new("crlNumber", crlNum)
+ @crl.extensions = ext
+
+ # Set last/next update
+ now = Time.now
+ @crl.last_update = now
+ # Keep CRL valid for 5 years
+ @crl.next_update = now + 5 * 365*24*60*60
+
+ sign_with_key(@crl)
+ Puppet.settings.write(:cacrl) do |f|
+ f.puts @crl.to_pem
+ end
+ end
+
+ def sign_with_key(signable, digest = OpenSSL::Digest::SHA1.new)
+ cakey = nil
+ if @config[:password]
+ begin
+ cakey = OpenSSL::PKey::RSA.new(
+ File.read(@config[:cakey]), @config[:password]
+ )
+ rescue
+ raise Puppet::Error,
+ "Decrypt of CA private key with password stored in @config[:capass] not possible"
+ end
+ else
+ cakey = OpenSSL::PKey::RSA.new(
+ File.read(@config[:cakey])
+ )
end
- def sign_with_key(signable, digest = OpenSSL::Digest::SHA1.new)
- cakey = nil
- if @config[:password]
- begin
- cakey = OpenSSL::PKey::RSA.new(
- File.read(@config[:cakey]), @config[:password]
- )
- rescue
- raise Puppet::Error,
- "Decrypt of CA private key with password stored in @config[:capass] not possible"
- end
- else
- cakey = OpenSSL::PKey::RSA.new(
- File.read(@config[:cakey])
- )
- end
-
- raise Puppet::Error, "CA Certificate is invalid" unless @cert.check_private_key(cakey)
+ raise Puppet::Error, "CA Certificate is invalid" unless @cert.check_private_key(cakey)
- signable.sign(cakey, digest)
- end
+ signable.sign(cakey, digest)
+ end
end
diff --git a/lib/puppet/sslcertificates/certificate.rb b/lib/puppet/sslcertificates/certificate.rb
index a9d1dd4ea..2d30bb09f 100644
--- a/lib/puppet/sslcertificates/certificate.rb
+++ b/lib/puppet/sslcertificates/certificate.rb
@@ -1,148 +1,148 @@
class Puppet::SSLCertificates::Certificate
- SSLCertificates = Puppet::SSLCertificates
-
- attr_accessor :certfile, :keyfile, :name, :dir, :hash, :type
- attr_accessor :key, :cert, :csr, :cacert
-
- @@params2names = {
- :name => "CN",
- :state => "ST",
- :country => "C",
- :email => "emailAddress",
- :org => "O",
- :city => "L",
- :ou => "OU"
+ SSLCertificates = Puppet::SSLCertificates
+
+ attr_accessor :certfile, :keyfile, :name, :dir, :hash, :type
+ attr_accessor :key, :cert, :csr, :cacert
+
+ @@params2names = {
+ :name => "CN",
+ :state => "ST",
+ :country => "C",
+ :email => "emailAddress",
+ :org => "O",
+ :city => "L",
+ :ou => "OU"
+ }
+
+ def certname
+ OpenSSL::X509::Name.new self.subject
+ end
+
+ def delete
+ [@certfile,@keyfile].each { |file|
+ File.unlink(file) if FileTest.exists?(file)
}
- def certname
- OpenSSL::X509::Name.new self.subject
+ if @hash
+ File.unlink(@hash) if FileTest.symlink?(@hash)
end
+ end
- def delete
- [@certfile,@keyfile].each { |file|
- File.unlink(file) if FileTest.exists?(file)
- }
-
- if @hash
- File.unlink(@hash) if FileTest.symlink?(@hash)
- end
- end
+ def exists?
+ FileTest.exists?(@certfile)
+ end
- def exists?
- FileTest.exists?(@certfile)
- end
-
- def getkey
- self.mkkey unless FileTest.exists?(@keyfile)
- if @password
+ def getkey
+ self.mkkey unless FileTest.exists?(@keyfile)
+ if @password
- @key = OpenSSL::PKey::RSA.new(
+ @key = OpenSSL::PKey::RSA.new(
- File.read(@keyfile),
+ File.read(@keyfile),
- @password
- )
- else
- @key = OpenSSL::PKey::RSA.new(
- File.read(@keyfile)
- )
- end
+ @password
+ )
+ else
+ @key = OpenSSL::PKey::RSA.new(
+ File.read(@keyfile)
+ )
end
+ end
- def initialize(hash)
- raise Puppet::Error, "You must specify the common name for the certificate" unless hash.include?(:name)
- @name = hash[:name]
-
- # init a few variables
- @cert = @key = @csr = nil
+ def initialize(hash)
+ raise Puppet::Error, "You must specify the common name for the certificate" unless hash.include?(:name)
+ @name = hash[:name]
- if hash.include?(:cert)
- @certfile = hash[:cert]
- @dir = File.dirname(@certfile)
- else
- @dir = hash[:dir] || Puppet[:certdir]
- @certfile = File.join(@dir, @name)
- end
+ # init a few variables
+ @cert = @key = @csr = nil
- @cacertfile ||= File.join(Puppet[:certdir], "ca.pem")
+ if hash.include?(:cert)
+ @certfile = hash[:cert]
+ @dir = File.dirname(@certfile)
+ else
+ @dir = hash[:dir] || Puppet[:certdir]
+ @certfile = File.join(@dir, @name)
+ end
- Puppet.recmkdir(@dir) unless FileTest.directory?(@dir)
+ @cacertfile ||= File.join(Puppet[:certdir], "ca.pem")
- unless @certfile =~ /\.pem$/
- @certfile += ".pem"
- end
- @keyfile = hash[:key] || File.join(
- Puppet[:privatekeydir], [@name,"pem"].join(".")
- )
- Puppet.recmkdir(@dir) unless FileTest.directory?(@dir)
+ Puppet.recmkdir(@dir) unless FileTest.directory?(@dir)
- [@keyfile].each { |file|
- dir = File.dirname(file)
+ unless @certfile =~ /\.pem$/
+ @certfile += ".pem"
+ end
+ @keyfile = hash[:key] || File.join(
+ Puppet[:privatekeydir], [@name,"pem"].join(".")
+ )
+ Puppet.recmkdir(@dir) unless FileTest.directory?(@dir)
- Puppet.recmkdir(dir) unless FileTest.directory?(dir)
- }
+ [@keyfile].each { |file|
+ dir = File.dirname(file)
- @ttl = hash[:ttl] || 365 * 24 * 60 * 60
- @selfsign = hash[:selfsign] || false
- @encrypt = hash[:encrypt] || false
- @replace = hash[:replace] || false
- @issuer = hash[:issuer] || nil
-
- if hash.include?(:type)
- case hash[:type]
- when :ca, :client, :server; @type = hash[:type]
- else
- raise "Invalid Cert type #{hash[:type]}"
- end
- else
- @type = :client
- end
+ Puppet.recmkdir(dir) unless FileTest.directory?(dir)
+ }
- @params = {:name => @name}
- [:state, :country, :email, :org, :ou].each { |param|
- @params[param] = hash[param] if hash.include?(param)
- }
+ @ttl = hash[:ttl] || 365 * 24 * 60 * 60
+ @selfsign = hash[:selfsign] || false
+ @encrypt = hash[:encrypt] || false
+ @replace = hash[:replace] || false
+ @issuer = hash[:issuer] || nil
+
+ if hash.include?(:type)
+ case hash[:type]
+ when :ca, :client, :server; @type = hash[:type]
+ else
+ raise "Invalid Cert type #{hash[:type]}"
+ end
+ else
+ @type = :client
+ end
- if @encrypt
- if @encrypt =~ /^\//
- File.open(@encrypt) { |f|
- @password = f.read.chomp
- }
- else
- raise Puppet::Error, ":encrypt must be a path to a pass phrase file"
- end
- else
- @password = nil
- end
+ @params = {:name => @name}
+ [:state, :country, :email, :org, :ou].each { |param|
+ @params[param] = hash[param] if hash.include?(param)
+ }
- @selfsign = hash.include?(:selfsign) && hash[:selfsign]
+ if @encrypt
+ if @encrypt =~ /^\//
+ File.open(@encrypt) { |f|
+ @password = f.read.chomp
+ }
+ else
+ raise Puppet::Error, ":encrypt must be a path to a pass phrase file"
+ end
+ else
+ @password = nil
end
- # this only works for servers, not for users
- def mkcsr
- self.getkey unless @key
+ @selfsign = hash.include?(:selfsign) && hash[:selfsign]
+ end
- name = OpenSSL::X509::Name.new self.subject
+ # this only works for servers, not for users
+ def mkcsr
+ self.getkey unless @key
- @csr = OpenSSL::X509::Request.new
- @csr.version = 0
- @csr.subject = name
- @csr.public_key = @key.public_key
- @csr.sign(@key, OpenSSL::Digest::SHA1.new)
+ name = OpenSSL::X509::Name.new self.subject
- #File.open(@csrfile, "w") { |f|
- # f << @csr.to_pem
- #}
+ @csr = OpenSSL::X509::Request.new
+ @csr.version = 0
+ @csr.subject = name
+ @csr.public_key = @key.public_key
+ @csr.sign(@key, OpenSSL::Digest::SHA1.new)
- raise Puppet::Error, "CSR sign verification failed" unless @csr.verify(@key.public_key)
+ #File.open(@csrfile, "w") { |f|
+ # f << @csr.to_pem
+ #}
- @csr
- end
+ raise Puppet::Error, "CSR sign verification failed" unless @csr.verify(@key.public_key)
- def mkkey
- # @key is the file
+ @csr
+ end
- @key = OpenSSL::PKey::RSA.new(1024)
+ def mkkey
+ # @key is the file
+
+ @key = OpenSSL::PKey::RSA.new(1024)
# { |p,n|
# case p
# when 0; Puppet.info "key info: ." # BN_generate_prime
@@ -156,100 +156,100 @@ class Puppet::SSLCertificates::Certificate
# end
# }
- if @password
- # passwdproc = proc { @password }
-
- keytext = @key.export(
+ if @password
+ # passwdproc = proc { @password }
- OpenSSL::Cipher::DES.new(:EDE3, :CBC),
+ keytext = @key.export(
- @password
- )
- File.open(@keyfile, "w", 0400) { |f|
- f << keytext
- }
- else
- File.open(@keyfile, "w", 0400) { |f|
- f << @key.to_pem
- }
- end
+ OpenSSL::Cipher::DES.new(:EDE3, :CBC),
- #cmd = "#{ossl} genrsa -out #{@key} 1024"
+ @password
+ )
+ File.open(@keyfile, "w", 0400) { |f|
+ f << keytext
+ }
+ else
+ File.open(@keyfile, "w", 0400) { |f|
+ f << @key.to_pem
+ }
end
- def mkselfsigned
- self.getkey unless @key
+ #cmd = "#{ossl} genrsa -out #{@key} 1024"
+ end
- raise Puppet::Error, "Cannot replace existing certificate" if @cert
+ def mkselfsigned
+ self.getkey unless @key
- args = {
- :name => self.certname,
- :ttl => @ttl,
- :issuer => nil,
- :serial => 0x0,
- :publickey => @key.public_key
- }
- if @type
- args[:type] = @type
- else
- args[:type] = :server
- end
- @cert = SSLCertificates.mkcert(args)
+ raise Puppet::Error, "Cannot replace existing certificate" if @cert
- @cert.sign(@key, OpenSSL::Digest::SHA1.new) if @selfsign
-
- @cert
+ args = {
+ :name => self.certname,
+ :ttl => @ttl,
+ :issuer => nil,
+ :serial => 0x0,
+ :publickey => @key.public_key
+ }
+ if @type
+ args[:type] = @type
+ else
+ args[:type] = :server
end
+ @cert = SSLCertificates.mkcert(args)
- def subject(string = false)
- subj = @@params2names.collect { |param, name|
- [name, @params[param]] if @params.include?(param)
- }.reject { |ary| ary.nil? }
+ @cert.sign(@key, OpenSSL::Digest::SHA1.new) if @selfsign
- if string
- return "/" + subj.collect { |ary|
- "%s=%s" % ary
- }.join("/") + "/"
- else
- return subj
- end
- end
+ @cert
+ end
- # verify that we can track down the cert chain or whatever
- def verify
- "openssl verify -verbose -CAfile /home/luke/.puppet/ssl/certs/ca.pem -purpose sslserver culain.madstop.com.pem"
+ def subject(string = false)
+ subj = @@params2names.collect { |param, name|
+ [name, @params[param]] if @params.include?(param)
+ }.reject { |ary| ary.nil? }
+
+ if string
+ return "/" + subj.collect { |ary|
+ "%s=%s" % ary
+ }.join("/") + "/"
+ else
+ return subj
end
+ end
- def write
- files = {
- @certfile => @cert,
- @keyfile => @key,
- }
- files[@cacertfile] = @cacert if defined?(@cacert)
+ # verify that we can track down the cert chain or whatever
+ def verify
+ "openssl verify -verbose -CAfile /home/luke/.puppet/ssl/certs/ca.pem -purpose sslserver culain.madstop.com.pem"
+ end
- files.each { |file,thing|
- if thing
- next if FileTest.exists?(file)
+ def write
+ files = {
+ @certfile => @cert,
+ @keyfile => @key,
+ }
+ files[@cacertfile] = @cacert if defined?(@cacert)
- text = nil
+ files.each { |file,thing|
+ if thing
+ next if FileTest.exists?(file)
- if thing.is_a?(OpenSSL::PKey::RSA) and @password
+ text = nil
- text = thing.export(
+ if thing.is_a?(OpenSSL::PKey::RSA) and @password
- OpenSSL::Cipher::DES.new(:EDE3, :CBC),
+ text = thing.export(
- @password
- )
- else
- text = thing.to_pem
- end
+ OpenSSL::Cipher::DES.new(:EDE3, :CBC),
- File.open(file, "w", 0660) { |f| f.print text }
- end
- }
+ @password
+ )
+ else
+ text = thing.to_pem
+ end
- SSLCertificates.mkhash(Puppet[:certdir], @cacert, @cacertfile) if defined?(@cacert)
- end
+ File.open(file, "w", 0660) { |f| f.print text }
+ end
+ }
+
+ SSLCertificates.mkhash(Puppet[:certdir], @cacert, @cacertfile) if defined?(@cacert)
+ end
end
diff --git a/lib/puppet/sslcertificates/inventory.rb b/lib/puppet/sslcertificates/inventory.rb
index c3f79ee6c..1075c1377 100644
--- a/lib/puppet/sslcertificates/inventory.rb
+++ b/lib/puppet/sslcertificates/inventory.rb
@@ -1,38 +1,38 @@
# A module for keeping track of all the certificates issued by the CA, ever
# Maintains the file "$cadir/inventory.txt"
module Puppet::SSLCertificates
- module Inventory
+ module Inventory
- # Add CERT to the inventory of issued certs in '$cadir/inventory.txt'
- # If no inventory exists yet, build an inventory and list all the
- # certificates that have been signed so far
- def self.add(cert)
- inited = false
- inited = true if FileTest.exists?(Puppet[:cert_inventory])
+ # Add CERT to the inventory of issued certs in '$cadir/inventory.txt'
+ # If no inventory exists yet, build an inventory and list all the
+ # certificates that have been signed so far
+ def self.add(cert)
+ inited = false
+ inited = true if FileTest.exists?(Puppet[:cert_inventory])
- Puppet.settings.write(:cert_inventory, "a") do |f|
- f.puts((inited ? nil : self.init).to_s + format(cert))
- end
- end
+ Puppet.settings.write(:cert_inventory, "a") do |f|
+ f.puts((inited ? nil : self.init).to_s + format(cert))
+ end
+ end
- private
+ private
- def self.init
- inv = "# Inventory of signed certificates\n"
- inv += "# SERIAL NOT_BEFORE NOT_AFTER SUBJECT\n"
- Dir.glob(File::join(Puppet[:signeddir], "*.pem")) do |f|
- inv += format(OpenSSL::X509::Certificate.new(File::read(f))) + "\n"
- end
- inv
- end
+ def self.init
+ inv = "# Inventory of signed certificates\n"
+ inv += "# SERIAL NOT_BEFORE NOT_AFTER SUBJECT\n"
+ Dir.glob(File::join(Puppet[:signeddir], "*.pem")) do |f|
+ inv += format(OpenSSL::X509::Certificate.new(File::read(f))) + "\n"
+ end
+ inv
+ end
- def self.format(cert)
- iso = '%Y-%m-%dT%H:%M:%S%Z'
- return "0x%04x %s %s %s" % [cert.serial,
- cert.not_before.strftime(iso),
- cert.not_after.strftime(iso),
- cert.subject]
- end
+ def self.format(cert)
+ iso = '%Y-%m-%dT%H:%M:%S%Z'
+ return "0x%04x %s %s %s" % [cert.serial,
+ cert.not_before.strftime(iso),
+ cert.not_after.strftime(iso),
+ cert.subject]
end
+ end
end
diff --git a/lib/puppet/sslcertificates/support.rb b/lib/puppet/sslcertificates/support.rb
index 919d68664..7d6708124 100644
--- a/lib/puppet/sslcertificates/support.rb
+++ b/lib/puppet/sslcertificates/support.rb
@@ -2,145 +2,145 @@ require 'puppet/sslcertificates'
# A module to handle reading of certificates.
module Puppet::SSLCertificates::Support
- class MissingCertificate < Puppet::Error; end
- class InvalidCertificate < Puppet::Error; end
+ class MissingCertificate < Puppet::Error; end
+ class InvalidCertificate < Puppet::Error; end
- attr_reader :cacert
+ attr_reader :cacert
- # Some metaprogramming to create methods for retrieving and creating keys.
- # This probably isn't fewer lines than defining each separately...
- def self.keytype(name, options, &block)
- var = "@#{name}"
+ # Some metaprogramming to create methods for retrieving and creating keys.
+ # This probably isn't fewer lines than defining each separately...
+ def self.keytype(name, options, &block)
+ var = "@#{name}"
- maker = "mk_#{name}"
- reader = "read_#{name}"
+ maker = "mk_#{name}"
+ reader = "read_#{name}"
- unless param = options[:param]
- raise ArgumentError, "You must specify the parameter for the key"
- end
-
- unless klass = options[:class]
- raise ArgumentError, "You must specify the class for the key"
- end
+ unless param = options[:param]
+ raise ArgumentError, "You must specify the parameter for the key"
+ end
- # Define the method that creates it.
- define_method(maker, &block)
+ unless klass = options[:class]
+ raise ArgumentError, "You must specify the class for the key"
+ end
- # Define the reading method.
- define_method(reader) do
- return nil unless FileTest.exists?(Puppet[param]) or rename_files_with_uppercase(Puppet[param])
+ # Define the method that creates it.
+ define_method(maker, &block)
- begin
- instance_variable_set(var, klass.new(File.read(Puppet[param])))
- rescue => detail
- raise InvalidCertificate, "Could not read #{param}: #{detail}"
- end
- end
+ # Define the reading method.
+ define_method(reader) do
+ return nil unless FileTest.exists?(Puppet[param]) or rename_files_with_uppercase(Puppet[param])
- # Define the overall method, which just calls the reader and maker
- # as appropriate.
- define_method(name) do
- unless cert = instance_variable_get(var)
- unless cert = send(reader)
- cert = send(maker)
- Puppet.settings.write(param) { |f| f.puts cert.to_pem }
- end
- instance_variable_set(var, cert)
- end
- cert
- end
+ begin
+ instance_variable_set(var, klass.new(File.read(Puppet[param])))
+ rescue => detail
+ raise InvalidCertificate, "Could not read #{param}: #{detail}"
+ end
end
- # The key pair.
- keytype :key, :param => :hostprivkey, :class => OpenSSL::PKey::RSA do
- Puppet.info "Creating a new SSL key at #{Puppet[:hostprivkey]}"
- key = OpenSSL::PKey::RSA.new(Puppet[:keylength])
-
- # Our key meta programming can only handle one file, so we have
- # to separately write out the public key.
- Puppet.settings.write(:hostpubkey) do |f|
- f.print key.public_key.to_pem
+ # Define the overall method, which just calls the reader and maker
+ # as appropriate.
+ define_method(name) do
+ unless cert = instance_variable_get(var)
+ unless cert = send(reader)
+ cert = send(maker)
+ Puppet.settings.write(param) { |f| f.puts cert.to_pem }
end
- return key
+ instance_variable_set(var, cert)
+ end
+ cert
end
+ end
- # Our certificate request
- keytype :csr, :param => :hostcsr, :class => OpenSSL::X509::Request do
- Puppet.info "Creating a new certificate request for #{Puppet[:certname]}"
+ # The key pair.
+ keytype :key, :param => :hostprivkey, :class => OpenSSL::PKey::RSA do
+ Puppet.info "Creating a new SSL key at #{Puppet[:hostprivkey]}"
+ key = OpenSSL::PKey::RSA.new(Puppet[:keylength])
- csr = OpenSSL::X509::Request.new
- csr.version = 0
- csr.subject = OpenSSL::X509::Name.new([["CN", Puppet[:certname]]])
- csr.public_key = key.public_key
- csr.sign(key, OpenSSL::Digest::MD5.new)
-
- return csr
+ # Our key meta programming can only handle one file, so we have
+ # to separately write out the public key.
+ Puppet.settings.write(:hostpubkey) do |f|
+ f.print key.public_key.to_pem
end
-
- keytype :cert, :param => :hostcert, :class => OpenSSL::X509::Certificate do
- raise MissingCertificate, "No host certificate"
+ return key
+ end
+
+ # Our certificate request
+ keytype :csr, :param => :hostcsr, :class => OpenSSL::X509::Request do
+ Puppet.info "Creating a new certificate request for #{Puppet[:certname]}"
+
+ csr = OpenSSL::X509::Request.new
+ csr.version = 0
+ csr.subject = OpenSSL::X509::Name.new([["CN", Puppet[:certname]]])
+ csr.public_key = key.public_key
+ csr.sign(key, OpenSSL::Digest::MD5.new)
+
+ return csr
+ end
+
+ keytype :cert, :param => :hostcert, :class => OpenSSL::X509::Certificate do
+ raise MissingCertificate, "No host certificate"
+ end
+
+ keytype :ca_cert, :param => :localcacert, :class => OpenSSL::X509::Certificate do
+ raise MissingCertificate, "No CA certificate"
+ end
+
+ # Request a certificate from the remote system. This does all of the work
+ # of creating the cert request, contacting the remote system, and
+ # storing the cert locally.
+ def requestcert
+ begin
+ cert, cacert = caclient.getcert(@csr.to_pem)
+ rescue => detail
+ puts detail.backtrace if Puppet[:trace]
+ raise Puppet::Error.new("Certificate retrieval failed: #{detail}")
end
- keytype :ca_cert, :param => :localcacert, :class => OpenSSL::X509::Certificate do
- raise MissingCertificate, "No CA certificate"
+ if cert.nil? or cert == ""
+ return nil
end
-
- # Request a certificate from the remote system. This does all of the work
- # of creating the cert request, contacting the remote system, and
- # storing the cert locally.
- def requestcert
- begin
- cert, cacert = caclient.getcert(@csr.to_pem)
- rescue => detail
- puts detail.backtrace if Puppet[:trace]
- raise Puppet::Error.new("Certificate retrieval failed: #{detail}")
- end
-
- if cert.nil? or cert == ""
- return nil
- end
- Puppet.settings.write(:hostcert) do |f| f.print cert end
- Puppet.settings.write(:localcacert) do |f| f.print cacert end
- #File.open(@certfile, "w", 0644) { |f| f.print cert }
- #File.open(@cacertfile, "w", 0644) { |f| f.print cacert }
- begin
- @cert = OpenSSL::X509::Certificate.new(cert)
- @cacert = OpenSSL::X509::Certificate.new(cacert)
- retrieved = true
- rescue => detail
- raise Puppet::Error.new(
- "Invalid certificate: #{detail}"
- )
- end
-
- raise Puppet::DevError, "Received invalid certificate" unless @cert.check_private_key(@key)
- retrieved
+ Puppet.settings.write(:hostcert) do |f| f.print cert end
+ Puppet.settings.write(:localcacert) do |f| f.print cacert end
+ #File.open(@certfile, "w", 0644) { |f| f.print cert }
+ #File.open(@cacertfile, "w", 0644) { |f| f.print cacert }
+ begin
+ @cert = OpenSSL::X509::Certificate.new(cert)
+ @cacert = OpenSSL::X509::Certificate.new(cacert)
+ retrieved = true
+ rescue => detail
+ raise Puppet::Error.new(
+ "Invalid certificate: #{detail}"
+ )
end
- # A hack method to deal with files that exist with a different case.
- # Just renames it; doesn't read it in or anything.
- def rename_files_with_uppercase(file)
- dir = File.dirname(file)
- short = File.basename(file)
+ raise Puppet::DevError, "Received invalid certificate" unless @cert.check_private_key(@key)
+ retrieved
+ end
- # If the dir isn't present, we clearly don't have the file.
- #return nil unless FileTest.directory?(dir)
+ # A hack method to deal with files that exist with a different case.
+ # Just renames it; doesn't read it in or anything.
+ def rename_files_with_uppercase(file)
+ dir = File.dirname(file)
+ short = File.basename(file)
- raise ArgumentError, "Tried to fix SSL files to a file containing uppercase" unless short.downcase == short
+ # If the dir isn't present, we clearly don't have the file.
+ #return nil unless FileTest.directory?(dir)
- return false unless File.directory?(dir)
+ raise ArgumentError, "Tried to fix SSL files to a file containing uppercase" unless short.downcase == short
- real_file = Dir.entries(dir).reject { |f| f =~ /^\./ }.find do |other|
- other.downcase == short
- end
+ return false unless File.directory?(dir)
- return nil unless real_file
+ real_file = Dir.entries(dir).reject { |f| f =~ /^\./ }.find do |other|
+ other.downcase == short
+ end
- full_file = File.join(dir, real_file)
+ return nil unless real_file
- Puppet.notice "Fixing case in #{full_file}; renaming to #{file}"
- File.rename(full_file, file)
+ full_file = File.join(dir, real_file)
- true
- end
+ Puppet.notice "Fixing case in #{full_file}; renaming to #{file}"
+ File.rename(full_file, file)
+
+ true
+ end
end