puppet 6.3.0-universal-darwin → 6.4.0-universal-darwin

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 (147) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +30 -0
  3. data/Gemfile.lock +9 -9
  4. data/lib/puppet.rb +13 -0
  5. data/lib/puppet/application/agent.rb +8 -12
  6. data/lib/puppet/application/device.rb +2 -3
  7. data/lib/puppet/application/filebucket.rb +6 -1
  8. data/lib/puppet/application/ssl.rb +102 -55
  9. data/lib/puppet/configurer.rb +8 -7
  10. data/lib/puppet/defaults.rb +3 -1
  11. data/lib/puppet/file_system.rb +24 -4
  12. data/lib/puppet/file_system/file_impl.rb +25 -0
  13. data/lib/puppet/file_system/jruby.rb +23 -0
  14. data/lib/puppet/file_system/windows.rb +84 -0
  15. data/lib/puppet/indirector/rest.rb +4 -2
  16. data/lib/puppet/loaders.rb +1 -0
  17. data/lib/puppet/network/http.rb +1 -0
  18. data/lib/puppet/network/http/base_pool.rb +18 -0
  19. data/lib/puppet/network/http/connection.rb +49 -17
  20. data/lib/puppet/network/http/nocache_pool.rb +9 -4
  21. data/lib/puppet/network/http/pool.rb +10 -11
  22. data/lib/puppet/network/http/session.rb +3 -2
  23. data/lib/puppet/network/http_pool.rb +32 -0
  24. data/lib/puppet/pops/loader/generic_plan_instantiator.rb +28 -0
  25. data/lib/puppet/pops/loader/loader_paths.rb +46 -10
  26. data/lib/puppet/pops/loader/module_loaders.rb +10 -3
  27. data/lib/puppet/provider/file/windows.rb +49 -1
  28. data/lib/puppet/provider/package/windows.rb +5 -1
  29. data/lib/puppet/reports/http.rb +2 -1
  30. data/lib/puppet/rest/client.rb +7 -3
  31. data/lib/puppet/rest/routes.rb +9 -44
  32. data/lib/puppet/ssl.rb +6 -0
  33. data/lib/puppet/ssl/error.rb +26 -0
  34. data/lib/puppet/ssl/host.rb +9 -92
  35. data/lib/puppet/ssl/ssl_context.rb +30 -0
  36. data/lib/puppet/ssl/ssl_provider.rb +232 -0
  37. data/lib/puppet/ssl/state_machine.rb +261 -0
  38. data/lib/puppet/ssl/validator.rb +1 -0
  39. data/lib/puppet/ssl/validator/default_validator.rb +1 -0
  40. data/lib/puppet/ssl/validator/no_validator.rb +2 -0
  41. data/lib/puppet/ssl/verifier.rb +134 -0
  42. data/lib/puppet/ssl/verifier_adapter.rb +48 -0
  43. data/lib/puppet/test/test_helper.rb +2 -1
  44. data/lib/puppet/type/exec.rb +30 -6
  45. data/lib/puppet/type/file/mode.rb +6 -1
  46. data/lib/puppet/type/file/source.rb +2 -2
  47. data/lib/puppet/type/filebucket.rb +12 -8
  48. data/lib/puppet/type/user.rb +14 -1
  49. data/lib/puppet/util/connection.rb +10 -5
  50. data/lib/puppet/util/feature.rb +11 -2
  51. data/lib/puppet/util/http_proxy.rb +3 -2
  52. data/lib/puppet/util/pidlock.rb +1 -1
  53. data/lib/puppet/util/ssl.rb +1 -10
  54. data/lib/puppet/util/windows/security.rb +29 -8
  55. data/lib/puppet/version.rb +1 -1
  56. data/lib/puppet/x509.rb +7 -0
  57. data/lib/puppet/x509/cert_provider.rb +286 -0
  58. data/lib/puppet/x509/pem_store.rb +55 -0
  59. data/locales/ja/puppet.po +740 -590
  60. data/locales/puppet.pot +433 -208
  61. data/man/man5/puppet.conf.5 +6 -3
  62. data/man/man8/puppet-agent.8 +1 -1
  63. data/man/man8/puppet-apply.8 +1 -1
  64. data/man/man8/puppet-catalog.8 +1 -1
  65. data/man/man8/puppet-config.8 +1 -1
  66. data/man/man8/puppet-describe.8 +1 -1
  67. data/man/man8/puppet-device.8 +1 -1
  68. data/man/man8/puppet-doc.8 +1 -1
  69. data/man/man8/puppet-epp.8 +1 -1
  70. data/man/man8/puppet-facts.8 +1 -1
  71. data/man/man8/puppet-filebucket.8 +6 -2
  72. data/man/man8/puppet-generate.8 +1 -1
  73. data/man/man8/puppet-help.8 +1 -1
  74. data/man/man8/puppet-key.8 +1 -1
  75. data/man/man8/puppet-lookup.8 +1 -1
  76. data/man/man8/puppet-man.8 +1 -1
  77. data/man/man8/puppet-module.8 +1 -1
  78. data/man/man8/puppet-node.8 +1 -1
  79. data/man/man8/puppet-parser.8 +1 -1
  80. data/man/man8/puppet-plugin.8 +1 -1
  81. data/man/man8/puppet-report.8 +1 -1
  82. data/man/man8/puppet-resource.8 +1 -1
  83. data/man/man8/puppet-script.8 +1 -1
  84. data/man/man8/puppet-ssl.8 +5 -1
  85. data/man/man8/puppet-status.8 +1 -1
  86. data/man/man8/puppet.8 +2 -2
  87. data/spec/fixtures/ssl/127.0.0.1-key.pem +67 -0
  88. data/spec/fixtures/ssl/127.0.0.1.pem +48 -0
  89. data/spec/fixtures/ssl/bad-basic-constraints.pem +59 -0
  90. data/spec/fixtures/ssl/bad-int-basic-constraints.pem +59 -0
  91. data/spec/fixtures/ssl/ca.pem +59 -0
  92. data/spec/fixtures/ssl/crl.pem +30 -0
  93. data/spec/fixtures/ssl/encrypted-key.pem +70 -0
  94. data/spec/fixtures/ssl/intermediate-agent-crl.pem +31 -0
  95. data/spec/fixtures/ssl/intermediate-agent.pem +60 -0
  96. data/spec/fixtures/ssl/intermediate-crl.pem +36 -0
  97. data/spec/fixtures/ssl/intermediate.pem +60 -0
  98. data/spec/fixtures/ssl/netlock-arany-utf8.pem +23 -0
  99. data/spec/fixtures/ssl/pluto-key.pem +67 -0
  100. data/spec/fixtures/ssl/pluto.pem +44 -0
  101. data/spec/fixtures/ssl/request-key.pem +67 -0
  102. data/spec/fixtures/ssl/request.pem +39 -0
  103. data/spec/fixtures/ssl/revoked-key.pem +67 -0
  104. data/spec/fixtures/ssl/revoked.pem +44 -0
  105. data/spec/fixtures/ssl/signed-key.pem +67 -0
  106. data/spec/fixtures/ssl/signed.pem +44 -0
  107. data/spec/fixtures/ssl/tampered-cert.pem +44 -0
  108. data/spec/fixtures/ssl/tampered-csr.pem +39 -0
  109. data/spec/integration/network/http_pool_spec.rb +222 -0
  110. data/spec/integration/provider/file/windows_spec.rb +162 -0
  111. data/spec/integration/rest/client_spec.rb +73 -0
  112. data/spec/integration/type/file_spec.rb +0 -19
  113. data/spec/lib/puppet/test_ca.rb +87 -50
  114. data/spec/lib/puppet_spec/fixtures.rb +20 -0
  115. data/spec/lib/puppet_spec/https.rb +84 -0
  116. data/spec/unit/application/agent_spec.rb +29 -30
  117. data/spec/unit/application/device_spec.rb +12 -49
  118. data/spec/unit/application/ssl_spec.rb +24 -38
  119. data/spec/unit/configurer_spec.rb +11 -11
  120. data/spec/unit/file_system/uniquefile_spec.rb +6 -0
  121. data/spec/unit/file_system_spec.rb +214 -0
  122. data/spec/unit/indirector/rest_spec.rb +3 -3
  123. data/spec/unit/network/http/connection_spec.rb +30 -90
  124. data/spec/unit/network/http/factory_spec.rb +1 -0
  125. data/spec/unit/network/http/nocache_pool_spec.rb +8 -8
  126. data/spec/unit/network/http/pool_spec.rb +63 -33
  127. data/spec/unit/network/http/session_spec.rb +8 -1
  128. data/spec/unit/network/http_pool_spec.rb +36 -0
  129. data/spec/unit/pops/loaders/loader_spec.rb +26 -1
  130. data/spec/unit/provider/package/windows_spec.rb +12 -1
  131. data/spec/unit/reports/http_spec.rb +7 -7
  132. data/spec/unit/rest/client_spec.rb +4 -6
  133. data/spec/unit/ssl/host_spec.rb +39 -33
  134. data/spec/unit/ssl/ssl_provider_spec.rb +428 -0
  135. data/spec/unit/ssl/state_machine_spec.rb +502 -0
  136. data/spec/unit/ssl/verifier_spec.rb +123 -0
  137. data/spec/unit/type/exec_spec.rb +63 -0
  138. data/spec/unit/type/file/source_spec.rb +5 -5
  139. data/spec/unit/type/filebucket_spec.rb +8 -6
  140. data/spec/unit/util/feature_spec.rb +2 -2
  141. data/spec/unit/util/storage_spec.rb +19 -19
  142. data/spec/unit/x509/cert_provider_spec.rb +527 -0
  143. data/spec/unit/x509/pem_store_spec.rb +160 -0
  144. data/tasks/generate_cert_fixtures.rake +158 -0
  145. metadata +78 -4
  146. data/MAINTAINERS +0 -47
  147. data/lib/puppet/rest/ssl_context.rb +0 -13
