puppet 2.7.17 → 2.7.18

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

Files changed (41) hide show
  1. data/CHANGELOG +16 -0
  2. data/conf/redhat/puppet.spec +4 -1
  3. data/lib/puppet.rb +1 -1
  4. data/lib/puppet/application/master.rb +26 -8
  5. data/lib/puppet/defaults.rb +4 -4
  6. data/lib/puppet/face/file/download.rb +1 -1
  7. data/lib/puppet/file_bucket/file.rb +6 -7
  8. data/lib/puppet/file_serving/configuration.rb +2 -1
  9. data/lib/puppet/file_serving/content.rb +1 -2
  10. data/lib/puppet/file_serving/metadata.rb +1 -2
  11. data/lib/puppet/file_serving/mount/modules.rb +4 -5
  12. data/lib/puppet/file_serving/{indirection_hooks.rb → terminus_selector.rb} +2 -5
  13. data/lib/puppet/indirector/file_bucket_file/selector.rb +49 -0
  14. data/lib/puppet/indirector/file_content/selector.rb +30 -0
  15. data/lib/puppet/indirector/file_metadata/selector.rb +30 -0
  16. data/lib/puppet/network/authstore.rb +10 -2
  17. data/lib/puppet/reports/store.rb +13 -6
  18. data/lib/puppet/ssl/base.rb +8 -0
  19. data/lib/puppet/ssl/certificate_authority.rb +10 -0
  20. data/lib/puppet/ssl/certificate_authority/interface.rb +4 -2
  21. data/lib/puppet/ssl/host.rb +1 -0
  22. data/spec/integration/file_bucket/file_spec.rb +44 -0
  23. data/spec/integration/file_serving/content_spec.rb +3 -8
  24. data/spec/integration/file_serving/metadata_spec.rb +4 -9
  25. data/spec/integration/network/rest_authconfig_spec.rb +22 -3
  26. data/spec/shared_behaviours/file_serving.rb +70 -58
  27. data/spec/shared_behaviours/file_serving_model.rb +73 -0
  28. data/spec/unit/file_serving/configuration_spec.rb +37 -29
  29. data/spec/unit/file_serving/content_spec.rb +1 -5
  30. data/spec/unit/file_serving/metadata_spec.rb +1 -5
  31. data/spec/unit/file_serving/mount/modules_spec.rb +8 -0
  32. data/spec/unit/file_serving/{indirection_hooks_spec.rb → terminus_selector_spec.rb} +10 -11
  33. data/spec/unit/indirector/file_bucket_file/selector_spec.rb +29 -0
  34. data/spec/unit/indirector/file_content/selector_spec.rb +10 -0
  35. data/spec/unit/indirector/file_metadata/selector_spec.rb +11 -0
  36. data/spec/unit/network/handler/ca_spec.rb +1 -0
  37. data/spec/unit/reports/store_spec.rb +28 -0
  38. data/spec/unit/ssl/certificate_authority/interface_spec.rb +17 -17
  39. data/spec/unit/ssl/certificate_authority_spec.rb +76 -11
  40. metadata +15 -8
  41. data/lib/puppet/file_bucket/file/indirection_hooks.rb +0 -9
@@ -6,7 +6,7 @@ require 'puppet/file_serving/content'
6
6
  describe Puppet::FileServing::Content do
7
7
  let(:path) { File.expand_path('/path') }
8
8
 
9
- it "should should be a subclass of Base" do
9
+ it "should be a subclass of Base" do
10
10
  Puppet::FileServing::Content.superclass.should equal(Puppet::FileServing::Base)
11
11
  end
12
12
 
@@ -14,10 +14,6 @@ describe Puppet::FileServing::Content do
14
14
  Puppet::FileServing::Content.indirection.name.should == :file_content
15
15
  end
16
16
 
17
- it "should should include the IndirectionHooks module in its indirection" do
18
- Puppet::FileServing::Content.indirection.singleton_class.included_modules.should include(Puppet::FileServing::IndirectionHooks)
19
- end
20
-
21
17
  it "should only support the raw format" do
