puppet 8.0.1-x86-mingw32 → 8.2.0-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CODEOWNERS +5 -5
- data/Gemfile.lock +47 -39
- data/ext/project_data.yaml +1 -1
- data/lib/puppet/defaults.rb +37 -7
- data/lib/puppet/http/client.rb +12 -5
- data/lib/puppet/http/service/ca.rb +32 -2
- data/lib/puppet/node/environment.rb +6 -4
- data/lib/puppet/pops/evaluator/deferred_resolver.rb +20 -3
- data/lib/puppet/ssl/oids.rb +2 -0
- data/lib/puppet/ssl/ssl_provider.rb +1 -1
- data/lib/puppet/ssl/state_machine.rb +143 -14
- data/lib/puppet/thread_local.rb +1 -4
- data/lib/puppet/version.rb +1 -1
- data/lib/puppet/x509/cert_provider.rb +29 -0
- data/locales/puppet.pot +2346 -2310
- data/man/man5/puppet.conf.5 +31 -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 +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 +1 -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 +63 -13
- data/spec/integration/application/apply_spec.rb +14 -0
- data/spec/integration/http/client_spec.rb +16 -0
- data/spec/lib/puppet/test_ca.rb +3 -10
- data/spec/unit/application/lookup_spec.rb +1 -0
- data/spec/unit/defaults_spec.rb +2 -40
- data/spec/unit/file_system/path_pattern_spec.rb +15 -0
- data/spec/unit/http/service/ca_spec.rb +83 -0
- data/spec/unit/ssl/ssl_provider_spec.rb +20 -0
- data/spec/unit/ssl/state_machine_spec.rb +143 -3
- data/spec/unit/x509/cert_provider_spec.rb +49 -0
- data/tasks/generate_cert_fixtures.rake +4 -0
- metadata +5 -9
    
        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
         | 
| @@ -95,6 +95,18 @@ describe Puppet::HTTP::Service::Ca do | |
| 95 95 | 
             
                    expect(err.response.code).to eq(404)
         | 
| 96 96 | 
             
                  end
         | 
| 97 97 | 
             
                end
         | 
| 98 | 
            +
             | 
| 99 | 
            +
                it 'raises a 304 response error if it is unmodified' do
         | 
| 100 | 
            +
                  stub_request(:get, url).to_return(status: [304, 'Not Modified'])
         | 
| 101 | 
            +
             | 
| 102 | 
            +
                  expect {
         | 
| 103 | 
            +
                    subject.get_certificate('ca', if_modified_since: Time.now)
         | 
| 104 | 
            +
                  }.to raise_error do |err|
         | 
| 105 | 
            +
                    expect(err).to be_an_instance_of(Puppet::HTTP::ResponseError)
         | 
| 106 | 
            +
                    expect(err.message).to eq("Not Modified")
         | 
| 107 | 
            +
                    expect(err.response.code).to eq(304)
         | 
| 108 | 
            +
                  end
         | 
| 109 | 
            +
                end
         | 
| 98 110 | 
             
              end
         | 
| 99 111 |  | 
| 100 112 | 
             
              context 'when getting CRLs' do
         | 
| @@ -195,4 +207,75 @@ describe Puppet::HTTP::Service::Ca do | |
| 195 207 | 
             
                  end
         | 
| 196 208 | 
             
                end
         | 
| 197 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
         | 
| 198 281 | 
             
            end
         | 
| @@ -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
         | 
| @@ -30,7 +30,9 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do | |
| 30 30 | 
             
                Puppet[:daemonize] = false
         | 
| 31 31 | 
             
                Puppet[:ssl_lockfile] = tmpfile('ssllock')
         | 
| 32 32 | 
             
                allow(Kernel).to receive(:sleep)
         | 
| 33 | 
            -
                 | 
| 33 | 
            +
                future = Time.now + (5 * 60)
         | 
| 34 | 
            +
                allow_any_instance_of(Puppet::X509::CertProvider).to receive(:crl_last_update).and_return(future)
         | 
| 35 | 
            +
                allow_any_instance_of(Puppet::X509::CertProvider).to receive(:ca_last_update).and_return(future)
         | 
| 34 36 | 
             
              end
         | 
| 35 37 |  | 
| 36 38 | 
             
              def expected_digest(name, content)
         | 
| @@ -396,6 +398,16 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do | |
| 396 398 | 
             
                  expect(File).to_not exist(Puppet[:localcacert])
         | 
| 397 399 | 
             
                end
         | 
