puppet 6.27.0 → 6.28.0

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +71 -11
  3. data/lib/puppet/agent.rb +47 -11
  4. data/lib/puppet/application/agent.rb +2 -12
  5. data/lib/puppet/http/client.rb +22 -2
  6. data/lib/puppet/provider/package/puppetserver_gem.rb +7 -16
  7. data/lib/puppet/provider/package/windows/exe_package.rb +30 -1
  8. data/lib/puppet/provider/package/windows/package.rb +2 -1
  9. data/lib/puppet/provider/package/windows.rb +14 -1
  10. data/lib/puppet/provider/user/directoryservice.rb +5 -0
  11. data/lib/puppet/ssl/ssl_provider.rb +65 -12
  12. data/lib/puppet/ssl/state_machine.rb +13 -17
  13. data/lib/puppet/type/user.rb +3 -0
  14. data/lib/puppet/version.rb +1 -1
  15. data/lib/puppet.rb +1 -14
  16. data/man/man5/puppet.conf.5 +2 -2
  17. data/man/man8/puppet-agent.8 +1 -1
  18. data/man/man8/puppet-apply.8 +1 -1
  19. data/man/man8/puppet-catalog.8 +1 -1
  20. data/man/man8/puppet-config.8 +1 -1
  21. data/man/man8/puppet-describe.8 +1 -1
  22. data/man/man8/puppet-device.8 +1 -1
  23. data/man/man8/puppet-doc.8 +1 -1
  24. data/man/man8/puppet-epp.8 +1 -1
  25. data/man/man8/puppet-facts.8 +1 -1
  26. data/man/man8/puppet-filebucket.8 +1 -1
  27. data/man/man8/puppet-generate.8 +1 -1
  28. data/man/man8/puppet-help.8 +1 -1
  29. data/man/man8/puppet-key.8 +1 -1
  30. data/man/man8/puppet-lookup.8 +1 -1
  31. data/man/man8/puppet-man.8 +1 -1
  32. data/man/man8/puppet-module.8 +1 -1
  33. data/man/man8/puppet-node.8 +1 -1
  34. data/man/man8/puppet-parser.8 +1 -1
  35. data/man/man8/puppet-plugin.8 +1 -1
  36. data/man/man8/puppet-report.8 +1 -1
  37. data/man/man8/puppet-resource.8 +1 -1
  38. data/man/man8/puppet-script.8 +1 -1
  39. data/man/man8/puppet-ssl.8 +1 -1
  40. data/man/man8/puppet-status.8 +1 -1
  41. data/man/man8/puppet.8 +2 -2
  42. data/spec/integration/application/agent_spec.rb +108 -0
  43. data/spec/integration/http/client_spec.rb +27 -10
  44. data/spec/lib/puppet_spec/https.rb +1 -1
  45. data/spec/lib/puppet_spec/puppetserver.rb +39 -2
  46. data/spec/unit/agent_spec.rb +28 -2
  47. data/spec/unit/application/agent_spec.rb +26 -16
  48. data/spec/unit/daemon_spec.rb +2 -11
  49. data/spec/unit/http/client_spec.rb +18 -0
  50. data/spec/unit/provider/package/puppetserver_gem_spec.rb +2 -2
  51. data/spec/unit/provider/package/windows/exe_package_spec.rb +17 -0
  52. data/spec/unit/ssl/ssl_provider_spec.rb +75 -1
  53. data/spec/unit/ssl/state_machine_spec.rb +1 -0
  54. data/tasks/generate_cert_fixtures.rake +5 -4
  55. metadata +2 -2
@@ -227,6 +227,9 @@ module Puppet
227
227
  * OS X 10.8 and higher use salted SHA512 PBKDF2 hashes. When managing passwords
228
228
  on these systems, the `salt` and `iterations` attributes need to be specified as
229
229
  well as the password.
