puppet 2.7.5 → 2.7.6

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 (140) hide show
  1. data/CHANGELOG +121 -0
  2. data/conf/redhat/puppet.spec +16 -7
  3. data/lib/puppet.rb +1 -1
  4. data/lib/puppet/application/cert.rb +17 -3
  5. data/lib/puppet/application/device.rb +1 -0
  6. data/lib/puppet/application/kick.rb +0 -2
  7. data/lib/puppet/application/resource.rb +73 -66
  8. data/lib/puppet/configurer/plugin_handler.rb +6 -2
  9. data/lib/puppet/defaults.rb +60 -5
  10. data/lib/puppet/face/ca.rb +11 -2
  11. data/lib/puppet/face/certificate.rb +33 -4
  12. data/lib/puppet/file_serving/fileset.rb +1 -1
  13. data/lib/puppet/file_serving/indirection_hooks.rb +2 -2
  14. data/lib/puppet/file_serving/metadata.rb +43 -4
  15. data/lib/puppet/indirector.rb +0 -1
  16. data/lib/puppet/indirector/request.rb +3 -4
  17. data/lib/puppet/indirector/resource/active_record.rb +3 -10
  18. data/lib/puppet/indirector/resource/ral.rb +2 -2
  19. data/lib/puppet/indirector/rest.rb +1 -1
  20. data/lib/puppet/network/handler/ca.rb +16 -106
  21. data/lib/puppet/network/handler/master.rb +0 -3
  22. data/lib/puppet/network/handler/runner.rb +1 -0
  23. data/lib/puppet/parser/scope.rb +10 -0
  24. data/lib/puppet/provider/file/posix.rb +72 -34
  25. data/lib/puppet/provider/file/windows.rb +100 -0
  26. data/lib/puppet/provider/group/windows_adsi.rb +2 -2
  27. data/lib/puppet/provider/user/windows_adsi.rb +19 -4
  28. data/lib/puppet/resource.rb +16 -0
  29. data/lib/puppet/resource/catalog.rb +1 -1
  30. data/lib/puppet/ssl/certificate.rb +2 -2
  31. data/lib/puppet/ssl/certificate_authority.rb +86 -10
  32. data/lib/puppet/ssl/certificate_authority/interface.rb +64 -19
  33. data/lib/puppet/ssl/certificate_factory.rb +112 -91
  34. data/lib/puppet/ssl/certificate_request.rb +88 -1
  35. data/lib/puppet/ssl/host.rb +20 -3
  36. data/lib/puppet/type/file.rb +15 -34
  37. data/lib/puppet/type/file/group.rb +11 -91
  38. data/lib/puppet/type/file/mode.rb +11 -41
  39. data/lib/puppet/type/file/owner.rb +18 -34
  40. data/lib/puppet/type/file/source.rb +22 -7
  41. data/lib/puppet/type/group.rb +4 -3
  42. data/lib/puppet/type/user.rb +4 -1
  43. data/lib/puppet/util.rb +59 -6
  44. data/lib/puppet/util/adsi.rb +11 -0
  45. data/lib/puppet/util/log.rb +4 -0
  46. data/lib/puppet/util/log/destinations.rb +7 -1
  47. data/lib/puppet/util/monkey_patches.rb +19 -0
  48. data/lib/puppet/util/network_device/config.rb +4 -5
  49. data/lib/puppet/util/settings.rb +5 -0
  50. data/lib/puppet/util/suidmanager.rb +0 -1
  51. data/lib/puppet/util/windows.rb +4 -0
  52. data/lib/puppet/util/windows/error.rb +16 -0
  53. data/lib/puppet/util/windows/security.rb +593 -0
  54. data/spec/integration/defaults_spec.rb +27 -0
  55. data/spec/integration/network/handler_spec.rb +1 -1
  56. data/spec/integration/type/file_spec.rb +382 -145
  57. data/spec/integration/util/windows/security_spec.rb +468 -0
  58. data/spec/shared_behaviours/file_serving.rb +4 -3
  59. data/spec/unit/application/agent_spec.rb +1 -0
  60. data/spec/unit/application/device_spec.rb +5 -0
  61. data/spec/unit/application/resource_spec.rb +62 -101
  62. data/spec/unit/configurer/downloader_spec.rb +2 -2
  63. data/spec/unit/configurer/plugin_handler_spec.rb +15 -8
  64. data/spec/unit/configurer_spec.rb +2 -2
  65. data/spec/unit/face/ca_spec.rb +34 -0
  66. data/spec/unit/face/certificate_spec.rb +168 -1
  67. data/spec/unit/file_serving/fileset_spec.rb +1 -1
  68. data/spec/unit/file_serving/indirection_hooks_spec.rb +1 -1
  69. data/spec/unit/file_serving/metadata_spec.rb +151 -107
  70. data/spec/unit/indirector/certificate_request/ca_spec.rb +0 -3
  71. data/spec/unit/indirector/direct_file_server_spec.rb +10 -9
  72. data/spec/unit/indirector/file_metadata/file_spec.rb +6 -4
  73. data/spec/unit/indirector/request_spec.rb +13 -3
  74. data/spec/unit/indirector/resource/active_record_spec.rb +4 -10
  75. data/spec/unit/indirector/resource/ral_spec.rb +6 -4
  76. data/spec/unit/indirector/rest_spec.rb +5 -6
  77. data/spec/unit/network/handler/ca_spec.rb +86 -0
  78. data/spec/unit/parser/collector_spec.rb +7 -7
  79. data/spec/unit/parser/scope_spec.rb +20 -0
  80. data/spec/unit/provider/file/posix_spec.rb +226 -0
  81. data/spec/unit/provider/file/windows_spec.rb +136 -0
  82. data/spec/unit/provider/group/windows_adsi_spec.rb +7 -2
  83. data/spec/unit/provider/user/windows_adsi_spec.rb +36 -3
  84. data/spec/unit/resource/catalog_spec.rb +20 -10
  85. data/spec/unit/resource_spec.rb +55 -8
  86. data/spec/unit/ssl/certificate_authority/interface_spec.rb +97 -54
  87. data/spec/unit/ssl/certificate_authority_spec.rb +133 -23
  88. data/spec/unit/ssl/certificate_factory_spec.rb +90 -70
  89. data/spec/unit/ssl/certificate_request_spec.rb +62 -1
  90. data/spec/unit/ssl/certificate_spec.rb +20 -14
  91. data/spec/unit/ssl/host_spec.rb +52 -6
  92. data/spec/unit/type/file/content_spec.rb +4 -4
  93. data/spec/unit/type/file/group_spec.rb +34 -96
  94. data/spec/unit/type/file/mode_spec.rb +88 -0
  95. data/spec/unit/type/file/owner_spec.rb +32 -123
  96. data/spec/unit/type/file/source_spec.rb +120 -41
  97. data/spec/unit/type/file_spec.rb +1033 -753
  98. data/spec/unit/type_spec.rb +19 -1
  99. data/spec/unit/util/adsi_spec.rb +19 -0
  100. data/spec/unit/util/log/destinations_spec.rb +75 -0
  101. data/spec/unit/util/log_spec.rb +15 -0
  102. data/spec/unit/util/network_device/config_spec.rb +7 -0
  103. data/spec/unit/util/settings_spec.rb +10 -0
  104. data/spec/unit/util_spec.rb +126 -13
  105. data/test/language/functions.rb +0 -1
  106. data/test/language/snippets.rb +0 -9
  107. data/test/lib/puppettest/exetest.rb +1 -1
  108. data/test/lib/puppettest/servertest.rb +0 -1
  109. data/test/rails/rails.rb +0 -1
  110. data/test/ral/type/filesources.rb +0 -60
  111. metadata +13 -33
  112. data/lib/puppet/network/client.rb +0 -174
  113. data/lib/puppet/network/client/ca.rb +0 -56
  114. data/lib/puppet/network/client/file.rb +0 -6
  115. data/lib/puppet/network/client/proxy.rb +0 -27
  116. data/lib/puppet/network/client/report.rb +0 -26
  117. data/lib/puppet/network/client/runner.rb +0 -10
  118. data/lib/puppet/network/client/status.rb +0 -4
  119. data/lib/puppet/network/http_server.rb +0 -3
  120. data/lib/puppet/network/http_server/mongrel.rb +0 -130
  121. data/lib/puppet/network/http_server/webrick.rb +0 -155
  122. data/lib/puppet/network/xmlrpc/client.rb +0 -211
  123. data/lib/puppet/provider/file/win32.rb +0 -72
  124. data/lib/puppet/sslcertificates.rb +0 -146
  125. data/lib/puppet/sslcertificates/ca.rb +0 -375
  126. data/lib/puppet/sslcertificates/certificate.rb +0 -255
  127. data/lib/puppet/sslcertificates/inventory.rb +0 -38
  128. data/lib/puppet/sslcertificates/support.rb +0 -146
  129. data/spec/integration/network/client_spec.rb +0 -18
  130. data/spec/unit/network/xmlrpc/client_spec.rb +0 -172
  131. data/spec/unit/sslcertificates/ca_spec.rb +0 -106
  132. data/test/certmgr/certmgr.rb +0 -308
  133. data/test/certmgr/inventory.rb +0 -69
  134. data/test/certmgr/support.rb +0 -105
  135. data/test/network/client/ca.rb +0 -69
  136. data/test/network/client/dipper.rb +0 -34
  137. data/test/network/handler/ca.rb +0 -273
  138. data/test/network/server/mongrel_test.rb +0 -99
  139. data/test/network/server/webrick.rb +0 -111
  140. data/test/network/xmlrpc/client.rb +0 -45
