diff options
Diffstat (limited to 'spec/unit/ssl')
-rwxr-xr-x | spec/unit/ssl/base_spec.rb | 48 | ||||
-rwxr-xr-x | spec/unit/ssl/certificate_authority/interface_spec.rb | 462 | ||||
-rwxr-xr-x | spec/unit/ssl/certificate_authority_spec.rb | 1150 | ||||
-rwxr-xr-x | spec/unit/ssl/certificate_factory_spec.rb | 150 | ||||
-rwxr-xr-x | spec/unit/ssl/certificate_request_spec.rb | 360 | ||||
-rwxr-xr-x | spec/unit/ssl/certificate_revocation_list_spec.rb | 230 | ||||
-rwxr-xr-x | spec/unit/ssl/certificate_spec.rb | 182 | ||||
-rwxr-xr-x | spec/unit/ssl/host_spec.rb | 1096 | ||||
-rwxr-xr-x | spec/unit/ssl/inventory_spec.rb | 240 | ||||
-rwxr-xr-x | spec/unit/ssl/key_spec.rb | 284 |
10 files changed, 2101 insertions, 2101 deletions
diff --git a/spec/unit/ssl/base_spec.rb b/spec/unit/ssl/base_spec.rb index 062ea3315..47575feab 100755 --- a/spec/unit/ssl/base_spec.rb +++ b/spec/unit/ssl/base_spec.rb @@ -7,37 +7,37 @@ require 'puppet/ssl/certificate' class TestCertificate < Puppet::SSL::Base; end describe Puppet::SSL::Certificate do + before :each do + @base = TestCertificate.new("name") + end + + describe "when fingerprinting content" do before :each do - @base = TestCertificate.new("name") + @cert = stub 'cert', :to_der => "DER" + @base.stubs(:content).returns(@cert) + OpenSSL::Digest.stubs(:constants).returns ["MD5", "DIGEST"] + @digest = stub_everything + OpenSSL::Digest.stubs(:const_get).returns @digest end - describe "when fingerprinting content" do - before :each do - @cert = stub 'cert', :to_der => "DER" - @base.stubs(:content).returns(@cert) - OpenSSL::Digest.stubs(:constants).returns ["MD5", "DIGEST"] - @digest = stub_everything - OpenSSL::Digest.stubs(:const_get).returns @digest - end - - it "should digest the certificate DER value and return a ':' seperated nibblet string" do - @cert.expects(:to_der).returns("DER") - @digest.expects(:hexdigest).with("DER").returns "digest" + it "should digest the certificate DER value and return a ':' seperated nibblet string" do + @cert.expects(:to_der).returns("DER") + @digest.expects(:hexdigest).with("DER").returns "digest" - @base.fingerprint.should == "DI:GE:ST" - end + @base.fingerprint.should == "DI:GE:ST" + end - it "should raise an error if the digest algorithm is not defined" do - OpenSSL::Digest.expects(:constants).returns [] + it "should raise an error if the digest algorithm is not defined" do + OpenSSL::Digest.expects(:constants).returns [] - lambda { @base.fingerprint }.should raise_error - end + lambda { @base.fingerprint }.should raise_error + end - it "should use the given digest algorithm" do - OpenSSL::Digest.stubs(:const_get).with("DIGEST").returns @digest - @digest.expects(:hexdigest).with("DER").returns "digest" + it "should use the given digest algorithm" do + OpenSSL::Digest.stubs(:const_get).with("DIGEST").returns @digest + @digest.expects(:hexdigest).with("DER").returns "digest" - @base.fingerprint(:digest).should == "DI:GE:ST" - end + @base.fingerprint(:digest).should == "DI:GE:ST" end + end end
\ No newline at end of file diff --git a/spec/unit/ssl/certificate_authority/interface_spec.rb b/spec/unit/ssl/certificate_authority/interface_spec.rb index 4d76b7e70..d8c351ae2 100755 --- a/spec/unit/ssl/certificate_authority/interface_spec.rb +++ b/spec/unit/ssl/certificate_authority/interface_spec.rb @@ -5,329 +5,329 @@ require File.dirname(__FILE__) + '/../../../spec_helper' require 'puppet/ssl/certificate_authority' describe "a normal interface method", :shared => true do - it "should call the method on the CA for each host specified if an array was provided" do - @ca.expects(@method).with("host1") - @ca.expects(@method).with("host2") + it "should call the method on the CA for each host specified if an array was provided" do + @ca.expects(@method).with("host1") + @ca.expects(@method).with("host2") - @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, :to => %w{host1 host2}) + @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, :to => %w{host1 host2}) - @applier.apply(@ca) - end + @applier.apply(@ca) + end - it "should call the method on the CA for all existing certificates if :all was provided" do - @ca.expects(:list).returns %w{host1 host2} + it "should call the method on the CA for all existing certificates if :all was provided" do + @ca.expects(:list).returns %w{host1 host2} - @ca.expects(@method).with("host1") - @ca.expects(@method).with("host2") + @ca.expects(@method).with("host1") + @ca.expects(@method).with("host2") - @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, :to => :all) + @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, :to => :all) - @applier.apply(@ca) - end + @applier.apply(@ca) + end end describe Puppet::SSL::CertificateAuthority::Interface do - before do - @class = Puppet::SSL::CertificateAuthority::Interface + before do + @class = Puppet::SSL::CertificateAuthority::Interface + end + describe "when initializing" do + it "should set its method using its settor" do + @class.any_instance.expects(:method=).with(:generate) + @class.new(:generate, :to => :all) end - describe "when initializing" do - it "should set its method using its settor" do - @class.any_instance.expects(:method=).with(:generate) - @class.new(:generate, :to => :all) - end - it "should set its subjects using the settor" do - @class.any_instance.expects(:subjects=).with(:all) - @class.new(:generate, :to => :all) - end + it "should set its subjects using the settor" do + @class.any_instance.expects(:subjects=).with(:all) + @class.new(:generate, :to => :all) + end - it "should set the digest if given" do - interface = @class.new(:generate, :to => :all, :digest => :digest) - interface.digest.should == :digest - end + it "should set the digest if given" do + interface = @class.new(:generate, :to => :all, :digest => :digest) + interface.digest.should == :digest + end - it "should set the digest to md5 if none given" do - interface = @class.new(:generate, :to => :all) - interface.digest.should == :MD5 - end + it "should set the digest to md5 if none given" do + interface = @class.new(:generate, :to => :all) + interface.digest.should == :MD5 end + end - describe "when setting the method" do - it "should set the method" do - @class.new(:generate, :to => :all).method.should == :generate - end + describe "when setting the method" do + it "should set the method" do + @class.new(:generate, :to => :all).method.should == :generate + end - it "should fail if the method isn't a member of the INTERFACE_METHODS array" do - Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.expects(:include?).with(:thing).returns false + it "should fail if the method isn't a member of the INTERFACE_METHODS array" do + Puppet::SSL::CertificateAuthority::Interface::INTERFACE_METHODS.expects(:include?).with(:thing).returns false - lambda { @class.new(:thing, :to => :all) }.should raise_error(ArgumentError) - end + lambda { @class.new(:thing, :to => :all) }.should raise_error(ArgumentError) end + end - describe "when setting the subjects" do - it "should set the subjects" do - @class.new(:generate, :to => :all).subjects.should == :all - end + describe "when setting the subjects" do + it "should set the subjects" do + @class.new(:generate, :to => :all).subjects.should == :all + end - it "should fail if the subjects setting isn't :all or an array" do - lambda { @class.new(:generate, "other") }.should raise_error(ArgumentError) - end + it "should fail if the subjects setting isn't :all or an array" do + lambda { @class.new(:generate, "other") }.should raise_error(ArgumentError) end + end + + it "should have a method for triggering the application" do + @class.new(:generate, :to => :all).should respond_to(:apply) + end - it "should have a method for triggering the application" do - @class.new(:generate, :to => :all).should respond_to(:apply) + describe "when applying" do + before do + # We use a real object here, because :verify can't be stubbed, apparently. + @ca = Object.new end - describe "when applying" do - before do - # We use a real object here, because :verify can't be stubbed, apparently. - @ca = Object.new - end + it "should raise InterfaceErrors" do + @applier = @class.new(:revoke, :to => :all) - it "should raise InterfaceErrors" do - @applier = @class.new(:revoke, :to => :all) + @ca.expects(:list).raises Puppet::SSL::CertificateAuthority::Interface::InterfaceError - @ca.expects(:list).raises Puppet::SSL::CertificateAuthority::Interface::InterfaceError + lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError) + end - lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError) - end + it "should log non-Interface failures rather than failing" do + @applier = @class.new(:revoke, :to => :all) - it "should log non-Interface failures rather than failing" do - @applier = @class.new(:revoke, :to => :all) + @ca.expects(:list).raises ArgumentError - @ca.expects(:list).raises ArgumentError + Puppet.expects(:err) - Puppet.expects(:err) + lambda { @applier.apply(@ca) }.should_not raise_error + end - lambda { @applier.apply(@ca) }.should_not raise_error - end + describe "with an empty array specified and the method is not list" do + it "should fail" do + @applier = @class.new(:sign, :to => []) + lambda { @applier.apply(@ca) }.should raise_error(ArgumentError) + end + end - describe "with an empty array specified and the method is not list" do - it "should fail" do - @applier = @class.new(:sign, :to => []) - lambda { @applier.apply(@ca) }.should raise_error(ArgumentError) - end - end + describe ":generate" do + it "should fail if :all was specified" do + @applier = @class.new(:generate, :to => :all) + lambda { @applier.apply(@ca) }.should raise_error(ArgumentError) + end - describe ":generate" do - it "should fail if :all was specified" do - @applier = @class.new(:generate, :to => :all) - lambda { @applier.apply(@ca) }.should raise_error(ArgumentError) - end + it "should call :generate on the CA for each host specified" do + @applier = @class.new(:generate, :to => %w{host1 host2}) - it "should call :generate on the CA for each host specified" do - @applier = @class.new(:generate, :to => %w{host1 host2}) + @ca.expects(:generate).with("host1") + @ca.expects(:generate).with("host2") - @ca.expects(:generate).with("host1") - @ca.expects(:generate).with("host2") + @applier.apply(@ca) + end + end - @applier.apply(@ca) - end - end + describe ":verify" do + before { @method = :verify } + #it_should_behave_like "a normal interface method" - describe ":verify" do - before { @method = :verify } - #it_should_behave_like "a normal interface method" + it "should call the method on the CA for each host specified if an array was provided" do + # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life. + end - it "should call the method on the CA for each host specified if an array was provided" do - # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life. - end + it "should call the method on the CA for all existing certificates if :all was provided" do + # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life. + end + end - it "should call the method on the CA for all existing certificates if :all was provided" do - # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life. - end - end + describe ":destroy" do + before { @method = :destroy } + it_should_behave_like "a normal interface method" + end - describe ":destroy" do - before { @method = :destroy } - it_should_behave_like "a normal interface method" - end + describe ":revoke" do + before { @method = :revoke } + it_should_behave_like "a normal interface method" + end - describe ":revoke" do - before { @method = :revoke } - it_should_behave_like "a normal interface method" + describe ":sign" do + describe "and an array of names was provided" do + before do + @applier = @class.new(:sign, :to => %w{host1 host2}) end - describe ":sign" do - describe "and an array of names was provided" do - before do - @applier = @class.new(:sign, :to => %w{host1 host2}) - end - - it "should sign the specified waiting certificate requests" do - @ca.expects(:sign).with("host1") - @ca.expects(:sign).with("host2") + it "should sign the specified waiting certificate requests" do + @ca.expects(:sign).with("host1") + @ca.expects(:sign).with("host2") - @applier.apply(@ca) - end - end + @applier.apply(@ca) + end + end - describe "and :all was provided" do - it "should sign all waiting certificate requests" do - @ca.stubs(:waiting?).returns(%w{cert1 cert2}) + describe "and :all was provided" do + it "should sign all waiting certificate requests" do + @ca.stubs(:waiting?).returns(%w{cert1 cert2}) - @ca.expects(:sign).with("cert1") - @ca.expects(:sign).with("cert2") + @ca.expects(:sign).with("cert1") + @ca.expects(:sign).with("cert2") - @applier = @class.new(:sign, :to => :all) - @applier.apply(@ca) - end + @applier = @class.new(:sign, :to => :all) + @applier.apply(@ca) + end - it "should fail if there are no waiting certificate requests" do - @ca.stubs(:waiting?).returns([]) + it "should fail if there are no waiting certificate requests" do + @ca.stubs(:waiting?).returns([]) - @applier = @class.new(:sign, :to => :all) - lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError) - end - end + @applier = @class.new(:sign, :to => :all) + lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError) end + end + end - describe ":list" do - describe "and an empty array was provided" do - it "should print a string containing all certificate requests" do - @ca.expects(:waiting?).returns %w{host1 host2} - @ca.stubs(:verify) + describe ":list" do + describe "and an empty array was provided" do + it "should print a string containing all certificate requests" do + @ca.expects(:waiting?).returns %w{host1 host2} + @ca.stubs(:verify) - @applier = @class.new(:list, :to => []) + @applier = @class.new(:list, :to => []) - @applier.expects(:puts).with "host1\nhost2" + @applier.expects(:puts).with "host1\nhost2" - @applier.apply(@ca) - end - end + @applier.apply(@ca) + end + end - describe "and :all was provided" do - it "should print a string containing all certificate requests and certificates" do - @ca.expects(:waiting?).returns %w{host1 host2} - @ca.expects(:list).returns %w{host3 host4} - @ca.stubs(:verify) - @ca.stubs(:fingerprint).returns "fingerprint" - @ca.expects(:verify).with("host3").raises(Puppet::SSL::CertificateAuthority::CertificateVerificationError.new(23), "certificate revoked") + describe "and :all was provided" do + it "should print a string containing all certificate requests and certificates" do + @ca.expects(:waiting?).returns %w{host1 host2} + @ca.expects(:list).returns %w{host3 host4} + @ca.stubs(:verify) + @ca.stubs(:fingerprint).returns "fingerprint" + @ca.expects(:verify).with("host3").raises(Puppet::SSL::CertificateAuthority::CertificateVerificationError.new(23), "certificate revoked") - @applier = @class.new(:list, :to => :all) + @applier = @class.new(:list, :to => :all) - @applier.expects(:puts).with "host1 (fingerprint)" - @applier.expects(:puts).with "host2 (fingerprint)" - @applier.expects(:puts).with "- host3 (fingerprint) (certificate revoked)" - @applier.expects(:puts).with "+ host4 (fingerprint)" + @applier.expects(:puts).with "host1 (fingerprint)" + @applier.expects(:puts).with "host2 (fingerprint)" + @applier.expects(:puts).with "- host3 (fingerprint) (certificate revoked)" + @applier.expects(:puts).with "+ host4 (fingerprint)" - @applier.apply(@ca) - end - end + @applier.apply(@ca) + end + end - describe "and :signed was provided" do - it "should print a string containing all signed certificate requests and certificates" do - @ca.expects(:list).returns %w{host1 host2} + describe "and :signed was provided" do + it "should print a string containing all signed certificate requests and certificates" do + @ca.expects(:list).returns %w{host1 host2} - @applier = @class.new(:list, :to => :signed) + @applier = @class.new(:list, :to => :signed) - @applier.apply(@ca) - end - end + @applier.apply(@ca) + end + end - describe "and an array of names was provided" do - it "should print a string of all named hosts that have a waiting request" do - @ca.expects(:waiting?).returns %w{host1 host2} - @ca.expects(:list).returns %w{host3 host4} - @ca.stubs(:fingerprint).returns "fingerprint" - @ca.stubs(:verify) + describe "and an array of names was provided" do + it "should print a string of all named hosts that have a waiting request" do + @ca.expects(:waiting?).returns %w{host1 host2} + @ca.expects(:list).returns %w{host3 host4} + @ca.stubs(:fingerprint).returns "fingerprint" + @ca.stubs(:verify) - @applier = @class.new(:list, :to => %w{host1 host2 host3 host4}) + @applier = @class.new(:list, :to => %w{host1 host2 host3 host4}) - @applier.expects(:puts).with "host1 (fingerprint)" - @applier.expects(:puts).with "host2 (fingerprint)" - @applier.expects(:puts).with "+ host3 (fingerprint)" - @applier.expects(:puts).with "+ host4 (fingerprint)" + @applier.expects(:puts).with "host1 (fingerprint)" + @applier.expects(:puts).with "host2 (fingerprint)" + @applier.expects(:puts).with "+ host3 (fingerprint)" + @applier.expects(:puts).with "+ host4 (fingerprint)" - @applier.apply(@ca) - end - end + @applier.apply(@ca) end + end + end - describe ":print" do - describe "and :all was provided" do - it "should print all certificates" do - @ca.expects(:list).returns %w{host1 host2} + describe ":print" do + describe "and :all was provided" do + it "should print all certificates" do + @ca.expects(:list).returns %w{host1 host2} - @applier = @class.new(:print, :to => :all) + @applier = @class.new(:print, :to => :all) - @ca.expects(:print).with("host1").returns "h1" - @applier.expects(:puts).with "h1" + @ca.expects(:print).with("host1").returns "h1" + @applier.expects(:puts).with "h1" - @ca.expects(:print).with("host2").returns "h2" - @applier.expects(:puts).with "h2" + @ca.expects(:print).with("host2").returns "h2" + @applier.expects(:puts).with "h2" - @applier.apply(@ca) - end - end + @applier.apply(@ca) + end + end - describe "and an array of names was provided" do - it "should print each named certificate if found" do - @applier = @class.new(:print, :to => %w{host1 host2}) + describe "and an array of names was provided" do + it "should print each named certificate if found" do + @applier = @class.new(:print, :to => %w{host1 host2}) - @ca.expects(:print).with("host1").returns "h1" - @applier.expects(:puts).with "h1" + @ca.expects(:print).with("host1").returns "h1" + @applier.expects(:puts).with "h1" - @ca.expects(:print).with("host2").returns "h2" - @applier.expects(:puts).with "h2" + @ca.expects(:print).with("host2").returns "h2" + @applier.expects(:puts).with "h2" - @applier.apply(@ca) - end + @applier.apply(@ca) + end - it "should log any named but not found certificates" do - @applier = @class.new(:print, :to => %w{host1 host2}) + it "should log any named but not found certificates" do + @applier = @class.new(:print, :to => %w{host1 host2}) - @ca.expects(:print).with("host1").returns "h1" - @applier.expects(:puts).with "h1" + @ca.expects(:print).with("host1").returns "h1" + @applier.expects(:puts).with "h1" - @ca.expects(:print).with("host2").returns nil - Puppet.expects(:err).with { |msg| msg.include?("host2") } + @ca.expects(:print).with("host2").returns nil + Puppet.expects(:err).with { |msg| msg.include?("host2") } - @applier.apply(@ca) - end - end + @applier.apply(@ca) end + end + end - describe ":fingerprint" do - it "should fingerprint with the set digest algorithm" do - @applier = @class.new(:fingerprint, :to => %w{host1}, :digest => :digest) + describe ":fingerprint" do + it "should fingerprint with the set digest algorithm" do + @applier = @class.new(:fingerprint, :to => %w{host1}, :digest => :digest) - @ca.expects(:fingerprint).with("host1", :digest).returns "fingerprint1" - @applier.expects(:puts).with "host1 fingerprint1" + @ca.expects(:fingerprint).with("host1", :digest).returns "fingerprint1" + @applier.expects(:puts).with "host1 fingerprint1" - @applier.apply(@ca) - end + @applier.apply(@ca) + end - describe "and :all was provided" do - it "should fingerprint all certificates (including waiting ones)" do - @ca.expects(:list).returns %w{host1} - @ca.expects(:waiting?).returns %w{host2} + describe "and :all was provided" do + it "should fingerprint all certificates (including waiting ones)" do + @ca.expects(:list).returns %w{host1} + @ca.expects(:waiting?).returns %w{host2} - @applier = @class.new(:fingerprint, :to => :all) + @applier = @class.new(:fingerprint, :to => :all) - @ca.expects(:fingerprint).with("host1", :MD5).returns "fingerprint1" - @applier.expects(:puts).with "host1 fingerprint1" + @ca.expects(:fingerprint).with("host1", :MD5).returns "fingerprint1" + @applier.expects(:puts).with "host1 fingerprint1" - @ca.expects(:fingerprint).with("host2", :MD5).returns "fingerprint2" - @applier.expects(:puts).with "host2 fingerprint2" + @ca.expects(:fingerprint).with("host2", :MD5).returns "fingerprint2" + @applier.expects(:puts).with "host2 fingerprint2" - @applier.apply(@ca) - end - end + @applier.apply(@ca) + end + end - describe "and an array of names was provided" do - it "should print each named certificate if found" do - @applier = @class.new(:fingerprint, :to => %w{host1 host2}) + describe "and an array of names was provided" do + it "should print each named certificate if found" do + @applier = @class.new(:fingerprint, :to => %w{host1 host2}) - @ca.expects(:fingerprint).with("host1", :MD5).returns "fingerprint1" - @applier.expects(:puts).with "host1 fingerprint1" + @ca.expects(:fingerprint).with("host1", :MD5).returns "fingerprint1" + @applier.expects(:puts).with "host1 fingerprint1" - @ca.expects(:fingerprint).with("host2", :MD5).returns "fingerprint2" - @applier.expects(:puts).with "host2 fingerprint2" + @ca.expects(:fingerprint).with("host2", :MD5).returns "fingerprint2" + @applier.expects(:puts).with "host2 fingerprint2" - @applier.apply(@ca) - end - end + @applier.apply(@ca) end + end end + end end diff --git a/spec/unit/ssl/certificate_authority_spec.rb b/spec/unit/ssl/certificate_authority_spec.rb index a39113d8f..39fee3f0a 100755 --- a/spec/unit/ssl/certificate_authority_spec.rb +++ b/spec/unit/ssl/certificate_authority_spec.rb @@ -5,768 +5,768 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/ssl/certificate_authority' describe Puppet::SSL::CertificateAuthority do - after do - Puppet::Util::Cacher.expire - Puppet.settings.clearused + after do + Puppet::Util::Cacher.expire + Puppet.settings.clearused + end + + def stub_ca_host + @key = mock 'key' + @key.stubs(:content).returns "cakey" + @cacert = mock 'certificate' + @cacert.stubs(:content).returns "cacertificate" + + @host = stub 'ssl_host', :key => @key, :certificate => @cacert, :name => Puppet::SSL::Host.ca_name + end + + it "should have a class method for returning a singleton instance" do + Puppet::SSL::CertificateAuthority.should respond_to(:instance) + end + + describe "when finding an existing instance" do + describe "and the host is a CA host and the run_mode is master" do + before do + Puppet.settings.stubs(:value).with(:ca).returns true + Puppet.run_mode.stubs(:master?).returns true + + @ca = mock('ca') + Puppet::SSL::CertificateAuthority.stubs(:new).returns @ca + end + + it "should return an instance" do + Puppet::SSL::CertificateAuthority.instance.should equal(@ca) + end + + it "should always return the same instance" do + Puppet::SSL::CertificateAuthority.instance.should equal(Puppet::SSL::CertificateAuthority.instance) + end end - def stub_ca_host - @key = mock 'key' - @key.stubs(:content).returns "cakey" - @cacert = mock 'certificate' - @cacert.stubs(:content).returns "cacertificate" + describe "and the host is not a CA host" do + it "should return nil" do + Puppet.settings.stubs(:value).with(:ca).returns false + Puppet.run_mode.stubs(:master?).returns true - @host = stub 'ssl_host', :key => @key, :certificate => @cacert, :name => Puppet::SSL::Host.ca_name + ca = mock('ca') + Puppet::SSL::CertificateAuthority.expects(:new).never + Puppet::SSL::CertificateAuthority.instance.should be_nil + end end - it "should have a class method for returning a singleton instance" do - Puppet::SSL::CertificateAuthority.should respond_to(:instance) - end - - describe "when finding an existing instance" do - describe "and the host is a CA host and the run_mode is master" do - before do - Puppet.settings.stubs(:value).with(:ca).returns true - Puppet.run_mode.stubs(:master?).returns true - - @ca = mock('ca') - Puppet::SSL::CertificateAuthority.stubs(:new).returns @ca - end - - it "should return an instance" do - Puppet::SSL::CertificateAuthority.instance.should equal(@ca) - end - - it "should always return the same instance" do - Puppet::SSL::CertificateAuthority.instance.should equal(Puppet::SSL::CertificateAuthority.instance) - end - end + describe "and the run_mode is not master" do + it "should return nil" do + Puppet.settings.stubs(:value).with(:ca).returns true + Puppet.run_mode.stubs(:master?).returns false - describe "and the host is not a CA host" do - it "should return nil" do - Puppet.settings.stubs(:value).with(:ca).returns false - Puppet.run_mode.stubs(:master?).returns true - - ca = mock('ca') - Puppet::SSL::CertificateAuthority.expects(:new).never - Puppet::SSL::CertificateAuthority.instance.should be_nil - end - end - - describe "and the run_mode is not master" do - it "should return nil" do - Puppet.settings.stubs(:value).with(:ca).returns true - Puppet.run_mode.stubs(:master?).returns false - - ca = mock('ca') - Puppet::SSL::CertificateAuthority.expects(:new).never - Puppet::SSL::CertificateAuthority.instance.should be_nil - end - end + ca = mock('ca') + Puppet::SSL::CertificateAuthority.expects(:new).never + Puppet::SSL::CertificateAuthority.instance.should be_nil + end end + end - describe "when initializing" do - before do - Puppet.settings.stubs(:use) - Puppet.settings.stubs(:value).returns "ca_testing" + describe "when initializing" do + before do + Puppet.settings.stubs(:use) + Puppet.settings.stubs(:value).returns "ca_testing" - Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup) - end + Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup) + end - it "should always set its name to the value of :certname" do - Puppet.settings.expects(:value).with(:certname).returns "ca_testing" + it "should always set its name to the value of :certname" do + Puppet.settings.expects(:value).with(:certname).returns "ca_testing" - Puppet::SSL::CertificateAuthority.new.name.should == "ca_testing" - end + Puppet::SSL::CertificateAuthority.new.name.should == "ca_testing" + end - it "should create an SSL::Host instance whose name is the 'ca_name'" do - Puppet::SSL::Host.expects(:ca_name).returns "caname" + it "should create an SSL::Host instance whose name is the 'ca_name'" do + Puppet::SSL::Host.expects(:ca_name).returns "caname" - host = stub 'host' - Puppet::SSL::Host.expects(:new).with("caname").returns host + host = stub 'host' + Puppet::SSL::Host.expects(:new).with("caname").returns host - Puppet::SSL::CertificateAuthority.new - end + Puppet::SSL::CertificateAuthority.new + end - it "should use the :main, :ca, and :ssl settings sections" do - Puppet.settings.expects(:use).with(:main, :ssl, :ca) - Puppet::SSL::CertificateAuthority.new - end + it "should use the :main, :ca, and :ssl settings sections" do + Puppet.settings.expects(:use).with(:main, :ssl, :ca) + Puppet::SSL::CertificateAuthority.new + end - it "should create an inventory instance" do - Puppet::SSL::Inventory.expects(:new).returns "inventory" + it "should create an inventory instance" do + Puppet::SSL::Inventory.expects(:new).returns "inventory" - Puppet::SSL::CertificateAuthority.new.inventory.should == "inventory" - end + Puppet::SSL::CertificateAuthority.new.inventory.should == "inventory" + end - it "should make sure the CA is set up" do - Puppet::SSL::CertificateAuthority.any_instance.expects(:setup) + it "should make sure the CA is set up" do + Puppet::SSL::CertificateAuthority.any_instance.expects(:setup) - Puppet::SSL::CertificateAuthority.new - end + Puppet::SSL::CertificateAuthority.new end + end - describe "when setting itself up" do - it "should generate the CA certificate if it does not have one" do - Puppet.settings.stubs :use + describe "when setting itself up" do + it "should generate the CA certificate if it does not have one" do + Puppet.settings.stubs :use - host = stub 'host' - Puppet::SSL::Host.stubs(:new).returns host + host = stub 'host' + Puppet::SSL::Host.stubs(:new).returns host - host.expects(:certificate).returns nil + host.expects(:certificate).returns nil - Puppet::SSL::CertificateAuthority.any_instance.expects(:generate_ca_certificate) - Puppet::SSL::CertificateAuthority.new - end + Puppet::SSL::CertificateAuthority.any_instance.expects(:generate_ca_certificate) + Puppet::SSL::CertificateAuthority.new end + end - describe "when retrieving the certificate revocation list" do - before do - Puppet.settings.stubs(:use) - Puppet.settings.stubs(:value).returns "ca_testing" - Puppet.settings.stubs(:value).with(:cacrl).returns "/my/crl" + describe "when retrieving the certificate revocation list" do + before do + Puppet.settings.stubs(:use) + Puppet.settings.stubs(:value).returns "ca_testing" + Puppet.settings.stubs(:value).with(:cacrl).returns "/my/crl" - cert = stub("certificate", :content => "real_cert") - key = stub("key", :content => "real_key") - @host = stub 'host', :certificate => cert, :name => "hostname", :key => key + cert = stub("certificate", :content => "real_cert") + key = stub("key", :content => "real_key") + @host = stub 'host', :certificate => cert, :name => "hostname", :key => key - Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup) - @ca = Puppet::SSL::CertificateAuthority.new + Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup) + @ca = Puppet::SSL::CertificateAuthority.new - @ca.stubs(:host).returns @host - end + @ca.stubs(:host).returns @host + end - it "should return any found CRL instance" do - crl = mock 'crl' - Puppet::SSL::CertificateRevocationList.expects(:find).returns crl - @ca.crl.should equal(crl) - end + it "should return any found CRL instance" do + crl = mock 'crl' + Puppet::SSL::CertificateRevocationList.expects(:find).returns crl + @ca.crl.should equal(crl) + end - it "should create, generate, and save a new CRL instance of no CRL can be found" do - crl = mock 'crl' - Puppet::SSL::CertificateRevocationList.expects(:find).returns nil + it "should create, generate, and save a new CRL instance of no CRL can be found" do + crl = mock 'crl' + Puppet::SSL::CertificateRevocationList.expects(:find).returns nil - Puppet::SSL::CertificateRevocationList.expects(:new).returns crl + Puppet::SSL::CertificateRevocationList.expects(:new).returns crl - crl.expects(:generate).with(@ca.host.certificate.content, @ca.host.key.content) - crl.expects(:save) + crl.expects(:generate).with(@ca.host.certificate.content, @ca.host.key.content) + crl.expects(:save) - @ca.crl.should equal(crl) - end + @ca.crl.should equal(crl) end + end - describe "when generating a self-signed CA certificate" do - before do - Puppet.settings.stubs(:use) - Puppet.settings.stubs(:value).returns "ca_testing" + describe "when generating a self-signed CA certificate" do + before do + Puppet.settings.stubs(:use) + Puppet.settings.stubs(:value).returns "ca_testing" - Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup) - Puppet::SSL::CertificateAuthority.any_instance.stubs(:crl) - @ca = Puppet::SSL::CertificateAuthority.new + Puppet::SSL::CertificateAuthority.any_instance.stubs(:setup) + Puppet::SSL::CertificateAuthority.any_instance.stubs(:crl) + @ca = Puppet::SSL::CertificateAuthority.new - @host = stub 'host', :key => mock("key"), :name => "hostname", :certificate => mock('certificate') + @host = stub 'host', :key => mock("key"), :name => "hostname", :certificate => mock('certificate') - Puppet::SSL::CertificateRequest.any_instance.stubs(:generate) + Puppet::SSL::CertificateRequest.any_instance.stubs(:generate) - @ca.stubs(:host).returns @host - end + @ca.stubs(:host).returns @host + end - it "should create and store a password at :capass" do - Puppet.settings.expects(:value).with(:capass).returns "/path/to/pass" + it "should create and store a password at :capass" do + Puppet.settings.expects(:value).with(:capass).returns "/path/to/pass" - FileTest.expects(:exist?).with("/path/to/pass").returns false + FileTest.expects(:exist?).with("/path/to/pass").returns false - fh = mock 'filehandle' - Puppet.settings.expects(:write).with(:capass).yields fh + fh = mock 'filehandle' + Puppet.settings.expects(:write).with(:capass).yields fh - fh.expects(:print).with { |s| s.length > 18 } + fh.expects(:print).with { |s| s.length > 18 } - @ca.stubs(:sign) + @ca.stubs(:sign) - @ca.generate_ca_certificate - end + @ca.generate_ca_certificate + end - it "should generate a key if one does not exist" do - @ca.stubs :generate_password - @ca.stubs :sign + it "should generate a key if one does not exist" do + @ca.stubs :generate_password + @ca.stubs :sign - @ca.host.expects(:key).returns nil - @ca.host.expects(:generate_key) + @ca.host.expects(:key).returns nil + @ca.host.expects(:generate_key) - @ca.generate_ca_certificate - end + @ca.generate_ca_certificate + end - it "should create and sign a self-signed cert using the CA name" do - request = mock 'request' - Puppet::SSL::CertificateRequest.expects(:new).with(@ca.host.name).returns request - request.expects(:generate).with(@ca.host.key) + it "should create and sign a self-signed cert using the CA name" do + request = mock 'request' + Puppet::SSL::CertificateRequest.expects(:new).with(@ca.host.name).returns request + request.expects(:generate).with(@ca.host.key) - @ca.expects(:sign).with(@host.name, :ca, request) + @ca.expects(:sign).with(@host.name, :ca, request) - @ca.stubs :generate_password + @ca.stubs :generate_password - @ca.generate_ca_certificate - end + @ca.generate_ca_certificate + end - it "should generate its CRL" do - @ca.stubs :generate_password - @ca.stubs :sign + it "should generate its CRL" do + @ca.stubs :generate_password + @ca.stubs :sign - @ca.host.expects(:key).returns nil - @ca.host.expects(:generate_key) + @ca.host.expects(:key).returns nil + @ca.host.expects(:generate_key) - @ca.expects(:crl) + @ca.expects(:crl) - @ca.generate_ca_certificate - end + @ca.generate_ca_certificate end + end - describe "when signing" do - before do - Puppet.settings.stubs(:use) + describe "when signing" do + before do + Puppet.settings.stubs(:use) - Puppet::SSL::CertificateAuthority.any_instance.stubs(:password?).returns true + Puppet::SSL::CertificateAuthority.any_instance.stubs(:password?).returns true - stub_ca_host + stub_ca_host - Puppet::SSL::Host.expects(:new).with(Puppet::SSL::Host.ca_name).returns @host + Puppet::SSL::Host.expects(:new).with(Puppet::SSL::Host.ca_name).returns @host - @ca = Puppet::SSL::CertificateAuthority.new + @ca = Puppet::SSL::CertificateAuthority.new - @name = "myhost" - @real_cert = stub 'realcert', :sign => nil - @cert = stub 'certificate', :content => @real_cert + @name = "myhost" + @real_cert = stub 'realcert', :sign => nil + @cert = stub 'certificate', :content => @real_cert - Puppet::SSL::Certificate.stubs(:new).returns @cert + Puppet::SSL::Certificate.stubs(:new).returns @cert - @cert.stubs(:content=) - @cert.stubs(:save) + @cert.stubs(:content=) + @cert.stubs(:save) - # Stub out the factory - @factory = stub 'factory', :result => "my real cert" - Puppet::SSL::CertificateFactory.stubs(:new).returns @factory + # Stub out the factory + @factory = stub 'factory', :result => "my real cert" + Puppet::SSL::CertificateFactory.stubs(:new).returns @factory - @request = stub 'request', :content => "myrequest", :name => @name + @request = stub 'request', :content => "myrequest", :name => @name - # And the inventory - @inventory = stub 'inventory', :add => nil - @ca.stubs(:inventory).returns @inventory + # And the inventory + @inventory = stub 'inventory', :add => nil + @ca.stubs(:inventory).returns @inventory - Puppet::SSL::CertificateRequest.stubs(:destroy) - end + Puppet::SSL::CertificateRequest.stubs(:destroy) + end - describe "and calculating the next certificate serial number" do - before do - @path = "/path/to/serial" - Puppet.settings.stubs(:value).with(:serial).returns @path + describe "and calculating the next certificate serial number" do + before do + @path = "/path/to/serial" + Puppet.settings.stubs(:value).with(:serial).returns @path - @filehandle = stub 'filehandle', :<< => @filehandle - Puppet.settings.stubs(:readwritelock).with(:serial).yields @filehandle - end + @filehandle = stub 'filehandle', :<< => @filehandle + Puppet.settings.stubs(:readwritelock).with(:serial).yields @filehandle + end - it "should default to 0x1 for the first serial number" do - @ca.next_serial.should == 0x1 - end + it "should default to 0x1 for the first serial number" do + @ca.next_serial.should == 0x1 + end - it "should return the current content of the serial file" do - FileTest.stubs(:exist?).with(@path).returns true - File.expects(:read).with(@path).returns "0002" + it "should return the current content of the serial file" do + FileTest.stubs(:exist?).with(@path).returns true + File.expects(:read).with(@path).returns "0002" - @ca.next_serial.should == 2 - end + @ca.next_serial.should == 2 + end - it "should write the next serial number to the serial file as hex" do - @filehandle.expects(:<<).with("0002") + it "should write the next serial number to the serial file as hex" do + @filehandle.expects(:<<).with("0002") - @ca.next_serial - end + @ca.next_serial + end - it "should lock the serial file while writing" do - Puppet.settings.expects(:readwritelock).with(:serial) + it "should lock the serial file while writing" do + Puppet.settings.expects(:readwritelock).with(:serial) - @ca.next_serial - end - end + @ca.next_serial + end + end - describe "its own certificate" do - before do - @serial = 10 - @ca.stubs(:next_serial).returns @serial - end - - it "should not look up a certificate request for the host" do - Puppet::SSL::CertificateRequest.expects(:find).never - - @ca.sign(@name, :ca, @request) - end - - it "should use a certificate type of :ca" do - Puppet::SSL::CertificateFactory.expects(:new).with do |*args| - args[0] == :ca - end.returns @factory - @ca.sign(@name, :ca, @request) - end - - it "should pass the provided CSR as the CSR" do - Puppet::SSL::CertificateFactory.expects(:new).with do |*args| - args[1] == "myrequest" - end.returns @factory - @ca.sign(@name, :ca, @request) - end - - it "should use the provided CSR's content as the issuer" do - Puppet::SSL::CertificateFactory.expects(:new).with do |*args| - args[2] == "myrequest" - end.returns @factory - @ca.sign(@name, :ca, @request) - end - - it "should pass the next serial as the serial number" do - Puppet::SSL::CertificateFactory.expects(:new).with do |*args| - args[3] == @serial - end.returns @factory - @ca.sign(@name, :ca, @request) - end - - it "should save the resulting certificate" do - @cert.expects(:save) - - @ca.sign(@name, :ca, @request) - end - end + describe "its own certificate" do + before do + @serial = 10 + @ca.stubs(:next_serial).returns @serial + end + + it "should not look up a certificate request for the host" do + Puppet::SSL::CertificateRequest.expects(:find).never + + @ca.sign(@name, :ca, @request) + end + + it "should use a certificate type of :ca" do + Puppet::SSL::CertificateFactory.expects(:new).with do |*args| + args[0] == :ca + end.returns @factory + @ca.sign(@name, :ca, @request) + end + + it "should pass the provided CSR as the CSR" do + Puppet::SSL::CertificateFactory.expects(:new).with do |*args| + args[1] == "myrequest" + end.returns @factory + @ca.sign(@name, :ca, @request) + end + + it "should use the provided CSR's content as the issuer" do + Puppet::SSL::CertificateFactory.expects(:new).with do |*args| + args[2] == "myrequest" + end.returns @factory + @ca.sign(@name, :ca, @request) + end + + it "should pass the next serial as the serial number" do + Puppet::SSL::CertificateFactory.expects(:new).with do |*args| + args[3] == @serial + end.returns @factory + @ca.sign(@name, :ca, @request) + end + + it "should save the resulting certificate" do + @cert.expects(:save) + + @ca.sign(@name, :ca, @request) + end + end - describe "another host's certificate" do - before do - @serial = 10 - @ca.stubs(:next_serial).returns @serial + describe "another host's certificate" do + before do + @serial = 10 + @ca.stubs(:next_serial).returns @serial - Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request - @cert.stubs :save - end + Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request + @cert.stubs :save + end - it "should use a certificate type of :server" do - Puppet::SSL::CertificateFactory.expects(:new).with do |*args| - args[0] == :server - end.returns @factory + it "should use a certificate type of :server" do + Puppet::SSL::CertificateFactory.expects(:new).with do |*args| + args[0] == :server + end.returns @factory - @ca.sign(@name) - end + @ca.sign(@name) + end - it "should use look up a CSR for the host in the :ca_file terminus" do - Puppet::SSL::CertificateRequest.expects(:find).with(@name).returns @request + it "should use look up a CSR for the host in the :ca_file terminus" do + Puppet::SSL::CertificateRequest.expects(:find).with(@name).returns @request - @ca.sign(@name) - end + @ca.sign(@name) + end - it "should fail if no CSR can be found for the host" do - Puppet::SSL::CertificateRequest.expects(:find).with(@name).returns nil + it "should fail if no CSR can be found for the host" do + Puppet::SSL::CertificateRequest.expects(:find).with(@name).returns nil - lambda { @ca.sign(@name) }.should raise_error(ArgumentError) - end + lambda { @ca.sign(@name) }.should raise_error(ArgumentError) + end - it "should use the CA certificate as the issuer" do - Puppet::SSL::CertificateFactory.expects(:new).with do |*args| - args[2] == @cacert.content - end.returns @factory - @ca.sign(@name) - end + it "should use the CA certificate as the issuer" do + Puppet::SSL::CertificateFactory.expects(:new).with do |*args| + args[2] == @cacert.content + end.returns @factory + @ca.sign(@name) + end - it "should pass the next serial as the serial number" do - Puppet::SSL::CertificateFactory.expects(:new).with do |*args| - args[3] == @serial - end.returns @factory - @ca.sign(@name) - end + it "should pass the next serial as the serial number" do + Puppet::SSL::CertificateFactory.expects(:new).with do |*args| + args[3] == @serial + end.returns @factory + @ca.sign(@name) + end - it "should sign the resulting certificate using its real key and a digest" do - digest = mock 'digest' - OpenSSL::Digest::SHA1.expects(:new).returns digest + it "should sign the resulting certificate using its real key and a digest" do + digest = mock 'digest' + OpenSSL::Digest::SHA1.expects(:new).returns digest - key = stub 'key', :content => "real_key" - @ca.host.stubs(:key).returns key + key = stub 'key', :content => "real_key" + @ca.host.stubs(:key).returns key - @cert.content.expects(:sign).with("real_key", digest) - @ca.sign(@name) - end + @cert.content.expects(:sign).with("real_key", digest) + @ca.sign(@name) + end - it "should save the resulting certificate" do - @cert.expects(:save) - @ca.sign(@name) - end + it "should save the resulting certificate" do + @cert.expects(:save) + @ca.sign(@name) + end - it "should remove the host's certificate request" do - Puppet::SSL::CertificateRequest.expects(:destroy).with(@name) + it "should remove the host's certificate request" do + Puppet::SSL::CertificateRequest.expects(:destroy).with(@name) - @ca.sign(@name) - end - end + @ca.sign(@name) + end + end - it "should create a certificate instance with the content set to the newly signed x509 certificate" do - @serial = 10 - @ca.stubs(:next_serial).returns @serial + it "should create a certificate instance with the content set to the newly signed x509 certificate" do + @serial = 10 + @ca.stubs(:next_serial).returns @serial - Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request - @cert.stubs :save - Puppet::SSL::Certificate.expects(:new).with(@name).returns @cert + Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request + @cert.stubs :save + Puppet::SSL::Certificate.expects(:new).with(@name).returns @cert - @ca.sign(@name) - end + @ca.sign(@name) + end - it "should return the certificate instance" do - @ca.stubs(:next_serial).returns @serial - Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request - @cert.stubs :save - @ca.sign(@name).should equal(@cert) - end + it "should return the certificate instance" do + @ca.stubs(:next_serial).returns @serial + Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request + @cert.stubs :save + @ca.sign(@name).should equal(@cert) + end - it "should add the certificate to its inventory" do - @ca.stubs(:next_serial).returns @serial - @inventory.expects(:add).with(@cert) + it "should add the certificate to its inventory" do + @ca.stubs(:next_serial).returns @serial + @inventory.expects(:add).with(@cert) - Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request - @cert.stubs :save - @ca.sign(@name) - end + Puppet::SSL::CertificateRequest.stubs(:find).with(@name).returns @request + @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 + 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' + 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 + 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 + 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 + 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"] + 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 [] + Puppet::SSL::CertificateRequest.stubs(:search).returns [] - @store = stub 'store', :allow => nil - Puppet::Network::AuthStore.stubs(:new).returns @store - end + @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 + 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") + @store.expects(:allow).with("one") + @store.expects(:allow).with("two") - @ca.autosign - end + @ca.autosign + end - it "should reparse the autosign configuration on each call" do - Puppet::Network::AuthStore.expects(:new).times(2).returns @store + it "should reparse the autosign configuration on each call" do + Puppet::Network::AuthStore.expects(:new).times(2).returns @store - @ca.autosign - @ca.autosign - end + @ca.autosign + @ca.autosign + end - it "should ignore comments" do - File.stubs(:readlines).with("/auto/sign").returns ["one\n", "#two\n"] + it "should ignore comments" do + File.stubs(:readlines).with("/auto/sign").returns ["one\n", "#two\n"] - @store.expects(:allow).with("one") - @ca.autosign - end + @store.expects(:allow).with("one") + @ca.autosign + end - it "should ignore blank lines" do - File.stubs(:readlines).with("/auto/sign").returns ["one\n", "\n"] + 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 + @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 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 + 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 - before do - Puppet.settings.stubs(:use) + describe "when managing certificate clients" do + before do + Puppet.settings.stubs(:use) - Puppet::SSL::CertificateAuthority.any_instance.stubs(:password?).returns true + Puppet::SSL::CertificateAuthority.any_instance.stubs(:password?).returns true - stub_ca_host + stub_ca_host - Puppet::SSL::Host.expects(:new).returns @host - Puppet::SSL::CertificateAuthority.any_instance.stubs(:host).returns @host + Puppet::SSL::Host.expects(:new).returns @host + Puppet::SSL::CertificateAuthority.any_instance.stubs(:host).returns @host - @cacert = mock 'certificate' - @cacert.stubs(:content).returns "cacertificate" - @ca = Puppet::SSL::CertificateAuthority.new - end + @cacert = mock 'certificate' + @cacert.stubs(:content).returns "cacertificate" + @ca = Puppet::SSL::CertificateAuthority.new + end - it "should have a method for acting on the SSL files" do - @ca.should respond_to(:apply) - end + it "should have a method for acting on the SSL files" do + @ca.should respond_to(:apply) + end - describe "when applying a method to a set of hosts" do - it "should fail if no subjects have been specified" do - lambda { @ca.apply(:generate) }.should raise_error(ArgumentError) - end - - it "should create an Interface instance with the specified method and the options" do - Puppet::SSL::CertificateAuthority::Interface.expects(:new).with(:generate, :to => :host).returns(stub('applier', :apply => nil)) - @ca.apply(:generate, :to => :host) - end - - it "should apply the Interface with itself as the argument" do - applier = stub('applier') - applier.expects(:apply).with(@ca) - Puppet::SSL::CertificateAuthority::Interface.expects(:new).returns applier - @ca.apply(:generate, :to => :ca_testing) - end - end + describe "when applying a method to a set of hosts" do + it "should fail if no subjects have been specified" do + lambda { @ca.apply(:generate) }.should raise_error(ArgumentError) + end + + it "should create an Interface instance with the specified method and the options" do + Puppet::SSL::CertificateAuthority::Interface.expects(:new).with(:generate, :to => :host).returns(stub('applier', :apply => nil)) + @ca.apply(:generate, :to => :host) + end + + it "should apply the Interface with itself as the argument" do + applier = stub('applier') + applier.expects(:apply).with(@ca) + Puppet::SSL::CertificateAuthority::Interface.expects(:new).returns applier + @ca.apply(:generate, :to => :ca_testing) + end + end - it "should be able to list waiting certificate requests" do - req1 = stub 'req1', :name => "one" - req2 = stub 'req2', :name => "two" - Puppet::SSL::CertificateRequest.expects(:search).with("*").returns [req1, req2] + it "should be able to list waiting certificate requests" do + req1 = stub 'req1', :name => "one" + req2 = stub 'req2', :name => "two" + Puppet::SSL::CertificateRequest.expects(:search).with("*").returns [req1, req2] - @ca.waiting?.should == %w{one two} - end + @ca.waiting?.should == %w{one two} + end - it "should delegate removing hosts to the Host class" do - Puppet::SSL::Host.expects(:destroy).with("myhost") + it "should delegate removing hosts to the Host class" do + Puppet::SSL::Host.expects(:destroy).with("myhost") - @ca.destroy("myhost") - end + @ca.destroy("myhost") + end - it "should be able to verify certificates" do - @ca.should respond_to(:verify) - end + it "should be able to verify certificates" do + @ca.should respond_to(:verify) + end - it "should list certificates as the sorted list of all existing signed certificates" do - cert1 = stub 'cert1', :name => "cert1" - cert2 = stub 'cert2', :name => "cert2" - Puppet::SSL::Certificate.expects(:search).with("*").returns [cert1, cert2] - @ca.list.should == %w{cert1 cert2} - end + it "should list certificates as the sorted list of all existing signed certificates" do + cert1 = stub 'cert1', :name => "cert1" + cert2 = stub 'cert2', :name => "cert2" + Puppet::SSL::Certificate.expects(:search).with("*").returns [cert1, cert2] + @ca.list.should == %w{cert1 cert2} + end - describe "and printing certificates" do - it "should return nil if the certificate cannot be found" do - Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil - @ca.print("myhost").should be_nil - end - - it "should print certificates by calling :to_text on the host's certificate" do - cert1 = stub 'cert1', :name => "cert1", :to_text => "mytext" - Puppet::SSL::Certificate.expects(:find).with("myhost").returns cert1 - @ca.print("myhost").should == "mytext" - end - end + describe "and printing certificates" do + it "should return nil if the certificate cannot be found" do + Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil + @ca.print("myhost").should be_nil + end + + it "should print certificates by calling :to_text on the host's certificate" do + cert1 = stub 'cert1', :name => "cert1", :to_text => "mytext" + Puppet::SSL::Certificate.expects(:find).with("myhost").returns cert1 + @ca.print("myhost").should == "mytext" + end + end - describe "and fingerprinting certificates" do - before :each do - @cert = stub 'cert', :name => "cert", :fingerprint => "DIGEST" - Puppet::SSL::Certificate.stubs(:find).with("myhost").returns @cert - Puppet::SSL::CertificateRequest.stubs(:find).with("myhost") - end - - it "should raise an error if the certificate or CSR cannot be found" do - Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil - Puppet::SSL::CertificateRequest.expects(:find).with("myhost").returns nil - lambda { @ca.fingerprint("myhost") }.should raise_error - end - - it "should try to find a CSR if no certificate can be found" do - Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil - Puppet::SSL::CertificateRequest.expects(:find).with("myhost").returns @cert - @cert.expects(:fingerprint) - @ca.fingerprint("myhost") - end - - it "should delegate to the certificate fingerprinting" do - @cert.expects(:fingerprint) - @ca.fingerprint("myhost") - end - - it "should propagate the digest algorithm to the certificate fingerprinting system" do - @cert.expects(:fingerprint).with(:digest) - @ca.fingerprint("myhost", :digest) - end - end + describe "and fingerprinting certificates" do + before :each do + @cert = stub 'cert', :name => "cert", :fingerprint => "DIGEST" + Puppet::SSL::Certificate.stubs(:find).with("myhost").returns @cert + Puppet::SSL::CertificateRequest.stubs(:find).with("myhost") + end + + it "should raise an error if the certificate or CSR cannot be found" do + Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil + Puppet::SSL::CertificateRequest.expects(:find).with("myhost").returns nil + lambda { @ca.fingerprint("myhost") }.should raise_error + end + + it "should try to find a CSR if no certificate can be found" do + Puppet::SSL::Certificate.expects(:find).with("myhost").returns nil + Puppet::SSL::CertificateRequest.expects(:find).with("myhost").returns @cert + @cert.expects(:fingerprint) + @ca.fingerprint("myhost") + end + + it "should delegate to the certificate fingerprinting" do + @cert.expects(:fingerprint) + @ca.fingerprint("myhost") + end + + it "should propagate the digest algorithm to the certificate fingerprinting system" do + @cert.expects(:fingerprint).with(:digest) + @ca.fingerprint("myhost", :digest) + end + end - describe "and verifying certificates" do - before do - @store = stub 'store', :verify => true, :add_file => nil, :purpose= => nil, :add_crl => true, :flags= => nil + describe "and verifying certificates" do + before do + @store = stub 'store', :verify => true, :add_file => nil, :purpose= => nil, :add_crl => true, :flags= => nil - OpenSSL::X509::Store.stubs(:new).returns @store + OpenSSL::X509::Store.stubs(:new).returns @store - Puppet.settings.stubs(:value).returns "crtstuff" + Puppet.settings.stubs(:value).returns "crtstuff" - @cert = stub 'cert', :content => "mycert" - Puppet::SSL::Certificate.stubs(:find).returns @cert + @cert = stub 'cert', :content => "mycert" + Puppet::SSL::Certificate.stubs(:find).returns @cert - @crl = stub('crl', :content => "mycrl") + @crl = stub('crl', :content => "mycrl") - @ca.stubs(:crl).returns @crl - end + @ca.stubs(:crl).returns @crl + end - it "should fail if the host's certificate cannot be found" do - Puppet::SSL::Certificate.expects(:find).with("me").returns(nil) + it "should fail if the host's certificate cannot be found" do + Puppet::SSL::Certificate.expects(:find).with("me").returns(nil) - lambda { @ca.verify("me") }.should raise_error(ArgumentError) - end + lambda { @ca.verify("me") }.should raise_error(ArgumentError) + end - it "should create an SSL Store to verify" do - OpenSSL::X509::Store.expects(:new).returns @store + it "should create an SSL Store to verify" do + OpenSSL::X509::Store.expects(:new).returns @store - @ca.verify("me") - end + @ca.verify("me") + end - it "should add the CA Certificate to the store" do - Puppet.settings.stubs(:value).with(:cacert).returns "/ca/cert" - @store.expects(:add_file).with "/ca/cert" + it "should add the CA Certificate to the store" do + Puppet.settings.stubs(:value).with(:cacert).returns "/ca/cert" + @store.expects(:add_file).with "/ca/cert" - @ca.verify("me") - end + @ca.verify("me") + end - it "should add the CRL to the store if the crl is enabled" do - @store.expects(:add_crl).with "mycrl" + it "should add the CRL to the store if the crl is enabled" do + @store.expects(:add_crl).with "mycrl" - @ca.verify("me") - end + @ca.verify("me") + end - it "should set the store purpose to OpenSSL::X509::PURPOSE_SSL_CLIENT" do - Puppet.settings.stubs(:value).with(:cacert).returns "/ca/cert" - @store.expects(:add_file).with "/ca/cert" + it "should set the store purpose to OpenSSL::X509::PURPOSE_SSL_CLIENT" do + Puppet.settings.stubs(:value).with(:cacert).returns "/ca/cert" + @store.expects(:add_file).with "/ca/cert" - @ca.verify("me") - end + @ca.verify("me") + end - it "should set the store flags to check the crl" do - @store.expects(:flags=).with OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK + it "should set the store flags to check the crl" do + @store.expects(:flags=).with OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK - @ca.verify("me") - end + @ca.verify("me") + end - it "should use the store to verify the certificate" do - @cert.expects(:content).returns "mycert" + it "should use the store to verify the certificate" do + @cert.expects(:content).returns "mycert" - @store.expects(:verify).with("mycert").returns true + @store.expects(:verify).with("mycert").returns true - @ca.verify("me") - end + @ca.verify("me") + end - it "should fail if the verification returns false" do - @cert.expects(:content).returns "mycert" + it "should fail if the verification returns false" do + @cert.expects(:content).returns "mycert" - @store.expects(:verify).with("mycert").returns false + @store.expects(:verify).with("mycert").returns false - lambda { @ca.verify("me") }.should raise_error - end - end + lambda { @ca.verify("me") }.should raise_error + end + end - describe "and revoking certificates" do - before do - @crl = mock 'crl' - @ca.stubs(:crl).returns @crl + describe "and revoking certificates" do + before do + @crl = mock 'crl' + @ca.stubs(:crl).returns @crl - @ca.stubs(:next_serial).returns 10 + @ca.stubs(:next_serial).returns 10 - @real_cert = stub 'real_cert', :serial => 15 - @cert = stub 'cert', :content => @real_cert - Puppet::SSL::Certificate.stubs(:find).returns @cert + @real_cert = stub 'real_cert', :serial => 15 + @cert = stub 'cert', :content => @real_cert + Puppet::SSL::Certificate.stubs(:find).returns @cert - end + end - it "should fail if the certificate revocation list is disabled" do - @ca.stubs(:crl).returns false + it "should fail if the certificate revocation list is disabled" do + @ca.stubs(:crl).returns false - lambda { @ca.revoke('ca_testing') }.should raise_error(ArgumentError) + lambda { @ca.revoke('ca_testing') }.should raise_error(ArgumentError) - end + end - it "should delegate the revocation to its CRL" do - @ca.crl.expects(:revoke) + it "should delegate the revocation to its CRL" do + @ca.crl.expects(:revoke) - @ca.revoke('host') - end + @ca.revoke('host') + end - it "should get the serial number from the local certificate if it exists" do - @ca.crl.expects(:revoke).with { |serial, key| serial == 15 } + it "should get the serial number from the local certificate if it exists" do + @ca.crl.expects(:revoke).with { |serial, key| serial == 15 } - Puppet::SSL::Certificate.expects(:find).with("host").returns @cert + Puppet::SSL::Certificate.expects(:find).with("host").returns @cert - @ca.revoke('host') - end + @ca.revoke('host') + end - it "should get the serial number from inventory if no local certificate exists" do - real_cert = stub 'real_cert', :serial => 15 - cert = stub 'cert', :content => real_cert - Puppet::SSL::Certificate.expects(:find).with("host").returns nil + it "should get the serial number from inventory if no local certificate exists" do + real_cert = stub 'real_cert', :serial => 15 + cert = stub 'cert', :content => real_cert + Puppet::SSL::Certificate.expects(:find).with("host").returns nil - @ca.inventory.expects(:serial).with("host").returns 16 + @ca.inventory.expects(:serial).with("host").returns 16 - @ca.crl.expects(:revoke).with { |serial, key| serial == 16 } - @ca.revoke('host') - end - end + @ca.crl.expects(:revoke).with { |serial, key| serial == 16 } + @ca.revoke('host') + end + end - it "should be able to generate a complete new SSL host" do - @ca.should respond_to(:generate) - end + it "should be able to generate a complete new SSL host" do + @ca.should respond_to(:generate) + end - describe "and generating certificates" do - before do - @host = stub 'host', :generate_certificate_request => nil - Puppet::SSL::Host.stubs(:new).returns @host - Puppet::SSL::Certificate.stubs(:find).returns nil + describe "and generating certificates" do + before do + @host = stub 'host', :generate_certificate_request => nil + Puppet::SSL::Host.stubs(:new).returns @host + Puppet::SSL::Certificate.stubs(:find).returns nil - @ca.stubs(:sign) - end + @ca.stubs(:sign) + end - it "should fail if a certificate already exists for the host" do - Puppet::SSL::Certificate.expects(:find).with("him").returns "something" + it "should fail if a certificate already exists for the host" do + Puppet::SSL::Certificate.expects(:find).with("him").returns "something" - lambda { @ca.generate("him") }.should raise_error(ArgumentError) - end + lambda { @ca.generate("him") }.should raise_error(ArgumentError) + end - it "should create a new Host instance with the correct name" do - Puppet::SSL::Host.expects(:new).with("him").returns @host + it "should create a new Host instance with the correct name" do + Puppet::SSL::Host.expects(:new).with("him").returns @host - @ca.generate("him") - end + @ca.generate("him") + end - it "should use the Host to generate the certificate request" do - @host.expects :generate_certificate_request + it "should use the Host to generate the certificate request" do + @host.expects :generate_certificate_request - @ca.generate("him") - end + @ca.generate("him") + end - it "should sign the generated request" do - @ca.expects(:sign).with("him") + it "should sign the generated request" do + @ca.expects(:sign).with("him") - @ca.generate("him") - end - end + @ca.generate("him") + end end + end end diff --git a/spec/unit/ssl/certificate_factory_spec.rb b/spec/unit/ssl/certificate_factory_spec.rb index 089ce3f43..de2093810 100755 --- a/spec/unit/ssl/certificate_factory_spec.rb +++ b/spec/unit/ssl/certificate_factory_spec.rb @@ -5,103 +5,103 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/ssl/certificate_factory' describe Puppet::SSL::CertificateFactory do - before do - @cert_type = mock 'cert_type' - @name = mock 'name' - @csr = stub 'csr', :subject => @name - @issuer = mock 'issuer' - @serial = mock 'serial' - - @factory = Puppet::SSL::CertificateFactory.new(@cert_type, @csr, @issuer, @serial) + before do + @cert_type = mock 'cert_type' + @name = mock 'name' + @csr = stub 'csr', :subject => @name + @issuer = mock 'issuer' + @serial = mock 'serial' + + @factory = Puppet::SSL::CertificateFactory.new(@cert_type, @csr, @issuer, @serial) + end + + describe "when initializing" do + it "should set its :cert_type to its first argument" do + @factory.cert_type.should equal(@cert_type) end - describe "when initializing" do - it "should set its :cert_type to its first argument" do - @factory.cert_type.should equal(@cert_type) - end - - it "should set its :csr to its second argument" do - @factory.csr.should equal(@csr) - end - - it "should set its :issuer to its third argument" do - @factory.issuer.should equal(@issuer) - end - - it "should set its :serial to its fourth argument" do - @factory.serial.should equal(@serial) - end + it "should set its :csr to its second argument" do + @factory.csr.should equal(@csr) + end - it "should set its name to the subject of the csr" do - @factory.name.should equal(@name) - end + it "should set its :issuer to its third argument" do + @factory.issuer.should equal(@issuer) end - describe "when generating the certificate" do - before do - @cert = mock 'cert' + it "should set its :serial to its fourth argument" do + @factory.serial.should equal(@serial) + end - @cert.stub_everything + it "should set its name to the subject of the csr" do + @factory.name.should equal(@name) + end + end - @factory.stubs :build_extensions + describe "when generating the certificate" do + before do + @cert = mock 'cert' - @factory.stubs :set_ttl + @cert.stub_everything - @issuer_name = mock 'issuer_name' - @issuer.stubs(:subject).returns @issuer_name + @factory.stubs :build_extensions - @public_key = mock 'public_key' - @csr.stubs(:public_key).returns @public_key + @factory.stubs :set_ttl - OpenSSL::X509::Certificate.stubs(:new).returns @cert - end + @issuer_name = mock 'issuer_name' + @issuer.stubs(:subject).returns @issuer_name - it "should return a new X509 certificate" do - OpenSSL::X509::Certificate.expects(:new).returns @cert - @factory.result.should equal(@cert) - end + @public_key = mock 'public_key' + @csr.stubs(:public_key).returns @public_key - it "should set the certificate's version to 2" do - @cert.expects(:version=).with 2 - @factory.result - end + OpenSSL::X509::Certificate.stubs(:new).returns @cert + end - it "should set the certificate's subject to the CSR's subject" do - @cert.expects(:subject=).with @name - @factory.result - end + it "should return a new X509 certificate" do + OpenSSL::X509::Certificate.expects(:new).returns @cert + @factory.result.should equal(@cert) + end - it "should set the certificate's issuer to the Issuer's subject" do - @cert.expects(:issuer=).with @issuer_name - @factory.result - end + it "should set the certificate's version to 2" do + @cert.expects(:version=).with 2 + @factory.result + end - it "should set the certificate's public key to the CSR's public key" do - @cert.expects(:public_key=).with @public_key - @factory.result - end + it "should set the certificate's subject to the CSR's subject" do + @cert.expects(:subject=).with @name + @factory.result + end - it "should set the certificate's serial number to the provided serial number" do - @cert.expects(:serial=).with @serial - @factory.result - end + it "should set the certificate's issuer to the Issuer's subject" do + @cert.expects(:issuer=).with @issuer_name + @factory.result + end - it "should build extensions for the certificate" do - @factory.expects(:build_extensions) - @factory.result - end + it "should set the certificate's public key to the CSR's public key" do + @cert.expects(:public_key=).with @public_key + @factory.result + end - it "should set the ttl of the certificate" do - @factory.expects(:set_ttl) - @factory.result - end + it "should set the certificate's serial number to the provided serial number" do + @cert.expects(:serial=).with @serial + @factory.result end - describe "when building extensions" do - it "should have tests" + it "should build extensions for the certificate" do + @factory.expects(:build_extensions) + @factory.result end - describe "when setting the ttl" do - it "should have tests" + it "should set the ttl of the certificate" do + @factory.expects(:set_ttl) + @factory.result end + end + + describe "when building extensions" do + it "should have tests" + end + + describe "when setting the ttl" do + it "should have tests" + end end diff --git a/spec/unit/ssl/certificate_request_spec.rb b/spec/unit/ssl/certificate_request_spec.rb index 253009b5d..437fc0556 100755 --- a/spec/unit/ssl/certificate_request_spec.rb +++ b/spec/unit/ssl/certificate_request_spec.rb @@ -6,215 +6,215 @@ require 'puppet/ssl/certificate_request' require 'puppet/ssl/key' describe Puppet::SSL::CertificateRequest do + before do + @class = Puppet::SSL::CertificateRequest + end + + it "should be extended with the Indirector module" do + @class.singleton_class.should be_include(Puppet::Indirector) + end + + it "should indirect certificate_request" do + @class.indirection.name.should == :certificate_request + end + + it "should use any provided name as its name" do + @class.new("myname").name.should == "myname" + end + + it "should only support the text format" do + @class.supported_formats.should == [:s] + end + + describe "when converting from a string" do + it "should create a CSR instance with its name set to the CSR subject and its content set to the extracted CSR" do + csr = stub 'csr', :subject => "/CN=Foo.madstop.com" + OpenSSL::X509::Request.expects(:new).with("my csr").returns(csr) + + mycsr = stub 'sslcsr' + mycsr.expects(:content=).with(csr) + + @class.expects(:new).with("foo.madstop.com").returns mycsr + + @class.from_s("my csr") + end + end + + describe "when managing instances" do + before do + @request = @class.new("myname") + end + + it "should have a name attribute" do + @request.name.should == "myname" + end + + it "should downcase its name" do + @class.new("MyName").name.should == "myname" + end + + it "should have a content attribute" do + @request.should respond_to(:content) + end + + it "should be able to read requests from disk" do + path = "/my/path" + File.expects(:read).with(path).returns("my request") + request = mock 'request' + OpenSSL::X509::Request.expects(:new).with("my request").returns(request) + @request.read(path).should equal(request) + @request.content.should equal(request) + end + + it "should return an empty string when converted to a string with no request" do + @request.to_s.should == "" + end + + it "should convert the request to pem format when converted to a string" do + request = mock 'request', :to_pem => "pem" + @request.content = request + @request.to_s.should == "pem" + end + + it "should have a :to_text method that it delegates to the actual key" do + real_request = mock 'request' + real_request.expects(:to_text).returns "requesttext" + @request.content = real_request + @request.to_text.should == "requesttext" + end + end + + describe "when generating" do before do - @class = Puppet::SSL::CertificateRequest + @instance = @class.new("myname") + + key = Puppet::SSL::Key.new("myname") + @key = key.generate + + @request = OpenSSL::X509::Request.new + OpenSSL::X509::Request.expects(:new).returns(@request) + + @request.stubs(:verify).returns(true) end - it "should be extended with the Indirector module" do - @class.singleton_class.should be_include(Puppet::Indirector) + it "should use the content of the provided key if the key is a Puppet::SSL::Key instance" do + key = Puppet::SSL::Key.new("test") + key.expects(:content).returns @key + + @request.expects(:sign).with{ |key, digest| key == @key } + @instance.generate(key) end - it "should indirect certificate_request" do - @class.indirection.name.should == :certificate_request + it "should log that it is creating a new certificate request" do + Puppet.expects(:info).twice + @instance.generate(@key) end - it "should use any provided name as its name" do - @class.new("myname").name.should == "myname" + it "should set the subject to [CN, name]" do + subject = mock 'subject' + OpenSSL::X509::Name.expects(:new).with([["CN", @instance.name]]).returns(subject) + @request.expects(:subject=).with(subject) + @instance.generate(@key) end - it "should only support the text format" do - @class.supported_formats.should == [:s] + it "should set the CN to the CSR name when the CSR is not for a CA" do + subject = mock 'subject' + OpenSSL::X509::Name.expects(:new).with { |subject| subject[0][1] == @instance.name }.returns(subject) + @request.expects(:subject=).with(subject) + @instance.generate(@key) end - describe "when converting from a string" do - it "should create a CSR instance with its name set to the CSR subject and its content set to the extracted CSR" do - csr = stub 'csr', :subject => "/CN=Foo.madstop.com" - OpenSSL::X509::Request.expects(:new).with("my csr").returns(csr) + it "should set the CN to the :ca_name setting when the CSR is for a CA" do + subject = mock 'subject' + Puppet.settings.expects(:value).with(:ca_name).returns "mycertname" + OpenSSL::X509::Name.expects(:new).with { |subject| subject[0][1] == "mycertname" }.returns(subject) + @request.expects(:subject=).with(subject) + Puppet::SSL::CertificateRequest.new(Puppet::SSL::CA_NAME).generate(@key) + end - mycsr = stub 'sslcsr' - mycsr.expects(:content=).with(csr) + it "should set the version to 0" do + @request.expects(:version=).with(0) + @instance.generate(@key) + end - @class.expects(:new).with("foo.madstop.com").returns mycsr + it "should set the public key to the provided key's public key" do + # Yay, the private key extracts a new key each time. + pubkey = @key.public_key + @key.stubs(:public_key).returns pubkey + @request.expects(:public_key=).with(@key.public_key) + @instance.generate(@key) + end - @class.from_s("my csr") - end + it "should sign the csr with the provided key and a digest" do + digest = mock 'digest' + OpenSSL::Digest::MD5.expects(:new).returns(digest) + @request.expects(:sign).with(@key, digest) + @instance.generate(@key) end - describe "when managing instances" do - before do - @request = @class.new("myname") - end + it "should verify the generated request using the public key" do + # Stupid keys don't have a competent == method. + @request.expects(:verify).with { |public_key| public_key.to_s == @key.public_key.to_s }.returns true + @instance.generate(@key) + end - it "should have a name attribute" do - @request.name.should == "myname" - end + it "should fail if verification fails" do + @request.expects(:verify).returns false - it "should downcase its name" do - @class.new("MyName").name.should == "myname" - end + lambda { @instance.generate(@key) }.should raise_error(Puppet::Error) + end - it "should have a content attribute" do - @request.should respond_to(:content) - end + it "should fingerprint the request" do + @instance.expects(:fingerprint) + @instance.generate(@key) + end - it "should be able to read requests from disk" do - path = "/my/path" - File.expects(:read).with(path).returns("my request") - request = mock 'request' - OpenSSL::X509::Request.expects(:new).with("my request").returns(request) - @request.read(path).should equal(request) - @request.content.should equal(request) - end + it "should display the fingerprint" do + Puppet.stubs(:info) + @instance.stubs(:fingerprint).returns("FINGERPRINT") + Puppet.expects(:info).with { |s| s =~ /FINGERPRINT/ } + @instance.generate(@key) + end - it "should return an empty string when converted to a string with no request" do - @request.to_s.should == "" - end + it "should return the generated request" do + @instance.generate(@key).should equal(@request) + end - it "should convert the request to pem format when converted to a string" do - request = mock 'request', :to_pem => "pem" - @request.content = request - @request.to_s.should == "pem" - end + it "should set its content to the generated request" do + @instance.generate(@key) + @instance.content.should equal(@request) + end + end - it "should have a :to_text method that it delegates to the actual key" do - real_request = mock 'request' - real_request.expects(:to_text).returns "requesttext" - @request.content = real_request - @request.to_text.should == "requesttext" - end - end - - describe "when generating" do - before do - @instance = @class.new("myname") + describe "when a CSR is saved" do + it "should allow arguments" do + csr = Puppet::SSL::CertificateRequest.new("me") + csr.class.indirection.stubs(:save) - key = Puppet::SSL::Key.new("myname") - @key = key.generate + lambda { csr.save :ipaddress => "foo" }.should_not raise_error + end - @request = OpenSSL::X509::Request.new - OpenSSL::X509::Request.expects(:new).returns(@request) + 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 - @request.stubs(:verify).returns(true) - end + csr = Puppet::SSL::CertificateRequest.new("me") + Puppet::SSL::CertificateRequest.indirection.expects(:save).with(nil, csr) - it "should use the content of the provided key if the key is a Puppet::SSL::Key instance" do - key = Puppet::SSL::Key.new("test") - key.expects(:content).returns @key + csr.save + end + end - @request.expects(:sign).with{ |key, digest| key == @key } - @instance.generate(key) - end + describe "and a CA is not available" do + it "should save the CSR" do + Puppet::SSL::CertificateAuthority.expects(:instance).returns nil - it "should log that it is creating a new certificate request" do - Puppet.expects(:info).twice - @instance.generate(@key) - end + csr = Puppet::SSL::CertificateRequest.new("me") + Puppet::SSL::CertificateRequest.indirection.expects(:save).with(nil, csr) - it "should set the subject to [CN, name]" do - subject = mock 'subject' - OpenSSL::X509::Name.expects(:new).with([["CN", @instance.name]]).returns(subject) - @request.expects(:subject=).with(subject) - @instance.generate(@key) - end - - it "should set the CN to the CSR name when the CSR is not for a CA" do - subject = mock 'subject' - OpenSSL::X509::Name.expects(:new).with { |subject| subject[0][1] == @instance.name }.returns(subject) - @request.expects(:subject=).with(subject) - @instance.generate(@key) - end - - it "should set the CN to the :ca_name setting when the CSR is for a CA" do - subject = mock 'subject' - Puppet.settings.expects(:value).with(:ca_name).returns "mycertname" - OpenSSL::X509::Name.expects(:new).with { |subject| subject[0][1] == "mycertname" }.returns(subject) - @request.expects(:subject=).with(subject) - Puppet::SSL::CertificateRequest.new(Puppet::SSL::CA_NAME).generate(@key) - end - - it "should set the version to 0" do - @request.expects(:version=).with(0) - @instance.generate(@key) - end - - it "should set the public key to the provided key's public key" do - # Yay, the private key extracts a new key each time. - pubkey = @key.public_key - @key.stubs(:public_key).returns pubkey - @request.expects(:public_key=).with(@key.public_key) - @instance.generate(@key) - end - - it "should sign the csr with the provided key and a digest" do - digest = mock 'digest' - OpenSSL::Digest::MD5.expects(:new).returns(digest) - @request.expects(:sign).with(@key, digest) - @instance.generate(@key) - end - - it "should verify the generated request using the public key" do - # Stupid keys don't have a competent == method. - @request.expects(:verify).with { |public_key| public_key.to_s == @key.public_key.to_s }.returns true - @instance.generate(@key) - end - - it "should fail if verification fails" do - @request.expects(:verify).returns false - - lambda { @instance.generate(@key) }.should raise_error(Puppet::Error) - end - - it "should fingerprint the request" do - @instance.expects(:fingerprint) - @instance.generate(@key) - end - - it "should display the fingerprint" do - Puppet.stubs(:info) - @instance.stubs(:fingerprint).returns("FINGERPRINT") - Puppet.expects(:info).with { |s| s =~ /FINGERPRINT/ } - @instance.generate(@key) - end - - it "should return the generated request" do - @instance.generate(@key).should equal(@request) - end - - it "should set its content to the generated request" do - @instance.generate(@key) - @instance.content.should equal(@request) - end - end - - describe "when a CSR is saved" do - it "should allow arguments" do - csr = Puppet::SSL::CertificateRequest.new("me") - csr.class.indirection.stubs(:save) - - lambda { csr.save :ipaddress => "foo" }.should_not raise_error - end - - 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(nil, 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(nil, csr) - - csr.save - end - end + csr.save + end end + end end diff --git a/spec/unit/ssl/certificate_revocation_list_spec.rb b/spec/unit/ssl/certificate_revocation_list_spec.rb index 3d15db78b..f9993d52e 100755 --- a/spec/unit/ssl/certificate_revocation_list_spec.rb +++ b/spec/unit/ssl/certificate_revocation_list_spec.rb @@ -5,164 +5,164 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/ssl/certificate_revocation_list' describe Puppet::SSL::CertificateRevocationList do - before do - @cert = stub 'cert', :subject => "mysubject" - @key = stub 'key', :private? => true + before do + @cert = stub 'cert', :subject => "mysubject" + @key = stub 'key', :private? => true - @class = Puppet::SSL::CertificateRevocationList - end + @class = Puppet::SSL::CertificateRevocationList + end - it "should only support the text format" do - @class.supported_formats.should == [:s] - end + it "should only support the text format" do + @class.supported_formats.should == [:s] + end - describe "when converting from a string" do - it "should create a CRL instance with its name set to 'foo' and its content set to the extracted CRL" do - crl = stub 'crl' - OpenSSL::X509::CRL.expects(:new).returns(crl) + describe "when converting from a string" do + it "should create a CRL instance with its name set to 'foo' and its content set to the extracted CRL" do + crl = stub 'crl' + OpenSSL::X509::CRL.expects(:new).returns(crl) - mycrl = stub 'sslcrl' - mycrl.expects(:content=).with(crl) + mycrl = stub 'sslcrl' + mycrl.expects(:content=).with(crl) - @class.expects(:new).with("foo").returns mycrl + @class.expects(:new).with("foo").returns mycrl - @class.from_s("my crl").should == mycrl - end + @class.from_s("my crl").should == mycrl end + end - describe "when an instance" do - before do - @class.any_instance.stubs(:read_or_generate) + describe "when an instance" do + before do + @class.any_instance.stubs(:read_or_generate) - @crl = @class.new("whatever") - end + @crl = @class.new("whatever") + end - it "should always use 'crl' for its name" do - @crl.name.should == "crl" - end + it "should always use 'crl' for its name" do + @crl.name.should == "crl" + end - it "should have a content attribute" do - @crl.should respond_to(:content) - end + it "should have a content attribute" do + @crl.should respond_to(:content) end + end - describe "when generating the crl" do - before do - @real_crl = mock 'crl' - @real_crl.stub_everything + describe "when generating the crl" do + before do + @real_crl = mock 'crl' + @real_crl.stub_everything - OpenSSL::X509::CRL.stubs(:new).returns(@real_crl) + OpenSSL::X509::CRL.stubs(:new).returns(@real_crl) - @class.any_instance.stubs(:read_or_generate) + @class.any_instance.stubs(:read_or_generate) - @crl = @class.new("crl") - end + @crl = @class.new("crl") + end - it "should set its issuer to the subject of the passed certificate" do - @real_crl.expects(:issuer=).with(@cert.subject) + it "should set its issuer to the subject of the passed certificate" do + @real_crl.expects(:issuer=).with(@cert.subject) - @crl.generate(@cert, @key) - end + @crl.generate(@cert, @key) + end - it "should set its version to 1" do - @real_crl.expects(:version=).with(1) + it "should set its version to 1" do + @real_crl.expects(:version=).with(1) - @crl.generate(@cert, @key) - end + @crl.generate(@cert, @key) + end - it "should create an instance of OpenSSL::X509::CRL" do - OpenSSL::X509::CRL.expects(:new).returns(@real_crl) + it "should create an instance of OpenSSL::X509::CRL" do + OpenSSL::X509::CRL.expects(:new).returns(@real_crl) - @crl.generate(@cert, @key) - end + @crl.generate(@cert, @key) + end - # The next three tests aren't good, but at least they - # specify the behaviour. - it "should add an extension for the CRL number" do - @real_crl.expects(:extensions=) - @crl.generate(@cert, @key) - end + # The next three tests aren't good, but at least they + # specify the behaviour. + it "should add an extension for the CRL number" do + @real_crl.expects(:extensions=) + @crl.generate(@cert, @key) + end - it "should set the last update time" do - @real_crl.expects(:last_update=) - @crl.generate(@cert, @key) - end + it "should set the last update time" do + @real_crl.expects(:last_update=) + @crl.generate(@cert, @key) + end - it "should set the next update time" do - @real_crl.expects(:next_update=) - @crl.generate(@cert, @key) - end + it "should set the next update time" do + @real_crl.expects(:next_update=) + @crl.generate(@cert, @key) + end - it "should sign the CRL" do - @real_crl.expects(:sign).with { |key, digest| key == @key } - @crl.generate(@cert, @key) - end + it "should sign the CRL" do + @real_crl.expects(:sign).with { |key, digest| key == @key } + @crl.generate(@cert, @key) + end - it "should set the content to the generated crl" do - @crl.generate(@cert, @key) - @crl.content.should equal(@real_crl) - end + it "should set the content to the generated crl" do + @crl.generate(@cert, @key) + @crl.content.should equal(@real_crl) + end - it "should return the generated crl" do - @crl.generate(@cert, @key).should equal(@real_crl) - end + it "should return the generated crl" do + @crl.generate(@cert, @key).should equal(@real_crl) end + end - # This test suite isn't exactly complete, because the - # SSL stuff is very complicated. It just hits the high points. - describe "when revoking a certificate" do - before do - @class.wrapped_class.any_instance.stubs(:issuer=) - @class.wrapped_class.any_instance.stubs(:sign) + # This test suite isn't exactly complete, because the + # SSL stuff is very complicated. It just hits the high points. + describe "when revoking a certificate" do + before do + @class.wrapped_class.any_instance.stubs(:issuer=) + @class.wrapped_class.any_instance.stubs(:sign) - @crl = @class.new("crl") - @crl.generate(@cert, @key) - @crl.content.stubs(:sign) + @crl = @class.new("crl") + @crl.generate(@cert, @key) + @crl.content.stubs(:sign) - @crl.stubs :save + @crl.stubs :save - @key = mock 'key' - end + @key = mock 'key' + end - it "should require a serial number and the CA's private key" do - lambda { @crl.revoke }.should raise_error(ArgumentError) - end + it "should require a serial number and the CA's private key" do + lambda { @crl.revoke }.should raise_error(ArgumentError) + end - it "should default to OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE as the revocation reason" do - # This makes it a bit more of an integration test than we'd normally like, but that's life - # with openssl. - reason = OpenSSL::ASN1::Enumerated(OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE) - OpenSSL::ASN1.expects(:Enumerated).with(OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE).returns reason + it "should default to OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE as the revocation reason" do + # This makes it a bit more of an integration test than we'd normally like, but that's life + # with openssl. + reason = OpenSSL::ASN1::Enumerated(OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE) + OpenSSL::ASN1.expects(:Enumerated).with(OpenSSL::OCSP::REVOKED_STATUS_KEYCOMPROMISE).returns reason - @crl.revoke(1, @key) - end + @crl.revoke(1, @key) + end - it "should mark the CRL as updated" do - time = Time.now - Time.stubs(:now).returns time + it "should mark the CRL as updated" do + time = Time.now + Time.stubs(:now).returns time - @crl.content.expects(:last_update=).with(time) + @crl.content.expects(:last_update=).with(time) - @crl.revoke(1, @key) - end + @crl.revoke(1, @key) + end - it "should mark the CRL valid for five years" do - time = Time.now - Time.stubs(:now).returns time + it "should mark the CRL valid for five years" do + time = Time.now + Time.stubs(:now).returns time - @crl.content.expects(:next_update=).with(time + (5 * 365*24*60*60)) + @crl.content.expects(:next_update=).with(time + (5 * 365*24*60*60)) - @crl.revoke(1, @key) - end + @crl.revoke(1, @key) + end - it "should sign the CRL with the CA's private key and a digest instance" do - @crl.content.expects(:sign).with { |key, digest| key == @key and digest.is_a?(OpenSSL::Digest::SHA1) } - @crl.revoke(1, @key) - end + it "should sign the CRL with the CA's private key and a digest instance" do + @crl.content.expects(:sign).with { |key, digest| key == @key and digest.is_a?(OpenSSL::Digest::SHA1) } + @crl.revoke(1, @key) + end - it "should save the CRL" do - @crl.expects :save - @crl.revoke(1, @key) - end + it "should save the CRL" do + @crl.expects :save + @crl.revoke(1, @key) end + end end diff --git a/spec/unit/ssl/certificate_spec.rb b/spec/unit/ssl/certificate_spec.rb index 6bd7e77f5..842aa35c5 100755 --- a/spec/unit/ssl/certificate_spec.rb +++ b/spec/unit/ssl/certificate_spec.rb @@ -5,120 +5,120 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/ssl/certificate' describe Puppet::SSL::Certificate do - before do - @class = Puppet::SSL::Certificate + before do + @class = Puppet::SSL::Certificate + end + + after do + @class.instance_variable_set("@ca_location", nil) + end + + it "should be extended with the Indirector module" do + @class.singleton_class.should be_include(Puppet::Indirector) + end + + it "should indirect certificate" do + @class.indirection.name.should == :certificate + end + + it "should only support the text format" do + @class.supported_formats.should == [:s] + end + + describe "when converting from a string" do + it "should create a certificate instance with its name set to the certificate subject and its content set to the extracted certificate" do + cert = stub 'certificate', :subject => "/CN=Foo.madstop.com" + OpenSSL::X509::Certificate.expects(:new).with("my certificate").returns(cert) + + mycert = stub 'sslcert' + mycert.expects(:content=).with(cert) + + @class.expects(:new).with("foo.madstop.com").returns mycert + + @class.from_s("my certificate") end - after do - @class.instance_variable_set("@ca_location", nil) + it "should create multiple certificate instances when asked" do + cert1 = stub 'cert1' + @class.expects(:from_s).with("cert1").returns cert1 + cert2 = stub 'cert2' + @class.expects(:from_s).with("cert2").returns cert2 + + @class.from_multiple_s("cert1\n---\ncert2").should == [cert1, cert2] end + end - it "should be extended with the Indirector module" do - @class.singleton_class.should be_include(Puppet::Indirector) + describe "when converting to a string" do + before do + @certificate = @class.new("myname") end - it "should indirect certificate" do - @class.indirection.name.should == :certificate + it "should return an empty string when it has no certificate" do + @certificate.to_s.should == "" end - it "should only support the text format" do - @class.supported_formats.should == [:s] + it "should convert the certificate to pem format" do + certificate = mock 'certificate', :to_pem => "pem" + @certificate.content = certificate + @certificate.to_s.should == "pem" end - describe "when converting from a string" do - it "should create a certificate instance with its name set to the certificate subject and its content set to the extracted certificate" do - cert = stub 'certificate', :subject => "/CN=Foo.madstop.com" - OpenSSL::X509::Certificate.expects(:new).with("my certificate").returns(cert) + it "should be able to convert multiple instances to a string" do + cert2 = @class.new("foo") + @certificate.expects(:to_s).returns "cert1" + cert2.expects(:to_s).returns "cert2" - mycert = stub 'sslcert' - mycert.expects(:content=).with(cert) + @class.to_multiple_s([@certificate, cert2]).should == "cert1\n---\ncert2" - @class.expects(:new).with("foo.madstop.com").returns mycert + end + end - @class.from_s("my certificate") - end + describe "when managing instances" do + before do + @certificate = @class.new("myname") + end - it "should create multiple certificate instances when asked" do - cert1 = stub 'cert1' - @class.expects(:from_s).with("cert1").returns cert1 - cert2 = stub 'cert2' - @class.expects(:from_s).with("cert2").returns cert2 + it "should have a name attribute" do + @certificate.name.should == "myname" + end - @class.from_multiple_s("cert1\n---\ncert2").should == [cert1, cert2] - end + it "should convert its name to a string and downcase it" do + @class.new(:MyName).name.should == "myname" end - describe "when converting to a string" do - before do - @certificate = @class.new("myname") - end + it "should have a content attribute" do + @certificate.should respond_to(:content) + end + + it "should return a nil expiration if there is no actual certificate" do + @certificate.stubs(:content).returns nil - it "should return an empty string when it has no certificate" do - @certificate.to_s.should == "" - end + @certificate.expiration.should be_nil + end - it "should convert the certificate to pem format" do - certificate = mock 'certificate', :to_pem => "pem" - @certificate.content = certificate - @certificate.to_s.should == "pem" - end + it "should use the expiration of the certificate as its expiration date" do + cert = stub 'cert' + @certificate.stubs(:content).returns cert - it "should be able to convert multiple instances to a string" do - cert2 = @class.new("foo") - @certificate.expects(:to_s).returns "cert1" - cert2.expects(:to_s).returns "cert2" + cert.expects(:not_after).returns "sometime" - @class.to_multiple_s([@certificate, cert2]).should == "cert1\n---\ncert2" + @certificate.expiration.should == "sometime" + end - end + it "should be able to read certificates from disk" do + path = "/my/path" + File.expects(:read).with(path).returns("my certificate") + certificate = mock 'certificate' + OpenSSL::X509::Certificate.expects(:new).with("my certificate").returns(certificate) + @certificate.read(path).should equal(certificate) + @certificate.content.should equal(certificate) end - describe "when managing instances" do - before do - @certificate = @class.new("myname") - end - - it "should have a name attribute" do - @certificate.name.should == "myname" - end - - it "should convert its name to a string and downcase it" do - @class.new(:MyName).name.should == "myname" - end - - it "should have a content attribute" do - @certificate.should respond_to(:content) - end - - it "should return a nil expiration if there is no actual certificate" do - @certificate.stubs(:content).returns nil - - @certificate.expiration.should be_nil - end - - it "should use the expiration of the certificate as its expiration date" do - cert = stub 'cert' - @certificate.stubs(:content).returns cert - - cert.expects(:not_after).returns "sometime" - - @certificate.expiration.should == "sometime" - end - - it "should be able to read certificates from disk" do - path = "/my/path" - File.expects(:read).with(path).returns("my certificate") - certificate = mock 'certificate' - OpenSSL::X509::Certificate.expects(:new).with("my certificate").returns(certificate) - @certificate.read(path).should equal(certificate) - @certificate.content.should equal(certificate) - end - - it "should have a :to_text method that it delegates to the actual key" do - real_certificate = mock 'certificate' - real_certificate.expects(:to_text).returns "certificatetext" - @certificate.content = real_certificate - @certificate.to_text.should == "certificatetext" - end + it "should have a :to_text method that it delegates to the actual key" do + real_certificate = mock 'certificate' + real_certificate.expects(:to_text).returns "certificatetext" + @certificate.content = real_certificate + @certificate.to_text.should == "certificatetext" end + end end diff --git a/spec/unit/ssl/host_spec.rb b/spec/unit/ssl/host_spec.rb index 0b6591d60..b2e43393c 100755 --- a/spec/unit/ssl/host_spec.rb +++ b/spec/unit/ssl/host_spec.rb @@ -5,703 +5,703 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/ssl/host' describe Puppet::SSL::Host do - before do - @class = Puppet::SSL::Host - @host = @class.new("myname") - end + before do + @class = Puppet::SSL::Host + @host = @class.new("myname") + end - after do - # Cleaned out any cached localhost instance. - Puppet::Util::Cacher.expire - end + after do + # Cleaned out any cached localhost instance. + Puppet::Util::Cacher.expire + end - it "should use any provided name as its name" do - @host.name.should == "myname" - end + it "should use any provided name as its name" do + @host.name.should == "myname" + end - it "should retrieve its public key from its private key" do - realkey = mock 'realkey' - key = stub 'key', :content => realkey - Puppet::SSL::Key.stubs(:find).returns(key) - pubkey = mock 'public_key' - realkey.expects(:public_key).returns pubkey + it "should retrieve its public key from its private key" do + realkey = mock 'realkey' + key = stub 'key', :content => realkey + Puppet::SSL::Key.stubs(:find).returns(key) + pubkey = mock 'public_key' + realkey.expects(:public_key).returns pubkey - @host.public_key.should equal(pubkey) - end + @host.public_key.should equal(pubkey) + end - it "should default to being a non-ca host" do - @host.ca?.should be_false - end + it "should default to being a non-ca host" do + @host.ca?.should be_false + end - it "should be a ca host if its name matches the CA_NAME" do - Puppet::SSL::Host.stubs(:ca_name).returns "yayca" - Puppet::SSL::Host.new("yayca").should be_ca - end + it "should be a ca host if its name matches the CA_NAME" do + Puppet::SSL::Host.stubs(:ca_name).returns "yayca" + Puppet::SSL::Host.new("yayca").should be_ca + end - it "should have a method for determining the CA location" do - Puppet::SSL::Host.should respond_to(:ca_location) - end + it "should have a method for determining the CA location" do + Puppet::SSL::Host.should respond_to(:ca_location) + end - it "should have a method for specifying the CA location" do - Puppet::SSL::Host.should respond_to(:ca_location=) - end + it "should have a method for specifying the CA location" do + Puppet::SSL::Host.should respond_to(:ca_location=) + end - it "should have a method for retrieving the default ssl host" do - Puppet::SSL::Host.should respond_to(:ca_location=) - end + it "should have a method for retrieving the default ssl host" do + Puppet::SSL::Host.should respond_to(:ca_location=) + end - it "should have a method for producing an instance to manage the local host's keys" do - Puppet::SSL::Host.should respond_to(:localhost) - end + it "should have a method for producing an instance to manage the local host's keys" do + Puppet::SSL::Host.should respond_to(:localhost) + end - it "should generate the certificate for the localhost instance if no certificate is available" do - host = stub 'host', :key => nil - Puppet::SSL::Host.expects(:new).returns host + it "should generate the certificate for the localhost instance if no certificate is available" do + host = stub 'host', :key => nil + Puppet::SSL::Host.expects(:new).returns host - host.expects(:certificate).returns nil - host.expects(:generate) + host.expects(:certificate).returns nil + host.expects(:generate) - Puppet::SSL::Host.localhost.should equal(host) - end + Puppet::SSL::Host.localhost.should equal(host) + end - it "should always read the key for the localhost instance in from disk" do - host = stub 'host', :certificate => "eh" - Puppet::SSL::Host.expects(:new).returns host + it "should always read the key for the localhost instance in from disk" do + host = stub 'host', :certificate => "eh" + Puppet::SSL::Host.expects(:new).returns host - host.expects(:key) + host.expects(:key) - Puppet::SSL::Host.localhost - end + Puppet::SSL::Host.localhost + end + + it "should cache the localhost instance" do + host = stub 'host', :certificate => "eh", :key => 'foo' + Puppet::SSL::Host.expects(:new).once.returns host + + Puppet::SSL::Host.localhost.should == Puppet::SSL::Host.localhost + end + + it "should be able to expire the cached instance" do + one = stub 'host1', :certificate => "eh", :key => 'foo' + two = stub 'host2', :certificate => "eh", :key => 'foo' + Puppet::SSL::Host.expects(:new).times(2).returns(one).then.returns(two) + + Puppet::SSL::Host.localhost.should equal(one) + Puppet::Util::Cacher.expire + Puppet::SSL::Host.localhost.should equal(two) + end + + it "should be able to verify its certificate matches its key" do + Puppet::SSL::Host.new("foo").should respond_to(:certificate_matches_key?) + end + + it "should consider the certificate invalid if it cannot find a key" do + host = Puppet::SSL::Host.new("foo") + host.expects(:key).returns nil + + host.should_not be_certificate_matches_key + end + + it "should consider the certificate invalid if it cannot find a certificate" do + host = Puppet::SSL::Host.new("foo") + host.expects(:key).returns mock("key") + host.expects(:certificate).returns nil + + host.should_not be_certificate_matches_key + end + + it "should consider the certificate invalid if the SSL certificate's key verification fails" do + host = Puppet::SSL::Host.new("foo") + + key = mock 'key', :content => "private_key" + sslcert = mock 'sslcert' + certificate = mock 'cert', :content => sslcert + + host.stubs(:key).returns key + host.stubs(:certificate).returns certificate - it "should cache the localhost instance" do - host = stub 'host', :certificate => "eh", :key => 'foo' - Puppet::SSL::Host.expects(:new).once.returns host + sslcert.expects(:check_private_key).with("private_key").returns false - Puppet::SSL::Host.localhost.should == Puppet::SSL::Host.localhost + host.should_not be_certificate_matches_key + end + + it "should consider the certificate valid if the SSL certificate's key verification succeeds" do + host = Puppet::SSL::Host.new("foo") + + key = mock 'key', :content => "private_key" + sslcert = mock 'sslcert' + certificate = mock 'cert', :content => sslcert + + host.stubs(:key).returns key + host.stubs(:certificate).returns certificate + + sslcert.expects(:check_private_key).with("private_key").returns true + + host.should be_certificate_matches_key + end + + describe "when specifying the CA location" do + before do + [Puppet::SSL::Key, Puppet::SSL::Certificate, Puppet::SSL::CertificateRequest, Puppet::SSL::CertificateRevocationList].each do |klass| + klass.stubs(:terminus_class=) + klass.stubs(:cache_class=) + end end - it "should be able to expire the cached instance" do - one = stub 'host1', :certificate => "eh", :key => 'foo' - two = stub 'host2', :certificate => "eh", :key => 'foo' - Puppet::SSL::Host.expects(:new).times(2).returns(one).then.returns(two) + it "should support the location ':local'" do + lambda { Puppet::SSL::Host.ca_location = :local }.should_not raise_error + end - Puppet::SSL::Host.localhost.should equal(one) - Puppet::Util::Cacher.expire - Puppet::SSL::Host.localhost.should equal(two) + it "should support the location ':remote'" do + lambda { Puppet::SSL::Host.ca_location = :remote }.should_not raise_error end - it "should be able to verify its certificate matches its key" do - Puppet::SSL::Host.new("foo").should respond_to(:certificate_matches_key?) + it "should support the location ':none'" do + lambda { Puppet::SSL::Host.ca_location = :none }.should_not raise_error end - it "should consider the certificate invalid if it cannot find a key" do - host = Puppet::SSL::Host.new("foo") - host.expects(:key).returns nil + it "should support the location ':only'" do + lambda { Puppet::SSL::Host.ca_location = :only }.should_not raise_error + end - host.should_not be_certificate_matches_key + it "should not support other modes" do + lambda { Puppet::SSL::Host.ca_location = :whatever }.should raise_error(ArgumentError) end - it "should consider the certificate invalid if it cannot find a certificate" do - host = Puppet::SSL::Host.new("foo") - host.expects(:key).returns mock("key") - host.expects(:certificate).returns nil + describe "as 'local'" do + it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do + Puppet::SSL::Certificate.expects(:cache_class=).with :file + Puppet::SSL::CertificateRequest.expects(:cache_class=).with :file + Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with :file + + Puppet::SSL::Host.ca_location = :local + end + + it "should set the terminus class for Key as :file" do + Puppet::SSL::Key.expects(:terminus_class=).with :file + + Puppet::SSL::Host.ca_location = :local + end - host.should_not be_certificate_matches_key + it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :ca" do + Puppet::SSL::Certificate.expects(:terminus_class=).with :ca + Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :ca + Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :ca + + Puppet::SSL::Host.ca_location = :local + end end - it "should consider the certificate invalid if the SSL certificate's key verification fails" do - host = Puppet::SSL::Host.new("foo") + describe "as 'remote'" do + it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do + Puppet::SSL::Certificate.expects(:cache_class=).with :file + Puppet::SSL::CertificateRequest.expects(:cache_class=).with :file + Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with :file + + Puppet::SSL::Host.ca_location = :remote + end - key = mock 'key', :content => "private_key" - sslcert = mock 'sslcert' - certificate = mock 'cert', :content => sslcert + it "should set the terminus class for Key as :file" do + Puppet::SSL::Key.expects(:terminus_class=).with :file - host.stubs(:key).returns key - host.stubs(:certificate).returns certificate + Puppet::SSL::Host.ca_location = :remote + end - sslcert.expects(:check_private_key).with("private_key").returns false + it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :rest" do + Puppet::SSL::Certificate.expects(:terminus_class=).with :rest + Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :rest + Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :rest - host.should_not be_certificate_matches_key + Puppet::SSL::Host.ca_location = :remote + end end - it "should consider the certificate valid if the SSL certificate's key verification succeeds" do - host = Puppet::SSL::Host.new("foo") + describe "as 'only'" do + it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :ca" do + Puppet::SSL::Key.expects(:terminus_class=).with :ca + Puppet::SSL::Certificate.expects(:terminus_class=).with :ca + Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :ca + Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :ca + + Puppet::SSL::Host.ca_location = :only + end - key = mock 'key', :content => "private_key" - sslcert = mock 'sslcert' - certificate = mock 'cert', :content => sslcert + it "should reset the cache class for Certificate, CertificateRevocationList, and CertificateRequest to nil" do + Puppet::SSL::Certificate.expects(:cache_class=).with nil + Puppet::SSL::CertificateRequest.expects(:cache_class=).with nil + Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with nil - host.stubs(:key).returns key - host.stubs(:certificate).returns certificate + Puppet::SSL::Host.ca_location = :only + end + end - sslcert.expects(:check_private_key).with("private_key").returns true + describe "as 'none'" do + it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :file" do + Puppet::SSL::Key.expects(:terminus_class=).with :file + Puppet::SSL::Certificate.expects(:terminus_class=).with :file + Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :file + Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :file - host.should be_certificate_matches_key + Puppet::SSL::Host.ca_location = :none + end end + end - describe "when specifying the CA location" do - before do - [Puppet::SSL::Key, Puppet::SSL::Certificate, Puppet::SSL::CertificateRequest, Puppet::SSL::CertificateRevocationList].each do |klass| - klass.stubs(:terminus_class=) - klass.stubs(:cache_class=) - end - end + it "should have a class method for destroying all files related to a given host" do + Puppet::SSL::Host.should respond_to(:destroy) + end - it "should support the location ':local'" do - lambda { Puppet::SSL::Host.ca_location = :local }.should_not raise_error - end + describe "when destroying a host's SSL files" do + before do + Puppet::SSL::Key.stubs(:destroy).returns false + Puppet::SSL::Certificate.stubs(:destroy).returns false + Puppet::SSL::CertificateRequest.stubs(:destroy).returns false + end - it "should support the location ':remote'" do - lambda { Puppet::SSL::Host.ca_location = :remote }.should_not raise_error - end + it "should destroy its certificate, certificate request, and key" do + Puppet::SSL::Key.expects(:destroy).with("myhost") + Puppet::SSL::Certificate.expects(:destroy).with("myhost") + Puppet::SSL::CertificateRequest.expects(:destroy).with("myhost") - it "should support the location ':none'" do - lambda { Puppet::SSL::Host.ca_location = :none }.should_not raise_error - end + Puppet::SSL::Host.destroy("myhost") + end - it "should support the location ':only'" do - lambda { Puppet::SSL::Host.ca_location = :only }.should_not raise_error - end + it "should return true if any of the classes returned true" do + Puppet::SSL::Certificate.expects(:destroy).with("myhost").returns true - it "should not support other modes" do - lambda { Puppet::SSL::Host.ca_location = :whatever }.should raise_error(ArgumentError) - end + Puppet::SSL::Host.destroy("myhost").should be_true + end - describe "as 'local'" do - it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do - Puppet::SSL::Certificate.expects(:cache_class=).with :file - Puppet::SSL::CertificateRequest.expects(:cache_class=).with :file - Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with :file + it "should return false if none of the classes returned true" do + Puppet::SSL::Host.destroy("myhost").should be_false + end + end - Puppet::SSL::Host.ca_location = :local - end + describe "when initializing" do + it "should default its name to the :certname setting" do + Puppet.settings.expects(:value).with(:certname).returns "myname" - it "should set the terminus class for Key as :file" do - Puppet::SSL::Key.expects(:terminus_class=).with :file + Puppet::SSL::Host.new.name.should == "myname" + end - Puppet::SSL::Host.ca_location = :local - end + it "should downcase a passed in name" do + Puppet::SSL::Host.new("Host.Domain.Com").name.should == "host.domain.com" + end - it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :ca" do - Puppet::SSL::Certificate.expects(:terminus_class=).with :ca - Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :ca - Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :ca + it "should downcase the certname if it's used" do + Puppet.settings.expects(:value).with(:certname).returns "Host.Domain.Com" + Puppet::SSL::Host.new.name.should == "host.domain.com" + end - Puppet::SSL::Host.ca_location = :local - end - end + it "should indicate that it is a CA host if its name matches the ca_name constant" do + Puppet::SSL::Host.stubs(:ca_name).returns "myca" + Puppet::SSL::Host.new("myca").should be_ca + end + end - describe "as 'remote'" do - it "should set the cache class for Certificate, CertificateRevocationList, and CertificateRequest as :file" do - Puppet::SSL::Certificate.expects(:cache_class=).with :file - Puppet::SSL::CertificateRequest.expects(:cache_class=).with :file - Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with :file + describe "when managing its private key" do + before do + @realkey = "mykey" + @key = stub 'key', :content => @realkey + end - Puppet::SSL::Host.ca_location = :remote - end + it "should return nil if the key is not set and cannot be found" do + Puppet::SSL::Key.expects(:find).with("myname").returns(nil) + @host.key.should be_nil + end - it "should set the terminus class for Key as :file" do - Puppet::SSL::Key.expects(:terminus_class=).with :file + it "should find the key in the Key class and return the Puppet instance" do + Puppet::SSL::Key.expects(:find).with("myname").returns(@key) + @host.key.should equal(@key) + end - Puppet::SSL::Host.ca_location = :remote - end + it "should be able to generate and save a new key" do + Puppet::SSL::Key.expects(:new).with("myname").returns(@key) - it "should set the terminus class for Certificate, CertificateRevocationList, and CertificateRequest as :rest" do - Puppet::SSL::Certificate.expects(:terminus_class=).with :rest - Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :rest - Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :rest + @key.expects(:generate) + @key.expects(:save) - Puppet::SSL::Host.ca_location = :remote - end - end + @host.generate_key.should be_true + @host.key.should equal(@key) + end - describe "as 'only'" do - it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :ca" do - Puppet::SSL::Key.expects(:terminus_class=).with :ca - Puppet::SSL::Certificate.expects(:terminus_class=).with :ca - Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :ca - Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :ca + it "should not retain keys that could not be saved" do + Puppet::SSL::Key.expects(:new).with("myname").returns(@key) - Puppet::SSL::Host.ca_location = :only - end + @key.stubs(:generate) + @key.expects(:save).raises "eh" - it "should reset the cache class for Certificate, CertificateRevocationList, and CertificateRequest to nil" do - Puppet::SSL::Certificate.expects(:cache_class=).with nil - Puppet::SSL::CertificateRequest.expects(:cache_class=).with nil - Puppet::SSL::CertificateRevocationList.expects(:cache_class=).with nil + lambda { @host.generate_key }.should raise_error + @host.key.should be_nil + end - Puppet::SSL::Host.ca_location = :only - end - end + it "should return any previously found key without requerying" do + Puppet::SSL::Key.expects(:find).with("myname").returns(@key).once + @host.key.should equal(@key) + @host.key.should equal(@key) + end + end - describe "as 'none'" do - it "should set the terminus class for Key, Certificate, CertificateRevocationList, and CertificateRequest as :file" do - Puppet::SSL::Key.expects(:terminus_class=).with :file - Puppet::SSL::Certificate.expects(:terminus_class=).with :file - Puppet::SSL::CertificateRequest.expects(:terminus_class=).with :file - Puppet::SSL::CertificateRevocationList.expects(:terminus_class=).with :file + describe "when managing its certificate request" do + before do + @realrequest = "real request" + @request = stub 'request', :content => @realrequest + end - Puppet::SSL::Host.ca_location = :none - end - end + it "should return nil if the key is not set and cannot be found" do + Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns(nil) + @host.certificate_request.should be_nil end - it "should have a class method for destroying all files related to a given host" do - Puppet::SSL::Host.should respond_to(:destroy) + it "should find the request in the Key class and return it and return the Puppet SSL request" do + Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns @request + + @host.certificate_request.should equal(@request) end - describe "when destroying a host's SSL files" do - before do - Puppet::SSL::Key.stubs(:destroy).returns false - Puppet::SSL::Certificate.stubs(:destroy).returns false - Puppet::SSL::CertificateRequest.stubs(:destroy).returns false - end + it "should generate a new key when generating the cert request if no key exists" do + Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request + + key = stub 'key', :public_key => mock("public_key"), :content => "mycontent" - it "should destroy its certificate, certificate request, and key" do - Puppet::SSL::Key.expects(:destroy).with("myhost") - Puppet::SSL::Certificate.expects(:destroy).with("myhost") - Puppet::SSL::CertificateRequest.expects(:destroy).with("myhost") + @host.expects(:key).times(2).returns(nil).then.returns(key) + @host.expects(:generate_key).returns(key) - Puppet::SSL::Host.destroy("myhost") - end + @request.stubs(:generate) + @request.stubs(:save) - it "should return true if any of the classes returned true" do - Puppet::SSL::Certificate.expects(:destroy).with("myhost").returns true + @host.generate_certificate_request + end + + it "should be able to generate and save a new request using the private key" do + Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request - Puppet::SSL::Host.destroy("myhost").should be_true - end + key = stub 'key', :public_key => mock("public_key"), :content => "mycontent" + @host.stubs(:key).returns(key) + @request.expects(:generate).with("mycontent") + @request.expects(:save) - it "should return false if none of the classes returned true" do - Puppet::SSL::Host.destroy("myhost").should be_false - end + @host.generate_certificate_request.should be_true + @host.certificate_request.should equal(@request) end - describe "when initializing" do - it "should default its name to the :certname setting" do - Puppet.settings.expects(:value).with(:certname).returns "myname" + it "should return any previously found request without requerying" do + Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns(@request).once + + @host.certificate_request.should equal(@request) + @host.certificate_request.should equal(@request) + end - Puppet::SSL::Host.new.name.should == "myname" - end + it "should not keep its certificate request in memory if the request cannot be saved" do + Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request - it "should downcase a passed in name" do - Puppet::SSL::Host.new("Host.Domain.Com").name.should == "host.domain.com" - end + key = stub 'key', :public_key => mock("public_key"), :content => "mycontent" + @host.stubs(:key).returns(key) + @request.stubs(:generate) + @request.expects(:save).raises "eh" - it "should downcase the certname if it's used" do - Puppet.settings.expects(:value).with(:certname).returns "Host.Domain.Com" - Puppet::SSL::Host.new.name.should == "host.domain.com" - end + lambda { @host.generate_certificate_request }.should raise_error - it "should indicate that it is a CA host if its name matches the ca_name constant" do - Puppet::SSL::Host.stubs(:ca_name).returns "myca" - Puppet::SSL::Host.new("myca").should be_ca - end + @host.certificate_request.should be_nil end + end - describe "when managing its private key" do - before do - @realkey = "mykey" - @key = stub 'key', :content => @realkey - end + describe "when managing its certificate" do + before do + @realcert = mock 'certificate' + @cert = stub 'cert', :content => @realcert - it "should return nil if the key is not set and cannot be found" do - Puppet::SSL::Key.expects(:find).with("myname").returns(nil) - @host.key.should be_nil - end + @host.stubs(:key).returns mock("key") + @host.stubs(:certificate_matches_key?).returns true + end - it "should find the key in the Key class and return the Puppet instance" do - Puppet::SSL::Key.expects(:find).with("myname").returns(@key) - @host.key.should equal(@key) - end + it "should find the CA certificate if it does not have a certificate" do + Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") + Puppet::SSL::Certificate.stubs(:find).with("myname").returns @cert - it "should be able to generate and save a new key" do - Puppet::SSL::Key.expects(:new).with("myname").returns(@key) + @host.certificate + end - @key.expects(:generate) - @key.expects(:save) + it "should not find the CA certificate if it is the CA host" do + @host.expects(:ca?).returns true + Puppet::SSL::Certificate.stubs(:find) + Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).never - @host.generate_key.should be_true - @host.key.should equal(@key) - end + @host.certificate + end - it "should not retain keys that could not be saved" do - Puppet::SSL::Key.expects(:new).with("myname").returns(@key) + it "should return nil if it cannot find a CA certificate" do + Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns nil + Puppet::SSL::Certificate.expects(:find).with("myname").never - @key.stubs(:generate) - @key.expects(:save).raises "eh" + @host.certificate.should be_nil + end - lambda { @host.generate_key }.should raise_error - @host.key.should be_nil - end + it "should find the key if it does not have one" do + Puppet::SSL::Certificate.stubs(:find) + @host.expects(:key).returns mock("key") - it "should return any previously found key without requerying" do - Puppet::SSL::Key.expects(:find).with("myname").returns(@key).once - @host.key.should equal(@key) - @host.key.should equal(@key) - end + @host.certificate end - describe "when managing its certificate request" do - before do - @realrequest = "real request" - @request = stub 'request', :content => @realrequest - end + it "should generate the key if one cannot be found" do + Puppet::SSL::Certificate.stubs(:find) - it "should return nil if the key is not set and cannot be found" do - Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns(nil) - @host.certificate_request.should be_nil - end + @host.expects(:key).returns nil + @host.expects(:generate_key) - it "should find the request in the Key class and return it and return the Puppet SSL request" do - Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns @request + @host.certificate + end + + it "should find the certificate in the Certificate class and return the Puppet certificate instance" do + Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") + Puppet::SSL::Certificate.expects(:find).with("myname").returns @cert - @host.certificate_request.should equal(@request) - end + @host.certificate.should equal(@cert) + end - it "should generate a new key when generating the cert request if no key exists" do - Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request + it "should fail if the found certificate does not match the private key" do + @host.expects(:certificate_matches_key?).returns false - key = stub 'key', :public_key => mock("public_key"), :content => "mycontent" + Puppet::SSL::Certificate.stubs(:find).returns @cert - @host.expects(:key).times(2).returns(nil).then.returns(key) - @host.expects(:generate_key).returns(key) + lambda { @host.certificate }.should raise_error(Puppet::Error) + end - @request.stubs(:generate) - @request.stubs(:save) + it "should return any previously found certificate" do + Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") + Puppet::SSL::Certificate.expects(:find).with("myname").returns(@cert).once - @host.generate_certificate_request - end + @host.certificate.should equal(@cert) + @host.certificate.should equal(@cert) + end + end - it "should be able to generate and save a new request using the private key" do - Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request + it "should have a method for listing certificate hosts" do + Puppet::SSL::Host.should respond_to(:search) + end - key = stub 'key', :public_key => mock("public_key"), :content => "mycontent" - @host.stubs(:key).returns(key) - @request.expects(:generate).with("mycontent") - @request.expects(:save) + describe "when listing certificate hosts" do + it "should default to listing all clients with any file types" do + Puppet::SSL::Key.expects(:search).returns [] + Puppet::SSL::Certificate.expects(:search).returns [] + Puppet::SSL::CertificateRequest.expects(:search).returns [] + Puppet::SSL::Host.search + end - @host.generate_certificate_request.should be_true - @host.certificate_request.should equal(@request) - end + it "should be able to list only clients with a key" do + Puppet::SSL::Key.expects(:search).returns [] + Puppet::SSL::Certificate.expects(:search).never + Puppet::SSL::CertificateRequest.expects(:search).never + Puppet::SSL::Host.search :for => Puppet::SSL::Key + end - it "should return any previously found request without requerying" do - Puppet::SSL::CertificateRequest.expects(:find).with("myname").returns(@request).once + it "should be able to list only clients with a certificate" do + Puppet::SSL::Key.expects(:search).never + Puppet::SSL::Certificate.expects(:search).returns [] + Puppet::SSL::CertificateRequest.expects(:search).never + Puppet::SSL::Host.search :for => Puppet::SSL::Certificate + end - @host.certificate_request.should equal(@request) - @host.certificate_request.should equal(@request) - end + it "should be able to list only clients with a certificate request" do + Puppet::SSL::Key.expects(:search).never + Puppet::SSL::Certificate.expects(:search).never + Puppet::SSL::CertificateRequest.expects(:search).returns [] + Puppet::SSL::Host.search :for => Puppet::SSL::CertificateRequest + end - it "should not keep its certificate request in memory if the request cannot be saved" do - Puppet::SSL::CertificateRequest.expects(:new).with("myname").returns @request + it "should return a Host instance created with the name of each found instance" do + key = stub 'key', :name => "key" + cert = stub 'cert', :name => "cert" + csr = stub 'csr', :name => "csr" - key = stub 'key', :public_key => mock("public_key"), :content => "mycontent" - @host.stubs(:key).returns(key) - @request.stubs(:generate) - @request.expects(:save).raises "eh" + Puppet::SSL::Key.expects(:search).returns [key] + Puppet::SSL::Certificate.expects(:search).returns [cert] + Puppet::SSL::CertificateRequest.expects(:search).returns [csr] - lambda { @host.generate_certificate_request }.should raise_error + returned = [] + %w{key cert csr}.each do |name| + result = mock(name) + returned << result + Puppet::SSL::Host.expects(:new).with(name).returns result + end - @host.certificate_request.should be_nil - end + result = Puppet::SSL::Host.search + returned.each do |r| + result.should be_include(r) + end end + end - describe "when managing its certificate" do - before do - @realcert = mock 'certificate' - @cert = stub 'cert', :content => @realcert + it "should have a method for generating all necessary files" do + Puppet::SSL::Host.new("me").should respond_to(:generate) + end - @host.stubs(:key).returns mock("key") - @host.stubs(:certificate_matches_key?).returns true - end + describe "when generating files" do + before do + @host = Puppet::SSL::Host.new("me") + @host.stubs(:generate_key) + @host.stubs(:generate_certificate_request) + end - it "should find the CA certificate if it does not have a certificate" do - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") - Puppet::SSL::Certificate.stubs(:find).with("myname").returns @cert + it "should generate a key if one is not present" do + @host.stubs(:key).returns nil + @host.expects(:generate_key) - @host.certificate - end + @host.generate + end - it "should not find the CA certificate if it is the CA host" do - @host.expects(:ca?).returns true - Puppet::SSL::Certificate.stubs(:find) - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).never + it "should generate a certificate request if one is not present" do + @host.expects(:certificate_request).returns nil + @host.expects(:generate_certificate_request) - @host.certificate - end + @host.generate + end - it "should return nil if it cannot find a CA certificate" do - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns nil - Puppet::SSL::Certificate.expects(:find).with("myname").never + describe "and it can create a certificate authority" do + before do + @ca = mock 'ca' + Puppet::SSL::CertificateAuthority.stubs(:instance).returns @ca + end - @host.certificate.should be_nil - end + it "should use the CA to sign its certificate request if it does not have a certificate" do + @host.expects(:certificate).returns nil - it "should find the key if it does not have one" do - Puppet::SSL::Certificate.stubs(:find) - @host.expects(:key).returns mock("key") + @ca.expects(:sign).with(@host.name) - @host.certificate - end + @host.generate + end + end - it "should generate the key if one cannot be found" do - Puppet::SSL::Certificate.stubs(:find) + describe "and it cannot create a certificate authority" do + before do + Puppet::SSL::CertificateAuthority.stubs(:instance).returns nil + end - @host.expects(:key).returns nil - @host.expects(:generate_key) + it "should seek its certificate" do + @host.expects(:certificate) - @host.certificate - end + @host.generate + end + end + end - it "should find the certificate in the Certificate class and return the Puppet certificate instance" do - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") - Puppet::SSL::Certificate.expects(:find).with("myname").returns @cert + it "should have a method for creating an SSL store" do + Puppet::SSL::Host.new("me").should respond_to(:ssl_store) + end - @host.certificate.should equal(@cert) - end + it "should always return the same store" do + host = Puppet::SSL::Host.new("foo") + store = mock 'store' + store.stub_everything + OpenSSL::X509::Store.expects(:new).returns store + host.ssl_store.should equal(host.ssl_store) + end - it "should fail if the found certificate does not match the private key" do - @host.expects(:certificate_matches_key?).returns false + describe "when creating an SSL store" do + before do + @host = Puppet::SSL::Host.new("me") + @store = mock 'store' + @store.stub_everything + OpenSSL::X509::Store.stubs(:new).returns @store - Puppet::SSL::Certificate.stubs(:find).returns @cert + Puppet.settings.stubs(:value).with(:localcacert).returns "ssl_host_testing" - lambda { @host.certificate }.should raise_error(Puppet::Error) - end + Puppet::SSL::CertificateRevocationList.stubs(:find).returns(nil) + end - it "should return any previously found certificate" do - Puppet::SSL::Certificate.expects(:find).with(Puppet::SSL::CA_NAME).returns mock("cacert") - Puppet::SSL::Certificate.expects(:find).with("myname").returns(@cert).once + it "should accept a purpose" do + @store.expects(:purpose=).with "my special purpose" + @host.ssl_store("my special purpose") + end - @host.certificate.should equal(@cert) - @host.certificate.should equal(@cert) - end + it "should default to OpenSSL::X509::PURPOSE_ANY as the purpose" do + @store.expects(:purpose=).with OpenSSL::X509::PURPOSE_ANY + @host.ssl_store end - it "should have a method for listing certificate hosts" do - Puppet::SSL::Host.should respond_to(:search) + it "should add the local CA cert file" do + Puppet.settings.stubs(:value).with(:localcacert).returns "/ca/cert/file" + @store.expects(:add_file).with "/ca/cert/file" + @host.ssl_store end - describe "when listing certificate hosts" do - it "should default to listing all clients with any file types" do - Puppet::SSL::Key.expects(:search).returns [] - Puppet::SSL::Certificate.expects(:search).returns [] - Puppet::SSL::CertificateRequest.expects(:search).returns [] - Puppet::SSL::Host.search - end + describe "and a CRL is available" do + before do + @crl = stub 'crl', :content => "real_crl" + Puppet::SSL::CertificateRevocationList.stubs(:find).returns @crl + Puppet.settings.stubs(:value).with(:certificate_revocation).returns true + end - it "should be able to list only clients with a key" do - Puppet::SSL::Key.expects(:search).returns [] - Puppet::SSL::Certificate.expects(:search).never - Puppet::SSL::CertificateRequest.expects(:search).never - Puppet::SSL::Host.search :for => Puppet::SSL::Key - end + it "should add the CRL" do + @store.expects(:add_crl).with "real_crl" + @host.ssl_store + end - it "should be able to list only clients with a certificate" do - Puppet::SSL::Key.expects(:search).never - Puppet::SSL::Certificate.expects(:search).returns [] - Puppet::SSL::CertificateRequest.expects(:search).never - Puppet::SSL::Host.search :for => Puppet::SSL::Certificate - end + it "should set the flags to OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK" do + @store.expects(:flags=).with OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK + @host.ssl_store + end + end + end - it "should be able to list only clients with a certificate request" do - Puppet::SSL::Key.expects(:search).never - Puppet::SSL::Certificate.expects(:search).never - Puppet::SSL::CertificateRequest.expects(:search).returns [] - Puppet::SSL::Host.search :for => Puppet::SSL::CertificateRequest - end + describe "when waiting for a cert" do + before do + @host = Puppet::SSL::Host.new("me") + end - it "should return a Host instance created with the name of each found instance" do - key = stub 'key', :name => "key" - cert = stub 'cert', :name => "cert" - csr = stub 'csr', :name => "csr" + it "should generate its certificate request and attempt to read the certificate again if no certificate is found" do + @host.expects(:certificate).times(2).returns(nil).then.returns "foo" + @host.expects(:generate) + @host.wait_for_cert(1) + end - Puppet::SSL::Key.expects(:search).returns [key] - Puppet::SSL::Certificate.expects(:search).returns [cert] - Puppet::SSL::CertificateRequest.expects(:search).returns [csr] + it "should catch and log errors during CSR saving" do + @host.expects(:certificate).times(2).returns(nil).then.returns "foo" + @host.expects(:generate).raises(RuntimeError).then.returns nil + @host.stubs(:sleep) + @host.wait_for_cert(1) + end - returned = [] - %w{key cert csr}.each do |name| - result = mock(name) - returned << result - Puppet::SSL::Host.expects(:new).with(name).returns result - end + it "should sleep and retry after failures saving the CSR if waitforcert is enabled" do + @host.expects(:certificate).times(2).returns(nil).then.returns "foo" + @host.expects(:generate).raises(RuntimeError).then.returns nil + @host.expects(:sleep).with(1) + @host.wait_for_cert(1) + end - result = Puppet::SSL::Host.search - returned.each do |r| - result.should be_include(r) - end - end + it "should exit after failures saving the CSR of waitforcert is disabled" do + @host.expects(:certificate).returns(nil) + @host.expects(:generate).raises(RuntimeError) + @host.expects(:puts) + @host.expects(:exit).with(1).raises(SystemExit) + lambda { @host.wait_for_cert(0) }.should raise_error(SystemExit) end - it "should have a method for generating all necessary files" do - Puppet::SSL::Host.new("me").should respond_to(:generate) + it "should exit if the wait time is 0 and it can neither find nor retrieve a certificate" do + @host.stubs(:certificate).returns nil + @host.expects(:generate) + @host.expects(:puts) + @host.expects(:exit).with(1).raises(SystemExit) + lambda { @host.wait_for_cert(0) }.should raise_error(SystemExit) end - describe "when generating files" do - before do - @host = Puppet::SSL::Host.new("me") - @host.stubs(:generate_key) - @host.stubs(:generate_certificate_request) - end + it "should sleep for the specified amount of time if no certificate is found after generating its certificate request" do + @host.expects(:certificate).times(3).returns(nil).then.returns(nil).then.returns "foo" + @host.expects(:generate) + + @host.expects(:sleep).with(1) + + @host.wait_for_cert(1) + end - it "should generate a key if one is not present" do - @host.stubs(:key).returns nil - @host.expects(:generate_key) + it "should catch and log exceptions during certificate retrieval" do + @host.expects(:certificate).times(3).returns(nil).then.raises(RuntimeError).then.returns("foo") + @host.stubs(:generate) + @host.stubs(:sleep) - @host.generate - end + Puppet.expects(:err) - it "should generate a certificate request if one is not present" do - @host.expects(:certificate_request).returns nil - @host.expects(:generate_certificate_request) - - @host.generate - end - - describe "and it can create a certificate authority" do - before do - @ca = mock 'ca' - Puppet::SSL::CertificateAuthority.stubs(:instance).returns @ca - end - - it "should use the CA to sign its certificate request if it does not have a certificate" do - @host.expects(:certificate).returns nil - - @ca.expects(:sign).with(@host.name) - - @host.generate - end - end - - describe "and it cannot create a certificate authority" do - before do - Puppet::SSL::CertificateAuthority.stubs(:instance).returns nil - end - - it "should seek its certificate" do - @host.expects(:certificate) - - @host.generate - end - end - end - - it "should have a method for creating an SSL store" do - Puppet::SSL::Host.new("me").should respond_to(:ssl_store) - end - - it "should always return the same store" do - host = Puppet::SSL::Host.new("foo") - store = mock 'store' - store.stub_everything - OpenSSL::X509::Store.expects(:new).returns store - host.ssl_store.should equal(host.ssl_store) - end - - describe "when creating an SSL store" do - before do - @host = Puppet::SSL::Host.new("me") - @store = mock 'store' - @store.stub_everything - OpenSSL::X509::Store.stubs(:new).returns @store - - Puppet.settings.stubs(:value).with(:localcacert).returns "ssl_host_testing" - - Puppet::SSL::CertificateRevocationList.stubs(:find).returns(nil) - end - - it "should accept a purpose" do - @store.expects(:purpose=).with "my special purpose" - @host.ssl_store("my special purpose") - end - - it "should default to OpenSSL::X509::PURPOSE_ANY as the purpose" do - @store.expects(:purpose=).with OpenSSL::X509::PURPOSE_ANY - @host.ssl_store - end - - it "should add the local CA cert file" do - Puppet.settings.stubs(:value).with(:localcacert).returns "/ca/cert/file" - @store.expects(:add_file).with "/ca/cert/file" - @host.ssl_store - end - - describe "and a CRL is available" do - before do - @crl = stub 'crl', :content => "real_crl" - Puppet::SSL::CertificateRevocationList.stubs(:find).returns @crl - Puppet.settings.stubs(:value).with(:certificate_revocation).returns true - end - - it "should add the CRL" do - @store.expects(:add_crl).with "real_crl" - @host.ssl_store - end - - it "should set the flags to OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK" do - @store.expects(:flags=).with OpenSSL::X509::V_FLAG_CRL_CHECK_ALL|OpenSSL::X509::V_FLAG_CRL_CHECK - @host.ssl_store - end - end - end - - describe "when waiting for a cert" do - before do - @host = Puppet::SSL::Host.new("me") - end - - it "should generate its certificate request and attempt to read the certificate again if no certificate is found" do - @host.expects(:certificate).times(2).returns(nil).then.returns "foo" - @host.expects(:generate) - @host.wait_for_cert(1) - end - - it "should catch and log errors during CSR saving" do - @host.expects(:certificate).times(2).returns(nil).then.returns "foo" - @host.expects(:generate).raises(RuntimeError).then.returns nil - @host.stubs(:sleep) - @host.wait_for_cert(1) - end - - it "should sleep and retry after failures saving the CSR if waitforcert is enabled" do - @host.expects(:certificate).times(2).returns(nil).then.returns "foo" - @host.expects(:generate).raises(RuntimeError).then.returns nil - @host.expects(:sleep).with(1) - @host.wait_for_cert(1) - end - - it "should exit after failures saving the CSR of waitforcert is disabled" do - @host.expects(:certificate).returns(nil) - @host.expects(:generate).raises(RuntimeError) - @host.expects(:puts) - @host.expects(:exit).with(1).raises(SystemExit) - lambda { @host.wait_for_cert(0) }.should raise_error(SystemExit) - end - - it "should exit if the wait time is 0 and it can neither find nor retrieve a certificate" do - @host.stubs(:certificate).returns nil - @host.expects(:generate) - @host.expects(:puts) - @host.expects(:exit).with(1).raises(SystemExit) - lambda { @host.wait_for_cert(0) }.should raise_error(SystemExit) - end - - it "should sleep for the specified amount of time if no certificate is found after generating its certificate request" do - @host.expects(:certificate).times(3).returns(nil).then.returns(nil).then.returns "foo" - @host.expects(:generate) - - @host.expects(:sleep).with(1) - - @host.wait_for_cert(1) - end - - it "should catch and log exceptions during certificate retrieval" do - @host.expects(:certificate).times(3).returns(nil).then.raises(RuntimeError).then.returns("foo") - @host.stubs(:generate) - @host.stubs(:sleep) - - Puppet.expects(:err) - - @host.wait_for_cert(1) - end + @host.wait_for_cert(1) end + end end diff --git a/spec/unit/ssl/inventory_spec.rb b/spec/unit/ssl/inventory_spec.rb index bf1dbfb48..a57d6fafc 100755 --- a/spec/unit/ssl/inventory_spec.rb +++ b/spec/unit/ssl/inventory_spec.rb @@ -5,176 +5,176 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/ssl/inventory' describe Puppet::SSL::Inventory do - before do - @class = Puppet::SSL::Inventory - end + before do + @class = Puppet::SSL::Inventory + end - it "should use the :certinventory setting for the path to the inventory file" do - Puppet.settings.expects(:value).with(:cert_inventory).returns "/inven/tory" + it "should use the :certinventory setting for the path to the inventory file" do + Puppet.settings.expects(:value).with(:cert_inventory).returns "/inven/tory" - @class.any_instance.stubs(:rebuild) + @class.any_instance.stubs(:rebuild) - @class.new.path.should == "/inven/tory" - end + @class.new.path.should == "/inven/tory" + end - describe "when initializing" do - it "should set its path to the inventory file" do - Puppet.settings.stubs(:value).with(:cert_inventory).returns "/inven/tory" - @class.new.path.should == "/inven/tory" - end + describe "when initializing" do + it "should set its path to the inventory file" do + Puppet.settings.stubs(:value).with(:cert_inventory).returns "/inven/tory" + @class.new.path.should == "/inven/tory" end + end - describe "when managing an inventory" do - before do - Puppet.settings.stubs(:value).with(:cert_inventory).returns "/inven/tory" + describe "when managing an inventory" do + before do + Puppet.settings.stubs(:value).with(:cert_inventory).returns "/inven/tory" - FileTest.stubs(:exist?).with("/inven/tory").returns true + FileTest.stubs(:exist?).with("/inven/tory").returns true - @inventory = @class.new + @inventory = @class.new - @cert = mock 'cert' - end + @cert = mock 'cert' + end - describe "and creating the inventory file" do - before do - Puppet.settings.stubs(:write) - FileTest.stubs(:exist?).with("/inven/tory").returns false + describe "and creating the inventory file" do + before do + Puppet.settings.stubs(:write) + FileTest.stubs(:exist?).with("/inven/tory").returns false - Puppet::SSL::Certificate.stubs(:search).returns [] - end + Puppet::SSL::Certificate.stubs(:search).returns [] + end - it "should log that it is building a new inventory file" do - Puppet.expects(:notice) + it "should log that it is building a new inventory file" do + Puppet.expects(:notice) - @inventory.rebuild - end + @inventory.rebuild + end - it "should use the Settings to write to the file" do - Puppet.settings.expects(:write).with(:cert_inventory) + it "should use the Settings to write to the file" do + Puppet.settings.expects(:write).with(:cert_inventory) - @inventory.rebuild - end + @inventory.rebuild + end - it "should add a header to the file" do - fh = mock 'filehandle' - Puppet.settings.stubs(:write).yields fh - fh.expects(:print).with { |str| str =~ /^#/ } + it "should add a header to the file" do + fh = mock 'filehandle' + Puppet.settings.stubs(:write).yields fh + fh.expects(:print).with { |str| str =~ /^#/ } - @inventory.rebuild - end + @inventory.rebuild + end - it "should add formatted information on all existing certificates" do - cert1 = mock 'cert1' - cert2 = mock 'cert2' + it "should add formatted information on all existing certificates" do + cert1 = mock 'cert1' + cert2 = mock 'cert2' - Puppet::SSL::Certificate.expects(:search).with("*").returns [cert1, cert2] + Puppet::SSL::Certificate.expects(:search).with("*").returns [cert1, cert2] - @class.any_instance.expects(:add).with(cert1) - @class.any_instance.expects(:add).with(cert2) + @class.any_instance.expects(:add).with(cert1) + @class.any_instance.expects(:add).with(cert2) - @inventory.rebuild - end - end + @inventory.rebuild + end + end - describe "and adding a certificate" do - it "should build the inventory file if one does not exist" do - Puppet.settings.stubs(:value).with(:cert_inventory).returns "/inven/tory" - Puppet.settings.stubs(:write) + describe "and adding a certificate" do + it "should build the inventory file if one does not exist" do + Puppet.settings.stubs(:value).with(:cert_inventory).returns "/inven/tory" + Puppet.settings.stubs(:write) - FileTest.expects(:exist?).with("/inven/tory").returns false + FileTest.expects(:exist?).with("/inven/tory").returns false - @inventory.expects(:rebuild) + @inventory.expects(:rebuild) - @inventory.add(@cert) - end + @inventory.add(@cert) + end - it "should use the Settings to write to the file" do - Puppet.settings.expects(:write).with(:cert_inventory, "a") + it "should use the Settings to write to the file" do + Puppet.settings.expects(:write).with(:cert_inventory, "a") - @inventory.add(@cert) - end + @inventory.add(@cert) + end - it "should use the actual certificate if it was passed a Puppet certificate" do - cert = Puppet::SSL::Certificate.new("mycert") - cert.content = @cert + it "should use the actual certificate if it was passed a Puppet certificate" do + cert = Puppet::SSL::Certificate.new("mycert") + cert.content = @cert - fh = stub 'filehandle', :print => nil - Puppet.settings.stubs(:write).yields fh + fh = stub 'filehandle', :print => nil + Puppet.settings.stubs(:write).yields fh - @inventory.expects(:format).with(@cert) + @inventory.expects(:format).with(@cert) - @inventory.add(@cert) - end + @inventory.add(@cert) + end - it "should add formatted certificate information to the end of the file" do - fh = mock 'filehandle' + it "should add formatted certificate information to the end of the file" do + fh = mock 'filehandle' - Puppet.settings.stubs(:write).yields fh + Puppet.settings.stubs(:write).yields fh - @inventory.expects(:format).with(@cert).returns "myformat" + @inventory.expects(:format).with(@cert).returns "myformat" - fh.expects(:print).with("myformat") + fh.expects(:print).with("myformat") - @inventory.add(@cert) - end - end + @inventory.add(@cert) + end + end - describe "and formatting a certificate" do - before do - @cert = stub 'cert', :not_before => Time.now, :not_after => Time.now, :subject => "mycert", :serial => 15 - end + describe "and formatting a certificate" do + before do + @cert = stub 'cert', :not_before => Time.now, :not_after => Time.now, :subject => "mycert", :serial => 15 + end - it "should print the serial number as a 4 digit hex number in the first field" do - @inventory.format(@cert).split[0].should == "0x000f" # 15 in hex - end + it "should print the serial number as a 4 digit hex number in the first field" do + @inventory.format(@cert).split[0].should == "0x000f" # 15 in hex + end - it "should print the not_before date in '%Y-%m-%dT%H:%M:%S%Z' format in the second field" do - @cert.not_before.expects(:strftime).with('%Y-%m-%dT%H:%M:%S%Z').returns "before_time" + it "should print the not_before date in '%Y-%m-%dT%H:%M:%S%Z' format in the second field" do + @cert.not_before.expects(:strftime).with('%Y-%m-%dT%H:%M:%S%Z').returns "before_time" - @inventory.format(@cert).split[1].should == "before_time" - end + @inventory.format(@cert).split[1].should == "before_time" + end - it "should print the not_after date in '%Y-%m-%dT%H:%M:%S%Z' format in the third field" do - @cert.not_after.expects(:strftime).with('%Y-%m-%dT%H:%M:%S%Z').returns "after_time" + it "should print the not_after date in '%Y-%m-%dT%H:%M:%S%Z' format in the third field" do + @cert.not_after.expects(:strftime).with('%Y-%m-%dT%H:%M:%S%Z').returns "after_time" - @inventory.format(@cert).split[2].should == "after_time" - end + @inventory.format(@cert).split[2].should == "after_time" + end - it "should print the subject in the fourth field" do - @inventory.format(@cert).split[3].should == "mycert" - end + it "should print the subject in the fourth field" do + @inventory.format(@cert).split[3].should == "mycert" + end - it "should add a carriage return" do - @inventory.format(@cert).should =~ /\n$/ - end + it "should add a carriage return" do + @inventory.format(@cert).should =~ /\n$/ + end - it "should produce a line consisting of the serial number, start date, expiration date, and subject" do - # Just make sure our serial and subject bracket the lines. - @inventory.format(@cert).should =~ /^0x.+mycert$/ - end - end + it "should produce a line consisting of the serial number, start date, expiration date, and subject" do + # Just make sure our serial and subject bracket the lines. + @inventory.format(@cert).should =~ /^0x.+mycert$/ + end + end - it "should be able to find a given host's serial number" do - @inventory.should respond_to(:serial) - end + it "should be able to find a given host's serial number" do + @inventory.should respond_to(:serial) + end - describe "and finding a serial number" do - it "should return nil if the inventory file is missing" do - FileTest.expects(:exist?).with("/inven/tory").returns false - @inventory.serial(:whatever).should be_nil - end + describe "and finding a serial number" do + it "should return nil if the inventory file is missing" do + FileTest.expects(:exist?).with("/inven/tory").returns false + @inventory.serial(:whatever).should be_nil + end - it "should return the serial number from the line matching the provided name" do - File.expects(:readlines).with("/inven/tory").returns ["0x00f blah blah /CN=me\n", "0x001 blah blah /CN=you\n"] + it "should return the serial number from the line matching the provided name" do + File.expects(:readlines).with("/inven/tory").returns ["0x00f blah blah /CN=me\n", "0x001 blah blah /CN=you\n"] - @inventory.serial("me").should == 15 - end + @inventory.serial("me").should == 15 + end - it "should return the number as an integer" do - File.expects(:readlines).with("/inven/tory").returns ["0x00f blah blah /CN=me\n", "0x001 blah blah /CN=you\n"] + it "should return the number as an integer" do + File.expects(:readlines).with("/inven/tory").returns ["0x00f blah blah /CN=me\n", "0x001 blah blah /CN=you\n"] - @inventory.serial("me").should == 15 - end - end + @inventory.serial("me").should == 15 + end end + end end diff --git a/spec/unit/ssl/key_spec.rb b/spec/unit/ssl/key_spec.rb index cfeaf7906..58193db28 100755 --- a/spec/unit/ssl/key_spec.rb +++ b/spec/unit/ssl/key_spec.rb @@ -5,194 +5,194 @@ require File.dirname(__FILE__) + '/../../spec_helper' require 'puppet/ssl/key' describe Puppet::SSL::Key do - before do - @class = Puppet::SSL::Key - end + before do + @class = Puppet::SSL::Key + end - it "should be extended with the Indirector module" do - @class.singleton_class.should be_include(Puppet::Indirector) - end + it "should be extended with the Indirector module" do + @class.singleton_class.should be_include(Puppet::Indirector) + end - it "should indirect key" do - @class.indirection.name.should == :key - end + it "should indirect key" do + @class.indirection.name.should == :key + end - it "should default to the :file terminus" do - @class.indirection.terminus_class.should == :file - end + it "should default to the :file terminus" do + @class.indirection.terminus_class.should == :file + end - it "should only support the text format" do - @class.supported_formats.should == [:s] - end + it "should only support the text format" do + @class.supported_formats.should == [:s] + end - it "should have a method for determining whether it's a CA key" do - @class.new("test").should respond_to(:ca?) - end + it "should have a method for determining whether it's a CA key" do + @class.new("test").should respond_to(:ca?) + end - it "should consider itself a ca key if its name matches the CA_NAME" do - @class.new(Puppet::SSL::Host.ca_name).should be_ca - end + it "should consider itself a ca key if its name matches the CA_NAME" do + @class.new(Puppet::SSL::Host.ca_name).should be_ca + end - describe "when initializing" do - it "should set its password file to the :capass if it's a CA key" do - Puppet.settings.stubs(:value).returns "whatever" - Puppet.settings.stubs(:value).with(:capass).returns "/ca/pass" + describe "when initializing" do + it "should set its password file to the :capass if it's a CA key" do + Puppet.settings.stubs(:value).returns "whatever" + Puppet.settings.stubs(:value).with(:capass).returns "/ca/pass" - key = Puppet::SSL::Key.new(Puppet::SSL::Host.ca_name) - key.password_file.should == "/ca/pass" - end + key = Puppet::SSL::Key.new(Puppet::SSL::Host.ca_name) + key.password_file.should == "/ca/pass" + end - it "should downcase its name" do - @class.new("MyName").name.should == "myname" - end + it "should downcase its name" do + @class.new("MyName").name.should == "myname" + end - it "should set its password file to the default password file if it is not the CA key" do - Puppet.settings.stubs(:value).returns "whatever" - Puppet.settings.stubs(:value).with(:passfile).returns "/normal/pass" + it "should set its password file to the default password file if it is not the CA key" do + Puppet.settings.stubs(:value).returns "whatever" + Puppet.settings.stubs(:value).with(:passfile).returns "/normal/pass" - key = Puppet::SSL::Key.new("notca") - key.password_file.should == "/normal/pass" - end + key = Puppet::SSL::Key.new("notca") + key.password_file.should == "/normal/pass" end + end - describe "when managing instances" do - before do - @key = @class.new("myname") - end + describe "when managing instances" do + before do + @key = @class.new("myname") + end - it "should have a name attribute" do - @key.name.should == "myname" - end + it "should have a name attribute" do + @key.name.should == "myname" + end - it "should have a content attribute" do - @key.should respond_to(:content) - end + it "should have a content attribute" do + @key.should respond_to(:content) + end - it "should be able to read keys from disk" do - path = "/my/path" - File.expects(:read).with(path).returns("my key") - key = mock 'key' - OpenSSL::PKey::RSA.expects(:new).returns(key) - @key.read(path).should equal(key) - @key.content.should equal(key) - end + it "should be able to read keys from disk" do + path = "/my/path" + File.expects(:read).with(path).returns("my key") + key = mock 'key' + OpenSSL::PKey::RSA.expects(:new).returns(key) + @key.read(path).should equal(key) + @key.content.should equal(key) + end - it "should not try to use the provided password file if the file does not exist" do - FileTest.stubs(:exist?).returns false - @key.password_file = "/path/to/password" + it "should not try to use the provided password file if the file does not exist" do + FileTest.stubs(:exist?).returns false + @key.password_file = "/path/to/password" - path = "/my/path" + path = "/my/path" - File.stubs(:read).with(path).returns("my key") - OpenSSL::PKey::RSA.expects(:new).with("my key", nil).returns(mock('key')) - File.expects(:read).with("/path/to/password").never + File.stubs(:read).with(path).returns("my key") + OpenSSL::PKey::RSA.expects(:new).with("my key", nil).returns(mock('key')) + File.expects(:read).with("/path/to/password").never - @key.read(path) - end + @key.read(path) + end - it "should read the key with the password retrieved from the password file if one is provided" do - FileTest.stubs(:exist?).returns true - @key.password_file = "/path/to/password" + it "should read the key with the password retrieved from the password file if one is provided" do + FileTest.stubs(:exist?).returns true + @key.password_file = "/path/to/password" - path = "/my/path" - File.expects(:read).with(path).returns("my key") - File.expects(:read).with("/path/to/password").returns("my password") + path = "/my/path" + File.expects(:read).with(path).returns("my key") + File.expects(:read).with("/path/to/password").returns("my password") - key = mock 'key' - OpenSSL::PKey::RSA.expects(:new).with("my key", "my password").returns(key) - @key.read(path).should equal(key) - @key.content.should equal(key) - end + key = mock 'key' + OpenSSL::PKey::RSA.expects(:new).with("my key", "my password").returns(key) + @key.read(path).should equal(key) + @key.content.should equal(key) + end - it "should return an empty string when converted to a string with no key" do - @key.to_s.should == "" - end + it "should return an empty string when converted to a string with no key" do + @key.to_s.should == "" + end - it "should convert the key to pem format when converted to a string" do - key = mock 'key', :to_pem => "pem" - @key.content = key - @key.to_s.should == "pem" - end + it "should convert the key to pem format when converted to a string" do + key = mock 'key', :to_pem => "pem" + @key.content = key + @key.to_s.should == "pem" + end - it "should have a :to_text method that it delegates to the actual key" do - real_key = mock 'key' - real_key.expects(:to_text).returns "keytext" - @key.content = real_key - @key.to_text.should == "keytext" - end + it "should have a :to_text method that it delegates to the actual key" do + real_key = mock 'key' + real_key.expects(:to_text).returns "keytext" + @key.content = real_key + @key.to_text.should == "keytext" end + end - describe "when generating the private key" do - before do - @instance = @class.new("test") + describe "when generating the private key" do + before do + @instance = @class.new("test") - @key = mock 'key' - end + @key = mock 'key' + end - it "should create an instance of OpenSSL::PKey::RSA" do - OpenSSL::PKey::RSA.expects(:new).returns(@key) + it "should create an instance of OpenSSL::PKey::RSA" do + OpenSSL::PKey::RSA.expects(:new).returns(@key) - @instance.generate - end + @instance.generate + end - it "should create the private key with the keylength specified in the settings" do - Puppet.settings.expects(:value).with(:keylength).returns("50") - OpenSSL::PKey::RSA.expects(:new).with(50).returns(@key) + it "should create the private key with the keylength specified in the settings" do + Puppet.settings.expects(:value).with(:keylength).returns("50") + OpenSSL::PKey::RSA.expects(:new).with(50).returns(@key) - @instance.generate - end + @instance.generate + end - it "should set the content to the generated key" do - OpenSSL::PKey::RSA.stubs(:new).returns(@key) - @instance.generate - @instance.content.should equal(@key) - end + it "should set the content to the generated key" do + OpenSSL::PKey::RSA.stubs(:new).returns(@key) + @instance.generate + @instance.content.should equal(@key) + end - it "should return the generated key" do - OpenSSL::PKey::RSA.stubs(:new).returns(@key) - @instance.generate.should equal(@key) - end + it "should return the generated key" do + OpenSSL::PKey::RSA.stubs(:new).returns(@key) + @instance.generate.should equal(@key) + end - it "should return the key in pem format" do - @instance.generate - @instance.content.expects(:to_pem).returns "my normal key" - @instance.to_s.should == "my normal key" - end + it "should return the key in pem format" do + @instance.generate + @instance.content.expects(:to_pem).returns "my normal key" + @instance.to_s.should == "my normal key" + end - describe "with a password file set" do - it "should return a nil password if the password file does not exist" do - FileTest.expects(:exist?).with("/path/to/pass").returns false - File.expects(:read).with("/path/to/pass").never + describe "with a password file set" do + it "should return a nil password if the password file does not exist" do + FileTest.expects(:exist?).with("/path/to/pass").returns false + File.expects(:read).with("/path/to/pass").never - @instance.password_file = "/path/to/pass" + @instance.password_file = "/path/to/pass" - @instance.password.should be_nil - end + @instance.password.should be_nil + end - it "should return the contents of the password file as its password" do - FileTest.expects(:exist?).with("/path/to/pass").returns true - File.expects(:read).with("/path/to/pass").returns "my password" + it "should return the contents of the password file as its password" do + FileTest.expects(:exist?).with("/path/to/pass").returns true + File.expects(:read).with("/path/to/pass").returns "my password" - @instance.password_file = "/path/to/pass" + @instance.password_file = "/path/to/pass" - @instance.password.should == "my password" - end + @instance.password.should == "my password" + end - it "should export the private key to text using the password" do - Puppet.settings.stubs(:value).with(:keylength).returns("50") + it "should export the private key to text using the password" do + Puppet.settings.stubs(:value).with(:keylength).returns("50") - @instance.password_file = "/path/to/pass" - @instance.stubs(:password).returns "my password" + @instance.password_file = "/path/to/pass" + @instance.stubs(:password).returns "my password" - OpenSSL::PKey::RSA.expects(:new).returns(@key) - @instance.generate + OpenSSL::PKey::RSA.expects(:new).returns(@key) + @instance.generate - cipher = mock 'cipher' - OpenSSL::Cipher::DES.expects(:new).with(:EDE3, :CBC).returns cipher - @key.expects(:export).with(cipher, "my password").returns "my encrypted key" + cipher = mock 'cipher' + OpenSSL::Cipher::DES.expects(:new).with(:EDE3, :CBC).returns cipher + @key.expects(:export).with(cipher, "my password").returns "my encrypted key" - @instance.to_s.should == "my encrypted key" - end - end + @instance.to_s.should == "my encrypted key" + end end + end end |