@@ -4,10 +4,11 @@
4
4
  # @api private
5
5
  #
6
6
  class Puppet::Network::HTTP::Session
7
- attr_reader :connection
7
+ attr_reader :connection, :verifier
8
8
 
9
- def initialize(connection, expiration_time)
9
+ def initialize(connection, verifier, expiration_time)
10
10
  @connection = connection
11
+ @verifier = verifier
11
12
  @expiration_time = expiration_time
12
13
  end
13
14
 
@@ -28,6 +28,7 @@ module Puppet::Network::HttpPool
28
28
  # @param verify_peer [Boolean] Whether to verify the peer credentials, if possible. Verification will not take place if the CA certificate is missing.
29
29
  # @return [Puppet::Network::HTTP::Connection]
30
30
  #
31
+ # @deprecated Use {#http_connection} instead.
31
32
  # @api public
32
33
  #
33
34
  def self.http_instance(host, port, use_ssl = true, verify_peer = true)
@@ -51,6 +52,7 @@ module Puppet::Network::HttpPool
51
52
  # verification on a Net::HTTP instance and report any errors and the certificates used.
52
53
  # @return [Puppet::Network::HTTP::Connection]
53
54
  #
55
+ # @deprecated Use {#http_connection} instead.
54
56
  # @api public