@@ -199,8 +199,9 @@ describe Puppet::SSL::CertificateAuthority do
199
199
  request = mock 'request'
200
200
  Puppet::SSL::CertificateRequest.expects(:new).with(@ca.host.name).returns request
201
201
  request.expects(:generate).with(@ca.host.key)
202
+ request.stubs(:request_extensions => [])
202
203
 
203
- @ca.expects(:sign).with(@host.name, :ca, request)
204
+ @ca.expects(:sign).with(@host.name, false, request)
204
205
 
205
206
  @ca.stubs :generate_password
206
207
 
@@ -243,10 +244,10 @@ describe Puppet::SSL::CertificateAuthority do
243
244
  Puppet::SSL::Certificate.indirection.stubs(:save)
244
245
 
245
246
  # Stub out the factory
246
- @factory = stub 'factory', :result => "my real cert"
247
- Puppet::SSL::CertificateFactory.stubs(:new).returns @factory
247
+ Puppet::SSL::CertificateFactory.stubs(:build).returns "my real cert"
248
248
 
249
- @request = stub 'request', :content => "myrequest", :name => @name
249
+ @request_content = stub "request content stub", :subject => @name
250
+ @request = stub 'request', :name => @name, :request_extensions => [], :subject_alt_names => [], :content => @request_content
250
251
 
