summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-12-27 17:18:35 +0000
committerluke <luke@980ebf18-57e1-0310-9a29-db15c13687c0>2006-12-27 17:18:35 +0000
commit8ff7e0c75eda0291a169074c67fa0a90db9c4e7b (patch)
tree412ef1e461736028c982176dbec377e5016a80c5
parentf1dc103396511d30aa8ae42036b6aa1aee712da3 (diff)
downloadpuppet-8ff7e0c75eda0291a169074c67fa0a90db9c4e7b.tar.gz
puppet-8ff7e0c75eda0291a169074c67fa0a90db9c4e7b.tar.xz
puppet-8ff7e0c75eda0291a169074c67fa0a90db9c4e7b.zip
Closing #362. Case-insensitivity is handled by downcasing all host names.
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@1971 980ebf18-57e1-0310-9a29-db15c13687c0
-rwxr-xr-xbin/puppetca23
-rw-r--r--lib/puppet/sslcertificates/ca.rb106
-rwxr-xr-xtest/certmgr/ca.rb72
-rwxr-xr-xtest/certmgr/certmgr.rb9
-rwxr-xr-xtest/executables/puppetca.rb92
5 files changed, 185 insertions, 117 deletions
diff --git a/bin/puppetca b/bin/puppetca
index 599ce58b4..92290c694 100755
--- a/bin/puppetca
+++ b/bin/puppetca
@@ -167,11 +167,11 @@ unless mode
exit(12)
end
-if mode == :generate or mode == :clean or mode == :revoke
- hosts = ARGV
+if [:generate, :clean, :revoke].include?(mode)
+ hosts = ARGV.collect { |h| h.downcase }
else
- hosts = ca.list
- unless hosts.length > 0
+ waiting = ca.list
+ unless waiting.length > 0
puts "No certificates to sign"
if ARGV.length > 0
exit(17)
@@ -179,11 +179,12 @@ else
exit(0)
end
end
+ to_sign = ARGV.collect { |h| h.downcase }
end
case mode
when :list
- puts hosts.join("\n")
+ puts waiting.join("\n")
when :clean
if hosts.empty?
$stderr.puts "You must specify one or more hosts to clean"
@@ -193,7 +194,7 @@ when :clean
ca.clean(host)
end
when :sign
- unless ARGV.length > 0 or all
+ unless to_sign.length > 0 or all
$stderr.puts(
"You must specify to sign all certificates or you must specify hostnames"
)
@@ -201,17 +202,17 @@ when :sign
end
unless all
- ARGV.each { |host|
- unless hosts.include?(host)
+ to_sign.each { |host|
+ unless waiting.include?(host)
$stderr.puts "No waiting request for %s" % host
end
}
- hosts = hosts.find_all { |host|
- ARGV.include?(host)
+ waiting = waiting.find_all { |host|
+ to_sign.include?(host)
}
end
- hosts.each { |host|
+ waiting.each { |host|
begin
csr = ca.getclientcsr(host)
rescue => detail
diff --git a/lib/puppet/sslcertificates/ca.rb b/lib/puppet/sslcertificates/ca.rb
index 19ea27228..572abafd7 100644
--- a/lib/puppet/sslcertificates/ca.rb
+++ b/lib/puppet/sslcertificates/ca.rb
@@ -85,40 +85,9 @@ class Puppet::SSLCertificates::CA
@config[:cacert]
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
- 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]
@@ -142,13 +111,13 @@ class Puppet::SSLCertificates::CA
end
def host2csrfile(hostname)
- File.join(Puppet[:csrdir], [hostname, "pem"].join("."))
+ 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, "pem"].join("."))
+ File.join(Puppet[:signeddir], [hostname.downcase, "pem"].join("."))
end
# Turn our hostname into a Name object
@@ -238,7 +207,8 @@ class Puppet::SSLCertificates::CA
return [OpenSSL::X509::Certificate.new(File.read(certfile)), @cert]
end
- # List certificates waiting to be signed.
+ # 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
return Dir.entries(Puppet[:csrdir]).find_all { |file|
file =~ /\.pem$/
@@ -283,6 +253,23 @@ class Puppet::SSLCertificates::CA
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)
+ if @config[:cacrl] == 'none'
+ raise Puppet::Error, "Revocation requires a CRL, but ca_crl is set to 'none'"
+ end
+ 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 = {}
@@ -363,23 +350,6 @@ class Puppet::SSLCertificates::CA
end
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)
- if @config[:cacrl] == 'none'
- raise Puppet::Error, "Revocation requires a CRL, but ca_crl is set to 'none'"
- end
- 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
-
# Store the certificate that we generate.
def storeclientcert(cert)
host = thing2name(cert)
@@ -396,6 +366,38 @@ class Puppet::SSLCertificates::CA
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
+ 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
+ end
+
private
def init_crl
if FileTest.exists?(@config[:cacrl])
diff --git a/test/certmgr/ca.rb b/test/certmgr/ca.rb
new file mode 100755
index 000000000..d01725970
--- /dev/null
+++ b/test/certmgr/ca.rb
@@ -0,0 +1,72 @@
+#!/usr/bin/env ruby
+
+$:.unshift("../lib").unshift("../../lib") if __FILE__ =~ /\.rb$/
+
+require 'puppet'
+require 'puppet/sslcertificates/ca.rb'
+require 'puppettest'
+require 'puppettest/certificates'
+
+class TestCA < Test::Unit::TestCase
+ include PuppetTest
+ def hosts
+ %w{host.domain.com Other.Testing.Com}
+ end
+ def mkca
+ Puppet::SSLCertificates::CA.new
+ end
+
+ def test_clean
+ dirs = [:csrdir, :signeddir, :publickeydir, :privatekeydir, :certdir]
+ ca = mkca
+
+ hosts.each do |host|
+ files = []
+ dirs.each do |dir|
+ dir = Puppet[dir]
+ # We handle case insensitivity through downcasing
+ file = File.join(dir, host.downcase + ".pem")
+ File.open(file, "w") do |f|
+ f.puts "testing"
+ end
+ files << file
+ end
+ assert_nothing_raised do
+ ca.clean(host)
+ end
+ files.each do |f|
+ assert(! FileTest.exists?(f), "File %s was not deleted" % f)
+ end
+ end
+ end
+
+ def test_host2Xfile
+ ca = mkca
+ hosts.each do |host|
+ {:signeddir => :host2certfile, :csrdir => :host2csrfile}.each do |dir, method|
+ val = nil
+ assert_nothing_raised do
+ val = ca.send(method, host)
+ end
+ assert_equal(File.join(Puppet[dir], host.downcase + ".pem"), val,
+ "incorrect response from %s" % method)
+ end
+ end
+ end
+
+ def test_list
+ ca = mkca
+ # Make a fake csr
+ dir = Puppet[:csrdir]
+ list = []
+ hosts.each do |host|
+ file = File.join(dir, host.downcase + ".pem")
+ File.open(file, "w") { |f| f.puts "yay" }
+ list << host.downcase
+ end
+
+ assert_equal(list.sort, ca.list.sort, "list was not correct")
+ end
+end
+
+# $Id$
diff --git a/test/certmgr/certmgr.rb b/test/certmgr/certmgr.rb
index 32934e8ce..90d516cb4 100755
--- a/test/certmgr/certmgr.rb
+++ b/test/certmgr/certmgr.rb
@@ -7,15 +7,6 @@ require 'puppet/sslcertificates.rb'
require 'puppettest'
require 'puppettest/certificates'
-# so, what kind of things do we want to test?
-
-# we don't need to test function, since we're confident in the
-# library tests. We do, however, need to test how things are actually
-# working in the language.
-
-# so really, we want to do things like test that our ast is correct
-# and test whether we've got things in the right scopes
-
class TestCertMgr < Test::Unit::TestCase
include PuppetTest::Certificates
def setup
diff --git a/test/executables/puppetca.rb b/test/executables/puppetca.rb
index f96e7a5f5..2eafb7f6c 100755
--- a/test/executables/puppetca.rb
+++ b/test/executables/puppetca.rb
@@ -9,6 +9,16 @@ require 'puppettest'
class TestPuppetCA < Test::Unit::TestCase
include PuppetTest::ExeTest
+
+ def gen_cert(ca, host)
+ runca("-g #{host}")
+ ca.getclientcert(host)[0]
+ end
+
+ def mkca
+ Puppet::Server::CA.new()
+ end
+
def mkcert(hostname)
cert = nil
assert_nothing_raised {
@@ -27,59 +37,53 @@ class TestPuppetCA < Test::Unit::TestCase
debug = "-d "
end
return %x{puppetca --user=#{Puppet[:user]} #{debug} --group=#{Puppet[:group]} --confdir=#{Puppet[:confdir]} --vardir=#{Puppet[:vardir]} #{args} 2>&1}
-
end
def test_signing
- ca = nil
+ ca = mkca
Puppet[:autosign] = false
- assert_nothing_raised {
- ca = Puppet::Server::CA.new()
- }
- #Puppet.warning "SSLDir is %s" % Puppet[:confdir]
- #system("find %s" % Puppet[:confdir])
+
+ %w{host.test.com Other.Testing.Com}.each do |host|
+ cert = mkcert(host)
+ resp = nil
+ assert_nothing_raised {
+ # We need to use a fake name so it doesn't think the cert is from
+ # itself. Strangely, getcert stores the csr, because it's a server-side
+ # method, not client.
+ resp = ca.getcert(cert.csr.to_pem, host, "127.0.0.1")
+ }
+ assert_equal(["",""], resp)
- cert = mkcert("host.test.com")
- resp = nil
- assert_nothing_raised {
- # We need to use a fake name so it doesn't think the cert is from
- # itself.
- resp = ca.getcert(cert.csr.to_pem, "fakename", "127.0.0.1")
- }
- assert_equal(["",""], resp)
- #Puppet.warning "SSLDir is %s" % Puppet[:confdir]
- #system("find %s" % Puppet[:confdir])
-
- output = nil
- assert_nothing_raised {
- output = runca("--list").chomp.split("\n").reject { |line| line =~ /warning:/ } # stupid ssl.rb
- }
- #Puppet.warning "SSLDir is %s" % Puppet[:confdir]
- #system("find %s" % Puppet[:confdir])
- assert_equal($?,0)
- assert_equal(%w{host.test.com}, output)
- assert_nothing_raised {
- output = runca("--sign -a").chomp.split("\n")
- }
+ output = nil
+ assert_nothing_raised {
+ output = runca("--list").chomp.split("\n").reject { |line| line =~ /warning:/ } # stupid ssl.rb
+ }
+ assert_equal($?,0)
+ assert_equal([host.downcase], output)
+ assert_nothing_raised {
+ output = runca("--sign -a").chomp.split("\n")
+ }
- assert_equal($?,0)
- assert_equal(["Signed host.test.com"], output)
+ assert_equal($?,0)
+ assert_equal(["Signed #{host.downcase}"], output)
- signedfile = File.join(Puppet[:signeddir], "host.test.com.pem")
- assert(FileTest.exists?(signedfile), "cert does not exist")
- assert(! FileTest.executable?(signedfile), "cert is executable")
+
+ signedfile = ca.ca.host2certfile(host)
+ assert(FileTest.exists?(signedfile), "cert does not exist")
+ assert(! FileTest.executable?(signedfile), "cert is executable")
- uid = Puppet::Util.uid(Puppet[:user])
+ uid = Puppet::Util.uid(Puppet[:user])
- if Puppet::SUIDManager.uid == 0
- assert(! FileTest.owned?(signedfile), "cert is owned by root")
+ if Puppet::SUIDManager.uid == 0
+ assert(! FileTest.owned?(signedfile), "cert is owned by root")
+ end
+ assert_nothing_raised {
+ output = runca("--list").chomp.split("\n")
+ }
+ assert_equal($?,0)
+ assert_equal(["No certificates to sign"], output)
end
- assert_nothing_raised {
- output = runca("--list").chomp.split("\n")
- }
- assert_equal($?,0)
- assert_equal(["No certificates to sign"], output)
end
# This method takes a long time to run because of all of the external
@@ -102,9 +106,7 @@ class TestPuppetCA < Test::Unit::TestCase
assert_equal(exp, revoked)
end
- def gen_cert(ca, host)
- runca("-g #{host}")
- ca.getclientcert(host)[0]
+ def test_case_insensitive_sign
end
end