Skip to content

Commit 9ff70a2

Browse files
committed
Revert "Merge pull request #8809 from joshcooper/revert_35121d8b87"
This reverts commit 845033b, reversing changes made to 3b2acd0.
1 parent 047c84e commit 9ff70a2

File tree

16 files changed

+277
-15
lines changed

16 files changed

+277
-15
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
test_name "agent run should fail if it finds an unknown resource type" do
2+
tag 'audit:high',
3+
'audit:integration'
4+
5+
require 'puppet/acceptance/common_utils'
6+
7+
require 'puppet/acceptance/environment_utils'
8+
extend Puppet::Acceptance::EnvironmentUtils
9+
10+
require 'puppet/acceptance/temp_file_utils'
11+
extend Puppet::Acceptance::TempFileUtils
12+
13+
step "agent should fail when it can't find a resource" do
14+
vendor_modules_path = master.tmpdir('vendor_modules')
15+
tmp_environment = mk_tmp_environment_with_teardown(master, 'tmp')
16+
17+
site_pp_content = <<-SITEPP
18+
define foocreateresource($one) {
19+
$msg = 'hello'
20+
notify { $name: message => $msg }
21+
}
22+
class example($x) {
23+
if $x == undef or $x == [] or $x == '' {
24+
notice 'foo'
25+
return()
26+
}
27+
notice 'bar'
28+
}
29+
node default {
30+
class { example: x => [] }
31+
create_resources('foocreateresource', {'blah'=>{'one'=>'two'}})
32+
mycustomtype{'foobar':}
33+
}
34+
SITEPP
35+
manifests_path = "/tmp/#{tmp_environment}/manifests"
36+
on(master, "mkdir -p '#{manifests_path}'")
37+
create_remote_file(master, "#{manifests_path}/site.pp", site_pp_content)
38+
39+
custom_type_content = <<-CUSTOMTYPE
40+
Puppet::Type.newtype(:mycustomtype) do
41+
@doc = "Create a new mycustomtype thing."
42+
43+
newparam(:name, :namevar => true) do
44+
desc "Name of mycustomtype instance"
45+
end
46+
47+
def refresh
48+
end
49+
end
50+
CUSTOMTYPE
51+
type_path = "#{vendor_modules_path}/foo/lib/puppet/type"
52+
on(master, "mkdir -p '#{type_path}'")
53+
create_remote_file(master, "#{type_path}/mycustomtype.rb", custom_type_content)
54+
55+
on(master, "chmod -R 750 '#{vendor_modules_path}' '/tmp/#{tmp_environment}'")
56+
on(master, "chown -R #{master.puppet['user']}:#{master.puppet['group']} '#{vendor_modules_path}' '/tmp/#{tmp_environment}'")
57+
58+
master_opts = {
59+
'main' => {
60+
'environment' => tmp_environment,
61+
'vendormoduledir' => vendor_modules_path
62+
}
63+
}
64+
65+
with_puppet_running_on(master, master_opts) do
66+
agents.each do |agent|
67+
teardown do
68+
agent.rm_rf(vendor_modules_path)
69+
end
70+
71+
on(agent, puppet('agent', '-t', '--environment', tmp_environment), acceptable_exit_codes: [1]) do |result|
72+
assert_match(/Error: Failed to apply catalog: Resource type 'Mycustomtype' was not found/, result.stderr)
73+
end
74+
end
75+
end
76+
end
77+
end

Diff for: api/schemas/catalog.json

+3
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@
4545
"line": {
4646
"type": "integer"
4747
},
48+
"kind": {
49+
"type": "string"
50+
},
4851
"file": {
4952
"type": "string"
5053
},

Diff for: benchmarks/serialization/catalog.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@
118118
"version": 1492108311,
119119
"code_id": null,
120120
"catalog_uuid": "c85cdf7e-f56d-4fc7-b513-3a00532cee91",
121-
"catalog_format": 1,
121+
"catalog_format": 2,
122122
"environment": "production",
123123
"resources": [
124124
{

Diff for: lib/puppet/defaults.rb

+6
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,12 @@ def self.initialize_default_settings!(settings)
761761
:owner => "service",
762762
:group => "service",
763763
:desc => "The directory where catalog previews per node are generated."
764+
},
765+
:location_trusted => {
766+
:default => false,
767+
:type => :boolean,
768+
:desc => "This will allow sending the name + password and the cookie header to all hosts that puppet may redirect to.
769+
This may or may not introduce a security breach if puppet redirects you to a site to which you'll send your authentication info and cookies."
764770
}
765771
)
766772