251
252
  # And the inventory
252
253
  @inventory = stub 'inventory', :add => nil
@@ -297,37 +298,45 @@ describe Puppet::SSL::CertificateAuthority do
297
298
  it "should not look up a certificate request for the host" do
298
299
  Puppet::SSL::CertificateRequest.indirection.expects(:find).never
299
300
 
300
- @ca.sign(@name, :ca, @request)
301
+ @ca.sign(@name, true, @request)
301
302
  end
302
303
 
303
304
  it "should use a certificate type of :ca" do
304
- Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
305
+ Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
305
306
  args[0] == :ca
306
- end.returns @factory
307
+ end.returns "my real cert"
307
308
  @ca.sign(@name, :ca, @request)
308
309
  end
309
310
 
310
311
  it "should pass the provided CSR as the CSR" do
311
- Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
312
- args[1] == "myrequest"
313
- end.returns @factory
312
+ Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
313
+ args[1] == @request
314
+ end.returns "my real cert"
314
315
  @ca.sign(@name, :ca, @request)
315
316
  end
316
317
 
317
318
  it "should use the provided CSR's content as the issuer" do
318
- Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
319
- args[2] == "myrequest"
320
- end.returns @factory
319
+ Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
320
+ args[2].subject == "myhost"
321
+ end.returns "my real cert"
321
322
  @ca.sign(@name, :ca, @request)