55
57
  #
56
58
  def self.http_ssl_instance(host, port, verifier = Puppet::SSL::Validator.default_validator())
@@ -58,4 +60,34 @@ module Puppet::Network::HttpPool
58
60
  :use_ssl => true,
59
61
  :verify => verifier)
60
62
  end
63
+
64
+ # Retrieve a connection for the given host and port.
65
+ #
66
+ # @param host [String] The host to connect to
67
+ # @param port [Integer] The port to connect to
68
+ # @param use_ssl [Boolean] Whether to use SSL, defaults to `true`.
69
+ # @param ssl_context [Puppet::SSL:SSLContext, nil] The ssl context to use
70
+ # when making HTTPS connections. Required when `use_ssl` is `true`.
71
+ # @return [Puppet::Network::HTTP::Connection]
72
+ #
73
+ # @api public
74
+ #
75
+ def self.connection(host, port, use_ssl: true, ssl_context: nil)
76
+ if use_ssl
77
+ unless ssl_context
78
+ # TRANSLATORS 'ssl_context' is an argument and should not be translated
79
+ raise ArgumentError, _("An ssl_context is required when connecting to 'https://%{host}:%{port}'") % { host: host, port: port }
80
+ end
81
+
82
+ verifier = Puppet::SSL::Verifier.new(host, ssl_context)
83
+ http_client_class.new(host, port, use_ssl: true, verifier: verifier)
84
+ else
85
+ if ssl_context
86
+ # TRANSLATORS 'ssl_context' is an argument and should not be translated
87
+ Puppet.warning(_("An ssl_context is unnecessary when connecting to 'http://%{host}:%{port}' and will be ignored") % { host: host, port: port })
88
+ end
89
+
90
+ http_client_class.new(host, port, use_ssl: false)
91
+ end
92
+ end
61
93
  end