230
+ * macOS 10.15 and higher require the salt to be 32-bytes. Since Puppet's user
231
+ resource requires the value to be hex encoded, the length of the salt's
232
+ string must be 64.
230
233
  * Windows passwords can be managed only in cleartext, because there is no Windows
231
234
  API for setting the password hash.
232
235
 
@@ -6,7 +6,7 @@
6
6
  # Raketasks and such to set the version based on the output of `git describe`
7
7
 
8
8
  module Puppet
9
- PUPPETVERSION = '6.27.0'
9
+ PUPPETVERSION = '6.28.0'
10
10
 
11
11
  ##
12
12
  # version is a public API method intended to always provide a fast and
data/lib/puppet.rb CHANGED
@@ -242,20 +242,7 @@ module Puppet
242
242
  {
243
243
  :environments => Puppet::Environments::Cached.new(Puppet::Environments::Combined.new(*loaders)),
244
244
  :http_pool => proc { Puppet.runtime[:http].pool },
245
- :ssl_context => proc {
246
- begin
247
- cert = Puppet::X509::CertProvider.new
248
- password = cert.load_private_key_password
249
- ssl = Puppet::SSL::SSLProvider.new
250
- ssl.load_context(certname: Puppet[:certname], password: password)
251
- rescue => e
252
- # TRANSLATORS: `message` is an already translated string of why SSL failed to initialize
253
- Puppet.log_exception(e, _("Failed to initialize SSL: %{message}") % { message: e.message })
254
- # TRANSLATORS: `puppet agent -t` is a command and should not be translated
255
- Puppet.err(_("Run `puppet agent -t`"))
256
- raise e
257
- end
258
- },
245
+ :ssl_context => proc { Puppet.runtime[:http].default_ssl_context },
259
246
  :ssl_host => proc { Puppet::SSL::Host.localhost(true) },
260
247
  :http_session => proc { Puppet.runtime[:http].create_session },
261
248
  :plugins => proc { Puppet::Plugins::Configuration.load_plugins },
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPETCONF" "5" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPETCONF" "5" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  \fBThis page is autogenerated; any changes will get overwritten\fR
6
6
  .
7
7
  .SH "Configuration settings"
@@ -945,7 +945,7 @@ The time to wait for data to be read from an HTTP connection\. If nothing is rea
945
945
  The HTTP User\-Agent string to send when making network requests\.
946
946
  .
947
947
  .IP "\(bu" 4
948
- \fIDefault\fR: \fBPuppet/6\.27\.0 Ruby/2\.7\.5\-p203 (x86_64\-linux)\fR
948
+ \fIDefault\fR: \fBPuppet/6\.28\.0 Ruby/2\.7\.5\-p203 (x86_64\-linux)\fR
949
949
  .
950
950
  .IP "" 0
951
951
  .
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-AGENT" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-AGENT" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-agent\fR \- The puppet agent daemon
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-APPLY" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-APPLY" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-apply\fR \- Apply Puppet manifests locally
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-CATALOG" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-CATALOG" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-catalog\fR \- Compile, save, view, and convert catalogs\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-CONFIG" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-CONFIG" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-config\fR \- Interact with Puppet\'s settings\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-DESCRIBE" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-DESCRIBE" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-describe\fR \- Display help about resource types
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-DEVICE" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-DEVICE" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-device\fR \- Manage remote network devices
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-DOC" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-DOC" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-doc\fR \- Generate Puppet references
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-EPP" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-EPP" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-epp\fR \- Interact directly with the EPP template parser/renderer\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-FACTS" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-FACTS" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-facts\fR \- Retrieve and store facts\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-FILEBUCKET" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-FILEBUCKET" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-filebucket\fR \- Store and retrieve files in a filebucket
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-GENERATE" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-GENERATE" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-generate\fR \- Generates Puppet code from Ruby definitions\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-HELP" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-HELP" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-help\fR \- Display Puppet help\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-KEY" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-KEY" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-key\fR \- Create, save, and remove certificate keys\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-LOOKUP" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-LOOKUP" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-lookup\fR \- Interactive Hiera lookup
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-MAN" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-MAN" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-man\fR \- Display Puppet manual pages\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-MODULE" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-MODULE" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-module\fR \- Creates, installs and searches for modules on the Puppet Forge\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-NODE" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-NODE" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-node\fR \- View and manage node definitions\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-PARSER" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-PARSER" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-parser\fR \- Interact directly with the parser\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-PLUGIN" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-PLUGIN" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-plugin\fR \- Interact with the Puppet plugin system\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-REPORT" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-REPORT" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-report\fR \- Create, display, and submit reports\.
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-RESOURCE" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-RESOURCE" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-resource\fR \- The resource abstraction layer shell
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-SCRIPT" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-SCRIPT" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-script\fR \- Run a puppet manifests as a script without compiling a catalog
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-SSL" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-SSL" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-ssl\fR \- Manage SSL keys and certificates for puppet SSL clients
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET\-STATUS" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET\-STATUS" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\-status\fR \- View puppet server status\.
data/man/man8/puppet.8 CHANGED
@@ -1,7 +1,7 @@
1
1
  .\" generated with Ronn/v0.7.3
2
2
  .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
3
  .
4
- .TH "PUPPET" "8" "March 2022" "Puppet, Inc." "Puppet manual"
4
+ .TH "PUPPET" "8" "July 2022" "Puppet, Inc." "Puppet manual"
5
5
  .
6
6
  .SH "NAME"
7
7
  \fBpuppet\fR
@@ -25,4 +25,4 @@ Specialized:
25
25
  catalog Compile, save, view, and convert catalogs\. describe Display help about resource types device Manage remote network devices doc Generate Puppet references epp Interact directly with the EPP template parser/renderer\. facts Retrieve and store facts\. filebucket Store and retrieve files in a filebucket generate Generates Puppet code from Ruby definitions\. node View and manage node definitions\. parser Interact directly with the parser\. plugin Interact with the Puppet plugin system\. script Run a puppet manifests as a script without compiling a catalog ssl Manage SSL keys and certificates for puppet SSL clients
26
26
  .
27
27
  .P
28
- See \'puppet help \fIsubcommand\fR \fIaction\fR\' for help on a specific subcommand action\. See \'puppet help \fIsubcommand\fR\' for help on a specific subcommand\. Puppet v6\.27\.0
28
+ See \'puppet help \fIsubcommand\fR \fIaction\fR\' for help on a specific subcommand action\. See \'puppet help \fIsubcommand\fR\' for help on a specific subcommand\. Puppet v6\.28\.0
@@ -3,6 +3,7 @@ require 'puppet_spec/files'
3
3
  require 'puppet_spec/puppetserver'
4
4
  require 'puppet_spec/compiler'
5
5
  require 'puppet_spec/https'
6
+ require 'puppet/application/agent'
6
7
 
7
8
  describe "puppet agent", unless: Puppet::Util::Platform.jruby? do
8
9
  include PuppetSpec::Files
@@ -737,4 +738,111 @@ describe "puppet agent", unless: Puppet::Util::Platform.jruby? do
737
738
  end
738
739
  end
739
740
  end
741
+
742
+ context "ssl" do
743
+ context "bootstrapping" do
744
+ before :each do
745
+ # reconfigure ssl to non-existent dir and files to force bootstrapping
746
+ dir = tmpdir('ssl')
747
+ Puppet[:ssldir] = dir
748
+ Puppet[:localcacert] = File.join(dir, 'ca.pem')
749
+ Puppet[:hostcrl] = File.join(dir, 'crl.pem')
750
+ Puppet[:hostprivkey] = File.join(dir, 'cert.pem')
751
+ Puppet[:hostcert] = File.join(dir, 'key.pem')
752
+
753
+ Puppet[:daemonize] = false
754
+ Puppet[:logdest] = 'console'
755
+ Puppet[:log_level] = 'info'
756
+ end
757
+
758
+ it "exits if the agent is not allowed to wait" do
759
+ Puppet[:waitforcert] = 0
760
+
761
+ server.start_server do |port|
762
+ Puppet[:serverport] = port
763
+ expect {
764
+ agent.run
765
+ }.to exit_with(1)
766
+ .and output(%r{Exiting now because the waitforcert setting is set to 0}).to_stdout
767
+ .and output(%r{Failed to submit the CSR, HTTP response was 404}).to_stderr
768
+ end
769
+ end
770
+
771
+ it "exits if the maxwaitforcert time is exceeded" do
772
+ Puppet[:waitforcert] = 1
773
+ Puppet[:maxwaitforcert] = 1
774
+
775
+ server.start_server do |port|
776
+ Puppet[:serverport] = port
777
+ expect {
778
+ agent.run
779
+ }.to exit_with(1)
780
+ .and output(%r{Couldn't fetch certificate from CA server; you might still need to sign this agent's certificate \(127.0.0.1\). Exiting now because the maxwaitforcert timeout has been exceeded.}).to_stdout
781
+ .and output(%r{Failed to submit the CSR, HTTP response was 404}).to_stderr
782
+ end
783
+ end
784
+ end
785
+
786
+ def copy_fixtures(sources, dest)
787
+ ssldir = File.join(PuppetSpec::FIXTURE_DIR, 'ssl')
788
+ File.open(dest, 'w') do |f|
789
+ sources.each do |s|
790
+ f.write(File.read(File.join(ssldir, s)))
791
+ end
792
+ end
793
+ end
794
+
795
+ it "reloads the CRL between runs" do
796
+ Puppet[:localcacert] = ca = tmpfile('ca')
797
+ Puppet[:hostcrl] = crl = tmpfile('crl')
798
+ Puppet[:hostcert] = cert = tmpfile('cert')
799
+ Puppet[:hostprivkey] = key = tmpfile('key')
800
+
801
+ copy_fixtures(%w[ca.pem intermediate.pem], ca)
802
+ copy_fixtures(%w[crl.pem intermediate-crl.pem], crl)
803
+ copy_fixtures(%w[127.0.0.1.pem], cert)
804
+ copy_fixtures(%w[127.0.0.1-key.pem], key)
805
+
806
+ revoked = cert_fixture('revoked.pem')
807
+ revoked_key = key_fixture('revoked-key.pem')
808
+
809
+ mounts = {}
810
+ mounts[:catalog] = -> (req, res) {
811
+ catalog = compile_to_catalog(<<~MANIFEST, node)
812
+ file { '#{cert}':
813
+ ensure => file,
814
+ content => '#{revoked}'
815
+ }
816
+ file { '#{key}':
817
+ ensure => file,
818
+ content => '#{revoked_key}'
819
+ }
820
+ MANIFEST
821
+
822
+ res.body = formatter.render(catalog)
823
+ res['Content-Type'] = formatter.mime
824
+ }
825
+
826
+ server.start_server(mounts: mounts) do |port|
827
+ Puppet[:serverport] = port
828
+ Puppet[:daemonize] = false
829
+ Puppet[:runinterval] = 1
830
+ Puppet[:waitforcert] = 1
831
+ Puppet[:maxwaitforcert] = 1
832
+
833
+ # simulate two runs of the agent, then return so we don't infinite loop
834
+ allow_any_instance_of(Puppet::Daemon).to receive(:run_event_loop) do |instance|
835
+ instance.agent.run(splay: false)
836
+ instance.agent.run(splay: false)
837
+ end
838
+
839
+ agent.command_line.args << '--verbose'
840
+ expect {
841
+ agent.run
842
+ }.to exit_with(1)
843
+ .and output(%r{Exiting now because the maxwaitforcert timeout has been exceeded}).to_stdout
844
+ .and output(%r{Certificate 'CN=revoked' is revoked}).to_stderr
845
+ end
846
+ end
847
+ end
740
848
  end
@@ -77,13 +77,13 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
77
77
  }