22
18
  Puppet::FileServing::Content.supported_formats.should == [:raw]
23
19
  end
@@ -6,7 +6,7 @@ require 'puppet/file_serving/metadata'
6
6
  describe Puppet::FileServing::Metadata do
7
7
  let(:foobar) { File.expand_path('/foo/bar') }
8
8
 
9
- it "should should be a subclass of Base" do
9
+ it "should be a subclass of Base" do
10
10
  Puppet::FileServing::Metadata.superclass.should equal(Puppet::FileServing::Base)
11
11
  end
12
12
 
@@ -14,10 +14,6 @@ describe Puppet::FileServing::Metadata do
14
14
  Puppet::FileServing::Metadata.indirection.name.should == :file_metadata
15
15
  end
16
16
 
17
- it "should should include the IndirectionHooks module in its indirection" do
18
- Puppet::FileServing::Metadata.indirection.singleton_class.included_modules.should include(Puppet::FileServing::IndirectionHooks)
19
- end
20
-
21
17
  it "should have a method that triggers attribute collection" do
22
18
  Puppet::FileServing::Metadata.new(foobar).should respond_to(:collect)
23
19
  end
@@ -11,6 +11,10 @@ describe Puppet::FileServing::Mount::Modules do
11
11
  end
12
12
 
13
13
  describe "when finding files" do
14
+ it "should fail if no module is specified" do
15
+ expect { @mount.find("", @request) }.to raise_error(/No module specified/)
16
+ end
17
+
14
18
  it "should use the provided environment to find the module" do
15
19
  @environment.expects(:module)
16
20
 
@@ -36,6 +40,10 @@ describe Puppet::FileServing::Mount::Modules do
36
40
  end
37
41
 
38
42
  describe "when searching for files" do
43
+ it "should fail if no module is specified" do
44
+ expect { @mount.find("", @request) }.to raise_error(/No module specified/)
45
+ end
46
+
39
47
  it "should use the node's environment to search the module" do
40
48
  @environment.expects(:module)
41
49
 
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env rspec
2
2
  require 'spec_helper'
3
3
 
4
- require 'puppet/file_serving/indirection_hooks'
4
+ require 'puppet/file_serving/terminus_selector'
5
5
 
6
- describe Puppet::FileServing::IndirectionHooks do
6
+ describe Puppet::FileServing::TerminusSelector do
7
7
  before do
8
8
  @object = Object.new
9
- @object.extend(Puppet::FileServing::IndirectionHooks)
9
+ @object.extend(Puppet::FileServing::TerminusSelector)
10
10
 
11
11
  @request = stub 'request', :key => "mymod/myfile", :options => {:node => "whatever"}, :server => nil, :protocol => nil
12
12
  end
@@ -14,17 +14,17 @@ describe Puppet::FileServing::IndirectionHooks do
14
14
  describe "when being used to select termini" do
15
15
  it "should return :file if the request key is fully qualified" do
16
16
  @request.expects(:key).returns File.expand_path('/foo')
17
- @object.select_terminus(@request).should == :file
17
+ @object.select(@request).should == :file
18
18
  end
19
19
 
20
20
  it "should return :file if the URI protocol is set to 'file'" do
21
21
  @request.expects(:protocol).returns "file"
22
- @object.select_terminus(@request).should == :file
22
+ @object.select(@request).should == :file
23
23
  end
24
24
 
25
25
  it "should fail when a protocol other than :puppet or :file is used" do
26
26
  @request.stubs(:protocol).returns "http"
27
- proc { @object.select_terminus(@request) }.should raise_error(ArgumentError)
27
+ proc { @object.select(@request) }.should raise_error(ArgumentError)
28
28
  end
29
29
 
30
30
  describe "and the protocol is 'puppet'" do
@@ -35,15 +35,15 @@ describe Puppet::FileServing::IndirectionHooks do
35
35
  it "should choose :rest when a server is specified" do