@@ -0,0 +1,28 @@
1
+ module Puppet::Pops
2
+ module Loader
3
+ # The GenericPlanInstantiator dispatches to either PuppetPlanInstantiator or a
4
+ # yaml_plan_instantiator injected through the Puppet context, depending on
5
+ # the type of the plan.
6
+ #
7
+ class GenericPlanInstantiator
8
+ def self.create(loader, typed_name, source_refs)
9
+ if source_refs.length > 1
10
+ raise ArgumentError, _("Found multiple files for plan '%{plan_name}' but only one is allowed") % { plan_name: typed_name.name }
11
+ end
12
+
13
+ source_ref = source_refs[0]
14
+ code_string = Puppet::FileSystem.read(source_ref, :encoding => 'utf-8')
15
+
16
+ instantiator = if source_ref.end_with?('.pp')
17
+ Puppet::Pops::Loader::PuppetPlanInstantiator
18
+ else
19
+ Puppet.lookup(:yaml_plan_instantiator) do
20
+ raise Puppet::DevError, _("No instantiator is available to load plan from %{source_ref}") % { source_ref: source_ref }
21
+ end
22
+ end
23
+
24
+ instantiator.create(loader, typed_name, source_ref, code_string)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -29,7 +29,7 @@ module LoaderPaths
29
29
  result << FunctionPath3x.new(loader)
30
30
  end
31
31
  when :plan
32
- result << PlanPathPP.new(loader)
32
+ result << PlanPath.new(loader)
33
33
  when :task
34
34
  result << TaskPath.new(loader) if Puppet[:tasks] && loader.loadables.include?(:task)
35
35
  when :type
@@ -312,27 +312,51 @@ module LoaderPaths
312
312
  end
313
313
  end
314
314
 
315
- class PlanPathPP < PuppetSmartPath
316
- PLAN_PATH_PP = File.join('plans')
315
+ class PlanPath < PuppetSmartPath
316
+ PLAN_PATH = File.join('plans')
317
+ PP_EXT = '.pp'.freeze
318
+ YAML_EXT = '.yaml'.freeze
319
+
320
+ def initialize(loader)
321
+ super
322
+
323
+ if Puppet.lookup(:yaml_plan_instantiator) { nil }
324
+ @extensions = [PP_EXT, YAML_EXT]
325
+ else
326
+ @extensions = [PP_EXT]
327
+ end
328
+ @init_filenames = @extensions.map { |ext| "init#{ext}" }
329
+ end
330
+
331
+ def extension
332
+ EMPTY_STRING
333
+ end
317
334
 
318
335
  def relative_path
319
- PLAN_PATH_PP
336
+ PLAN_PATH
320
337
  end
321
338
 
322
339
  def instantiator()
323
- Puppet::Pops::Loader::PuppetPlanInstantiator
340
+ Puppet::Pops::Loader::GenericPlanInstantiator
341
+ end
342
+
343
+ def fuzzy_matching?
344
+ true
345
+ end
346
+
347
+ def valid_path?(path)
348
+ @extensions.any? { |ext| path.end_with?(ext) } && path.start_with?(generic_path)
324
349
  end
325
350
 
326
351
  def typed_name(type, name_authority, relative_path, module_name)
327
- if relative_path == 'init.pp' && !(module_name.nil? || module_name.empty?)
352
+ if @init_filenames.include?(relative_path) && !(module_name.nil? || module_name.empty?)
328
353
  TypedName.new(type, module_name, name_authority)
329
354
  else
330
355
  n = ''
331
356
  n << module_name unless module_name.nil?