322
323
  end
323
324
 
324
325
  it "should pass the next serial as the serial number" do
325
- Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
326
+ Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
326
327
  args[3] == @serial
327
- end.returns @factory
328
+ end.returns "my real cert"
328
329
  @ca.sign(@name, :ca, @request)
329
330
  end
330
331
 
332
+ it "should sign the certificate request even if it contains alt names" do
333
+ @request.stubs(:subject_alt_names).returns %w[DNS:foo DNS:bar DNS:baz]
334
+
335
+ expect do
336
+ @ca.sign(@name, false, @request)
337
+ end.should_not raise_error(Puppet::SSL::CertificateAuthority::CertificateSigningError)
338
+ end
339
+
331
340
  it "should save the resulting certificate" do
332
341
  Puppet::SSL::Certificate.indirection.expects(:save).with(@cert)
333
342
 
@@ -345,9 +354,9 @@ describe Puppet::SSL::CertificateAuthority do
345
354
  end
346
355
 
347
356
  it "should use a certificate type of :server" do
348
- Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
357
+ Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
349
358
  args[0] == :server
350
- end.returns @factory
359
+ end.returns "my real cert"
351
360
 
352
361
  @ca.sign(@name)
353
362
  end
@@ -364,17 +373,45 @@ describe Puppet::SSL::CertificateAuthority do
364
373
  lambda { @ca.sign(@name) }.should raise_error(ArgumentError)
365
374
  end
366
375
 
376
+ it "should fail if an unknown request extension is present" do
377
+ @request.stubs :request_extensions => [{ "oid" => "bananas",
378
+ "value" => "delicious" }]
379
+ expect { @ca.sign(@name) }.
380
+ should raise_error(/CSR has request extensions that are not permitted/)
381
+ end
382
+
383
+ it "should fail if the CSR contains alt names and they are not expected" do
384
+ @request.stubs(:subject_alt_names).returns %w[DNS:foo DNS:bar DNS:baz]
385
+
386
+ expect do
387
+ @ca.sign(@name, false)
388
+ end.to raise_error(Puppet::SSL::CertificateAuthority::CertificateSigningError, /CSR '#{@name}' contains subject alternative names \(.*?\), which are disallowed. Use `puppet cert --allow-dns-alt-names sign #{@name}` to sign this request./)
389
+ end
390
+
391
+ it "should not fail if the CSR does not contain alt names and they are expected" do
392
+ @request.stubs(:subject_alt_names).returns []
393
+ expect { @ca.sign(@name, true) }.should_not raise_error
394
+ end
395
+
396
+ it "should reject alt names by default" do
397
+ @request.stubs(:subject_alt_names).returns %w[DNS:foo DNS:bar DNS:baz]
398
+
399
+ expect do
400
+ @ca.sign(@name)
401
+ end.to raise_error(Puppet::SSL::CertificateAuthority::CertificateSigningError, /CSR '#{@name}' contains subject alternative names \(.*?\), which are disallowed. Use `puppet cert --allow-dns-alt-names sign #{@name}` to sign this request./)
402
+ end
403
+
367
404
  it "should use the CA certificate as the issuer" do
368
- Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
405
+ Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
369
406
  args[2] == @cacert.content
