puppet 8.1.0-x86-mingw32 → 8.3.1-x86-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Gemfile.lock +39 -45
- data/ext/project_data.yaml +2 -2
- data/lib/puppet/application/doc.rb +1 -1
- data/lib/puppet/application/ssl.rb +42 -7
- data/lib/puppet/application.rb +5 -1
- data/lib/puppet/defaults.rb +17 -5
- data/lib/puppet/face/config.rb +1 -1
- data/lib/puppet/face/epp.rb +2 -2
- data/lib/puppet/face/module/list.rb +2 -2
- data/lib/puppet/face/parser.rb +1 -1
- data/lib/puppet/functions/split.rb +28 -1
- data/lib/puppet/http/client.rb +12 -5
- data/lib/puppet/http/service/ca.rb +25 -0
- data/lib/puppet/indirector/facts/facter.rb +1 -1
- data/lib/puppet/indirector/file_bucket_file/file.rb +1 -1
- data/lib/puppet/indirector/indirection.rb +1 -1
- data/lib/puppet/info_service/task_information_service.rb +1 -1
- data/lib/puppet/module_tool.rb +1 -1
- data/lib/puppet/network/formats.rb +3 -3
- data/lib/puppet/network/http/memory_response.rb +1 -1
- data/lib/puppet/node/environment.rb +6 -4
- data/lib/puppet/parameter/value_collection.rb +1 -1
- data/lib/puppet/parser/files.rb +4 -3
- data/lib/puppet/parser/functions.rb +1 -1
- data/lib/puppet/pops/evaluator/deferred_resolver.rb +20 -3
- data/lib/puppet/pops/loader/loader_paths.rb +4 -4
- data/lib/puppet/pops/lookup/explainer.rb +1 -1
- data/lib/puppet/pops/lookup/hiera_config.rb +1 -1
- data/lib/puppet/pops/model/factory.rb +1 -1
- data/lib/puppet/pops/model/tree_dumper.rb +1 -1
- data/lib/puppet/pops/parser/epp_support.rb +1 -1
- data/lib/puppet/pops/parser/evaluating_parser.rb +1 -1
- data/lib/puppet/pops/parser/pn_parser.rb +1 -1
- data/lib/puppet/pops/pn.rb +1 -1
- data/lib/puppet/pops/serialization/json_path.rb +1 -1
- data/lib/puppet/pops/time/timespan.rb +4 -4
- data/lib/puppet/pops/types/ruby_generator.rb +2 -2
- data/lib/puppet/pops/types/string_converter.rb +6 -6
- data/lib/puppet/pops/types/type_formatter.rb +2 -2
- data/lib/puppet/pops/types/types.rb +1 -1
- data/lib/puppet/provider/nameservice/directoryservice.rb +2 -2
- data/lib/puppet/provider/package/apt.rb +1 -1
- data/lib/puppet/provider/package/dnf.rb +1 -1
- data/lib/puppet/provider/package/yum.rb +1 -1
- data/lib/puppet/provider/user/directoryservice.rb +1 -1
- data/lib/puppet/reference/configuration.rb +1 -1
- data/lib/puppet/reference/indirection.rb +1 -1
- data/lib/puppet/reports.rb +1 -1
- data/lib/puppet/ssl/oids.rb +2 -0
- data/lib/puppet/ssl/ssl_provider.rb +1 -1
- data/lib/puppet/ssl/state_machine.rb +60 -9
- data/lib/puppet/transaction/report.rb +1 -1
- data/lib/puppet/type/filebucket.rb +1 -1
- data/lib/puppet/util/diff.rb +1 -1
- data/lib/puppet/util/execution.rb +9 -4
- data/lib/puppet/util/inifile.rb +2 -2
- data/lib/puppet/util/monkey_patches.rb +18 -0
- data/lib/puppet/util/package/version/rpm.rb +1 -1
- data/lib/puppet/util/provider_features.rb +1 -1
- data/lib/puppet/util/selinux.rb +1 -1
- data/lib/puppet/util/windows/access_control_entry.rb +1 -1
- data/lib/puppet/util/windows/access_control_list.rb +1 -1
- data/lib/puppet/util/windows/adsi.rb +9 -2
- data/lib/puppet/util/windows/error.rb +1 -1
- data/lib/puppet/util/windows/file.rb +2 -2
- data/lib/puppet/util/windows/process.rb +1 -1
- data/lib/puppet/util/windows/sid.rb +4 -2
- data/lib/puppet/util.rb +2 -3
- data/lib/puppet/version.rb +1 -1
- data/lib/puppet/x509/cert_provider.rb +13 -2
- data/locales/puppet.pot +106 -74
- data/man/man5/puppet.conf.5 +16 -2
- 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 +1 -1
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +1 -1
- data/man/man8/puppet-lookup.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.8 +2 -2
- data/spec/fixtures/ssl/127.0.0.1-key.pem +107 -107
- data/spec/fixtures/ssl/127.0.0.1.pem +52 -51
- data/spec/fixtures/ssl/bad-basic-constraints.pem +56 -56
- data/spec/fixtures/ssl/bad-int-basic-constraints.pem +53 -53
- data/spec/fixtures/ssl/ca.pem +54 -54
- data/spec/fixtures/ssl/crl.pem +26 -26
- data/spec/fixtures/ssl/ec-key.pem +11 -11
- data/spec/fixtures/ssl/ec.pem +33 -32
- data/spec/fixtures/ssl/encrypted-ec-key.pem +12 -12
- data/spec/fixtures/ssl/encrypted-key.pem +108 -108
- data/spec/fixtures/ssl/intermediate-agent-crl.pem +26 -26
- data/spec/fixtures/ssl/intermediate-agent.pem +56 -56
- data/spec/fixtures/ssl/intermediate-crl.pem +29 -29
- data/spec/fixtures/ssl/intermediate.pem +53 -53
- data/spec/fixtures/ssl/oid-key.pem +107 -107
- data/spec/fixtures/ssl/oid.pem +51 -50
- data/spec/fixtures/ssl/pluto-key.pem +107 -107
- data/spec/fixtures/ssl/pluto.pem +52 -51
- data/spec/fixtures/ssl/renewed.pem +67 -0
- data/spec/fixtures/ssl/request-key.pem +107 -107
- data/spec/fixtures/ssl/request.pem +50 -48
- data/spec/fixtures/ssl/revoked-key.pem +107 -107
- data/spec/fixtures/ssl/revoked.pem +51 -50
- data/spec/fixtures/ssl/signed-key.pem +107 -107
- data/spec/fixtures/ssl/signed.pem +49 -48
- data/spec/fixtures/ssl/tampered-cert.pem +51 -50
- data/spec/fixtures/ssl/tampered-csr.pem +50 -48
- data/spec/fixtures/ssl/unknown-127.0.0.1-key.pem +107 -107
- data/spec/fixtures/ssl/unknown-127.0.0.1.pem +50 -49
- data/spec/fixtures/ssl/unknown-ca-key.pem +107 -107
- data/spec/fixtures/ssl/unknown-ca.pem +54 -54
- data/spec/integration/application/agent_spec.rb +27 -27
- data/spec/integration/application/apply_spec.rb +14 -0
- data/spec/integration/http/client_spec.rb +16 -0
- data/spec/integration/type/exec_spec.rb +13 -0
- data/spec/lib/puppet/test_ca.rb +3 -10
- data/spec/lib/puppet_spec/verbose.rb +10 -1
- data/spec/unit/agent_spec.rb +2 -9
- data/spec/unit/application/ssl_spec.rb +49 -0
- data/spec/unit/defaults_spec.rb +2 -40
- data/spec/unit/file_system/path_pattern_spec.rb +15 -0
- data/spec/unit/functions/split_spec.rb +6 -0
- data/spec/unit/http/service/ca_spec.rb +71 -0
- data/spec/unit/info_service_spec.rb +1 -1
- data/spec/unit/ssl/certificate_signer_spec.rb +17 -0
- data/spec/unit/ssl/ssl_provider_spec.rb +21 -1
- data/spec/unit/ssl/state_machine_spec.rb +75 -3
- data/spec/unit/util/execution_spec.rb +1 -0
- data/spec/unit/util/monkey_patches_spec.rb +42 -0
- data/spec/unit/util/windows/adsi_spec.rb +25 -0
- data/spec/unit/x509/cert_provider_spec.rb +23 -0
- data/tasks/generate_cert_fixtures.rake +4 -0
- metadata +11 -13
@@ -1,4 +1,4 @@
|
|
1
|
-
# Support code for running stuff with warnings disabled
|
1
|
+
# Support code for running stuff with warnings disabled or enabled
|
2
2
|
module Kernel
|
3
3
|
def with_verbose_disabled
|
4
4
|
verbose, $VERBOSE = $VERBOSE, nil
|
@@ -6,4 +6,13 @@ module Kernel
|
|
6
6
|
$VERBOSE = verbose
|
7
7
|
return result
|
8
8
|
end
|
9
|
+
|
10
|
+
def with_verbose_enabled
|
11
|
+
verbose, $VERBOSE = $VERBOSE, true
|
12
|
+
begin
|
13
|
+
yield
|
14
|
+
ensure
|
15
|
+
$VERBOSE = verbose
|
16
|
+
end
|
17
|
+
end
|
9
18
|
end
|
data/spec/unit/agent_spec.rb
CHANGED
@@ -15,19 +15,12 @@ class AgentTestClient
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
def without_warnings
|
19
|
-
flag = $VERBOSE
|
20
|
-
$VERBOSE = nil
|
21
|
-
yield
|
22
|
-
$VERBOSE = flag
|
23
|
-
end
|
24
|
-
|
25
18
|
describe Puppet::Agent do
|
26
19
|
before do
|
27
20
|
@agent = Puppet::Agent.new(AgentTestClient, false)
|
28
21
|
|
29
22
|
# make Puppet::Application safe for stubbing; restore in an :after block; silence warnings for this.
|
30
|
-
|
23
|
+
with_verbose_disabled { Puppet::Application = Class.new(Puppet::Application) }
|
31
24
|
allow(Puppet::Application).to receive(:clear?).and_return(true)
|
32
25
|
Puppet::Application.class_eval do
|
33
26
|
class << self
|
@@ -44,7 +37,7 @@ describe Puppet::Agent do
|
|
44
37
|
|
45
38
|
after do
|
46
39
|
# restore Puppet::Application from stub-safe subclass, and silence warnings
|
47
|
-
|
40
|
+
with_verbose_disabled { Puppet::Application = Puppet::Application.superclass }
|
48
41
|
end
|
49
42
|
|
50
43
|
it "should set its client class at initialization" do
|
@@ -171,6 +171,50 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
|
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
174
|
+
context 'when generating a CSR' do
|
175
|
+
let(:csr_path) { Puppet[:hostcsr] }
|
176
|
+
let(:requestdir) { Puppet[:requestdir] }
|
177
|
+
|
178
|
+
before do
|
179
|
+
ssl.command_line.args << 'generate_request'
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'generates an RSA private key' do
|
183
|
+
File.unlink(Puppet[:hostprivkey])
|
184
|
+
|
185
|
+
expects_command_to_pass(%r{Generated certificate request in '#{csr_path}'})
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'generates an EC private key' do
|
189
|
+
Puppet[:key_type] = 'ec'
|
190
|
+
File.unlink(Puppet[:hostprivkey])
|
191
|
+
|
192
|
+
expects_command_to_pass(%r{Generated certificate request in '#{csr_path}'})
|
193
|
+
end
|
194
|
+
|
195
|
+
it 'registers OIDs' do
|
196
|
+
expect(Puppet::SSL::Oids).to receive(:register_puppet_oids)
|
197
|
+
|
198
|
+
expects_command_to_pass(%r{Generated certificate request in '#{csr_path}'})
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'saves the CSR locally' do
|
202
|
+
expects_command_to_pass(%r{Generated certificate request in '#{csr_path}'})
|
203
|
+
|
204
|
+
expect(Puppet::FileSystem).to be_exist(csr_path)
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'accepts dns alt names' do
|
208
|
+
Puppet[:dns_alt_names] = 'majortom'
|
209
|
+
|
210
|
+
expects_command_to_pass
|
211
|
+
|
212
|
+
csr = Puppet::SSL::CertificateRequest.new(name)
|
213
|
+
csr.read(csr_path)
|
214
|
+
expect(csr.subject_alt_names).to include('DNS:majortom')
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
174
218
|
context 'when downloading a certificate' do
|
175
219
|
before do
|
176
220
|
ssl.command_line.args << 'download_cert'
|
@@ -347,6 +391,11 @@ describe Puppet::Application::Ssl, unless: Puppet::Util::Platform.jruby? do
|
|
347
391
|
expects_command_to_fail(%r{Failed to connect to the CA to determine if certificate #{name} has been cleaned})
|
348
392
|
end
|
349
393
|
|
394
|
+
it 'raises if we have extra args' do
|
395
|
+
ssl.command_line.args << 'hostname.example.biz'
|
396
|
+
expects_command_to_fail(/Extra arguments detected: hostname.example.biz/)
|
397
|
+
end
|
398
|
+
|
350
399
|
context 'when deleting local CA' do
|
351
400
|
before do
|
352
401
|
ssl.command_line.args << '--localca'
|
data/spec/unit/defaults_spec.rb
CHANGED
@@ -3,46 +3,8 @@ require 'puppet/settings'
|
|
3
3
|
|
4
4
|
describe "Defaults" do
|
5
5
|
describe ".default_diffargs" do
|
6
|
-
|
7
|
-
|
8
|
-
allow(Facter).to receive(:value).with(:kernel).and_return("AIX")
|
9
|
-
end
|
10
|
-
|
11
|
-
describe "on 5.3" do
|
12
|
-
before(:each) do
|
13
|
-
allow(Facter).to receive(:value).with(:kernelmajversion).and_return("5300")
|
14
|
-
end
|
15
|
-
|
16
|
-
it "should be empty" do
|
17
|
-
expect(Puppet.default_diffargs).to eq("")
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
[ "",
|
22
|
-
nil,
|
23
|
-
"6300",
|
24
|
-
"7300",
|
25
|
-
].each do |kernel_version|
|
26
|
-
describe "on kernel version #{kernel_version.inspect}" do
|
27
|
-
before(:each) do
|
28
|
-
allow(Facter).to receive(:value).with(:kernelmajversion).and_return(kernel_version)
|
29
|
-
end
|
30
|
-
|
31
|
-
it "should be '-u'" do
|
32
|
-
expect(Puppet.default_diffargs).to eq("-u")
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
describe "on everything else" do
|
39
|
-
before(:each) do
|
40
|
-
allow(Facter).to receive(:value).with(:kernel).and_return("NOT_AIX")
|
41
|
-
end
|
42
|
-
|
43
|
-
it "should be '-u'" do
|
44
|
-
expect(Puppet.default_diffargs).to eq("-u")
|
45
|
-
end
|
6
|
+
it "should be '-u'" do
|
7
|
+
expect(Puppet.default_diffargs).to eq("-u")
|
46
8
|
end
|
47
9
|
end
|
48
10
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
require 'puppet_spec/files'
|
3
3
|
require 'puppet/file_system'
|
4
|
+
require 'puppet/util'
|
4
5
|
|
5
6
|
describe Puppet::FileSystem::PathPattern do
|
6
7
|
include PuppetSpec::Files
|
@@ -132,6 +133,20 @@ describe Puppet::FileSystem::PathPattern do
|
|
132
133
|
File.join(dir, "found_two")])
|
133
134
|
end
|
134
135
|
|
136
|
+
it 'globs wildcard patterns properly' do
|
137
|
+
# See PUP-11788 and https://github.com/jruby/jruby/issues/7836.
|
138
|
+
pending 'JRuby does not properly handle Dir.glob' if Puppet::Util::Platform.jruby?
|
139
|
+
|
140
|
+
dir = tmpdir('globtest')
|
141
|
+
create_file_in(dir, 'foo.pp')
|
142
|
+
create_file_in(dir, 'foo.pp.pp')
|
143
|
+
|
144
|
+
pattern = Puppet::FileSystem::PathPattern.absolute(File.join(dir, '**/*.pp'))
|
145
|
+
|
146
|
+
expect(pattern.glob).to match_array([File.join(dir, 'foo.pp'),
|
147
|
+
File.join(dir, 'foo.pp.pp')])
|
148
|
+
end
|
149
|
+
|
135
150
|
def create_file_in(dir, name)
|
136
151
|
File.open(File.join(dir, name), "w") { |f| f.puts "data" }
|
137
152
|
end
|
@@ -50,4 +50,10 @@ describe 'the split function' do
|
|
50
50
|
it 'should handle pattern in Regexp Type form with missing regular expression' do
|
51
51
|
expect(split('ab',type_parser.parse('Regexp'))).to eql(['a', 'b'])
|
52
52
|
end
|
53
|
+
|
54
|
+
it 'should handle sensitive String' do
|
55
|
+
expect(split(Puppet::Pops::Types::PSensitiveType::Sensitive.new('a,b'), ',')).to be_a(Puppet::Pops::Types::PSensitiveType::Sensitive)
|
56
|
+
expect(split(Puppet::Pops::Types::PSensitiveType::Sensitive.new('a,b'), /,/)).to be_a(Puppet::Pops::Types::PSensitiveType::Sensitive)
|
57
|
+
expect(split(Puppet::Pops::Types::PSensitiveType::Sensitive.new('a,b'), type_parser.parse('Regexp[/,/]'))).to be_a(Puppet::Pops::Types::PSensitiveType::Sensitive)
|
58
|
+
end
|
53
59
|
end
|
@@ -207,4 +207,75 @@ describe Puppet::HTTP::Service::Ca do
|
|
207
207
|
end
|
208
208
|
end
|
209
209
|
end
|
210
|
+
|
211
|
+
context 'when getting certificates' do
|
212
|
+
let(:cert) { cert_fixture('signed.pem') }
|
213
|
+
let(:pem) { cert.to_pem }
|
214
|
+
let(:url) { "https://www.example.com/puppet-ca/v1/certificate_renewal" }
|
215
|
+
let(:cert_context) { Puppet::SSL::SSLContext.new(client_cert: pem) }
|
216
|
+
let(:client) { Puppet::HTTP::Client.new(ssl_context: cert_context) }
|
217
|
+
let(:session) { Puppet::HTTP::Session.new(client, []) }
|
218
|
+
let(:subject) { client.create_session.route_to(:ca) }
|
219
|
+
|
220
|
+
it "gets a certificate from the 'certificate_renewal' endpoint" do
|
221
|
+
stub_request(:post, url).to_return(body: pem)
|
222
|
+
|
223
|
+
_, body = subject.post_certificate_renewal(cert_context)
|
224
|
+
expect(body).to eq(pem)
|
225
|
+
end
|
226
|
+
|
227
|
+
it 'returns the request response' do
|
228
|
+
stub_request(:post, url).to_return(body: 'pem')
|
229
|
+
|
230
|
+
resp, _ = subject.post_certificate_renewal(cert_context)
|
231
|
+
expect(resp).to be_a(Puppet::HTTP::Response)
|
232
|
+
end
|
233
|
+
|
234
|
+
it 'accepts text/plain responses' do
|
235
|
+
stub_request(:post, url).with(headers: {'Accept' => 'text/plain'})
|
236
|
+
|
237
|
+
subject.post_certificate_renewal(cert_context)
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'raises an ArgumentError if the SSL context does not contain a client cert' do
|
241
|
+
stub_request(:post, url)
|
242
|
+
expect { subject.post_certificate_renewal(ssl_context) }.to raise_error(ArgumentError, 'SSL context must contain a client certificate.')
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'raises response error if unsuccessful' do
|
246
|
+
stub_request(:post, url).to_return(status: [400, 'Bad Request'])
|
247
|
+
|
248
|
+
expect {
|
249
|
+
subject.post_certificate_renewal(cert_context)
|
250
|
+
}.to raise_error do |err|
|
251
|
+
expect(err).to be_an_instance_of(Puppet::HTTP::ResponseError)
|
252
|
+
expect(err.message).to eq('Bad Request')
|
253
|
+
expect(err.response.code).to eq(400)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
it 'raises a response error if unsuccessful' do
|
258
|
+
stub_request(:post, url).to_return(status: [404, 'Not Found'])
|
259
|
+
|
260
|
+
expect {
|
261
|
+
subject.post_certificate_renewal(cert_context)
|
262
|
+
}.to raise_error do |err|
|
263
|
+
expect(err).to be_an_instance_of(Puppet::HTTP::ResponseError)
|
264
|
+
expect(err.message).to eq("Not Found")
|
265
|
+
expect(err.response.code).to eq(404)
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
it 'raises a response error if unsuccessful' do
|
270
|
+
stub_request(:post, url).to_return(status: [404, 'Forbidden'])
|
271
|
+
|
272
|
+
expect {
|
273
|
+
subject.post_certificate_renewal(cert_context)
|
274
|
+
}.to raise_error do |err|
|
275
|
+
expect(err).to be_an_instance_of(Puppet::HTTP::ResponseError)
|
276
|
+
expect(err.message).to eq("Forbidden")
|
277
|
+
expect(err.response.code).to eq(404)
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
210
281
|
end
|
@@ -47,7 +47,7 @@ describe "Puppet::InfoService" do
|
|
47
47
|
:content => metadata.to_json}]]})
|
48
48
|
File.write("#{modpath}/#{mod_name}/tasks/atask.json", "NOT JSON")
|
49
49
|
|
50
|
-
expect(Puppet).to receive(:send_log).with(:err,
|
50
|
+
expect(Puppet).to receive(:send_log).with(:err, /unexpected token at 'NOT JSON'/)
|
51
51
|
|
52
52
|
@tasks = Puppet::InfoService.tasks_per_environment(env_name)
|
53
53
|
expect(@tasks.map{|t| t[:name]}).to contain_exactly('test1::btask', 'test1::ctask')
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Puppet::SSL::CertificateSigner do
|
4
|
+
include PuppetSpec::Files
|
5
|
+
|
6
|
+
let(:wrong_key) { OpenSSL::PKey::RSA.new(512) }
|
7
|
+
let(:client_cert) { cert_fixture('signed.pem') }
|
8
|
+
|
9
|
+
# jruby-openssl >= 0.13.0 (JRuby >= 9.3.5.0) raises an error when signing a
|
10
|
+
# certificate when there is a discrepancy between the certificate and key.
|
11
|
+
it 'raises if client cert signature is invalid', if: Puppet::Util::Platform.jruby? && RUBY_VERSION.to_f >= 2.6 do
|
12
|
+
expect {
|
13
|
+
client_cert.sign(wrong_key, OpenSSL::Digest::SHA256.new)
|
14
|
+
}.to raise_error(OpenSSL::X509::CertificateError,
|
15
|
+
'invalid public key data')
|
16
|
+
end
|
17
|
+
end
|
@@ -338,7 +338,7 @@ describe Puppet::SSL::SSLProvider do
|
|
338
338
|
end
|
339
339
|
end
|
340
340
|
|
341
|
-
it 'raises if intermediate CA signature is invalid' do
|
341
|
+
it 'raises if intermediate CA signature is invalid', unless: Puppet::Util::Platform.jruby? && RUBY_VERSION.to_f >= 2.6 do
|
342
342
|
int = global_cacerts.last
|
343
343
|
int.public_key = wrong_key.public_key if Puppet::Util::Platform.jruby?
|
344
344
|
int.sign(wrong_key, OpenSSL::Digest::SHA256.new)
|
@@ -634,4 +634,24 @@ describe Puppet::SSL::SSLProvider do
|
|
634
634
|
"The CSR for host 'CN=signed' does not match the public key")
|
635
635
|
end
|
636
636
|
end
|
637
|
+
|
638
|
+
context 'printing' do
|
639
|
+
let(:client_cert) { cert_fixture('signed.pem') }
|
640
|
+
let(:private_key) { key_fixture('signed-key.pem') }
|
641
|
+
let(:config) { { cacerts: global_cacerts, crls: global_crls, client_cert: client_cert, private_key: private_key } }
|
642
|
+
|
643
|
+
it 'prints in debug' do
|
644
|
+
Puppet[:log_level] = 'debug'
|
645
|
+
|
646
|
+
ctx = subject.create_context(**config)
|
647
|
+
subject.print(ctx)
|
648
|
+
expect(@logs.map(&:message)).to include(
|
649
|
+
/Verified CA certificate 'CN=Test CA' fingerprint/,
|
650
|
+
/Verified CA certificate 'CN=Test CA Subauthority' fingerprint/,
|
651
|
+
/Verified client certificate 'CN=signed' fingerprint/,
|
652
|
+
/Using CRL 'CN=Test CA' authorityKeyIdentifier '(keyid:)?[A-Z0-9:]{59}' crlNumber '0'/,
|
653
|
+
/Using CRL 'CN=Test CA Subauthority' authorityKeyIdentifier '(keyid:)?[A-Z0-9:]{59}' crlNumber '0'/
|
654
|
+
)
|
655
|
+
end
|
656
|
+
end
|
637
657
|
end
|
@@ -487,7 +487,7 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
487
487
|
expect(state.next_state.ssl_context.cacerts.map(&:to_pem)).to eq(new_ca_bundle)
|
488
488
|
end
|
489
489
|
|
490
|
-
it 'updates the `last_update` time' do
|
490
|
+
it 'updates the `last_update` time on successful CA refresh' do
|
491
491
|
stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 200, body: new_ca_bundle.join)
|
492
492
|
|
493
493
|
expect_any_instance_of(Puppet::X509::CertProvider).to receive(:ca_last_update=).with(be_within(60).of(Time.now))
|
@@ -495,6 +495,14 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
495
495
|
state.next_state
|
496
496
|
end
|
497
497
|
|
498
|
+
it "does not update the `last_update` time when CA refresh fails" do
|
499
|
+
stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_raise(Errno::ECONNREFUSED)
|
500
|
+
|
501
|
+
expect_any_instance_of(Puppet::X509::CertProvider).to receive(:ca_last_update=).never
|
502
|
+
|
503
|
+
state.next_state
|
504
|
+
end
|
505
|
+
|
498
506
|
it 'forces the NeedCRLs to refresh' do
|
499
507
|
stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 200, body: new_ca_bundle.join)
|
500
508
|
|
@@ -737,6 +745,26 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
737
745
|
state.next_state
|
738
746
|
}.to raise_error(OpenSSL::PKey::RSAError)
|
739
747
|
end
|
748
|
+
|
749
|
+
it "transitions to Done if current time plus renewal interval is less than cert's \"NotAfter\" time" do
|
750
|
+
allow(cert_provider).to receive(:load_private_key).and_return(private_key)
|
751
|
+
allow(cert_provider).to receive(:load_client_cert).and_return(client_cert)
|
752
|
+
|
753
|
+
st = state.next_state
|
754
|
+
expect(st).to be_instance_of(Puppet::SSL::StateMachine::Done)
|
755
|
+
end
|
756
|
+
|
757
|
+
it "returns NeedRenewedCert if current time plus renewal interval is greater than cert's \"NotAfter\" time" do
|
758
|
+
client_cert.not_after=(Time.now + 300)
|
759
|
+
allow(cert_provider).to receive(:load_private_key).and_return(private_key)
|
760
|
+
allow(cert_provider).to receive(:load_client_cert).and_return(client_cert)
|
761
|
+
|
762
|
+
ssl_context = Puppet::SSL::SSLContext.new(cacerts: [cacert], client_cert: client_cert, crls: [crl])
|
763
|
+
state = Puppet::SSL::StateMachine::NeedKey.new(machine, ssl_context)
|
764
|
+
|
765
|
+
st = state.next_state
|
766
|
+
expect(st).to be_instance_of(Puppet::SSL::StateMachine::NeedRenewedCert)
|
767
|
+
end
|
740
768
|
end
|
741
769
|
|
742
770
|
context 'in state NeedSubmitCSR' do
|
@@ -778,7 +806,7 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
778
806
|
state.next_state
|
779
807
|
end
|
780
808
|
|
781
|
-
it 'includes CSR attributes' do
|
809
|
+
it 'includes CSR attributes', :unless => RUBY_PLATFORM == 'java' do
|
782
810
|
Puppet[:csr_attributes] = write_csr_attributes(
|
783
811
|
'custom_attributes' => {
|
784
812
|
'1.3.6.1.4.1.34380.1.2.1' => 'CSR specific info',
|
@@ -792,7 +820,8 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
792
820
|
csr.custom_attributes
|
793
821
|
).to contain_exactly(
|
794
822
|
{'oid' => '1.3.6.1.4.1.34380.1.2.1', 'value' => 'CSR specific info'},
|
795
|
-
{'oid' => '1.3.6.1.4.1.34380.1.2.2', 'value' => 'more CSR specific info'}
|
823
|
+
{'oid' => '1.3.6.1.4.1.34380.1.2.2', 'value' => 'more CSR specific info'},
|
824
|
+
{'oid' => 'pp_auth_auto_renew', 'value' => 'true'}
|
796
825
|
)
|
797
826
|
end.to_return(status: 200)
|
798
827
|
|
@@ -1041,5 +1070,48 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do
|
|
1041
1070
|
expect(state.next_state).to be_an_instance_of(Puppet::SSL::StateMachine::LockFailure)
|
1042
1071
|
end
|
1043
1072
|
end
|
1073
|
+
|
1074
|
+
context 'in state NeedRenewedCert' do
|
1075
|
+
before :each do
|
1076
|
+
client_cert.not_after=(Time.now + 300)
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
let(:ssl_context) { Puppet::SSL::SSLContext.new(cacerts: cacerts, client_cert: client_cert, crls: crls,)}
|
1080
|
+
let(:state) { Puppet::SSL::StateMachine::NeedRenewedCert.new(machine, ssl_context, private_key) }
|
1081
|
+
let(:renewed_cert) { cert_fixture('renewed.pem') }
|
1082
|
+
|
1083
|
+
it 'returns Done with renewed cert when successful' do
|
1084
|
+
allow(cert_provider).to receive(:save_client_cert)
|
1085
|
+
stub_request(:post, %r{puppet-ca/v1/certificate_renewal}).to_return(status: 200, body: renewed_cert.to_pem)
|
1086
|
+
|
1087
|
+
st = state.next_state
|
1088
|
+
expect(st).to be_an_instance_of(Puppet::SSL::StateMachine::Done)
|
1089
|
+
expect(st.ssl_context[:client_cert]).to eq(renewed_cert)
|
1090
|
+
end
|
1091
|
+
|
1092
|
+
it 'logs a warning message when failing with a non-404 status' do
|
1093
|
+
stub_request(:post, %r{puppet-ca/v1/certificate_renewal}).to_return(status: 400, body: 'Failed to automatically renew certificate: 400 Bad request')
|
1094
|
+
|
1095
|
+
expect(Puppet).to receive(:warning).with(/Failed to automatically renew certificate/)
|
1096
|
+
st = state.next_state
|
1097
|
+
expect(st).to be_an_instance_of(Puppet::SSL::StateMachine::Done)
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
it 'logs an info message when failing with 404' do
|
1101
|
+
stub_request(:post, %r{puppet-ca/v1/certificate_renewal}).to_return(status: 404, body: 'Certificate autorenewal has not been enabled on the server.')
|
1102
|
+
|
1103
|
+
expect(Puppet).to receive(:info).with('Certificate autorenewal has not been enabled on the server.')
|
1104
|
+
st = state.next_state
|
1105
|
+
expect(st).to be_an_instance_of(Puppet::SSL::StateMachine::Done)
|
1106
|
+
end
|
1107
|
+
|
1108
|
+
it 'logs a warning message when failing with no HTTP status' do
|
1109
|
+
stub_request(:post, %r{puppet-ca/v1/certificate_renewal}).to_raise(Errno::ECONNREFUSED)
|
1110
|
+
|
1111
|
+
expect(Puppet).to receive(:warning).with(/Unable to automatically renew certificate:/)
|
1112
|
+
st = state.next_state
|
1113
|
+
expect(st).to be_an_instance_of(Puppet::SSL::StateMachine::Done)
|
1114
|
+
end
|
1115
|
+
end
|
1044
1116
|
end
|
1045
1117
|
end
|
@@ -29,6 +29,7 @@ describe Puppet::Util::Execution, if: !Puppet::Util::Platform.jruby? do
|
|
29
29
|
allow(FFI::WIN32).to receive(:CloseHandle).with(thread_handle)
|
30
30
|
else
|
31
31
|
allow(Process).to receive(:waitpid2).with(pid, Process::WNOHANG).and_return(nil, [pid, double('child_status', :exitstatus => exitstatus)])
|
32
|
+
allow(Process).to receive(:waitpid2).with(pid, 0).and_return(nil, [pid, double('child_status', :exitstatus => exitstatus)])
|
32
33
|
allow(Process).to receive(:waitpid2).with(pid).and_return([pid, double('child_status', :exitstatus => exitstatus)])
|
33
34
|
end
|
34
35
|
end
|
@@ -2,6 +2,48 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
require 'puppet/util/monkey_patches'
|
4
4
|
|
5
|
+
describe Dir do
|
6
|
+
describe '.exists?' do
|
7
|
+
it 'returns false if the directory does not exist' do
|
8
|
+
expect(Dir.exists?('/madeupdirectory')).to be false
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'returns true if the directory exists' do
|
12
|
+
expect(Dir.exists?(__dir__)).to be true
|
13
|
+
end
|
14
|
+
|
15
|
+
if RUBY_VERSION >= '3.2'
|
16
|
+
it 'logs a warning message' do
|
17
|
+
expect(Dir).to receive(:warn).with("Dir.exists?('#{__dir__}') is deprecated, use Dir.exist? instead")
|
18
|
+
with_verbose_enabled do
|
19
|
+
Dir.exists?(__dir__)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe File do
|
27
|
+
describe '.exists?' do
|
28
|
+
it 'returns false if the directory does not exist' do
|
29
|
+
expect(File.exists?('spec/unit/util/made_up_file')).to be false
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'returns true if the file exists' do
|
33
|
+
expect(File.exists?(__FILE__)).to be true
|
34
|
+
end
|
35
|
+
|
36
|
+
if RUBY_VERSION >= '3.2'
|
37
|
+
it 'logs a warning message' do
|
38
|
+
expect(File).to receive(:warn).with("File.exists?('#{__FILE__}') is deprecated, use File.exist? instead")
|
39
|
+
with_verbose_enabled do
|
40
|
+
File.exists?(__FILE__)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
5
47
|
describe Symbol do
|
6
48
|
after :all do
|
7
49
|
$unique_warnings.delete('symbol_comparison') if $unique_warnings
|
@@ -95,6 +95,31 @@ describe Puppet::Util::Windows::ADSI, :if => Puppet::Util::Platform.windows? do
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
+
describe '.get_sids' do
|
99
|
+
it 'returns an array of SIDs given two an array of ADSI children' do
|
100
|
+
child1 = double('child1', name: 'Administrator', sid: 'S-1-5-21-3882680660-671291151-3888264257-500')
|
101
|
+
child2 = double('child2', name: 'Guest', sid: 'S-1-5-21-3882680660-671291151-3888264257-501')
|
102
|
+
allow(Puppet::Util::Windows::SID).to receive(:ads_to_principal).with(child1).and_return('Administrator')
|
103
|
+
allow(Puppet::Util::Windows::SID).to receive(:ads_to_principal).with(child2).and_return('Guest')
|
104
|
+
sids = Puppet::Util::Windows::ADSI::ADSIObject.get_sids([child1, child2])
|
105
|
+
expect(sids).to eq(['Administrator', 'Guest'])
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'returns an array of SIDs given an ADSI child and ads_to_principal returning domain failure' do
|
109
|
+
child = double('child1', name: 'Administrator', sid: 'S-1-5-21-3882680660-671291151-3888264257-500')
|
110
|
+
allow(Puppet::Util::Windows::SID).to receive(:ads_to_principal).with(child).and_raise(Puppet::Util::Windows::Error.new('', Puppet::Util::Windows::SID::ERROR_TRUSTED_DOMAIN_FAILURE))
|
111
|
+
sids = Puppet::Util::Windows::ADSI::ADSIObject.get_sids([child])
|
112
|
+
expect(sids[0]).to eq(Puppet::Util::Windows::SID::Principal.new(child.name, child.sid, child.name, nil, :SidTypeUnknown))
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'returns an array of SIDs given an ADSI child and ads_to_principal returning relationship failure' do
|
116
|
+
child = double('child1', name: 'Administrator', sid: 'S-1-5-21-3882680660-671291151-3888264257-500')
|
117
|
+
allow(Puppet::Util::Windows::SID).to receive(:ads_to_principal).with(child).and_raise(Puppet::Util::Windows::Error.new('', Puppet::Util::Windows::SID::ERROR_TRUSTED_RELATIONSHIP_FAILURE))
|
118
|
+
sids = Puppet::Util::Windows::ADSI::ADSIObject.get_sids([child])
|
119
|
+
expect(sids[0]).to eq(Puppet::Util::Windows::SID::Principal.new(child.name, child.sid, child.name, nil, :SidTypeUnknown))
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
98
123
|
describe Puppet::Util::Windows::ADSI::User do
|
99
124
|
let(:username) { 'testuser' }
|
100
125
|
let(:domain) { 'DOMAIN' }
|
@@ -586,6 +586,29 @@ describe Puppet::X509::CertProvider do
|
|
586
586
|
end
|
587
587
|
end
|
588
588
|
|
589
|
+
context 'when creating', :unless => RUBY_PLATFORM == 'java' do
|
590
|
+
context 'requests' do
|
591
|
+
let(:name) { 'tom' }
|
592
|
+
let(:requestdir) { tmpdir('cert_provider') }
|
593
|
+
let(:provider) { create_provider(requestdir: requestdir) }
|
594
|
+
let(:key) { OpenSSL::PKey::RSA.new(Puppet[:keylength]) }
|
595
|
+
|
596
|
+
it 'has the auto-renew attribute by default for agents that support automatic renewal' do
|
597
|
+
csr = provider.create_request(name, key)
|
598
|
+
# need to create CertificateRequest instance from csr in order to view CSR attributes
|
599
|
+
wrapped_csr = Puppet::SSL::CertificateRequest.from_instance csr
|
600
|
+
expect(wrapped_csr.custom_attributes).to include('oid' => 'pp_auth_auto_renew', 'value' => 'true')
|
601
|
+
end
|
602
|
+
|
603
|
+
it 'does not have the auto-renew attribute for agents that do not support automatic renewal' do
|
604
|
+
Puppet[:hostcert_renewal_interval] = 0
|
605
|
+
csr = provider.create_request(name, key)
|
606
|
+
wrapped_csr = Puppet::SSL::CertificateRequest.from_instance csr
|
607
|
+
expect(wrapped_csr.custom_attributes.length).to eq(0)
|
608
|
+
end
|
609
|
+
end
|
610
|
+
end
|
611
|
+
|
589
612
|
context 'CA last update time' do
|
590
613
|
let(:ca_path) { tmpfile('pem_ca') }
|
591
614
|
|
@@ -94,6 +94,10 @@ task(:gen_cert_fixtures) do
|
|
94
94
|
save(dir, 'signed.pem', signed[:cert])
|
95
95
|
save(dir, 'signed-key.pem', signed[:private_key])
|
96
96
|
|
97
|
+
# Create a cert for host "renewed" and issued by "Test CA Subauthority"
|
98
|
+
renewed = ca.create_cert('renewed', inter[:cert], inter[:private_key], reuse_key: signed[:private_key])
|
99
|
+
save(dir, 'renewed.pem', renewed[:cert])
|
100
|
+
|
97
101
|
# Create an encrypted version of the above private key for host "signed"
|
98
102
|
save(dir, 'encrypted-key.pem', signed[:private_key]) do |x509|
|
99
103
|
# private key password was chosen at random
|