~ubuntu-branches/ubuntu/precise/puppet/precise-security

« back to all changes in this revision

Viewing changes to .pc/2.7.17-Puppet-July-2012-CVE-fixes.patch/spec/unit/ssl/certificate_authority/interface_spec.rb

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2012-07-10 07:58:03 UTC
  • Revision ID: package-import@ubuntu.com-20120710075803-og8iubg2a90dtk7f
Tags: 2.7.11-1ubuntu2.1
* SECURITY UPDATE: Multiple July 2012 security issues
  - debian/patches/2.7.17-Puppet-July-2012-CVE-fixes.patch: upstream
    patch to fix multiple security issues.
  - CVE-2012-3864: arbitrary file read on master from authenticated
    clients
  - CVE-2012-3865: arbitrary file delete or denial of service on master
    from authenticated clients
  - CVE-2012-3866: last_run_report.yaml report file is world readable and
    leads to arbitrary file read on master by an agent
  - CVE-2012-3867: insufficient input validation for agent cert hostnames

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env rspec
 
2
require 'spec_helper'
 
3
 
 
4
require 'puppet/ssl/certificate_authority'
 
5
 
 
6
shared_examples_for "a normal interface method" do
 
7
  it "should call the method on the CA for each host specified if an array was provided" do
 
8
    @ca.expects(@method).with("host1")
 
9
    @ca.expects(@method).with("host2")
 
10
 
 
11
    @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, :to => %w{host1 host2})
 
12
 
 
13
    @applier.apply(@ca)
 
14
  end
 
15
 
 
16
  it "should call the method on the CA for all existing certificates if :all was provided" do
 
17
    @ca.expects(:list).returns %w{host1 host2}
 
18
 
 
19
    @ca.expects(@method).with("host1")
 
20
    @ca.expects(@method).with("host2")
 
21
 
 
22
    @applier = Puppet::SSL::CertificateAuthority::Interface.new(@method, :to => :all)
 
23
 
 
24
    @applier.apply(@ca)
 
25
  end
 
26
end
 
27
 
 
28
describe Puppet::SSL::CertificateAuthority::Interface do
 
29
  before do
 
30
    @class = Puppet::SSL::CertificateAuthority::Interface
 
31
  end
 
32
  describe "when initializing" do
 
33
    it "should set its method using its settor" do
 
34
      instance = @class.new(:generate, :to => :all)
 
35
      instance.method.should == :generate
 
36
    end
 
37
 
 
38
    it "should set its subjects using the settor" do
 
39
      instance = @class.new(:generate, :to => :all)
 
40
      instance.subjects.should == :all
 
41
    end
 
42
 
 
43
    it "should set the digest if given" do
 
44
      interface = @class.new(:generate, :to => :all, :digest => :digest)
 
45
      interface.digest.should == :digest
 
46
    end
 
47
 
 
48
    it "should set the digest to md5 if none given" do
 
49
      interface = @class.new(:generate, :to => :all)
 
50
      interface.digest.should == :MD5
 
51
    end
 
52
  end
 
53
 
 
54
  describe "when setting the method" do
 
55
    it "should set the method" do
 
56
      instance = @class.new(:generate, :to => :all)
 
57
      instance.method = :list
 
58
 
 
59
      instance.method.should == :list
 
60
    end
 
61
 
 
62
    it "should fail if the method isn't a member of the INTERFACE_METHODS array" do
 
63
      lambda { @class.new(:thing, :to => :all) }.should raise_error(ArgumentError, /Invalid method thing to apply/)
 
64
    end
 
65
  end
 
66
 
 
67
  describe "when setting the subjects" do
 
68
    it "should set the subjects" do
 
69
      instance = @class.new(:generate, :to => :all)
 
70
      instance.subjects = :signed
 
71
 
 
72
      instance.subjects.should == :signed
 
73
    end
 
74
 
 
75
    it "should fail if the subjects setting isn't :all or an array" do
 
76
      lambda { @class.new(:generate, :to => "other") }.should raise_error(ArgumentError, /Subjects must be an array or :all; not other/)
 
77
    end
 
78
  end
 
