diff options
| author | Luke Kanies <luke@madstop.com> | 2008-05-06 16:45:29 -0500 |
|---|---|---|
| committer | Luke Kanies <luke@madstop.com> | 2008-05-06 16:45:29 -0500 |
| commit | d78b4ba48a0fdf63906fb0ede2cd8c2e634ef442 (patch) | |
| tree | 1ec6c902ab64b7b575c0ac192ea470d9116efd17 | |
| parent | a822ef9ce5c6d603f4a98b9dda0dbf4661528128 (diff) | |
| download | puppet-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.rb | 53 | ||||
| -rw-r--r-- | lib/puppet/ssl/certificate_request.rb | 9 | ||||
| -rwxr-xr-x | spec/unit/ssl/certificate_authority.rb | 88 | ||||
| -rwxr-xr-x | spec/unit/ssl/certificate_request.rb | 25 |
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 |
