summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuke Kanies <luke@madstop.com>2008-04-17 21:39:24 -0500
committerLuke Kanies <luke@madstop.com>2008-04-17 21:39:24 -0500
commit71db9b58349f75a54649d9b0d1fead8d01593f7a (patch)
tree4e17f61f1b53863477e6917818bb1893a55693b1
parente5c4687593766955de09e5613c892ce82a2a989d (diff)
downloadpuppet-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.rb2
-rw-r--r--lib/puppet/indirector/ssl_file.rb2
-rw-r--r--lib/puppet/ssl/certificate_authority.rb3
-rw-r--r--lib/puppet/ssl/host.rb4
-rwxr-xr-xspec/integration/ssl/certificate_authority.rb108
-rwxr-xr-xspec/integration/ssl/certificate_request.rb55
-rwxr-xr-xspec/integration/ssl/host.rb70
-rwxr-xr-xspec/unit/indirector/ssl_file.rb4
-rwxr-xr-xspec/unit/ssl/certificate_authority.rb4
-rwxr-xr-xspec/unit/ssl/host.rb6
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