78
78
  }
79
79
 
80
- let(:systemstore) do
81
- res = tmpfile('systemstore')
80
+ let(:cert_file) do
81
+ res = tmpfile('cert_file')
82
82
  File.write(res, https_server.ca_cert)
83
83
  res
84
84
  end
85
85
 
86
- it "mutually authenticates the connection" do
86
+ it "mutually authenticates the connection using an explicit context" do
87
87
  client_context = ssl_provider.create_context(
88
88
  cacerts: [https_server.ca_cert], crls: [https_server.ca_crl],
89
89
  client_cert: https_server.server_cert, private_key: https_server.server_key
@@ -95,10 +95,27 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
95
95
  end
96
96
  end
97
97
 
98
+ it "mutually authenticates the connection when the client and server certs are issued from different CAs" do
99
+ # this is the client cert's CA, key and cert
100
+ Puppet[:localcacert] = fixtures('ssl/unknown-ca.pem')
101
+ Puppet[:hostprivkey] = fixtures('ssl/unknown-127.0.0.1-key.pem')
102
+ Puppet[:hostcert] = fixtures('ssl/unknown-127.0.0.1.pem')
103
+
104
+ # this is the server cert's CA that the client needs in order to authenticate the server
105
+ Puppet[:ssl_trust_store] = fixtures('ssl/ca.pem')
106
+
107
+ # need to pass both the client and server CAs. The former is needed so the server can authenticate our client cert
108
+ https_server = PuppetSpec::HTTPSServer.new(ca_cert: [cert_fixture('ca.pem'), cert_fixture('unknown-ca.pem')])
109
+ https_server.start_server(ctx_proc: ctx_proc) do |port|
110
+ res = client.get(URI("https://127.0.0.1:#{port}"), options: {include_system_store: true})
111
+ expect(res).to be_success
112
+ end
113
+ end
114
+
98
115
  it "connects when the server's CA is in the system store and the connection is mutually authenticated using create_context" do
99
- Puppet::Util.withenv("SSL_CERT_FILE" => systemstore) do
116
+ Puppet::Util.withenv("SSL_CERT_FILE" => cert_file) do
100
117
  client_context = ssl_provider.create_context(
101
- cacerts: [https_server.ca_cert], crls: [https_server.ca_crl],
118
+ cacerts: [], crls: [],
102
119
  client_cert: https_server.server_cert, private_key: https_server.server_key,
103
120
  revocation: false, include_system_store: true
104
121
  )
@@ -109,8 +126,8 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
109
126
  end
110
127
  end
111
128
 
112
- it "connects when the server's CA is in the system store and the connection is mutually authenticated uning load_context" do
113
- Puppet::Util.withenv("SSL_CERT_FILE" => systemstore) do
129
+ it "connects when the server's CA is in the system store and the connection is mutually authenticated using load_context" do
130
+ Puppet::Util.withenv("SSL_CERT_FILE" => cert_file) do
114
131
  client_context = ssl_provider.load_context(revocation: false, include_system_store: true)
115
132
  https_server.start_server(ctx_proc: ctx_proc) do |port|
116
133
  res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: client_context})
