~ubuntu-branches/ubuntu/quantal/puppet/quantal-security

« back to all changes in this revision

Viewing changes to spec/unit/face/certificate_spec.rb

  • Committer: Bazaar Package Importer
  • Author(s): Marc Deslauriers
  • Date: 2011-10-24 15:05:12 UTC
  • Revision ID: james.westby@ubuntu.com-20111024150512-yxqwfdp6hcs6of5l
Tags: 2.7.1-1ubuntu3.2
* SECURITY UPDATE: puppet master impersonation via incorrect certificates
  - debian/patches/CVE-2011-3872.patch: refactor certificate handling.
  - Thanks to upstream for providing the patch.
  - CVE-2011-3872

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
require 'puppet/ssl/host'
6
6
 
7
7
describe Puppet::Face[:certificate, '0.0.1'] do
 
8
  include PuppetSpec::Files
 
9
 
 
10
  let(:ca) { Puppet::SSL::CertificateAuthority.instance }
 
11
 
 
12
  before :each do
 
13
    Puppet[:confdir] = tmpdir('conf')
 
14
    Puppet::SSL::CertificateAuthority.stubs(:ca?).returns true
 
15
 
 
16
    Puppet::SSL::Host.ca_location = :local
 
17
 
 
18
    # We can't cache the CA between tests, because each one has its own SSL dir.
 
19
    ca = Puppet::SSL::CertificateAuthority.new
 
20
    Puppet::SSL::CertificateAuthority.stubs(:new).returns ca
 
21
    Puppet::SSL::CertificateAuthority.stubs(:instance).returns ca
 
22
  end
 
23
 
8
24
  it "should have a ca-location option" do
9
25
    subject.should be_option :ca_location
10
26
  end
11
27
 
12
28
  it "should set the ca location when invoked" do
13
 
    Puppet::SSL::Host.expects(:ca_location=).with(:foo)
14
 
    Puppet::SSL::Host.indirection.expects(:save)
15
 
    subject.sign "hello, friend", :ca_location => :foo
 
29
    Puppet::SSL::Host.expects(:ca_location=).with(:local)
 
30
    ca.expects(:sign).with do |name,options|
 
31
      name == "hello, friend"
 
32
    end
 
33
 
 
34
    subject.sign "hello, friend", :ca_location => :local
16
35
  end
17
36
 
18
37
  it "(#7059) should set the ca location when an inherited action is invoked" do
20
39
    subject.indirection.expects(:find)
21
40
    subject.find "hello, friend", :ca_location => :foo
22
41
  end
 
42
 
 
43
  describe "#generate" do
 
44
    let(:options) { {:ca_location => 'local'} }
 
45
    let(:host) { Puppet::SSL::Host.new(hostname) }
 
46
    let(:csr) { host.certificate_request }
 
47
 
 
48
    describe "for the current host" do
 
49
      let(:hostname) { Puppet[:certname] }
 
50
 
 
51
      it "should generate a CSR for this host" do
 
52
        subject.generate(hostname, options)
 
53
 
 
54
        csr.content.subject.to_s.should == "/CN=#{Puppet[:certname]}"
 
55
        csr.name.should == Puppet[:certname]
 
56
      end
 
57
 
 
58
      it "should add dns_alt_names from the global config if not otherwise specified" do
 
59
        Puppet[:dns_alt_names] = 'from,the,config'
 
60
 
 
61
        subject.generate(hostname, options)
 