332
- unless extension.empty?
333
- # Remove extension
334
- relative_path = relative_path[0..-(extension.length+1)]
335
- end
357
+ ext = @extensions.find { |extension| relative_path.end_with?(extension) }
358
+ relative_path = relative_path[0..-(ext.length+1)]
359
+
336
360
  relative_path.split('/').each do |segment|
337
361
  n << '::' if n.size > 0
338
362
  n << segment
@@ -340,6 +364,18 @@ module LoaderPaths
340
364
  TypedName.new(type, n, name_authority)
341
365
  end
342
366
  end
367
+
368
+ def effective_path(typed_name, start_index_in_name)
369
+ # Puppet name to path always skips the name-space as that is part of the generic path
370
+ # i.e. <module>/mymodule/functions/foo.pp is the function mymodule::foo
371
+ parts = typed_name.name_parts
372
+ if start_index_in_name > 0
373
+ return nil if start_index_in_name >= parts.size
374
+ parts = parts[start_index_in_name..-1]
375
+ end
376
+ basename = File.join(generic_path, parts)
377
+ @extensions.map { |ext| "#{basename}#{ext}" }
378
+ end
343
379
  end
344
380
 
345
381
  # SmartPaths
@@ -407,9 +407,16 @@ module ModuleLoaders
407
407
  origin = sp.effective_path(typed_name, is_global ? 0 : 1)
408
408
  unless origin.nil?
409
409
  if sp.fuzzy_matching?
410
- # Find all paths that might be related to origin
411
- origins = candidate_paths(origin)
412
- return [origins, sp] unless origins.empty?
410
+ # If there are multiple *specific* paths for the file, find
411
+ # whichever ones exist. Otherwise, find all paths that *might* be
412
+ # related to origin
413
+ if origin.is_a?(Array)
414
+ origins = origin.map { |ori| existing_path(ori) }.compact
415
+ return [origins, sp] unless origins.empty?
416
+ else
417
+ origins = candidate_paths(origin)
418
+ return [origins, sp] unless origins.empty?
419
+ end
413
420
  else
414
421
  existing = existing_path(origin)
415
422
  return [origin, sp] unless existing.nil?
@@ -71,7 +71,9 @@ Puppet::Type.type(:file).provide :windows do
71
71
 
72
72
  def mode=(value)
73
73
  begin
74
- set_mode(value.to_i(8), resource[:path])
74
+ managing_owner = !resource[:owner].nil?
75
+ managing_group = !resource[:group].nil?
76
+ set_mode(value.to_i(8), resource[:path], true, managing_owner, managing_group)
75
77
  rescue => detail
76
78
  error = Puppet::Error.new(_("failed to set mode %{mode} on %{path}: %{message}") % { mode: mode, path: resource[:path], message: detail.message })
77
79
  error.set_backtrace detail.backtrace
@@ -86,6 +88,52 @@ Puppet::Type.type(:file).provide :windows do
86
88
  end
87
89
  end
88
90
 
91
+ # munge the windows group permissions if the user or group are set to SYSTEM
92
+ #
93
+ # when SYSTEM user is the group or user and the resoure is not managing them then treat
94
+ # the resource as insync if System has FullControl access.
95
+ #
96
+ # @param [String] current - the current mode returned by the resource
97
+ # @param [String] should - what the mode should be
98
+ #
99
+ # @return [String, nil] munged mode or nil if the resource should be out of sync
100
+ def munge_windows_system_group(current, should)
101
+ [
102
+ {
103
+ 'type' => 'group',
104
+ 'resource' => resource[:group],
105
+ 'set_to_user' => group,
106
+ 'fullcontrol' => "070".to_i(8),
107
+ 'remove_mask' => "707".to_i(8),
108
+ 'should_mask' => (should[0].to_i(8) & "070".to_i(8)),
109
+ },
110
+ {
111
+ 'type' => 'owner',
112
+ 'resource' => resource[:owner],
113
+ 'set_to_user' => owner,
114
+ 'fullcontrol' => "700".to_i(8),
115
+ 'remove_mask' => "077".to_i(8),
116
+ 'should_mask' => (should[0].to_i(8) & "700".to_i(8)),
117
+ }
118
+ ].each do |mode_part|
119
+ if mode_part['resource'].nil? && (mode_part['set_to_user'] == Puppet::Util::Windows::SID::LocalSystem)
120
+ if (current.to_i(8) & mode_part['fullcontrol']) == mode_part['fullcontrol']
121
+ # Since the group is LocalSystem, and the permissions are FullControl,
122
+ # replace the value returned with the value expected. This will treat
123
+ # this specific situation as "insync"
124
+ current = ( (current.to_i(8) & mode_part['remove_mask']) | mode_part['should_mask'] ).to_s(8).rjust(4, '0')
125
+ else
126
+ # If the SYSTEM account does _not_ have FullControl in this scenario, we should
127
+ # force the resource out of sync no matter what.
128
+ #TRANSLATORS 'SYSTEM' is a Windows name and should not be translated
129
+ Puppet.debug _("%{resource_name}: %{mode_part_type} set to SYSTEM. SYSTEM permissions cannot be set below FullControl ('7')") % { resource_name: resource[:name], mode_part_type: mode_part['type']}
130
+ return nil
131
+ end
132
+ end
133
+ end
134
+ current
135
+ end
136
+
89
137
  attr_reader :file
