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.
- checksums.yaml +4 -4
- data/CODEOWNERS +30 -0
- data/Gemfile.lock +9 -9
- data/lib/puppet.rb +13 -0
- data/lib/puppet/application/agent.rb +8 -12
- data/lib/puppet/application/device.rb +2 -3
- data/lib/puppet/application/filebucket.rb +6 -1
- data/lib/puppet/application/ssl.rb +102 -55
- data/lib/puppet/configurer.rb +8 -7
- data/lib/puppet/defaults.rb +3 -1
- data/lib/puppet/file_system.rb +24 -4
- data/lib/puppet/file_system/file_impl.rb +25 -0
- data/lib/puppet/file_system/jruby.rb +23 -0
- data/lib/puppet/file_system/windows.rb +84 -0
- data/lib/puppet/indirector/rest.rb +4 -2
- data/lib/puppet/loaders.rb +1 -0
- data/lib/puppet/network/http.rb +1 -0
- data/lib/puppet/network/http/base_pool.rb +18 -0
- data/lib/puppet/network/http/connection.rb +49 -17
- data/lib/puppet/network/http/nocache_pool.rb +9 -4
- data/lib/puppet/network/http/pool.rb +10 -11
- data/lib/puppet/network/http/session.rb +3 -2
- data/lib/puppet/network/http_pool.rb +32 -0
- data/lib/puppet/pops/loader/generic_plan_instantiator.rb +28 -0
- data/lib/puppet/pops/loader/loader_paths.rb +46 -10
- data/lib/puppet/pops/loader/module_loaders.rb +10 -3
- data/lib/puppet/provider/file/windows.rb +49 -1
- data/lib/puppet/provider/package/windows.rb +5 -1
- data/lib/puppet/reports/http.rb +2 -1
- data/lib/puppet/rest/client.rb +7 -3
- data/lib/puppet/rest/routes.rb +9 -44
- data/lib/puppet/ssl.rb +6 -0
- data/lib/puppet/ssl/error.rb +26 -0
- data/lib/puppet/ssl/host.rb +9 -92
- data/lib/puppet/ssl/ssl_context.rb +30 -0
- data/lib/puppet/ssl/ssl_provider.rb +232 -0
- data/lib/puppet/ssl/state_machine.rb +261 -0
- data/lib/puppet/ssl/validator.rb +1 -0
- data/lib/puppet/ssl/validator/default_validator.rb +1 -0
- data/lib/puppet/ssl/validator/no_validator.rb +2 -0
- data/lib/puppet/ssl/verifier.rb +134 -0
- data/lib/puppet/ssl/verifier_adapter.rb +48 -0
- data/lib/puppet/test/test_helper.rb +2 -1
- data/lib/puppet/type/exec.rb +30 -6
- data/lib/puppet/type/file/mode.rb +6 -1
- data/lib/puppet/type/file/source.rb +2 -2
- data/lib/puppet/type/filebucket.rb +12 -8
- data/lib/puppet/type/user.rb +14 -1
- data/lib/puppet/util/connection.rb +10 -5
- data/lib/puppet/util/feature.rb +11 -2
- data/lib/puppet/util/http_proxy.rb +3 -2
- data/lib/puppet/util/pidlock.rb +1 -1
- data/lib/puppet/util/ssl.rb +1 -10
- data/lib/puppet/util/windows/security.rb +29 -8
- data/lib/puppet/version.rb +1 -1
- data/lib/puppet/x509.rb +7 -0
- data/lib/puppet/x509/cert_provider.rb +286 -0
- data/lib/puppet/x509/pem_store.rb +55 -0
- data/locales/ja/puppet.po +740 -590
- data/locales/puppet.pot +433 -208
- data/man/man5/puppet.conf.5 +6 -3
- data/man/man8/puppet-agent.8 +1 -1
- data/man/man8/puppet-apply.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-config.8 +1 -1
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +1 -1
- data/man/man8/puppet-doc.8 +1 -1
- data/man/man8/puppet-epp.8 +1 -1
- data/man/man8/puppet-facts.8 +1 -1
- data/man/man8/puppet-filebucket.8 +6 -2
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +1 -1
- data/man/man8/puppet-key.8 +1 -1
- data/man/man8/puppet-lookup.8 +1 -1
- data/man/man8/puppet-man.8 +1 -1
- data/man/man8/puppet-module.8 +1 -1
- data/man/man8/puppet-node.8 +1 -1
- data/man/man8/puppet-parser.8 +1 -1
- data/man/man8/puppet-plugin.8 +1 -1
- data/man/man8/puppet-report.8 +1 -1
- data/man/man8/puppet-resource.8 +1 -1
- data/man/man8/puppet-script.8 +1 -1
- data/man/man8/puppet-ssl.8 +5 -1
- data/man/man8/puppet-status.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/ssl/127.0.0.1-key.pem +67 -0
- data/spec/fixtures/ssl/127.0.0.1.pem +48 -0
- data/spec/fixtures/ssl/bad-basic-constraints.pem +59 -0
- data/spec/fixtures/ssl/bad-int-basic-constraints.pem +59 -0
- data/spec/fixtures/ssl/ca.pem +59 -0
- data/spec/fixtures/ssl/crl.pem +30 -0
- data/spec/fixtures/ssl/encrypted-key.pem +70 -0
- data/spec/fixtures/ssl/intermediate-agent-crl.pem +31 -0
- data/spec/fixtures/ssl/intermediate-agent.pem +60 -0
- data/spec/fixtures/ssl/intermediate-crl.pem +36 -0
- data/spec/fixtures/ssl/intermediate.pem +60 -0
- data/spec/fixtures/ssl/netlock-arany-utf8.pem +23 -0
- data/spec/fixtures/ssl/pluto-key.pem +67 -0
- data/spec/fixtures/ssl/pluto.pem +44 -0
- data/spec/fixtures/ssl/request-key.pem +67 -0
- data/spec/fixtures/ssl/request.pem +39 -0
- data/spec/fixtures/ssl/revoked-key.pem +67 -0
- data/spec/fixtures/ssl/revoked.pem +44 -0
- data/spec/fixtures/ssl/signed-key.pem +67 -0
- data/spec/fixtures/ssl/signed.pem +44 -0
- data/spec/fixtures/ssl/tampered-cert.pem +44 -0
- data/spec/fixtures/ssl/tampered-csr.pem +39 -0
- data/spec/integration/network/http_pool_spec.rb +222 -0
- data/spec/integration/provider/file/windows_spec.rb +162 -0
- data/spec/integration/rest/client_spec.rb +73 -0
- data/spec/integration/type/file_spec.rb +0 -19
- data/spec/lib/puppet/test_ca.rb +87 -50
- data/spec/lib/puppet_spec/fixtures.rb +20 -0
- data/spec/lib/puppet_spec/https.rb +84 -0
- data/spec/unit/application/agent_spec.rb +29 -30
- data/spec/unit/application/device_spec.rb +12 -49
- data/spec/unit/application/ssl_spec.rb +24 -38
- data/spec/unit/configurer_spec.rb +11 -11
- data/spec/unit/file_system/uniquefile_spec.rb +6 -0
- data/spec/unit/file_system_spec.rb +214 -0
- data/spec/unit/indirector/rest_spec.rb +3 -3
- data/spec/unit/network/http/connection_spec.rb +30 -90
- data/spec/unit/network/http/factory_spec.rb +1 -0
- data/spec/unit/network/http/nocache_pool_spec.rb +8 -8
- data/spec/unit/network/http/pool_spec.rb +63 -33
- data/spec/unit/network/http/session_spec.rb +8 -1
- data/spec/unit/network/http_pool_spec.rb +36 -0
- data/spec/unit/pops/loaders/loader_spec.rb +26 -1
- data/spec/unit/provider/package/windows_spec.rb +12 -1
- data/spec/unit/reports/http_spec.rb +7 -7
- data/spec/unit/rest/client_spec.rb +4 -6
- data/spec/unit/ssl/host_spec.rb +39 -33
- data/spec/unit/ssl/ssl_provider_spec.rb +428 -0
- data/spec/unit/ssl/state_machine_spec.rb +502 -0
- data/spec/unit/ssl/verifier_spec.rb +123 -0
- data/spec/unit/type/exec_spec.rb +63 -0
- data/spec/unit/type/file/source_spec.rb +5 -5
- data/spec/unit/type/filebucket_spec.rb +8 -6
- data/spec/unit/util/feature_spec.rb +2 -2
- data/spec/unit/util/storage_spec.rb +19 -19
- data/spec/unit/x509/cert_provider_spec.rb +527 -0
- data/spec/unit/x509/pem_store_spec.rb +160 -0
- data/tasks/generate_cert_fixtures.rake +158 -0
- metadata +78 -4
- data/MAINTAINERS +0 -47
- 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 <<
|
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
|
316
|
-
|
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
|
-
|
336
|
+
PLAN_PATH
|
320
337
|
end
|
321
338
|
|
322
339
|
def instantiator()
|
323
|
-
Puppet::Pops::Loader::
|
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
|
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
|
-
|
333
|
-
|
334
|
-
|
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
|
-
#
|
411
|
-
|
412
|
-
|
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
|
-
|
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
|
-
|
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
|
data/lib/puppet/reports/http.rb
CHANGED
@@ -28,7 +28,8 @@ Puppet::Reports.register_report(:http) do
|
|
28
28
|
}
|
29
29
|
end
|
30
30
|
use_ssl = url.scheme == 'https'
|
31
|
-
|
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 }
|
data/lib/puppet/rest/client.rb
CHANGED
@@ -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::
|
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
|
80
|
-
@client.ssl_config.verify_mode = ssl_context
|
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
|
data/lib/puppet/rest/routes.rb
CHANGED
@@ -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::
|
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
|
-
|
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::
|
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
|
-
|
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.
|
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::
|
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
|
-
|
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::
|
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
|
-
|
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
|
data/lib/puppet/ssl.rb
CHANGED
@@ -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
|