36
36
  @request.stubs(:protocol).returns "puppet"
37
37
  @request.expects(:server).returns "foo"
38
- @object.select_terminus(@request).should == :rest
38
+ @object.select(@request).should == :rest
39
39
  end
40
40
 
41
41
  # This is so a given file location works when bootstrapping with no server.
42
42
  it "should choose :rest when the Settings name isn't 'puppet'" do
43
43
  @request.stubs(:protocol).returns "puppet"
44
- @request.stubs(:server).returns "foo"
44
+ # We have to stub this because we can't set name
45
45
  Puppet.settings.stubs(:value).with(:name).returns "foo"
46
- @object.select_terminus(@request).should == :rest
46
+ @object.select(@request).should == :rest
47
47
  end
48
48
 
49
49
  it "should choose :file_server when the settings name is 'puppet' and no server is specified" do
@@ -51,8 +51,7 @@ describe Puppet::FileServing::IndirectionHooks do
51
51
 
52
52
  @request.expects(:protocol).returns "puppet"
53
53
  @request.expects(:server).returns nil
54
- Puppet.settings.expects(:value).with(:name).returns "puppet"
55
- @object.select_terminus(@request).should == :file_server
54
+ @object.select(@request).should == :file_server
56
55
  end
57
56
  end
58
57
  end
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env rspec
2
+ require 'spec_helper'
3
+
4
+ require 'puppet/indirector/file_bucket_file/selector'
5
+ require 'puppet/indirector/file_bucket_file/file'
6
+ require 'puppet/indirector/file_bucket_file/rest'
7
+
8
+ describe Puppet::FileBucketFile::Selector do
9
+ %w[head find save search destroy].each do |method|
10
+ describe "##{method}" do
11
+ it "should proxy to rest terminus for https requests" do
12
+ request = stub 'request', :protocol => 'https'
13
+
14
+ Puppet::FileBucketFile::Rest.any_instance.expects(method).with(request)
15
+
16
+ subject.send(method, request)
17
+ end
18
+
19
+ it "should proxy to file terminus for other requests" do
20
+ request = stub 'request', :protocol => 'file'
21
+
22
+ Puppet::FileBucketFile::File.any_instance.expects(method).with(request)
23
+
24
+ subject.send(method, request)
25
+ end
26
+ end
27
+ end
28
+ end
29
+
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env rspec
2
+ require 'spec_helper'
3
+
4
+ require 'puppet/indirector/file_content/selector'
5
+
6
+ describe Puppet::Indirector::FileContent::Selector do
7
+ include PuppetSpec::Files
8
+
9
+ it_should_behave_like "Puppet::FileServing::Files", :file_content
10
+ end
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rspec
2
+ require 'spec_helper'
3
+
4
+ require 'puppet/indirector/file_metadata/selector'
5
+
6
+ describe Puppet::Indirector::FileMetadata::Selector do
7
+ include PuppetSpec::Files
8
+
9
+ it_should_behave_like "Puppet::FileServing::Files", :file_metadata
10
+ end
11
+
@@ -31,6 +31,7 @@ describe Puppet::Network::Handler::CA, :unless => Puppet.features.microsoft_wind
31
31
  Puppet::SSL::CertificateAuthority.stubs(:ca?).returns false
32
32
 
33
33
  csr = OpenSSL::X509::Request.new
34
+ csr.subject = OpenSSL::X509::Name.new([["CN", "anything"]])
34
35
  subject.getcert(csr.to_pem).should == ''
35
36
  end
36
37
 
@@ -44,5 +44,33 @@ describe processor do
44
44
  FileUtils.expects(:mv).in_sequence(writeseq).with(File.join(Dir.tmpdir, "foo123"), File.join(Puppet[:reportdir], @report.host, "201101061200.yaml"))
45
45
  @report.process
46
46
  end