62
 
 
63
        expected = %W[DNS:from DNS:the DNS:config DNS:#{hostname}]
 
64
 
 
65
        csr.subject_alt_names.should =~ expected
 
66
      end
 
67
 
 
68
      it "should add the provided dns_alt_names if they are specified" do
 
69
        Puppet[:dns_alt_names] = 'from,the,config'
 
70
 
 
71
        subject.generate(hostname, options.merge(:dns_alt_names => 'explicit,alt,names'))
 
72
 
 
73
        expected = %W[DNS:explicit DNS:alt DNS:names DNS:#{hostname}]
 
74
 
 
75
        csr.subject_alt_names.should =~ expected
 
76
      end
 
77
    end
 
78
 
 
79
    describe "for another host" do
 
80
      let(:hostname) { Puppet[:certname] + 'different' }
 
81
 
 
82
      it "should generate a CSR for the specified host" do
 
83
        subject.generate(hostname, options)
 
84
 
 
85
        csr.content.subject.to_s.should == "/CN=#{hostname}"
 
86
        csr.name.should == hostname
 
87
      end
 
88
 
 
89
      it "should fail if a CSR already exists for the host" do
 
90
        subject.generate(hostname, options)
 
91
 
 
92
        expect do
 
93
          subject.generate(hostname, options)
 
94
        end.to raise_error(RuntimeError, /#{hostname} already has a requested certificate; ignoring certificate request/)
 
95
      end
 
96
 
 
97
      it "should add not dns_alt_names from the config file" do
 
98
        Puppet[:dns_alt_names] = 'from,the,config'
 
99
 
 
100
        subject.generate(hostname, options)
 
101
 
 
102
        csr.subject_alt_names.should be_empty
 
103
      end
 
104
 
 
105
      it "should add the provided dns_alt_names if they are specified" do
 
106
        Puppet[:dns_alt_names] = 'from,the,config'
 
107
 
 
108
        subject.generate(hostname, options.merge(:dns_alt_names => 'explicit,alt,names'))
 
109
 
 
110
        expected = %W[DNS:explicit DNS:alt DNS:names DNS:#{hostname}]
 
111
 
 
112
        csr.subject_alt_names.should =~ expected
 
113
      end
 
114
    end
 
115
  end
 
116
 
 
117
  describe "#sign" do
 
118
    let(:options) { {:ca_location => 'local'} }
 
119
    let(:host) { Puppet::SSL::Host.new(hostname) }
 
120
    let(:hostname) { "foobar" }
 
121
 
 
122
    it "should sign the certificate request if one is waiting" do
 
123
      subject.generate(hostname, options)
 
124
 
 
125
      subject.sign(hostname, options)
 
126
 
 
127
      host.certificate_request.should be_nil
 
128
      host.certificate.should be_a(Puppet::SSL::Certificate)
 
129
      host.state.should == 'signed'
 
130
    end
 
131
 
 
132
    it "should fail if there is no waiting certificate request" do
 
133
      expect do
 
134
        subject.sign(hostname, options)
 
135
      end.to raise_error(ArgumentError, /Could not find certificate request for #{hostname}/)
 
136
    end
 
137
 
 
138
    describe "when ca_location is local" do
 
139
      describe "when the request has dns alt names" do
 
140
        before :each do
 
141
          subject.generate(hostname, options.merge(:dns_alt_names => 'some,alt,names'))
 
142
        end
 
143
 
 
144
        it "should refuse to sign the request if allow_dns_alt_names is not set" do
 
145
          expect do
 
146
            subject.sign(hostname, options)
 
147
          end.to raise_error(Puppet::SSL::CertificateAuthority::CertificateSigningError,
 
148
                             /CSR '#{hostname}' contains subject alternative names \(.*?\), which are disallowed. Use `puppet cert --allow-dns-alt-names sign #{hostname}` to sign this request./i)
 
149
 
 
150
          host.state.should == 'requested'
 
151
        end
 
152
 
 
153
        it "should sign the request if allow_dns_alt_names is set" do
 
154
          expect do
 
155
            subject.sign(hostname, options.merge(:allow_dns_alt_names => true))
 
156
          end.not_to raise_error
 
157
 
 
158
          host.state.should == 'signed'
 
159
        end
 
160
      end
 
161
 
 
162
      describe "when the request has no dns alt names" do
 
163
        before :each do
 
164
          subject.generate(hostname, options)
 
165
        end
 
166
 
 
167
        it "should sign the request if allow_dns_alt_names is set" do
 
168
          expect { subject.sign(hostname, options.merge(:allow_dns_alt_names => true)) }.not_to raise_error
 
169
 
 
170
          host.state.should == 'signed'
 
171
        end
 
172
 
 
173
        it "should sign the request if allow_dns_alt_names is not set" do
 
174
          expect { subject.sign(hostname, options) }.not_to raise_error
 
175
 
 
176
          host.state.should == 'signed'
 
177
        end
 
178
      end
 
179
    end
 
180
 
 
181
    describe "when ca_location is remote" do
 
182
      let(:options) { {:ca_location => :remote} }
 
183
      it "should fail if allow-dns-alt-names is specified" do
 
184
        expect do
 
185
          subject.sign(hostname, options.merge(:allow_dns_alt_names => true))
 
186
        end
 
187
      end
 
188
    end
 
189
  end
23
190
end