| 398 400 |  | 
| 401 | 
            +
                it 'skips CA refresh if it has not expired' do
         | 
| 402 | 
            +
                  Puppet[:ca_refresh_interval] = '1y'
         | 
| 403 | 
            +
                  Puppet::FileSystem.touch(Puppet[:localcacert], mtime: Time.now)
         | 
| 404 | 
            +
             | 
| 405 | 
            +
                  allow_any_instance_of(Puppet::X509::CertProvider).to receive(:load_cacerts).and_return(cacerts)
         | 
| 406 | 
            +
             | 
| 407 | 
            +
                  # we're expecting a net/http request to never be made
         | 
| 408 | 
            +
                  state.next_state
         | 
| 409 | 
            +
                end
         | 
| 410 | 
            +
             | 
| 399 411 | 
             
                context 'when verifying CA cert bundle' do
         | 
| 400 412 | 
             
                  before :each do
         | 
| 401 413 | 
             
                    allow(cert_provider).to receive(:load_cacerts).and_return(nil)
         | 
| @@ -436,6 +448,69 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do | |
| 436 448 | 
             
                    expect(st.message).to eq("CA bundle with digest (SHA256) #{fingerprint} did not match expected digest WR:ON:G!")
         | 
| 437 449 | 
             
                  end
         | 
| 438 450 | 
             
                end
         | 
| 451 | 
            +
             | 
| 452 | 
            +
                context 'when refreshing a CA bundle' do
         | 
| 453 | 
            +
                  before :each do
         | 
| 454 | 
            +
                    Puppet[:ca_refresh_interval] = '1s'
         | 
| 455 | 
            +
                    allow_any_instance_of(Puppet::X509::CertProvider).to receive(:load_cacerts).and_return(cacerts)
         | 
| 456 | 
            +
             | 
| 457 | 
            +
                    yesterday = Time.now - (24 * 60 * 60)
         | 
| 458 | 
            +
                    allow_any_instance_of(Puppet::X509::CertProvider).to receive(:ca_last_update).and_return(yesterday)
         | 
| 459 | 
            +
                  end
         | 
| 460 | 
            +
             | 
| 461 | 
            +
                  let(:new_ca_bundle) do
         | 
| 462 | 
            +
                    # add 'unknown' cert to the bundle
         | 
| 463 | 
            +
                    [cacert, cert_fixture('intermediate.pem'), cert_fixture('unknown-ca.pem')].map(&:to_pem)
         | 
| 464 | 
            +
                  end
         | 
| 465 | 
            +
             | 
| 466 | 
            +
                  it 'uses the local CA if it has not been modified' do
         | 
| 467 | 
            +
                    stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 304)
         | 
| 468 | 
            +
             | 
| 469 | 
            +
                    expect(state.next_state.ssl_context.cacerts).to eq(cacerts)
         | 
| 470 | 
            +
                  end
         | 
| 471 | 
            +
             | 
| 472 | 
            +
                  it 'uses the local CA if refreshing fails in HTTP layer' do
         | 
| 473 | 
            +
                    stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 503)
         | 
| 474 | 
            +
             | 
| 475 | 
            +
                    expect(state.next_state.ssl_context.cacerts).to eq(cacerts)
         | 
| 476 | 
            +
                  end
         | 
| 477 | 
            +
             | 
| 478 | 
            +
                  it 'uses the local CA if refreshing fails in TCP layer' do
         | 
| 479 | 
            +
                    stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_raise(Errno::ECONNREFUSED)
         | 
| 480 | 
            +
             | 
| 481 | 
            +
                    expect(state.next_state.ssl_context.cacerts).to eq(cacerts)
         | 
| 482 | 
            +
                  end
         | 
| 483 | 
            +
             | 
| 484 | 
            +
                  it 'uses the updated crl for the future requests' do
         | 
| 485 | 
            +
                    stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 200, body: new_ca_bundle.join)
         | 
| 486 | 
            +
             | 
| 487 | 
            +
                    expect(state.next_state.ssl_context.cacerts.map(&:to_pem)).to eq(new_ca_bundle)
         | 
| 488 | 
            +
                  end
         | 
| 489 | 
            +
             | 
| 490 | 
            +
                  it 'updates the `last_update` time on successful CA refresh' do
         | 
| 491 | 
            +
                    stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 200, body: new_ca_bundle.join)
         | 
| 492 | 
            +
             | 
| 493 | 
            +
                    expect_any_instance_of(Puppet::X509::CertProvider).to receive(:ca_last_update=).with(be_within(60).of(Time.now))
         | 