47
+
48
+ ['..', 'hello/', '/hello', 'he/llo', 'hello/..', '.'].each do |node|
49
+ it "rejects #{node.inspect}" do
50
+ @report.host = node
51
+ expect { @report.process }.to raise_error(ArgumentError, /Invalid node/)
52
+ end
53
+ end
54
+
55
+ ['.hello', 'hello.', '..hi', 'hi..'].each do |node|
56
+ it "accepts #{node.inspect}" do
57
+ @report.host = node
58
+ @report.process
59
+ end
60
+ end
61
+ end
62
+
63
+ describe "::destroy" do
64
+ ['..', 'hello/', '/hello', 'he/llo', 'hello/..', '.'].each do |node|
65
+ it "rejects #{node.inspect}" do
66
+ expect { processor.destroy(node) }.to raise_error(ArgumentError, /Invalid node/)
67
+ end
68
+ end
69
+
70
+ ['.hello', 'hello.', '..hi', 'hi..'].each do |node|
71
+ it "accepts #{node.inspect}" do
72
+ processor.destroy(node)
73
+ end
74
+ end
47
75
  end
48
76
  end
@@ -216,9 +216,9 @@ describe Puppet::SSL::CertificateAuthority::Interface do
216
216
  applier = @class.new(:list, :to => [])
217
217
 
218
218
  applier.expects(:puts).with(<<-OUTPUT.chomp)
219
- host1 (fingerprint)
220
- host2 (fingerprint)
221
- host3 (fingerprint)
219
+ "host1" (fingerprint)
220
+ "host2" (fingerprint)
221
+ "host3" (fingerprint)
222
222
  OUTPUT
223
223
 
224
224
  applier.apply(@ca)
@@ -232,12 +232,12 @@ describe Puppet::SSL::CertificateAuthority::Interface do
232
232
  applier = @class.new(:list, :to => :all)
233
233
 
234
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)
235
+ "host1" (fingerprint)
236
+ "host2" (fingerprint)
237
+ "host3" (fingerprint)
238
+ + "host5" (fingerprint)
239
+ + "host6" (fingerprint)
240
+ - "host4" (fingerprint) (certificate revoked)
241
241
  OUTPUT
242
242
 
243
243
  applier.apply(@ca)
@@ -249,9 +249,9 @@ describe Puppet::SSL::CertificateAuthority::Interface do
249
249
  applier = @class.new(:list, :to => :signed)
250
250
 
251
251
  applier.expects(:puts).with(<<-OUTPUT.chomp)
252
- + host4 (fingerprint)
253
- + host5 (fingerprint)
254
- + host6 (fingerprint)
252
+ + "host4" (fingerprint)
253
+ + "host5" (fingerprint)
254
+ + "host6" (fingerprint)
255
255
  OUTPUT
256
256
 
257
257
  applier.apply(@ca)
@@ -263,7 +263,7 @@ describe Puppet::SSL::CertificateAuthority::Interface do
263
263
  applier = @class.new(:list, :to => ['host1'])
264
264
 
265
265
  applier.expects(:puts).with(<<-OUTPUT.chomp)
266
- host1 (fingerprint) (alt names: DNS:foo, DNS:bar)
266
+ "host1" (fingerprint) (alt names: "DNS:foo", "DNS:bar")
267
267
  OUTPUT
268
268
 
269
269
  applier.apply(@ca)
@@ -275,10 +275,10 @@ describe Puppet::SSL::CertificateAuthority::Interface do
275
275
  applier = @class.new(:list, :to => %w{host1 host2 host4 host5})
276
276
 
277
277
  applier.expects(:puts).with(<<-OUTPUT.chomp)
278
- host1 (fingerprint)
279
- host2 (fingerprint)
280
- + host4 (fingerprint)
281
- + host5 (fingerprint)
278
+ "host1" (fingerprint)
279
+ "host2" (fingerprint)
280
+ + "host4" (fingerprint)
281
+ + "host5" (fingerprint)
282
282
  OUTPUT
283
283
 
284
284
  applier.apply(@ca)
@@ -246,7 +246,7 @@ describe Puppet::SSL::CertificateAuthority do
246
246
  # Stub out the factory