370
- end.returns @factory
407
+ end.returns "my real cert"
371
408
  @ca.sign(@name)
372
409
  end
373
410
 
374
411
  it "should pass the next serial as the serial number" do
375
- Puppet::SSL::CertificateFactory.expects(:new).with do |*args|
412
+ Puppet::SSL::CertificateFactory.expects(:build).with do |*args|
376
413
  args[3] == @serial
377
- end.returns @factory
414
+ end.returns "my real cert"
378
415
  @ca.sign(@name)
379
416
  end
380
417
 
@@ -399,6 +436,80 @@ describe Puppet::SSL::CertificateAuthority do
399
436
 
400
437
  @ca.sign(@name)
401
438
  end
439
+
440
+ it "should check the internal signing policies" do
441
+ @ca.expects(:check_internal_signing_policies).returns true
442
+ @ca.sign(@name)
443
+ end
444
+ end
445
+
446
+ context "#check_internal_signing_policies" do
447
+ before do
448
+ @serial = 10
449
+ @ca.stubs(:next_serial).returns @serial
450
+
451
+ Puppet::SSL::CertificateRequest.indirection.stubs(:find).with(@name).returns @request
452
+ @cert.stubs :save
453
+ end
454
+
455
+ it "should reject a critical extension that isn't on the whitelist" do
456
+ @request.stubs(:request_extensions).returns [{ "oid" => "banana",
457
+ "value" => "yumm",
458
+ "critical" => true }]
459
+ expect { @ca.sign(@name) }.to raise_error(
460
+ Puppet::SSL::CertificateAuthority::CertificateSigningError,
461
+ /request extensions that are not permitted/
462
+ )
463
+ end
464
+
465
+ it "should reject a non-critical extension that isn't on the whitelist" do
466
+ @request.stubs(:request_extensions).returns [{ "oid" => "peach",
467
+ "value" => "meh",
468
+ "critical" => false }]
469
+ expect { @ca.sign(@name) }.to raise_error(
470
+ Puppet::SSL::CertificateAuthority::CertificateSigningError,
471
+ /request extensions that are not permitted/
472
+ )
473
+ end
474
+
475
+ it "should reject non-whitelist extensions even if a valid extension is present" do
476
+ @request.stubs(:request_extensions).returns [{ "oid" => "peach",
477
+ "value" => "meh",
478
+ "critical" => false },
479
+ { "oid" => "subjectAltName",
480
+ "value" => "DNS:foo",
481
+ "critical" => true }]
482
+ expect { @ca.sign(@name) }.to raise_error(
483
+ Puppet::SSL::CertificateAuthority::CertificateSigningError,
484
+ /request extensions that are not permitted/
485
+ )
486
+ end
487
+
488
+ it "should reject a subjectAltName for a non-DNS value" do
489
+ @request.stubs(:subject_alt_names).returns ['DNS:foo', 'email:bar@example.com']
490
+ expect { @ca.sign(@name, true) }.to raise_error(
491
+ Puppet::SSL::CertificateAuthority::CertificateSigningError,
492
+ /subjectAltName outside the DNS label space/
493
+ )
494
+ end
495
+
496
+ it "should reject a wildcard subject" do
497
+ @request.content.stubs(:subject).
498
+ returns(OpenSSL::X509::Name.new([["CN", "*.local"]]))
499
+
500
+ expect { @ca.sign(@name) }.to raise_error(
501
+ Puppet::SSL::CertificateAuthority::CertificateSigningError,
502
+ /subject contains a wildcard/
503
+ )
504
+ end
505
+
506
+ it "should reject a wildcard subjectAltName" do
507
+ @request.stubs(:subject_alt_names).returns ['DNS:foo', 'DNS:*.bar']
508
+ expect { @ca.sign(@name, true) }.to raise_error(
509
+ Puppet::SSL::CertificateAuthority::CertificateSigningError,
510
+ /subjectAltName contains a wildcard/
511
+ )
512
+ end
402
513
  end