| 494 | 
            +
             | 
| 495 | 
            +
                    state.next_state
         | 
| 496 | 
            +
                  end
         | 
| 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 | 
            +
             | 
| 506 | 
            +
                  it 'forces the NeedCRLs to refresh' do
         | 
| 507 | 
            +
                    stub_request(:get, %r{puppet-ca/v1/certificate/ca}).to_return(status: 200, body: new_ca_bundle.join)
         | 
| 508 | 
            +
             | 
| 509 | 
            +
                    st = state.next_state
         | 
| 510 | 
            +
                    expect(st).to be_an_instance_of(Puppet::SSL::StateMachine::NeedCRLs)
         | 
| 511 | 
            +
                    expect(st.force_crl_refresh).to eq(true)
         | 
| 512 | 
            +
                  end
         | 
| 513 | 
            +
                end
         | 
| 439 514 | 
             
              end
         | 
| 440 515 |  | 
| 441 516 | 
             
              context 'NeedCRLs' do
         | 
| @@ -533,6 +608,7 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do | |
| 533 608 |  | 
| 534 609 | 
             
                  allow_any_instance_of(Puppet::X509::CertProvider).to receive(:load_crls).and_return(crls)
         | 
| 535 610 |  | 
| 611 | 
            +
                  # we're expecting a net/http request to never be made
         | 
| 536 612 | 
             
                  state.next_state
         | 
| 537 613 | 
             
                end
         | 
| 538 614 |  | 
| @@ -669,6 +745,26 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do | |
| 669 745 | 
             
                      state.next_state
         | 
| 670 746 | 
             
                    }.to raise_error(OpenSSL::PKey::RSAError)
         | 
| 671 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
         | 
| 672 768 | 
             
                end
         | 
| 673 769 |  | 
| 674 770 | 
             
                context 'in state NeedSubmitCSR' do
         | 
| @@ -710,7 +806,7 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do | |
| 710 806 | 
             
                    state.next_state
         | 
| 711 807 | 
             
                  end
         | 
| 712 808 |  | 
| 713 | 
            -
                  it 'includes CSR attributes' do
         | 
| 809 | 
            +
                  it 'includes CSR attributes', :unless => RUBY_PLATFORM == 'java' do
         | 