Diff for: lib/puppet/http/client.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ def execute_streaming(request, options: {}, &block)
346346

347347
while !done do
348348
connect(request.uri, options: options) do |http|
349-
apply_auth(request, basic_auth)
349+
apply_auth(request, basic_auth) if redirects.zero?
350350

351351
# don't call return within the `request` block
352352
http.request(request) do |nethttp|

Diff for: lib/puppet/http/redirector.rb

+5
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ def redirect_to(request, response, redirects)
4949
new_request = request.class.new(url)
5050
new_request.body = request.body
5151
request.each do |header, value|
52+
unless Puppet[:location_trusted]
53+
# skip adding potentially sensitive header to other hosts
54+
next if header.casecmp('Authorization').zero? && request.uri.host.casecmp(location.host) != 0
55+
next if header.casecmp('Cookie').zero? && request.uri.host.casecmp(location.host) != 0
56+
end
5257
new_request[header] = value
5358
end
5459

Diff for: lib/puppet/parser/resource.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ class Puppet::Parser::Resource < Puppet::Resource
1313

1414
attr_accessor :source, :scope, :collector_id
1515
attr_accessor :virtual, :override, :translated, :catalog, :evaluated
16-
attr_accessor :file, :line
16+
attr_accessor :file, :line, :kind
1717

1818
attr_reader :exported, :parameters
1919