79
 
 
80
  it "should have a method for triggering the application" do
 
81
    @class.new(:generate, :to => :all).should respond_to(:apply)
 
82
  end
 
83
 
 
84
  describe "when applying" do
 
85
    before do
 
86
      # We use a real object here, because :verify can't be stubbed, apparently.
 
87
      @ca = Object.new
 
88
    end
 
89
 
 
90
    it "should raise InterfaceErrors" do
 
91
      @applier = @class.new(:revoke, :to => :all)
 
92
 
 
93
      @ca.expects(:list).raises Puppet::SSL::CertificateAuthority::Interface::InterfaceError
 
94
 
 
95
      lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError)
 
96
    end
 
97
 
 
98
    it "should log non-Interface failures rather than failing" do
 
99
      @applier = @class.new(:revoke, :to => :all)
 
100
 
 
101
      @ca.expects(:list).raises ArgumentError
 
102
 
 
103
      Puppet.expects(:err)
 
104
 
 
105
      lambda { @applier.apply(@ca) }.should_not raise_error
 
106
    end
 
107
 
 
108
    describe "with an empty array specified and the method is not list" do
 
109
      it "should fail" do
 
110
        @applier = @class.new(:sign, :to => [])
 
111
        lambda { @applier.apply(@ca) }.should raise_error(ArgumentError)
 
112
      end
 
113
    end
 
114
 
 
115
    describe ":generate" do
 
116
      it "should fail if :all was specified" do
 
117
        @applier = @class.new(:generate, :to => :all)
 
118
        lambda { @applier.apply(@ca) }.should raise_error(ArgumentError)
 
119
      end
 
120
 
 
121
      it "should call :generate on the CA for each host specified" do
 
122
        @applier = @class.new(:generate, :to => %w{host1 host2})
 
123
 
 
124
        @ca.expects(:generate).with("host1", {})
 
125
        @ca.expects(:generate).with("host2", {})
 
126
 
 
127
        @applier.apply(@ca)
 
128
      end
 
129
    end
 
130
 
 
131
    describe ":verify" do
 
132
      before { @method = :verify }
 
133
      #it_should_behave_like "a normal interface method"
 
134
 
 
135
      it "should call the method on the CA for each host specified if an array was provided" do
 
136
        # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life.
 
137
      end
 
138
 
 
139
      it "should call the method on the CA for all existing certificates if :all was provided" do
 
140
        # LAK:NOTE Mocha apparently doesn't allow you to mock :verify, but I'm confident this works in real life.
 
141
      end
 
142
    end
 
143
 
 
144
    describe ":destroy" do
 
145
      before { @method = :destroy }
 
146
      it_should_behave_like "a normal interface method"
 
147
    end
 
148
 
 
149
    describe ":revoke" do
 
150
      before { @method = :revoke }
 
151
      it_should_behave_like "a normal interface method"
 
152
    end
 
153
 
 
154
    describe ":sign" do
 
155
      describe "and an array of names was provided" do
 
156
        let(:applier) { @class.new(:sign, @options.merge(:to => %w{host1 host2})) }
 
157
 
 
158
        it "should sign the specified waiting certificate requests" do
 
159
          @options = {:allow_dns_alt_names => false}
 
160
 
 
161
          @ca.expects(:sign).with("host1", false)
 
162
          @ca.expects(:sign).with("host2", false)
 
163
 
 
164
          applier.apply(@ca)
 
165
        end
 
166
 
 
167
        it "should sign the certificate requests with alt names if specified" do
 
168
          @options = {:allow_dns_alt_names => true}
 
169
 
 
170
          @ca.expects(:sign).with("host1", true)
 
171
          @ca.expects(:sign).with("host2", true)
 
172
 
 
173
          applier.apply(@ca)
 
174
        end
 
175
      end
 
176
 
 
177
      describe "and :all was provided" do
 
178
        it "should sign all waiting certificate requests" do
 
179
          @ca.stubs(:waiting?).returns(%w{cert1 cert2})
 
180
 
 
181
          @ca.expects(:sign).with("cert1", nil)
 
182
          @ca.expects(:sign).with("cert2", nil)
 