247
247
  Puppet::SSL::CertificateFactory.stubs(:build).returns "my real cert"
248
248
 
249
- @request_content = stub "request content stub", :subject => @name
249
+ @request_content = stub "request content stub", :subject => OpenSSL::X509::Name.new([['CN', @name]])
250
250
  @request = stub 'request', :name => @name, :request_extensions => [], :subject_alt_names => [], :content => @request_content
251
251
 
252
252
  # And the inventory
@@ -303,28 +303,28 @@ describe Puppet::SSL::CertificateAuthority do
303
303
 
304
304
  it "should use a certificate type of :ca" do
305
305
  Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
306
- args[0] == :ca
306
+ args[0].should == :ca
307
307
  end.returns "my real cert"
308
308
  @ca.sign(@name, :ca, @request)
309
309
  end
310
310
 
311
311
  it "should pass the provided CSR as the CSR" do
312
312
  Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
313
- args[1] == @request
313
+ args[1].should == @request
314
314
  end.returns "my real cert"
315
315
  @ca.sign(@name, :ca, @request)
316
316
  end
317
317
 
318
318
  it "should use the provided CSR's content as the issuer" do
319
319
  Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
320
- args[2].subject == "myhost"
320
+ args[2].subject.to_s.should == "/CN=myhost"
321
321
  end.returns "my real cert"
322
322
  @ca.sign(@name, :ca, @request)
323
323
  end
324
324
 
325
325
  it "should pass the next serial as the serial number" do
326
326
  Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
327
- args[3] == @serial
327
+ args[3].should == @serial
328
328
  end.returns "my real cert"
329
329
  @ca.sign(@name, :ca, @request)
330
330
  end
@@ -452,11 +452,76 @@ describe Puppet::SSL::CertificateAuthority do
452
452
  @cert.stubs :save
453
453
  end
454
454
 
455
+ it "should reject CSRs whose CN doesn't match the name for which we're signing them" do
456
+ # Shorten this so the test doesn't take too long
457
+ Puppet[:keylength] = 1024
458
+ key = Puppet::SSL::Key.new('the_certname')
459
+ key.generate
460
+
461
+ csr = Puppet::SSL::CertificateRequest.new('the_certname')
462
+ csr.generate(key)
463
+
464
+ expect do
465
+ @ca.check_internal_signing_policies('not_the_certname', csr, false)
466
+ end.to raise_error(
467
+ Puppet::SSL::CertificateAuthority::CertificateSigningError,
468
+ /common name "the_certname" does not match expected certname "not_the_certname"/
469
+ )
470
+ end
471
+
472
+ describe "when validating the CN" do
473
+ before :all do
474
+ Puppet[:keylength] = 1024
475
+ @signing_key = Puppet::SSL::Key.new('my_signing_key')
476
+ @signing_key.generate
477
+ end
478
+
479
+ [
480
+ 'completely_okay',
481
+ 'sure, why not? :)',
482
+ 'so+many(things)-are=allowed.',
483
+ 'this"is#just&madness%you[see]',
484
+ 'and even a (an?) \\!',
485
+ 'waltz, nymph, for quick jigs vex bud.',
486
+ '{552c04ca-bb1b-11e1-874b-60334b04494e}'
487
+ ].each do |name|
488
+ it "should accept #{name.inspect}" do
489
+ csr = Puppet::SSL::CertificateRequest.new(name)
490
+ csr.generate(@signing_key)
491
+
492
+ @ca.check_internal_signing_policies(name, csr, false)
493
+ end
494
+ end
495
+
496
+ [
497
+ 'super/bad',
498
+ "not\neven\tkind\rof",
499
+ "ding\adong\a",
500
+ "hidden\b\b\b\b\b\bmessage",
501
+ "☃ :("
502
+ ].each do |name|
503
+ it "should reject #{name.inspect}" do
504
+ # We aren't even allowed to make objects with these names, so let's
505
+ # stub that to simulate an invalid one coming from outside Puppet
506
+ Puppet::SSL::CertificateRequest.stubs(:validate_certname)
507
+ csr = Puppet::SSL::CertificateRequest.new(name)
508
+ csr.generate(@signing_key)
509
+
510
+ expect do
511
+ @ca.check_internal_signing_policies(name, csr, false)
512
+ end.to raise_error(
513
+ Puppet::SSL::CertificateAuthority::CertificateSigningError,
514
+ /subject contains unprintable or non-ASCII characters/
515
+ )
516
+ end
517
+ end
518
+ end
519
+
455
520
  it "should reject a critical extension that isn't on the whitelist" do