403
514
 
404
515
  it "should create a certificate instance with the content set to the newly signed x509 certificate" do
@@ -763,8 +874,7 @@ describe Puppet::SSL::CertificateAuthority do
763
874
  end
764
875
 
765
876
  it "should sign the generated request" do
766
- @ca.expects(:sign).with("him")
767
-
877
+ @ca.expects(:sign).with("him", false)
768
878
  @ca.generate("him")
769
879
  end
770
880
  end
@@ -4,103 +4,123 @@ require 'spec_helper'
4
4
  require 'puppet/ssl/certificate_factory'
5
5
 
6
6
  describe Puppet::SSL::CertificateFactory do
7
- before do
8
- @cert_type = mock 'cert_type'
9
- @name = mock 'name'
10
- @csr = stub 'csr', :subject => @name
11
- @issuer = mock 'issuer'
12
- @serial = mock 'serial'
13
-
14
- @factory = Puppet::SSL::CertificateFactory.new(@cert_type, @csr, @issuer, @serial)
7
+ let :serial do OpenSSL::BN.new('12') end
8
+ let :name do "example.local" end
9
+ let :x509_name do OpenSSL::X509::Name.new([['CN', name]]) end
10
+ let :key do Puppet::SSL::Key.new(name).generate end
11
+ let :csr do
12
+ csr = Puppet::SSL::CertificateRequest.new(name)
13
+ csr.generate(key)
14
+ csr
15
15
  end
16
-
17
- describe "when initializing" do
18
- it "should set its :cert_type to its first argument" do
19
- @factory.cert_type.should equal(@cert_type)
20
- end
21
-
22
- it "should set its :csr to its second argument" do
23
- @factory.csr.should equal(@csr)
24
- end
25
-
26
- it "should set its :issuer to its third argument" do
27
- @factory.issuer.should equal(@issuer)
28
- end
29
-
30
- it "should set its :serial to its fourth argument" do
31
- @factory.serial.should equal(@serial)
32
- end
33
-
34
- it "should set its name to the subject of the csr" do
35
- @factory.name.should equal(@name)
36
- end
16
+ let :issuer do
17
+ cert = OpenSSL::X509::Certificate.new
18
+ cert.subject = OpenSSL::X509::Name.new([["CN", 'issuer.local']])
19
+ cert
37
20
  end
38
21
 
39
22
  describe "when generating the certificate" do
40
- before do
41
- @cert = mock 'cert'
42
-
43
- @cert.stub_everything
44
-
45
- @factory.stubs :build_extensions
46
-
47
- @factory.stubs :set_ttl
48
-
49
- @issuer_name = mock 'issuer_name'
50
- @issuer.stubs(:subject).returns @issuer_name
51
-
52
- @public_key = mock 'public_key'
53
- @csr.stubs(:public_key).returns @public_key
54
-
55
- OpenSSL::X509::Certificate.stubs(:new).returns @cert
56
- end
57
-
58
23
  it "should return a new X509 certificate" do
59
- OpenSSL::X509::Certificate.expects(:new).returns @cert
60
- @factory.result.should equal(@cert)
24
+ subject.build(:server, csr, issuer, serial).should_not ==
25
+ subject.build(:server, csr, issuer, serial)
61
26
  end
62
27
 
63
28
  it "should set the certificate's version to 2" do
64
- @cert.expects(:version=).with 2
65
- @factory.result
29
+ subject.build(:server, csr, issuer, serial).version.should == 2
66
30
  end
67
31
 
68
32
  it "should set the certificate's subject to the CSR's subject" do
69
- @cert.expects(:subject=).with @name
70
- @factory.result
33
+ cert = subject.build(:server, csr, issuer, serial)
34
+ cert.subject.should eql x509_name
71
35
  end
72
36
 
73
37
  it "should set the certificate's issuer to the Issuer's subject" do
