summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-05-06 16:45:29 -0500
committerLuke Kanies <luke@madstop.com>2008-05-06 16:45:29 -0500
commitd78b4ba48a0fdf63906fb0ede2cd8c2e634ef442 (patch)
tree1ec6c902ab64b7b575c0ac192ea470d9116efd17
parenta822ef9ce5c6d603f4a98b9dda0dbf4661528128 (diff)
downloadpuppet-d78b4ba48a0fdf63906fb0ede2cd8c2e634ef442.tar.gz
puppet-d78b4ba48a0fdf63906fb0ede2cd8c2e634ef442.tar.xz
puppet-d78b4ba48a0fdf63906fb0ede2cd8c2e634ef442.zip
Adding autosigning to the new CA.
Now the CSR class triggers autosigning when any CSR is saved, if it's running on a CA host.
-rw-r--r--lib/puppet/ssl/certificate_authority.rb53
-rw-r--r--lib/puppet/ssl/certificate_request.rb9
-rwxr-xr-xspec/unit/ssl/certificate_authority.rb88
-rwxr-xr-xspec/unit/ssl/certificate_request.rb25
4 files changed, 142 insertions, 33 deletions
diff --git a/lib/puppet/ssl/certificate_authority.rb b/lib/puppet/ssl/certificate_authority.rb
index 9385110d2..0329f5354 100644
--- a/lib/puppet/ssl/certificate_authority.rb
+++ b/lib/puppet/ssl/certificate_authority.rb
@@ -42,37 +42,44 @@ class Puppet::SSL::CertificateAuthority
applier.apply(self)
end
- # FIXME autosign? should probably accept both hostnames and IP addresses
- def autosign?(hostname)
- # simple values are easy
- if autosign == true or autosign == false
- return autosign
+ # If autosign is configured, then autosign all CSRs that match our configuration.
+ def autosign
+ return unless auto = autosign?
+
+ store = nil
+ if auto != true
+ store = autosign_store(auto)
end
- # we only otherwise know how to handle files
- unless autosign =~ /^\//
- raise Puppet::Error, "Invalid autosign value %s" %
- autosign.inspect
+ Puppet::SSL::CertificateRequest.search("*").each do |csr|
+ sign(csr.name) if auto == true or store.allowed?(csr.name, "127.1.1.1")
end
+ end
- unless FileTest.exists?(autosign)
- unless defined? @@warnedonautosign
- @@warnedonautosign = true
- Puppet.info "Autosign is enabled but %s is missing" % autosign
- end
+ # Do we autosign? This returns true, false, or a filename.
+ def autosign?
+ auto = Puppet[:autosign]
+ return false if ['false', false].include?(auto)
+ return true if ['true', true].include?(auto)
+
+ raise ArgumentError, "The autosign configuration '%s' must be a fully qualified file" % auto unless auto =~ /^\//
+ if FileTest.exist?(auto)
+ return auto
+ else
return false
end
+ end
+
+ # Create an AuthStore for autosigning.
+ def autosign_store(file)
auth = Puppet::Network::AuthStore.new
- File.open(autosign) { |f|
- f.each { |line|
- next if line =~ /^\s*#/
- next if line =~ /^\s*$/
- auth.allow(line.chomp)
- }
- }
+ File.readlines(file).each do |line|
+ next if line =~ /^\s*#/
+ next if line =~ /^\s*$/
+ auth.allow(line.chomp)
+ end
- # for now, just cheat and pass a fake IP address to allowed?
- return auth.allowed?(hostname, "127.1.1.1")
+ auth
end
# Retrieve (or create, if necessary) the certificate revocation list.
diff --git a/lib/puppet/ssl/certificate_request.rb b/lib/puppet/ssl/certificate_request.rb
index 2c93a9c56..34cae5a3e 100644
--- a/lib/puppet/ssl/certificate_request.rb
+++ b/lib/puppet/ssl/certificate_request.rb
@@ -24,4 +24,13 @@ class Puppet::SSL::CertificateRequest < Puppet::SSL::Base
@content = csr
end
+
+ def save
+ super()
+
+ # Try to autosign the CSR.
+ if ca = Puppet::SSL::CertificateAuthority.instance
+ ca.autosign
+ end
+ end
end
diff --git a/spec/unit/ssl/certificate_authority.rb b/spec/unit/ssl/certificate_authority.rb
index 12516b816..b0be0e450 100755
--- a/spec/unit/ssl/certificate_authority.rb
+++ b/spec/unit/ssl/certificate_authority.rb
@@ -451,6 +451,84 @@ describe Puppet::SSL::CertificateAuthority do
@cert.stubs :save
@ca.sign(@name)
end
+
+ it "should have a method for triggering autosigning of available CSRs" do
+ @ca.should respond_to(:autosign)
+ end
+
+ describe "when autosigning certificates" do
+ it "should do nothing if autosign is disabled" do
+ Puppet.settings.expects(:value).with(:autosign).returns 'false'
+
+ Puppet::SSL::CertificateRequest.expects(:search).never
+ @ca.autosign
+ end
+
+ it "should do nothing if no autosign.conf exists" do
+ Puppet.settings.expects(:value).with(:autosign).returns '/auto/sign'
+ FileTest.expects(:exist?).with("/auto/sign").returns false
+
+ Puppet::SSL::CertificateRequest.expects(:search).never
+ @ca.autosign
+ end
+
+ describe "and autosign is enabled and the autosign.conf file exists" do
+ before do
+ Puppet.settings.stubs(:value).with(:autosign).returns '/auto/sign'
+ FileTest.stubs(:exist?).with("/auto/sign").returns true
+ File.stubs(:readlines).with("/auto/sign").returns ["one\n", "two\n"]
+
+ Puppet::SSL::CertificateRequest.stubs(:search).returns []
+
+ @store = stub 'store', :allow => nil
+ Puppet::Network::AuthStore.stubs(:new).returns @store
+ end
+
+ describe "when creating the AuthStore instance to verify autosigning" do
+ it "should create an AuthStore with each line in the configuration file allowed to be autosigned" do
+ Puppet::Network::AuthStore.expects(:new).returns @store
+
+ @store.expects(:allow).with("one")
+ @store.expects(:allow).with("two")
+
+ @ca.autosign
+ end
+
+ it "should reparse the autosign configuration on each call" do
+ Puppet::Network::AuthStore.expects(:new).times(2).returns @store
+
+ @ca.autosign
+ @ca.autosign
+ end
+
+ it "should ignore comments" do
+ File.stubs(:readlines).with("/auto/sign").returns ["one\n", "#two\n"]
+
+ @store.expects(:allow).with("one")
+ @ca.autosign
+ end
+
+ it "should ignore blank lines" do
+ File.stubs(:readlines).with("/auto/sign").returns ["one\n", "\n"]
+
+ @store.expects(:allow).with("one")
+ @ca.autosign
+ end
+ end
+
+ it "should sign all CSRs whose hostname matches the autosign configuration" do
+ csr1 = mock 'csr1'
+ csr2 = mock 'csr2'
+ Puppet::SSL::CertificateRequest.stubs(:search).returns [csr1, csr2]
+ end
+
+ it "should not sign CSRs whose hostname does not match the autosign configuration" do
+ csr1 = mock 'csr1'
+ csr2 = mock 'csr2'
+ Puppet::SSL::CertificateRequest.stubs(:search).returns [csr1, csr2]
+ end
+ end
+ end
end
describe "when managing certificate clients" do
@@ -679,14 +757,4 @@ describe Puppet::SSL::CertificateAuthority do
end
end
end
-
- it "should have a method for triggering autosigning of available CSRs"
-
- describe "when autosigning certificates" do
- it "should do nothing if autosign is disabled"
-
- it "should do nothing if no autosign.conf exists"
-
- it "should sign all CSRs whose hostname matches the autosign configuration"
- end
end
diff --git a/spec/unit/ssl/certificate_request.rb b/spec/unit/ssl/certificate_request.rb
index 718363f93..351e5bbd5 100755
--- a/spec/unit/ssl/certificate_request.rb
+++ b/spec/unit/ssl/certificate_request.rb
@@ -139,4 +139,29 @@ describe Puppet::SSL::CertificateRequest do
@instance.content.should equal(@request)
end
end
+
+ describe "when a CSR is saved" do
+ describe "and a CA is available" do
+ it "should save the CSR and trigger autosigning" do
+ ca = mock 'ca', :autosign
+ Puppet::SSL::CertificateAuthority.expects(:instance).returns ca
+
+ csr = Puppet::SSL::CertificateRequest.new("me")
+ Puppet::SSL::CertificateRequest.indirection.expects(:save).with(csr)
+
+ csr.save
+ end
+ end
+
+ describe "and a CA is not available" do
+ it "should save the CSR" do
+ Puppet::SSL::CertificateAuthority.expects(:instance).returns nil
+
+ csr = Puppet::SSL::CertificateRequest.new("me")
+ Puppet::SSL::CertificateRequest.indirection.expects(:save).with(csr)
+
+ csr.save
+ end
+ end
+ end
end