Diff for: lib/puppet/pops/evaluator/runtime3_resource_support.rb

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ def self.create_resources(file, line, scope, virtual, exported, type_name, resou
4040
:parameters => evaluated_parameters,
4141
:file => file,
4242
:line => line,
43+
:kind => Puppet::Resource.to_kind(resolved_type),
4344
:exported => exported,
4445
:virtual => virtual,
4546
# WTF is this? Which source is this? The file? The name of the context ?

Diff for: lib/puppet/resource.rb

+38-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class Puppet::Resource
1111
include Puppet::Util::PsychSupport
1212

1313
include Enumerable
14-
attr_accessor :file, :line, :catalog, :exported, :virtual, :strict
14+
attr_accessor :file, :line, :catalog, :exported, :virtual, :strict, :kind
1515
attr_reader :type, :title, :parameters
1616

1717
# @!attribute [rw] sensitive_parameters
@@ -29,10 +29,15 @@ class Puppet::Resource
2929
EMPTY_ARRAY = [].freeze
3030
EMPTY_HASH = {}.freeze
3131

32-
ATTRIBUTES = [:file, :line, :exported].freeze
32+
ATTRIBUTES = [:file, :line, :exported, :kind].freeze
3333
TYPE_CLASS = 'Class'.freeze
3434
TYPE_NODE = 'Node'.freeze
3535

36+
CLASS_STRING = 'class'.freeze
37+
DEFINED_TYPE_STRING = 'defined_type'.freeze
38+
COMPILABLE_TYPE_STRING = 'compilable_type'.freeze
39+
UNKNOWN_TYPE_STRING = 'unknown'.freeze
40+
3641
PCORE_TYPE_KEY = '__ptype'.freeze
3742
VALUE_KEY = 'value'.freeze
3843

@@ -193,6 +198,18 @@ def builtin_type?
193198
resource_type.is_a?(Puppet::CompilableResourceType)
194199
end
195200

201+
def self.to_kind(resource_type)
202+
if resource_type == CLASS_STRING
203+
CLASS_STRING
204+
elsif resource_type.is_a?(Puppet::Resource::Type) && resource_type.type == :definition
205+
DEFINED_TYPE_STRING
206+
elsif resource_type.is_a?(Puppet::CompilableResourceType)
207+
COMPILABLE_TYPE_STRING
208+
else
209+
UNKNOWN_TYPE_STRING
210+
end
211+
end
212+
196213
# Iterate over each param/value pair, as required for Enumerable.
197214
def each
198215
parameters.each { |p,v| yield p, v }
@@ -247,6 +264,7 @@ def initialize(type, title = nil, attributes = EMPTY_HASH)
247264
src = type
248265
self.file = src.file
249266
self.line = src.line
267+
self.kind = src.kind
250268
self.exported = src.exported
251269
self.virtual = src.virtual
252270
self.set_tags(src)
@@ -309,6 +327,7 @@ def initialize(type, title = nil, attributes = EMPTY_HASH)
309327

310328
rt = resource_type
311329

330+
self.kind = self.class.to_kind(rt) unless kind
312331
if strict? && rt.nil?
313332
if self.class?
314333
raise ArgumentError, _("Could not find declared class %{title}") % { title: title }
@@ -468,10 +487,24 @@ def to_ref
468487
ref
469488
end
470489

471-
# Convert our resource to a RAL resource instance. Creates component
472-
# instances for resource types that don't exist.
490+
# Convert our resource to a RAL resource instance. Creates component
491+
# instances for resource types that are not of a compilable_type kind. In case
492+
# the resource doesn’t exist and it’s compilable_type kind, raise an error.
493+
# There are certain cases where a resource won't be in a catalog, such as
494+
# when we create a resource directly by using Puppet::Resource.new(...), so we
495+
# must check its kind before deciding whether the catalog format is of an older
496+
# version or not.
473497
def to_ral
474-
typeklass = Puppet::Type.type(self.type) || Puppet::Type.type(:component)
498+
if self.kind == COMPILABLE_TYPE_STRING
499+
typeklass = Puppet::Type.type(self.type)
500+
elsif self.catalog && self.catalog.catalog_format >= 2
501+
typeklass = Puppet::Type.type(:component)
502+
else
503+
typeklass = Puppet::Type.type(self.type) || Puppet::Type.type(:component)
504+
end
505+
506+
raise(Puppet::Error, "Resource type '#{self.type}' was not found") unless typeklass
507+
475508
typeklass.new(self)
476509
end
477510

Diff for: lib/puppet/resource/catalog.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ def initialize(name = nil, environment = Puppet::Node::Environment::NONE, code_i
313313
super()
314314
@name = name
315315
@catalog_uuid = SecureRandom.uuid
316-
@catalog_format = 1
316+
@catalog_format = 2
317317
@metadata = {}
318318
@recursive_metadata = {}
319319
@classes = []

Diff for: spec/fixtures/integration/application/agent/cached_deferred_catalog.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"version": 1607629733,
77
"code_id": null,
88
"catalog_uuid": "afc8472a-306b-4b24-b060-e956dffb79b8",
9-
"catalog_format": 1,
9+
"catalog_format": 2,
1010
"environment": "production",
1111
"resources": [
1212
{
@@ -50,6 +50,7 @@
5050
],
5151
"file": "",
5252
"line": 1,
53+
"kind": "compilable_type",
5354
"exported": false,
5455
"parameters": {
5556
"message": {

Diff for: spec/integration/parser/pcore_resource_spec.rb

+10
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,16 @@ def self.title_patterns
122122
expect(catalog.resource(:test3, "x/y")['message']).to eq('x/y works')
123123
end
124124

125+
it 'considers Pcore types to be builtin ' do
126+
genface.types
127+
catalog = compile_to_catalog(<<-MANIFEST)
128+
test1 { 'a':
129+
message => 'a works'
130+
}
131+
MANIFEST
132+
expect(catalog.resource(:test1, "a").kind).to eq('compilable_type')
133+
end
134+
125135
it 'the validity of attribute names are checked' do
126136
genface.types
127137
expect do

Diff for: spec/unit/configurer_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -879,7 +879,7 @@ def expects_neither_new_or_cached_catalog
879879
expect(configurer.run).to be_nil
880880
end
881881

882-
it "should proceed with the cached catalog if its environment matchs the local environment" do
882+
it "should proceed with the cached catalog if its environment matches the local environment" do
883883
expects_cached_catalog_only(catalog)
884884

885885
expect(configurer.run).to eq(0)

Diff for: spec/unit/http/client_spec.rb

+58-1
Original file line numberDiff line numberDiff line change
@@ -597,11 +597,68 @@ def redirect_to(status: 302, url:)
597597
expect(response).to be_success
598598
end
599599

600-
it "preserves basic authorization" do
600+
it "does not preserve basic authorization when redirecting to different hosts" do
601+
stub_request(:get, start_url).with(basic_auth: credentials).to_return(redirect_to(url: other_host))
602+
stub_request(:get, other_host).to_return(status: 200)
603+
604+
client.get(start_url, options: {basic_auth: {user: 'user', password: 'pass'}})
605+
expect(a_request(:get, other_host).
606+
with{ |req| !req.headers.key?('Authorization')}).to have_been_made
607+
end
608+
609+
it "does preserve basic authorization when redirecting to the same hosts" do
610+
stub_request(:get, start_url).with(basic_auth: credentials).to_return(redirect_to(url: bar_url))
611+
stub_request(:get, bar_url).with(basic_auth: credentials).to_return(status: 200)
612+
613+
client.get(start_url, options: {basic_auth: {user: 'user', password: 'pass'}})
614+
expect(a_request(:get, bar_url).
615+
with{ |req| req.headers.key?('Authorization')}).to have_been_made
616+
end
617+
618+
it "does not preserve cookie header when redirecting to different hosts" do
619+
headers = { 'Cookie' => 'TEST_COOKIE'}
620+
621+
stub_request(:get, start_url).with(headers: headers).to_return(redirect_to(url: other_host))
622+
stub_request(:get, other_host).to_return(status: 200)
623+
624+
client.get(start_url, headers: headers)
625+
expect(a_request(:get, other_host).
626+
with{ |req| !req.headers.key?('Cookie')}).to have_been_made
627+
end
628+
629+
it "does preserve cookie header when redirecting to the same hosts" do
630+
headers = { 'Cookie' => 'TEST_COOKIE'}
631+
632+
stub_request(:get, start_url).with(headers: headers).to_return(redirect_to(url: bar_url))
633+
stub_request(:get, bar_url).with(headers: headers).to_return(status: 200)
634+
635+
client.get(start_url, headers: headers)
636+
expect(a_request(:get, bar_url).
637+
with{ |req| req.headers.key?('Cookie')}).to have_been_made
638+
end
639+
640+
it "does preserves cookie header and basic authentication when Puppet[:location_trusted] is true redirecting to different hosts" do
641+
headers = { 'cookie' => 'TEST_COOKIE'}
642+
Puppet[:location_trusted] = true
643+
644+
stub_request(:get, start_url).with(headers: headers, basic_auth: credentials).to_return(redirect_to(url: other_host))
645+
stub_request(:get, other_host).with(headers: headers, basic_auth: credentials).to_return(status: 200)
646+
647+
client.get(start_url, headers: headers, options: {basic_auth: {user: 'user', password: 'pass'}})
648+
expect(a_request(:get, other_host).
649+
with{ |req| req.headers.key?('Authorization') && req.headers.key?('Cookie')}).to have_been_made
650+
end
651+
652+
it "treats hosts as case-insensitive" do
653+
start_url = URI("https://www.EXAmple.com:8140/Start")
654+
bar_url = "https://www.example.com:8140/bar"
655+
601656
stub_request(:get, start_url).with(basic_auth: credentials).to_return(redirect_to(url: bar_url))
602657
stub_request(:get, bar_url).with(basic_auth: credentials).to_return(status: 200)
603658

604659
client.get(start_url, options: {basic_auth: {user: 'user', password: 'pass'}})
660+
expect(a_request(:get, bar_url).
661+
with{ |req| req.headers.key?('Authorization')}).to have_been_made
605662
end
606663

607664
it "redirects given a relative location" do

Diff for: spec/unit/resource/catalog_spec.rb

+14-1
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104

105105
it "should include the current catalog_format" do
106106
catalog = Puppet::Resource::Catalog.new("host")
107-
expect(catalog.catalog_format).to eq(1)
107+
expect(catalog.catalog_format).to eq(2)
108108
end
109109

110110
describe "when compiling" do
@@ -178,6 +178,7 @@
178178
@original.add_edge(@middle, @bottom)
179179
@original.add_edge(@bottom, @bottomobject)
180180

181+
@original.catalog_format = 1
181182
@catalog = @original.to_ral
182183
end
183184

@@ -190,6 +191,18 @@
190191
end
191192
end
192193

194+
it "should raise if an unknown resource is being converted" do
195+
@new_res = Puppet::Resource.new "Unknown", "type", :kind => 'compilable_type'
196+
@resource_array = [@new_res]
197+
198+
@original.add_resource(*@resource_array)
199+
@original.add_edge(@bottomobject, @new_res)
200+
201+
@original.catalog_format = 2
202+
203+
expect { @original.to_ral }.to raise_error(Puppet::Error, "Resource type 'Unknown' was not found")
204+
end
205+
193206
it "should copy the tag list to the new catalog" do
194207
expect(@catalog.tags.sort).to eq(@original.tags.sort)
195208
end

0 commit comments

Comments
 (0)