90
138
  private
91
139
  def file
@@ -63,7 +63,11 @@ Puppet::Type.type(:package).provide(:windows, :parent => Puppet::Provider::Packa
63
63
  installer = Puppet::Provider::Package::Windows::Package.installer_class(resource)
64
64
 
65
65
  command = [installer.install_command(resource), install_options].flatten.compact.join(' ')
66
- output = execute(command, :failonfail => false, :combine => true, :cwd => File.dirname(resource[:source]), :suppress_window => true)
66
+ working_dir = File.dirname(resource[:source])
67
+ if !Puppet::FileSystem.exist?(working_dir) && resource[:source] =~ /\.msi"?\Z/i
68
+ working_dir = nil
69
+ end
70
+ output = execute(command, :failonfail => false, :combine => true, :cwd => working_dir, :suppress_window => true)
67
71
 
68
72
  check_result(output.exitstatus)
69
73
  end
@@ -28,7 +28,8 @@ Puppet::Reports.register_report(:http) do
28
28
  }
29
29
  end
30
30
  use_ssl = url.scheme == 'https'
31
- conn = Puppet::Network::HttpPool.http_instance(url.host, url.port, use_ssl)
31
+ ssl_context = use_ssl ? Puppet.lookup(:ssl_context) : nil
32
+ conn = Puppet::Network::HttpPool.connection(url.host, url.port, use_ssl: use_ssl, ssl_context: ssl_context)
32
33
  response = conn.post(url.path, self.to_yaml, headers, options)
33
34
  unless response.kind_of?(Net::HTTPSuccess)
34
35
  Puppet.err _("Unable to submit report to %{url} [%{code}] %{message}") % { url: Puppet[:reporturl].to_s, code: response.code, message: response.msg }
@@ -10,7 +10,7 @@ module Puppet::Rest
10
10
  attr_reader :dns_resolver
11
11
 
12
12
  # Create a new HTTP client for querying the given API.
13
- # @param [Puppet::Rest::SSLContext] ssl_context the SSL configuration for this client
13
+ # @param [Puppet::SSL::SSLContext] ssl_context the SSL configuration for this client
14
14
  # @param [Integer] receive_timeout how long in seconds this client will wait
15
15
  # for a response after making a request
16
16
  # @param [HTTPClient] client the third-party HTTP client wrapped by this
@@ -76,8 +76,12 @@ module Puppet::Rest
76
76
 
77
77
  def configure_verify_mode(ssl_context)
78
78
  @client.ssl_config.verify_callback = @verifier
79
- @client.ssl_config.cert_store = ssl_context.cert_store
80
- @client.ssl_config.verify_mode = ssl_context.verify_mode
79
+ @client.ssl_config.cert_store = ssl_context[:store]
80
+ @client.ssl_config.verify_mode = if !ssl_context[:verify_peer]
81
+ OpenSSL::SSL::VERIFY_NONE
82
+ else
83
+ OpenSSL::SSL::VERIFY_PEER
84
+ end
81
85
  end
82
86
  end
83
87
  end
@@ -18,7 +18,7 @@ module Puppet::Rest
18
18
 