74
- @cert.expects(:issuer=).with @issuer_name
75
- @factory.result
38
+ cert = subject.build(:server, csr, issuer, serial)
39
+ cert.issuer.should eql issuer.subject
76
40
  end
77
41
 
78
42
  it "should set the certificate's public key to the CSR's public key" do
79
- @cert.expects(:public_key=).with @public_key
80
- @factory.result
43
+ cert = subject.build(:server, csr, issuer, serial)
44
+ cert.public_key.should be_public
45
+ cert.public_key.to_s.should == csr.content.public_key.to_s
81
46
  end
82
47
 
83
48
  it "should set the certificate's serial number to the provided serial number" do
84
- @cert.expects(:serial=).with @serial
85
- @factory.result
49
+ cert = subject.build(:server, csr, issuer, serial)
50
+ cert.serial.should == serial
51
+ end
52
+
53
+ it "should have 24 hours grace on the start of the cert" do
54
+ cert = subject.build(:server, csr, issuer, serial)
55
+ cert.not_before.should be_within(1).of(Time.now - 24*60*60)
56
+ end
57
+
58
+ it "should set the default TTL of the certificate" do
59
+ ttl = Puppet::SSL::CertificateFactory.ttl
60
+ cert = subject.build(:server, csr, issuer, serial)
61
+ cert.not_after.should be_within(1).of(Time.now + ttl)
62
+ end
63
+
64
+ it "should respect a custom TTL for the CA" do
65
+ Puppet[:ca_ttl] = 12
66
+ cert = subject.build(:server, csr, issuer, serial)
67
+ cert.not_after.should be_within(1).of(Time.now + 12)
86
68
  end
87
69
 
88
70
  it "should build extensions for the certificate" do
89
- @factory.expects(:build_extensions)
90
- @factory.result
71
+ cert = subject.build(:server, csr, issuer, serial)
72
+ cert.extensions.map {|x| x.to_h }.find {|x| x["oid"] == "nsComment" }.should ==
73
+ { "oid" => "nsComment",
74
+ "value" => "Puppet Ruby/OpenSSL Internal Certificate",
75
+ "critical" => false }
91
76
  end
92
77
 
93
- it "should set the ttl of the certificate" do
94
- @factory.expects(:set_ttl)
95
- @factory.result
78
+ # See #2848 for why we are doing this: we need to make sure that
79
+ # subjectAltName is set if the CSR has it, but *not* if it is set when the
80
+ # certificate is built!
81
+ it "should not add subjectAltNames from dns_alt_names" do
82
+ Puppet[:dns_alt_names] = 'one, two'
83
+ # Verify the CSR still has no extReq, just in case...
84
+ csr.request_extensions.should == []
85
+ cert = subject.build(:server, csr, issuer, serial)
86
+
87
+ cert.extensions.find {|x| x.oid == 'subjectAltName' }.should be_nil
96
88
  end
97
- end
98
89
 
99
- describe "when building extensions" do
100
- it "should have tests"
101
- end
90
+ it "should add subjectAltName when the CSR requests them" do
91
+ Puppet[:dns_alt_names] = ''
92
+
93
+ expect = %w{one two} + [name]
94
+
95
+ csr = Puppet::SSL::CertificateRequest.new(name)
96
+ csr.generate(key, :dns_alt_names => expect.join(', '))
102
97
 