456
521
  @request.stubs(:request_extensions).returns [{ "oid" => "banana",
457
522
  "value" => "yumm",
458
523
  "critical" => true }]
459
- expect { @ca.sign(@name) }.to raise_error(
524
+ expect { @ca.check_internal_signing_policies(@name, @request, false) }.to raise_error(
460
525
  Puppet::SSL::CertificateAuthority::CertificateSigningError,
461
526
  /request extensions that are not permitted/
462
527
  )
@@ -466,7 +531,7 @@ describe Puppet::SSL::CertificateAuthority do
466
531
  @request.stubs(:request_extensions).returns [{ "oid" => "peach",
467
532
  "value" => "meh",
468
533
  "critical" => false }]
469
- expect { @ca.sign(@name) }.to raise_error(
534
+ expect { @ca.check_internal_signing_policies(@name, @request, false) }.to raise_error(
470
535
  Puppet::SSL::CertificateAuthority::CertificateSigningError,
471
536
  /request extensions that are not permitted/
472
537
  )
@@ -479,7 +544,7 @@ describe Puppet::SSL::CertificateAuthority do
479
544
  { "oid" => "subjectAltName",
480
545
  "value" => "DNS:foo",
481
546
  "critical" => true }]
482
- expect { @ca.sign(@name) }.to raise_error(
547
+ expect { @ca.check_internal_signing_policies(@name, @request, false) }.to raise_error(
483
548
  Puppet::SSL::CertificateAuthority::CertificateSigningError,
484
549
  /request extensions that are not permitted/
485
550
  )
@@ -487,7 +552,7 @@ describe Puppet::SSL::CertificateAuthority do
487
552
 
488
553
  it "should reject a subjectAltName for a non-DNS value" do
489
554
  @request.stubs(:subject_alt_names).returns ['DNS:foo', 'email:bar@example.com']
490
- expect { @ca.sign(@name, true) }.to raise_error(
555
+ expect { @ca.check_internal_signing_policies(@name, @request, true) }.to raise_error(
491
556
  Puppet::SSL::CertificateAuthority::CertificateSigningError,
492
557
  /subjectAltName outside the DNS label space/
493
558
  )
@@ -497,7 +562,7 @@ describe Puppet::SSL::CertificateAuthority do
497
562
  @request.content.stubs(:subject).
498
563
  returns(OpenSSL::X509::Name.new([["CN", "*.local"]]))
499
564
 
500
- expect { @ca.sign(@name) }.to raise_error(
565
+ expect { @ca.check_internal_signing_policies('*.local', @request, false) }.to raise_error(
501
566
  Puppet::SSL::CertificateAuthority::CertificateSigningError,
502
567
  /subject contains a wildcard/
503
568
  )
@@ -505,7 +570,7 @@ describe Puppet::SSL::CertificateAuthority do
505
570
 
506
571
  it "should reject a wildcard subjectAltName" do
507
572
  @request.stubs(:subject_alt_names).returns ['DNS:foo', 'DNS:*.bar']
508
- expect { @ca.sign(@name, true) }.to raise_error(
573
+ expect { @ca.check_internal_signing_policies(@name, @request, true) }.to raise_error(
509
574
  Puppet::SSL::CertificateAuthority::CertificateSigningError,
510
575
  /subjectAltName contains a wildcard/
511
576
  )