19
19
  # Make an HTTP request to fetch the named certificate
20
20
  # @param [String] name the name of the certificate to fetch
21
- # @param [Puppet::Rest::SSLContext] ssl_context the ssl content to use when making the request
21
+ # @param [Puppet::SSL::SSLContext] ssl_context the ssl content to use when making the request
22
22
  # @raise [Puppet::Rest::ResponseError] if the response status is not OK
23
23
  # @return [String] the PEM-encoded certificate or certificate bundle
24
24
  def self.get_certificate(name, ssl_context)
@@ -28,21 +28,7 @@ module Puppet::Rest
28
28
 
29
29
  use_ssl = url.is_a? URI::HTTPS
30
30
 
31
- # Deeper levels of the code assume that if we have any number of
32
- # certificate related files, we have all of the certificate related
33
- # files. This assumption caused us to download the certificate twice.
34
- # We have to hard code `verify_mode=false` so we don't attempt to
35
- # download the certificate so that we can download the certificate.
36
- #
37
- # This is related to PUP-9094. We won't have so many issues with this
38
- # once we are using the httpclient gem to handle this work. We were
39
- # unable to get this work completed in time for Puppet 6.0.0, so we had
40
- # to switch back to using Puppet::Network::HttpPool, which has
41
- # unfortunate limitations (i.e., an all or nothing approach to cert
42
- # verification).
43
- verify_mode = false
44
-
45
- client = Puppet::Network::HttpPool.http_instance(url.host, url.port, use_ssl, verify_mode)
31
+ client = Puppet::Network::HttpPool.connection(url.host, url.port, use_ssl: use_ssl, ssl_context: ssl_context)
46
32
 
47
33
  response = client.get(url.request_uri, header)
48
34
  unless response.code.to_i == 200
@@ -57,7 +43,7 @@ module Puppet::Rest
57
43
 
58
44
  # Make an HTTP request to fetch the named crl
59
45
  # @param [String] name the crl to fetch
60
- # @param [Puppet::Rest::SSLContext] ssl_context the ssl content to use when making the request
46
+ # @param [Puppet::SSL::SSLContext] ssl_context the ssl content to use when making the request
61
47
  # @raise [Puppet::Rest::ResponseError] if the response status is not OK
62
48
  # @return [String] the PEM-encoded crl
63
49
  def self.get_crls(name, ssl_context)
@@ -67,28 +53,14 @@ module Puppet::Rest
67
53
 
68
54
  use_ssl = url.is_a? URI::HTTPS
69
55
 
70
- # Deeper levels of the code assume that if we have any number of
71
- # certificate related files, we have all of the certificate related
72
- # files. Unfortunately, this causes us to get stuck in an infinite loop,
73
- # so we have to hard code `verify_mode=false` so we don't attempt to use
74
- # files that do not exist yet in order to download those files.
75
- #
76
- # This is related to PUP-9094. We won't have so many issues with this
77
- # once we are using the httpclient gem to handle this work. We were
78
- # unable to get this work completed in time for Puppet 6.0.0, so we had
79
- # to switch back to using Puppet::Network::HttpPool, which has
80
- # unfortunate limitations (i.e., an all or nothing approach to cert
81
- # verification).
82
- verify_mode = false
83
-
84
- client = Puppet::Network::HttpPool.http_instance(url.host, url.port, use_ssl, verify_mode)
56
+ client = Puppet::Network::HttpPool.connection(url.host, url.port, use_ssl: use_ssl, ssl_context: ssl_context)
85
57
 
86
58
  response = client.get(url.request_uri, header)
87
59
  unless response.code.to_i == 200
88
60
  raise Puppet::Rest::ResponseError.new(response.message, response)
89
61
  end
90
62
 
91
- Puppet.debug _("Downloaded certificate revocation list for %{name} from %{server}") % { name: name, server: ca.server }
63
+ Puppet.info _("Downloaded certificate revocation list for %{name} from %{server}") % { name: name, server: ca.server }
92
64
 
93
65
  uncompress_body(response)
94
66
  end
@@ -97,7 +69,7 @@ module Puppet::Rest
97
69
  # Make an HTTP request to send the named CSR
98
70
  # @param [String] csr_pem the contents of the CSR to sent to the CA
