diff options
author | Luke Kanies <luke@madstop.com> | 2008-04-17 21:39:24 -0500 |
---|---|---|
committer | Luke Kanies <luke@madstop.com> | 2008-04-17 21:39:24 -0500 |
commit | 71db9b58349f75a54649d9b0d1fead8d01593f7a (patch) | |
tree | 4e17f61f1b53863477e6917818bb1893a55693b1 | |
parent | e5c4687593766955de09e5613c892ce82a2a989d (diff) | |
download | puppet-71db9b58349f75a54649d9b0d1fead8d01593f7a.tar.gz puppet-71db9b58349f75a54649d9b0d1fead8d01593f7a.tar.xz puppet-71db9b58349f75a54649d9b0d1fead8d01593f7a.zip |
Adding integration tests for a lot of the SSL code.
This flushed out some problems, and things mostly look good
now, but I don't think we're quite there yet.
-rw-r--r-- | lib/puppet/defaults.rb | 2 | ||||
-rw-r--r-- | lib/puppet/indirector/ssl_file.rb | 2 | ||||
-rw-r--r-- | lib/puppet/ssl/certificate_authority.rb | 3 | ||||
-rw-r--r-- | lib/puppet/ssl/host.rb | 4 | ||||
-rwxr-xr-x | spec/integration/ssl/certificate_authority.rb | 108 | ||||
-rwxr-xr-x | spec/integration/ssl/certificate_request.rb | 55 | ||||
-rwxr-xr-x | spec/integration/ssl/host.rb | 70 | ||||
-rwxr-xr-x | spec/unit/indirector/ssl_file.rb | 4 | ||||
-rwxr-xr-x | spec/unit/ssl/certificate_authority.rb | 4 | ||||
-rwxr-xr-x | spec/unit/ssl/host.rb | 6 |
10 files changed, 246 insertions, 12 deletions
diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb index 7b206901c..ff302e8db 100644 --- a/lib/puppet/defaults.rb +++ b/lib/puppet/defaults.rb @@ -167,7 +167,7 @@ module Puppet certificate. By default, only the server gets an alias set up, and only for 'puppet'."], :certdir => ["$ssldir/certs", "The certificate directory."], :publickeydir => ["$ssldir/public_keys", "The public key directory."], - :requestdir => ["$ssldir/public_keys", "The public key directory."], + :requestdir => ["$ssldir/certificate_requests", "Where host certificate requests are stored."], :privatekeydir => { :default => "$ssldir/private_keys", :mode => 0750, :desc => "The private key directory." diff --git a/lib/puppet/indirector/ssl_file.rb b/lib/puppet/indirector/ssl_file.rb index 7b3561263..44a66fab2 100644 --- a/lib/puppet/indirector/ssl_file.rb +++ b/lib/puppet/indirector/ssl_file.rb @@ -47,7 +47,7 @@ class Puppet::Indirector::SslFile < Puppet::Indirector::Terminus end def initialize - Puppet.settings.use(:ssl) + Puppet.settings.use(:main, :ssl) (collection_directory || file_location) or raise Puppet::DevError, "No file or directory setting provided; terminus %s cannot function" % self.class.name end diff --git a/lib/puppet/ssl/certificate_authority.rb b/lib/puppet/ssl/certificate_authority.rb index 2ed45e08b..f9786fb1a 100644 --- a/lib/puppet/ssl/certificate_authority.rb +++ b/lib/puppet/ssl/certificate_authority.rb @@ -27,7 +27,7 @@ class Puppet::SSL::CertificateAuthority request.generate(host.key) # Create a self-signed certificate. - @certificate = sign(name, :ca, request) + @certificate = sign(host.name, :ca, request) end def initialize @@ -40,7 +40,6 @@ class Puppet::SSL::CertificateAuthority # Sign a given certificate request. def sign(hostname, cert_type = :server, self_signing_csr = nil) - # This is a self-signed certificate if self_signing_csr csr = self_signing_csr diff --git a/lib/puppet/ssl/host.rb b/lib/puppet/ssl/host.rb index 42f881568..9b0ba2c71 100644 --- a/lib/puppet/ssl/host.rb +++ b/lib/puppet/ssl/host.rb @@ -17,6 +17,8 @@ class Puppet::SSL::Host attr_reader :name attr_accessor :ca + attr_writer :key, :certificate, :certificate_request + CA_NAME = "ca" # This is the constant that people will use to mark that a given host is @@ -150,7 +152,7 @@ class Puppet::SSL::Host def initialize(name) @name = name @key = @certificate = @certificate_request = nil - @ca = false + @ca = (name == self.class.ca_name) end # Extract the public key from the private key. diff --git a/spec/integration/ssl/certificate_authority.rb b/spec/integration/ssl/certificate_authority.rb new file mode 100755 index 000000000..769823a49 --- /dev/null +++ b/spec/integration/ssl/certificate_authority.rb @@ -0,0 +1,108 @@ +#!/usr/bin/env ruby +# +# Created by Luke Kanies on 2008-4-17. +# Copyright (c) 2008. All rights reserved. + +require File.dirname(__FILE__) + '/../../spec_helper' + +require 'puppet/ssl/certificate_authority' +require 'tempfile' + +describe Puppet::SSL::CertificateAuthority do + before do + # Get a safe temporary file + file = Tempfile.new("host_integration_testing") + @dir = file.path + file.delete + + Puppet.settings[:confdir] = @dir + Puppet.settings[:vardir] = @dir + + Puppet::SSL::Host.ca_location = :only + @ca = Puppet::SSL::CertificateAuthority.new + end + + after { + Puppet::SSL::Host.ca_location = :none + + system("rm -rf %s" % @dir) + Puppet.settings.clear + + # This is necessary so the terminus instances don't lie around. + Puppet::SSL::Key.indirection.clear_cache + Puppet::SSL::Certificate.indirection.clear_cache + Puppet::SSL::CertificateRequest.indirection.clear_cache + } + + it "should create a CA host" do + @ca.host.should be_ca + end + + it "should be able to generate a certificate" do + @ca.generate_ca_certificate + + @ca.host.certificate.should be_instance_of(Puppet::SSL::Certificate.wrapped_class) + end + + describe "when signing certificates" do + before do + @host = Puppet::SSL::Host.new("luke.madstop.com") + + # We have to provide the key, since when we're in :ca_only mode, we can only interact + # with the CA key. + key = Puppet::SSL::Key.new(@host.name) + key.generate + + @host.key = key + @host.generate_certificate_request + + path = File.join(Puppet[:requestdir], "luke.madstop.com.pem") + end + + it "should be able to sign certificates" do + @ca.sign("luke.madstop.com") + end + + it "should save the signed certificate" do + @ca.sign("luke.madstop.com") + + Puppet::SSL::Certificate.find("luke.madstop.com").should be_instance_of(Puppet::SSL::Certificate) + end + + it "should be able to sign multiple certificates" do + @other = Puppet::SSL::Host.new("other.madstop.com") + okey = Puppet::SSL::Key.new(@other.name) + okey.generate + @other.key = okey + @other.generate_certificate_request + + @ca.sign("luke.madstop.com") + @ca.sign("other.madstop.com") + + Puppet::SSL::Certificate.find("other.madstop.com").should be_instance_of(Puppet::SSL::Certificate) + Puppet::SSL::Certificate.find("luke.madstop.com").should be_instance_of(Puppet::SSL::Certificate) + end + + it "should save the signed certificate to the :signeddir" do + @ca.sign("luke.madstop.com") + + client_cert = File.join(Puppet[:signeddir], "luke.madstop.com.pem") + File.read(client_cert).should == Puppet::SSL::Certificate.find("luke.madstop.com").content.to_s + end + + it "should save valid certificates" do + @ca.sign("luke.madstop.com") + + ssl = %x{which openssl} + + unless ssl + pending "No ssl available" + else + ca_cert = Puppet[:cacert] + client_cert = File.join(Puppet[:signeddir], "luke.madstop.com.pem") + output = %x{openssl verify -CAfile #{ca_cert} #{client_cert}} + $?.should == 0 + end + end + end +end diff --git a/spec/integration/ssl/certificate_request.rb b/spec/integration/ssl/certificate_request.rb new file mode 100755 index 000000000..d3567bcce --- /dev/null +++ b/spec/integration/ssl/certificate_request.rb @@ -0,0 +1,55 @@ +#!/usr/bin/env ruby +# +# Created by Luke Kanies on 2008-4-17. +# Copyright (c) 2008. All rights reserved. + +require File.dirname(__FILE__) + '/../../spec_helper' + +require 'puppet/ssl/certificate_request' +require 'tempfile' + +describe Puppet::SSL::Host do + before do + # Get a safe temporary file + file = Tempfile.new("csr_integration_testing") + @dir = file.path + file.delete + + Puppet.settings[:confdir] = @dir + Puppet.settings[:vardir] = @dir + + @csr = Puppet::SSL::CertificateRequest.new("luke.madstop.com") + + @key = OpenSSL::PKey::RSA.new(512) + end + + after { + system("rm -rf %s" % @dir) + Puppet.settings.clear + + # This is necessary so the terminus instances don't lie around. + Puppet::SSL::CertificateRequest.indirection.clear_cache + } + + it "should be able to generate CSRs" do + @csr.generate(@key) + end + + it "should be able to save CSRs" do + @csr.save + end + + it "should be able to find saved certificate requests via the Indirector" do + @csr.generate(@key) + @csr.save + + Puppet::SSL::CertificateRequest.find("luke.madstop.com").should be_instance_of(Puppet::SSL::CertificateRequest) + end + + it "should save the completely CSR when saving" do + @csr.generate(@key) + @csr.save + + Puppet::SSL::CertificateRequest.find("luke.madstop.com").content.to_s.should == @csr.content.to_s + end +end diff --git a/spec/integration/ssl/host.rb b/spec/integration/ssl/host.rb new file mode 100755 index 000000000..63d7aca5b --- /dev/null +++ b/spec/integration/ssl/host.rb @@ -0,0 +1,70 @@ +#!/usr/bin/env ruby +# +# Created by Luke Kanies on 2008-4-17. +# Copyright (c) 2008. All rights reserved. + +require File.dirname(__FILE__) + '/../../spec_helper' + +require 'puppet/ssl/host' +require 'tempfile' + +describe Puppet::SSL::Host do + before do + # Get a safe temporary file + file = Tempfile.new("host_integration_testing") + @dir = file.path + file.delete + + Puppet.settings[:confdir] = @dir + Puppet.settings[:vardir] = @dir + + @host = Puppet::SSL::Host.new("luke.madstop.com") + end + + after { + system("rm -rf %s" % @dir) + Puppet.settings.clear + + # This is necessary so the terminus instances don't lie around. + Puppet::SSL::Key.indirection.clear_cache + Puppet::SSL::CertificateRequest.indirection.clear_cache + } + + it "should be considered a CA host if its name is equal to 'ca'" do + Puppet::SSL::Host.new("ca").should be_ca + end + + describe "when managing its key" do + it "should be able to generate and save a key" do + @host.generate_key + end + + it "should save the key such that the Indirector can find it" do + @host.generate_key + + Puppet::SSL::Key.find(@host.name).content.to_s.should == @host.key.to_s + end + + it "should save the private key into the :privatekeydir" do + @host.generate_key + File.read(File.join(Puppet.settings[:privatekeydir], "luke.madstop.com.pem")).should == @host.key.to_s + end + end + + describe "when managing its certificate request" do + it "should be able to generate and save a certificate request" do + @host.generate_certificate_request + end + + it "should save the certificate request such that the Indirector can find it" do + @host.generate_certificate_request + + Puppet::SSL::CertificateRequest.find(@host.name).content.to_s.should == @host.certificate_request.to_s + end + + it "should save the private certificate request into the :privatekeydir" do + @host.generate_certificate_request + File.read(File.join(Puppet.settings[:requestdir], "luke.madstop.com.pem")).should == @host.certificate_request.to_s + end + end +end diff --git a/spec/unit/indirector/ssl_file.rb b/spec/unit/indirector/ssl_file.rb index aed2a8769..864ba1420 100755 --- a/spec/unit/indirector/ssl_file.rb +++ b/spec/unit/indirector/ssl_file.rb @@ -25,8 +25,8 @@ describe Puppet::Indirector::SslFile do Puppet.settings.stubs(:value).with(:trace).returns(false) end - it "should use ssl upon initialization" do - Puppet.settings.expects(:use).with(:ssl) + it "should use :main and :ssl upon initialization" do + Puppet.settings.expects(:use).with(:main, :ssl) @file_class.new end diff --git a/spec/unit/ssl/certificate_authority.rb b/spec/unit/ssl/certificate_authority.rb index 285877301..83a3eb009 100755 --- a/spec/unit/ssl/certificate_authority.rb +++ b/spec/unit/ssl/certificate_authority.rb @@ -73,12 +73,12 @@ describe Puppet::SSL::CertificateAuthority do @ca.generate_ca_certificate end - it "should create and sign a self-signed cert" do + 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(@ca.name, :ca, request) + @ca.expects(:sign).with(@host.name, :ca, request) @ca.stubs :generate_password diff --git a/spec/unit/ssl/host.rb b/spec/unit/ssl/host.rb index 482286b93..55aaa4e51 100755 --- a/spec/unit/ssl/host.rb +++ b/spec/unit/ssl/host.rb @@ -28,9 +28,9 @@ describe Puppet::SSL::Host do @host.ca?.should be_false end - it "should be able to be a ca host" do - @host.ca = true - @host.ca?.should be_true + 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 |