183
 
 
184
          @applier = @class.new(:sign, :to => :all)
 
185
          @applier.apply(@ca)
 
186
        end
 
187
 
 
188
        it "should fail if there are no waiting certificate requests" do
 
189
          @ca.stubs(:waiting?).returns([])
 
190
 
 
191
          @applier = @class.new(:sign, :to => :all)
 
192
          lambda { @applier.apply(@ca) }.should raise_error(Puppet::SSL::CertificateAuthority::Interface::InterfaceError)
 
193
        end
 
194
      end
 
195
    end
 
196
 
 
197
    describe ":list" do
 
198
      before :each do
 
199
        @cert = Puppet::SSL::Certificate.new 'foo'
 
200
        @csr = Puppet::SSL::CertificateRequest.new 'bar'
 
201
 
 
202
        @cert.stubs(:subject_alt_names).returns []
 
203
        @csr.stubs(:subject_alt_names).returns []
 
204
 
 
205
        Puppet::SSL::Certificate.indirection.stubs(:find).returns @cert
 
206
        Puppet::SSL::CertificateRequest.indirection.stubs(:find).returns @csr
 
207
 
 
208
        @ca.expects(:waiting?).returns %w{host1 host2 host3}
 
209
        @ca.expects(:list).returns %w{host4 host5 host6}
 
210
        @ca.stubs(:fingerprint).returns "fingerprint"
 
211
        @ca.stubs(:verify)
 
212
      end
 
213
 
 
214
      describe "and an empty array was provided" do
 
215
        it "should print all certificate requests" do
 
216
          applier = @class.new(:list, :to => [])
 
217
 
 
218
          applier.expects(:puts).with(<<-OUTPUT.chomp)
 
219
  host1 (fingerprint)
 
220
  host2 (fingerprint)
 
221
  host3 (fingerprint)
 
222
          OUTPUT
 
223
 
 
224
          applier.apply(@ca)
 
225
        end
 
226
      end
 
227
 
 
228
      describe "and :all was provided" do
 
229
        it "should print a string containing all certificate requests and certificates" do
 
230
          @ca.stubs(:verify).with("host4").raises(Puppet::SSL::CertificateAuthority::CertificateVerificationError.new(23), "certificate revoked")
 
231
 
 
232
          applier = @class.new(:list, :to => :all)
 
233
 
 
234
          applier.expects(:puts).with(<<-OUTPUT.chomp)
 
235
  host1 (fingerprint)
 
236
  host2 (fingerprint)
 
237
  host3 (fingerprint)
 
238
+ host5 (fingerprint)
 
239
+ host6 (fingerprint)
 
240
- host4 (fingerprint) (certificate revoked)
 
241
          OUTPUT
 
242
 
 
243
          applier.apply(@ca)
 
244
        end
 
245
      end
 
246
 
 
247
      describe "and :signed was provided" do
 
248
        it "should print a string containing all signed certificate requests and certificates" do
 
249
          applier = @class.new(:list, :to => :signed)
 
250
 
 
251
          applier.expects(:puts).with(<<-OUTPUT.chomp)
 
252
+ host4 (fingerprint)
 
253
+ host5 (fingerprint)
 
254
+ host6 (fingerprint)
 
255
          OUTPUT
 
256
 
 
257
          applier.apply(@ca)
 
258
        end
 
259
 
 
260
        it "should include subject alt names if they are on the certificate request" do
 
261
          @csr.stubs(:subject_alt_names).returns ["DNS:foo", "DNS:bar"]
 
262
 
 
263
          applier = @class.new(:list, :to => ['host1'])
 
264
 
 
265
          applier.expects(:puts).with(<<-OUTPUT.chomp)
 
266
  host1 (fingerprint) (alt names: DNS:foo, DNS:bar)
 
267
          OUTPUT
 
268
 
 
269
          applier.apply(@ca)
 
270
        end
 
271
      end
 
272
 
 
273
      describe "and an array of names was provided" do
 
274
        it "should print all named hosts" do
 
275
          applier = @class.new(:list, :to => %w{host1 host2 host4 host5})
 