99
71
  # @param [String] name the name of the host whose CSR is being submitted
100
- # @param [Puppet::Rest::SSLContext] ssl_context the ssl content to use when making the request
72
+ # @param [Puppet::SSL::SSLContext] ssl_context the ssl content to use when making the request
101
73
  # @rasies [Puppet::Rest::ResponseError] if the response status is not OK
102
74
  def self.put_certificate_request(csr_pem, name, ssl_context)
103
75
  ca.with_base_url(Puppet::Network::Resolver.new) do |url|
@@ -108,10 +80,7 @@ module Puppet::Rest
108
80
 
109
81
  use_ssl = url.is_a? URI::HTTPS
110
82
 
111
- # See notes above as to why verify_mode is hardcoded to false
112
- verify_mode = false
113
-
114
- client = Puppet::Network::HttpPool.http_instance(url.host, url.port, use_ssl, verify_mode)
83
+ client = Puppet::Network::HttpPool.connection(url.host, url.port, use_ssl: use_ssl, ssl_context: ssl_context)
115
84
 
116
85
  response = client.put(url.request_uri, csr_pem, header)
117
86
  if response.code.to_i == 200
@@ -124,7 +93,7 @@ module Puppet::Rest
124
93
 
125
94
  # Make an HTTP request to get the named CSR
126
95
  # @param [String] name the name of the host whose CSR is being queried
127
- # @param [Puppet::Rest::SSLContext] ssl_context the ssl content to use when making the request
96
+ # @param [Puppet::SSL::SSLContext] ssl_context the ssl content to use when making the request
128
97
  # @rasies [Puppet::Rest::ResponseError] if the response status is not OK
129
98
  # @return [String] the PEM encoded certificate request
130
99
  def self.get_certificate_request(name, ssl_context)
@@ -134,11 +103,7 @@ module Puppet::Rest
134
103
 
135
104
  use_ssl = url.is_a? URI::HTTPS
136
105
 
137
- # See notes above as to why verify_mode is hardcoded to false
138
- verify_mode = false
139
-
140
- client = Puppet::Network::HttpPool.http_instance(url.host, url.port, use_ssl, verify_mode)
141
-
106
+ client = Puppet::Network::HttpPool.connection(url.host, url.port, use_ssl: use_ssl, ssl_context: ssl_context)
142
107
 
143
108
  response = client.get(url.request_uri, header)
144
109
  unless response.code.to_i == 200
@@ -9,4 +9,10 @@ module Puppet::SSL # :nodoc:
9
9
  require 'puppet/ssl/validator'
10
10
  require 'puppet/ssl/validator/no_validator'
11
11
  require 'puppet/ssl/validator/default_validator'
12
+ require 'puppet/ssl/error'
13
+ require 'puppet/ssl/ssl_context'
14
+ require 'puppet/ssl/verifier'
15
+ require 'puppet/ssl/verifier_adapter'
16
+ require 'puppet/ssl/ssl_provider'
17
+ require 'puppet/ssl/state_machine'
12
18
  end
@@ -0,0 +1,26 @@
1
+ module Puppet::SSL
2
+ class SSLError < Puppet::Error; end
3
+
4
+ class CertVerifyError < Puppet::SSL::SSLError
5
+ attr_reader :code, :cert
6
+ def initialize(message, code, cert)
7
+ super(message)
8
+ @code = code
9
+ @cert = cert
10
+ end
11
+ end
12
+
13
+ class CertMismatchError < Puppet::SSL::SSLError
14
+ def initialize(peer_cert, host)
15
+ valid_certnames = [peer_cert.subject.to_s.sub(/.*=/, ''),
16
+ *Puppet::SSL::Certificate.subject_alt_names_for(peer_cert)].uniq
17
+ if valid_certnames.size > 1
18
+ expected_certnames = _("expected one of %{certnames}") % { certnames: valid_certnames.join(', ') }
19
+ else
20
+ expected_certnames = _("expected %{certname}") % { certname: valid_certnames.first }
21
+ end
22
+
23
+ super(_("Server hostname '%{host}' did not match server certificate; %{expected_certnames}") % { host: host, expected_certnames: expected_certnames })
24
+ end
25
+ end
26
+ end