103
- describe "when setting the ttl" do
104
- it "should have tests"
98
+ csr.request_extensions.should_not be_nil
99
+ csr.subject_alt_names.should =~ expect.map{|x| "DNS:#{x}"}
100
+
101
+ cert = subject.build(:server, csr, issuer, serial)
102
+ san = cert.extensions.find {|x| x.oid == 'subjectAltName' }
103
+ san.should_not be_nil
104
+ expect.each do |name|
105
+ san.value.should =~ /DNS:#{name}\b/i
106
+ end
107
+ end
108
+
109
+ # Can't check the CA here, since that requires way more infrastructure
110
+ # that I want to build up at this time. We can verify the critical
111
+ # values, though, which are non-CA certs. --daniel 2011-10-11
112
+ { :ca => 'CA:TRUE',
113
+ :terminalsubca => ['CA:TRUE', 'pathlen:0'],
114
+ :server => 'CA:FALSE',
115
+ :ocsp => 'CA:FALSE',
116
+ :client => 'CA:FALSE',
117
+ }.each do |name, value|
118
+ it "should set basicConstraints for #{name} #{value.inspect}" do
119
+ cert = subject.build(name, csr, issuer, serial)
120
+ bc = cert.extensions.find {|x| x.oid == 'basicConstraints' }
121
+ bc.should be
122
+ bc.value.split(/\s*,\s*/).should =~ Array(value)
123
+ end
124
+ end
105
125
  end
106
126
  end
@@ -125,7 +125,7 @@ describe Puppet::SSL::CertificateRequest do
125
125
 
126
126
  it "should set the CN to the :ca_name setting when the CSR is for a CA" do
127
127
  subject = mock 'subject'
128
- Puppet.settings.expects(:value).with(:ca_name).returns "mycertname"
128
+ Puppet[:ca_name] = "mycertname"
129
129
  OpenSSL::X509::Name.expects(:new).with { |subject| subject[0][1] == "mycertname" }.returns(subject)
130
130
  @request.expects(:subject=).with(subject)
131
131
  Puppet::SSL::CertificateRequest.new(Puppet::SSL::CA_NAME).generate(@key)
@@ -144,6 +144,67 @@ describe Puppet::SSL::CertificateRequest do
144
144
  @instance.generate(@key)
145
145
  end
146
146
 
147
+ context "without subjectAltName / dns_alt_names" do
148
+ before :each do
149
+ Puppet[:dns_alt_names] = ""
150
+ end
151
+
152
+ ["extreq", "msExtReq"].each do |name|
153
+ it "should not add any #{name} attribute" do
154
+ @request.expects(:add_attribute).never
155
+ @request.expects(:attributes=).never
156
+ @instance.generate(@key)
157
+ end
158
+
159
+ it "should return no subjectAltNames" do
160
+ @instance.generate(@key)
161
+ @instance.subject_alt_names.should be_empty
162
+ end
163
+ end
164
+ end
165
+
166
+ context "with dns_alt_names" do
167
+ before :each do
168
+ Puppet[:dns_alt_names] = "one, two, three"
169
+ end
170
+
171
+ ["extreq", "msExtReq"].each do |name|
172
+ it "should not add any #{name} attribute" do
173
+ @request.expects(:add_attribute).never
174
+ @request.expects(:attributes=).never
175
+ @instance.generate(@key)
176
+ end
177
+
178
+ it "should return no subjectAltNames" do
179
+ @instance.generate(@key)
180
+ @instance.subject_alt_names.should be_empty
181
+ end
182
+ end
183
+ end
184
+
185
+ context "with subjectAltName to generate request" do
186
+ before :each do
187
+ Puppet[:dns_alt_names] = ""
188
+ end
189
+
190
+ it "should add an extreq attribute" do
191
+ @request.expects(:add_attribute).with do |arg|
192
+ arg.value.value.all? do |x|
193
+ x.value.all? do |y|
194
+ y.value[0].value == "subjectAltName"
195
+ end
196
+ end
197
+ end
198
+
199
+ @instance.generate(@key, :dns_alt_names => 'one, two')
200
+ end
201
+
202
+ it "should return the subjectAltName values" do
203
+ @instance.generate(@key, :dns_alt_names => 'one,two')
204
+ @instance.subject_alt_names.should =~ ["DNS:myname", "DNS:one", "DNS:two"]
205
+ end
206
+ end
207
+
147
208
  it "should sign the csr with the provided key and a digest" do
148
209
  digest = mock 'digest'
149
210
  OpenSSL::Digest::MD5.expects(:new).returns(digest)