276
 
 
277
          applier.expects(:puts).with(<<-OUTPUT.chomp)
 
278
  host1 (fingerprint)
 
279
  host2 (fingerprint)
 
280
+ host4 (fingerprint)
 
281
+ host5 (fingerprint)
 
282
            OUTPUT
 
283
 
 
284
          applier.apply(@ca)
 
285
        end
 
286
      end
 
287
    end
 
288
 
 
289
    describe ":print" do
 
290
      describe "and :all was provided" do
 
291
        it "should print all certificates" do
 
292
          @ca.expects(:list).returns %w{host1 host2}
 
293
 
 
294
          @applier = @class.new(:print, :to => :all)
 
295
 
 
296
          @ca.expects(:print).with("host1").returns "h1"
 
297
          @applier.expects(:puts).with "h1"
 
298
 
 
299
          @ca.expects(:print).with("host2").returns "h2"
 
300
          @applier.expects(:puts).with "h2"
 
301
 
 
302
          @applier.apply(@ca)
 
303
        end
 
304
      end
 
305
 
 
306
      describe "and an array of names was provided" do
 
307
        it "should print each named certificate if found" do
 
308
          @applier = @class.new(:print, :to => %w{host1 host2})
 
309
 
 
310
          @ca.expects(:print).with("host1").returns "h1"
 
311
          @applier.expects(:puts).with "h1"
 
312
 
 
313
          @ca.expects(:print).with("host2").returns "h2"
 
314
          @applier.expects(:puts).with "h2"
 
315
 
 
316
          @applier.apply(@ca)
 
317
        end
 
318
 
 
319
        it "should log any named but not found certificates" do
 
320
          @applier = @class.new(:print, :to => %w{host1 host2})
 
321
 
 
322
          @ca.expects(:print).with("host1").returns "h1"
 
323
          @applier.expects(:puts).with "h1"
 
324
 
 
325
          @ca.expects(:print).with("host2").returns nil
 
326
          Puppet.expects(:err).with { |msg| msg.include?("host2") }
 
327
 
 
328
          @applier.apply(@ca)
 
329
        end
 
330
      end
 
331
    end
 
332
 
 
333
    describe ":fingerprint" do
 
334
      it "should fingerprint with the set digest algorithm" do
 
335
        @applier = @class.new(:fingerprint, :to => %w{host1}, :digest => :digest)
 
336
 
 
337
        @ca.expects(:fingerprint).with("host1", :digest).returns "fingerprint1"
 
338
        @applier.expects(:puts).with "host1 fingerprint1"
 
339
 
 
340
        @applier.apply(@ca)
 
341
      end
 
342
 
 
343
      describe "and :all was provided" do
 
344
        it "should fingerprint all certificates (including waiting ones)" do
 
345
          @ca.expects(:list).returns %w{host1}
 
346
          @ca.expects(:waiting?).returns %w{host2}
 
347
 
 
348
          @applier = @class.new(:fingerprint, :to => :all)
 
349
 
 
350
          @ca.expects(:fingerprint).with("host1", :MD5).returns "fingerprint1"
 
351
          @applier.expects(:puts).with "host1 fingerprint1"
 
352
 
 
353
          @ca.expects(:fingerprint).with("host2", :MD5).returns "fingerprint2"
 
354
          @applier.expects(:puts).with "host2 fingerprint2"
 
355
 
 
356
          @applier.apply(@ca)
 
357
        end
 
358
      end
 
359
 
 
360
      describe "and an array of names was provided" do
 
361
        it "should print each named certificate if found" do
 
362
          @applier = @class.new(:fingerprint, :to => %w{host1 host2})
 
363
 
 
364
          @ca.expects(:fingerprint).with("host1", :MD5).returns "fingerprint1"
 
365
          @applier.expects(:puts).with "host1 fingerprint1"
 
366
 
 
367
          @ca.expects(:fingerprint).with("host2", :MD5).returns "fingerprint2"
 
368
          @applier.expects(:puts).with "host2 fingerprint2"
 
369
 
 
370
          @applier.apply(@ca)
 
371
        end
 
372
      end
 
373
    end
 
374
  end
 
375
end