@@ -132,12 +149,12 @@ describe Puppet::HTTP::Client, unless: Puppet::Util::Platform.jruby? do
132
149
 
133
150
  it "connects when the server's CA is in the system store" do
134
151
  # create a temp cacert bundle
135
- ssl_file = tmpfile('systemstore')
136
- File.write(ssl_file, https_server.ca_cert)
152
+ cert_file = tmpfile('cert_file')
153
+ File.write(cert_file, https_server.ca_cert)
137
154
 
138
155
  # override path to system cacert bundle, this must be done before
139
156
  # the SSLContext is created and the call to X509::Store.set_default_paths
140
- Puppet::Util.withenv("SSL_CERT_FILE" => ssl_file) do
157
+ Puppet::Util.withenv("SSL_CERT_FILE" => cert_file) do
141
158
  system_context = ssl_provider.create_system_context(cacerts: [])
142
159
  https_server.start_server do |port|
143
160
  res = client.get(URI("https://127.0.0.1:#{port}"), options: {ssl_context: system_context})
@@ -40,7 +40,7 @@ class PuppetSpec::HTTPSServer
40
40
 
41
41
  IO.pipe {|stop_pipe_r, stop_pipe_w|
42
42
  store = OpenSSL::X509::Store.new
43
- store.add_cert(@ca_cert)
43
+ Array(@ca_cert).each { |c| store.add_cert(c) }
44
44
  store.purpose = OpenSSL::X509::PURPOSE_SSL_CLIENT
45
45
  ctx = OpenSSL::SSL::SSLContext.new
46
46
  ctx.cert_store = store
@@ -72,6 +72,40 @@ class PuppetSpec::Puppetserver
72
72
  end
73
73
  end
74
74
 
75
+ class CertificateServlet < WEBrick::HTTPServlet::AbstractServlet
76
+ def initialize(server, ca_cert)
77
+ super(server)
78
+ @ca_cert = ca_cert
79
+ end
80
+
81
+ def do_GET request, response
82
+ if request.path =~ %r{/puppet-ca/v1/certificate/ca$}
83
+ response['Content-Type'] = 'text/plain'
84
+ response.body = @ca_cert.to_pem
85
+ else
86
+ response.status = 404
87
+ end
88
+ end
89
+ end
90
+
91
+ class CertificateRevocationListServlet < WEBrick::HTTPServlet::AbstractServlet
92
+ def initialize(server, crl)
93
+ super(server)
94
+ @crl = crl
95
+ end
96
+
97
+ def do_GET request, response
98
+ response['Content-Type'] = 'text/plain'
99
+ response.body = @crl.to_pem
100
+ end
101
+ end
102
+
103
+ class CertificateRequestServlet < WEBrick::HTTPServlet::AbstractServlet
104
+ def do_PUT request, response
105
+ response.status = 404
106
+ end
107
+ end
108
+
75
109
  def initialize
76
110
  @ca_cert = cert_fixture('ca.pem')
77
111
  @ca_crl = crl_fixture('crl.pem')
@@ -125,15 +159,18 @@ class PuppetSpec::Puppetserver
125
159
  register_mount('/puppet/v3/static_file_content', mounts[:static_file_content], StaticFileContentServlet)
126
160
  register_mount('/puppet/v3/report', mounts[:report], ReportServlet)
127
161
  register_mount('/puppet/v3/file_bucket_file', mounts[:filebucket], FilebucketServlet)
162
+ register_mount('/puppet-ca/v1/certificate', mounts[:certificate], CertificateServlet, @ca_cert)
163
+ register_mount('/puppet-ca/v1/certificate_revocation_list', mounts[:certificate_revocation_list], CertificateRevocationListServlet, @ca_crl)
164
+ register_mount('/puppet-ca/v1/certificate_request', mounts[:certificate_request], CertificateRequestServlet)
128
165
  end
129
166
 
130
- def register_mount(path, user_proc, default_servlet)
167
+ def register_mount(path, user_proc, default_servlet, *args)
131
168
  handler = if user_proc
132
169
  WEBrick::HTTPServlet::ProcHandler.new(user_proc)
133
170
  else
134
171
  default_servlet
135
172
  end
136
- @https.mount(path, handler)
173
+ @https.mount(path, handler, *args)
137
174
  end
138
175
 
139
176
  def upload_directory