| 714 810 | 
             
                    Puppet[:csr_attributes] = write_csr_attributes(
         | 
| 715 811 | 
             
                      'custom_attributes' => {
         | 
| 716 812 | 
             
                          '1.3.6.1.4.1.34380.1.2.1' => 'CSR specific info',
         | 
| @@ -724,7 +820,8 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do | |
| 724 820 | 
             
                        csr.custom_attributes
         | 
| 725 821 | 
             
                      ).to contain_exactly(
         | 
| 726 822 | 
             
                             {'oid' => '1.3.6.1.4.1.34380.1.2.1', 'value' => 'CSR specific info'},
         | 
| 727 | 
            -
                             {'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'}
         | 
| 728 825 | 
             
                           )
         | 
| 729 826 | 
             
                    end.to_return(status: 200)
         | 
| 730 827 |  | 
| @@ -973,5 +1070,48 @@ describe Puppet::SSL::StateMachine, unless: Puppet::Util::Platform.jruby? do | |
| 973 1070 | 
             
                    expect(state.next_state).to be_an_instance_of(Puppet::SSL::StateMachine::LockFailure)
         | 
| 974 1071 | 
             
                  end
         | 
| 975 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
         | 
| 976 1116 | 
             
              end
         | 
| 977 1117 | 
             
            end
         | 
| @@ -586,6 +586,55 @@ 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 | 
            +
             | 
| 612 | 
            +
              context 'CA last update time' do
         | 
| 613 | 
            +
                let(:ca_path) { tmpfile('pem_ca') }
         | 
| 614 | 
            +
             | 
| 615 | 
            +
                it 'returns nil if the CA does not exist' do
         | 
| 616 | 
            +
                  provider = create_provider(capath: '/does/not/exist')
         | 
| 617 | 
            +
             | 
| 618 | 
            +
                  expect(provider.ca_last_update).to be_nil
         | 
| 619 | 
            +
                end
         | 
| 620 | 
            +
             | 
| 621 | 
            +
                it 'returns the last update time' do
         | 
| 622 | 
            +
                  time = Time.now - 30
         | 
| 623 | 
            +
                  Puppet::FileSystem.touch(ca_path, mtime: time)
         | 
| 624 | 
            +
                  provider = create_provider(capath: ca_path)
         | 
| 625 | 
            +
             | 
| 626 | 
            +
                  expect(provider.ca_last_update).to be_within(1).of(time)
         | 
| 627 | 
            +
                end
         | 
| 628 | 
            +
             | 
| 629 | 
            +
                it 'sets the last update time' do
         | 
| 630 | 
            +
                  time = Time.now - 30
         | 
| 631 | 
            +
                  provider = create_provider(capath: ca_path)
         | 
| 632 | 
            +
                  provider.ca_last_update = time
         | 
| 633 | 
            +
             | 
| 634 | 
            +
                  expect(Puppet::FileSystem.stat(ca_path).mtime).to be_within(1).of(time)
         | 
| 635 | 
            +
                end
         | 
| 636 | 
            +
              end
         | 
| 637 | 
            +
             | 
| 589 638 | 
             
              context 'CRL last update time' do
         | 
| 590 639 | 
             
                let(:crl_path) { tmpfile('pem_crls') }
         | 
| 591 640 |  | 
| @@ -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
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: puppet
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 8.0 | 
| 4 | 
            +
              version: 8.2.0
         | 
| 5 5 | 
             
            platform: x86-mingw32
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Puppet Labs
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2023- | 
| 11 | 
            +
            date: 2023-08-22 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: facter
         | 
| @@ -113,9 +113,6 @@ dependencies: | |
| 113 113 | 
             
                - - "~>"
         | 
| 114 114 | 
             
                  - !ruby/object:Gem::Version
         | 
| 115 115 | 
             
                    version: '1.0'
         | 
| 116 | 
            -
                - - "<"
         | 
| 117 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 118 | 
            -
                    version: 1.2.0
         | 
| 119 116 | 
             
              type: :runtime
         | 
| 120 117 | 
             
              prerelease: false
         | 
| 121 118 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| @@ -123,9 +120,6 @@ dependencies: | |
| 123 120 | 
             
                - - "~>"
         | 
| 124 121 | 
             
                  - !ruby/object:Gem::Version
         | 
| 125 122 | 
             
                    version: '1.0'
         | 
| 126 | 
            -
                - - "<"
         | 
| 127 | 
            -
                  - !ruby/object:Gem::Version
         | 
| 128 | 
            -
                    version: 1.2.0
         | 
| 129 123 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 130 124 | 
             
              name: deep_merge
         | 
| 131 125 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -1366,6 +1360,7 @@ files: | |
| 1366 1360 | 
             
            - spec/fixtures/ssl/oid.pem
         | 
| 1367 1361 | 
             
            - spec/fixtures/ssl/pluto-key.pem
         | 
| 1368 1362 | 
             
            - spec/fixtures/ssl/pluto.pem
         | 
| 1363 | 
            +
            - spec/fixtures/ssl/renewed.pem
         | 
| 1369 1364 | 
             
            - spec/fixtures/ssl/request-key.pem
         | 
| 1370 1365 | 
             
            - spec/fixtures/ssl/request.pem
         | 
| 1371 1366 | 
             
            - spec/fixtures/ssl/revoked-key.pem
         | 
| @@ -2557,7 +2552,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement | |
| 2557 2552 | 
             
                - !ruby/object:Gem::Version
         | 
| 2558 2553 | 
             
                  version: 1.3.1
         | 
| 2559 2554 | 
             
            requirements: []
         | 
| 2560 | 
            -
            rubygems_version: 3. | 
| 2555 | 
            +
            rubygems_version: 3.4.12
         | 
| 2561 2556 | 
             
            signing_key: 
         | 
| 2562 2557 | 
             
            specification_version: 4
         | 
| 2563 2558 | 
             
            summary: Puppet, an automated configuration management tool
         | 
| @@ -2629,6 +2624,7 @@ test_files: | |
| 2629 2624 | 
             
            - spec/fixtures/ssl/oid.pem
         | 
| 2630 2625 | 
             
            - spec/fixtures/ssl/pluto-key.pem
         | 
| 2631 2626 | 
             
            - spec/fixtures/ssl/pluto.pem
         | 
| 2627 | 
            +
            - spec/fixtures/ssl/renewed.pem
         | 
| 2632 2628 | 
             
            - spec/fixtures/ssl/request-key.pem
         | 
| 2633 2629 | 
             
            - spec/fixtures/ssl/request.pem
         | 
| 2634 2630 | 
             
            - spec/fixtures/ssl/revoked-key.pem
         |