Skip to content

Commit c36f718

Browse files
authored
Merge pull request #8057 from joshcooper/report_include_system_store_7737
(PUP-7737) Allow http report processor to trust the system CA store
2 parents f136aea + 3f6ffa8 commit c36f718

File tree

3 files changed

+67
-3
lines changed

3 files changed

+67
-3
lines changed

lib/puppet/defaults.rb

+10
Original file line numberDiff line numberDiff line change
@@ -1795,6 +1795,16 @@ def self.initialize_default_settings!(settings)
17951795
:type => :boolean,
17961796
:desc => "Whether to send reports after every transaction.",
17971797
},
1798+
:report_include_system_store => {
1799+
:default => false,
1800+
:type => :boolean,
1801+
:desc => "Whether the 'http' report processor should include the system
1802+
certificate store when submitting reports to HTTPS URLs. If false, then
1803+
the 'http' processor will only trust HTTPS report servers whose certificates
1804+
are issued by the puppet CA or one of its intermediate CAs. If true, the
1805+
processor will additionally trust CA certificates in the system's
1806+
certificate store."
1807+
},
17981808
:resubmit_facts => {
17991809
:default => false,
18001810
:type => :boolean,

lib/puppet/reports/http.rb

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ def process
2323
options = {
2424
:metric_id => [:puppet, :report, :http],
2525
:body => self.to_yaml,
26+
:include_system_store => Puppet[:report_include_system_store],
2627
}
2728

2829
if url.user && url.password

spec/integration/application/apply_spec.rb

+56-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
require 'puppet_spec/compiler'
44
require 'puppet_spec/https'
55

6-
describe "apply" do
6+
describe "apply", unless: Puppet::Util::Platform.jruby? do
77
include PuppetSpec::Files
88

99
before :each do
@@ -258,7 +258,7 @@ class mod {
258258
expect(@logs.map(&:to_s)).to include(/{environment =>.*/)
259259
end
260260

261-
it "applies a given file even when an ENC is configured", :unless => Puppet::Util::Platform.windows? || RUBY_PLATFORM == 'java' do
261+
it "applies a given file even when an ENC is configured", :unless => Puppet::Util::Platform.windows? || Puppet::Util::Platform.jruby? do
262262
manifest = file_containing("manifest.pp", "notice('specific manifest applied')")
263263
enc = script_containing('enc_script',
264264
:windows => '@echo classes: []' + "\n" + '@echo environment: special',
@@ -379,7 +379,7 @@ def init_cli_args_and_apply_app(args, execute)
379379
# External node script execution will fail, likely due to the tampering
380380
# with the basic file descriptors.
381381
# Workaround: Define a log destination and merely inspect logs.
382-
context "with an ENC", :unless => RUBY_PLATFORM == 'java' do
382+
context "with an ENC" do
383383
let(:logdest) { tmpfile('logdest') }
384384
let(:args) { ['-e', execute, '--logdest', logdest ] }
385385
let(:enc) do
@@ -587,6 +587,14 @@ def bogus()
587587
end
588588

589589
let(:apply) { Puppet::Application[:apply] }
590+
let(:unknown_server) do
591+
unknown_ca_cert = cert_fixture('unknown-ca.pem')
592+
PuppetSpec::HTTPSServer.new(
593+
ca_cert: unknown_ca_cert,
594+
server_cert: cert_fixture('unknown-127.0.0.1.pem'),
595+
server_key: key_fixture('unknown-127.0.0.1-key.pem')
596+
)
597+
end
590598

591599
it 'submits a report via reporturl' do
592600
report = nil
@@ -609,5 +617,50 @@ def bogus()
609617
expect(report.resource_statuses['Notify[hi]']).to be_a(Puppet::Resource::Status)
610618
end
611619
end
620+
621+
it 'rejects an HTTPS report server whose root cert is not the puppet CA' do
622+
unknown_server.start_server do |https_port|
623+
Puppet[:reporturl] = "https://127.0.0.1:#{https_port}/reports/upload"
624+
625+
# processing the report happens after the transaction is finished,
626+
# so we expect exit code 0, with a later failure on stderr
627+
expect {
628+
apply.command_line.args = ['-e', 'notify { "hi": }']
629+
apply.run
630+
}.to exit_with(0)
631+
.and output(/Applied catalog/).to_stdout
632+
.and output(/Report processor failed: certificate verify failed \[self signed certificate in certificate chain for CN=Unknown CA\]/).to_stderr
633+
end
634+
end
635+
636+
it 'accepts an HTTPS report servers whose cert is in the system CA store' do
637+
Puppet[:report_include_system_store] = true
638+
report = nil
639+
640+
response_proc = -> (req, res) {
641+
report = Puppet::Transaction::Report.convert_from(:yaml, req.body)
642+
}
643+
644+
# create a temp cacert bundle
645+
ssl_file = tmpfile('systemstore')
646+
File.write(ssl_file, unknown_server.ca_cert.to_pem)
647+
648+
unknown_server.start_server(response_proc: response_proc) do |https_port|
649+
Puppet[:reporturl] = "https://127.0.0.1:#{https_port}/reports/upload"
650+
651+
# override path to system cacert bundle, this must be done before
652+
# the SSLContext is created and the call to X509::Store.set_default_paths
653+
Puppet::Util.withenv("SSL_CERT_FILE" => ssl_file) do
654+
expect {
655+
apply.command_line.args = ['-e', 'notify { "hi": }']
656+
apply.run
657+
}.to exit_with(0)
658+
.and output(/Applied catalog/).to_stdout
659+
end
660+
661+
expect(report).to be_a(Puppet::Transaction::Report)
662+
expect(report.resource_statuses['Notify[hi]']).to be_a(Puppet::Resource::Status)
663+
end
664+
end
612665
end
613666
end

0 commit comments

Comments
 (0)