diff options
author | Brice Figureau <brice-puppet@daysofwonder.com> | 2009-12-28 19:41:24 +0100 |
---|---|---|
committer | James Turnbull <james@lovedthanlost.net> | 2010-01-18 23:17:21 +1100 |
commit | a9fb82b0026e75a670fec553b17de3b0f091c2a5 (patch) | |
tree | 26ef68872617a636115ff10dea90e1f71d776a88 /lib/puppet | |
parent | a967b93a51ce509cf8631d78b8be8d4ab6da5657 (diff) | |
download | puppet-a9fb82b0026e75a670fec553b17de3b0f091c2a5.tar.gz puppet-a9fb82b0026e75a670fec553b17de3b0f091c2a5.tar.xz puppet-a9fb82b0026e75a670fec553b17de3b0f091c2a5.zip |
Feature #2839 - fingerprint certificate
This patch adds two things:
* certificate fingerprinting in --list mode
* a puppetca action called "--fingerprint" to display fingerprints
of given certificates
It is also possible to use --digest to specify a specific digest
algorithm.
Signed-off-by: Brice Figureau <brice-puppet@daysofwonder.com>
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/application/puppetca.rb | 8 | ||||
-rw-r--r-- | lib/puppet/ssl/certificate_authority.rb | 23 | ||||
-rw-r--r-- | lib/puppet/ssl/certificate_authority/interface.rb | 24 |
3 files changed, 46 insertions, 9 deletions
diff --git a/lib/puppet/application/puppetca.rb b/lib/puppet/application/puppetca.rb index adc1a6ff5..6ef867762 100644 --- a/lib/puppet/application/puppetca.rb +++ b/lib/puppet/application/puppetca.rb @@ -6,7 +6,7 @@ Puppet::Application.new(:puppetca) do should_parse_config - attr_accessor :mode, :all, :ca + attr_accessor :mode, :all, :ca, :digest def find_mode(opt) modes = Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS @@ -22,6 +22,10 @@ Puppet::Application.new(:puppetca) do @all = true end + option("--digest DIGEST", "-d") do |arg| + @digest = arg + end + option("--debug", "-d") do |arg| Puppet::Util::Log.level = :debug end @@ -44,7 +48,7 @@ Puppet::Application.new(:puppetca) do end begin @ca.apply(:revoke, :to => hosts) if @mode == :destroy - @ca.apply(@mode, :to => hosts) + @ca.apply(@mode, :to => hosts, :digest => @digest) rescue => detail puts detail.backtrace if Puppet[:trace] puts detail.to_s diff --git a/lib/puppet/ssl/certificate_authority.rb b/lib/puppet/ssl/certificate_authority.rb index 8e4fd7a08..f2213707d 100644 --- a/lib/puppet/ssl/certificate_authority.rb +++ b/lib/puppet/ssl/certificate_authority.rb @@ -53,7 +53,7 @@ class Puppet::SSL::CertificateAuthority unless options[:to] raise ArgumentError, "You must specify the hosts to apply to; valid values are an array or the symbol :all" end - applier = Interface.new(method, options[:to]) + applier = Interface.new(method, options) applier.apply(self) end @@ -291,6 +291,27 @@ class Puppet::SSL::CertificateAuthority end end + def fingerprint(name, md = :MD5) + unless cert = Puppet::SSL::Certificate.find(name) + raise ArgumentError, "Could not find a certificate for %s" % name + end + + require 'openssl/digest' + + # ruby 1.8.x openssl digest constants are string + # but in 1.9.x they are symbols + mds = md.to_s.upcase + if OpenSSL::Digest.constants.include?(mds) + md = mds + elsif OpenSSL::Digest.constants.include?(mds.to_sym) + md = mds.to_sym + else + raise ArgumentError, "#{md} is not a valid digest algorithm for fingerprinting certificate #{name}" + end + + OpenSSL::Digest.hexdigest(md, cert.content.to_der).scan(/../).join(':').upcase + end + # List the waiting certificate requests. def waiting? Puppet::SSL::CertificateRequest.search("*").collect { |r| r.name } diff --git a/lib/puppet/ssl/certificate_authority/interface.rb b/lib/puppet/ssl/certificate_authority/interface.rb index 3f91434e3..0023808f2 100644 --- a/lib/puppet/ssl/certificate_authority/interface.rb +++ b/lib/puppet/ssl/certificate_authority/interface.rb @@ -2,11 +2,11 @@ # on the CA. It's only used by the 'puppetca' executable, and its # job is to provide a CLI-like interface to the CA class. class Puppet::SSL::CertificateAuthority::Interface - INTERFACE_METHODS = [:destroy, :list, :revoke, :generate, :sign, :print, :verify] + INTERFACE_METHODS = [:destroy, :list, :revoke, :generate, :sign, :print, :verify, :fingerprint] class InterfaceError < ArgumentError; end - attr_reader :method, :subjects + attr_reader :method, :subjects, :digest # Actually perform the work. def apply(ca) @@ -38,9 +38,10 @@ class Puppet::SSL::CertificateAuthority::Interface end end - def initialize(method, subjects) + def initialize(method, options) self.method = method - self.subjects = subjects + self.subjects = options[:to] + @digest = options[:digest] || :MD5 end # List the hosts. @@ -67,9 +68,9 @@ class Puppet::SSL::CertificateAuthority::Interface invalid = details.to_s end if not invalid and signed.include?(host) - puts "+ " + host + puts "+ #{host} (#{ca.fingerprint(host, @digest)})" elsif invalid - puts "- " + host + " (" + invalid + ")" + puts "- #{host} (#{ca.fingerprint(host, @digest)}) (#{invalid})" else puts host end @@ -93,6 +94,17 @@ class Puppet::SSL::CertificateAuthority::Interface end end + # Print certificate information. + def fingerprint(ca) + (subjects == :all ? ca.list : subjects).each do |host| + if value = ca.fingerprint(host, @digest) + puts "#{host} #{value}" + else + Puppet.err "Could not find certificate for %s" % host + end + end + end + # Sign a given certificate. def sign(ca) list = subjects == :all ? ca.waiting? : subjects |