Skip to content

Commit

Permalink
Always use the local file_bucket on master
Browse files Browse the repository at this point in the history
This fixes an issue where the master could be made to issue arbitrary
HTTPS requests through carefully constructed URLs. Now the master will
always use the file_bucket, whereas other applications retain their
behavior of dynamically selecting the source (rest or file) based on the
particular request.
  • Loading branch information
nicklewis committed Jun 27, 2012
1 parent 29ae87d commit e7ef153
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 11 deletions.
2 changes: 2 additions & 0 deletions lib/puppet/application/master.rb
Expand Up @@ -144,6 +144,8 @@ def setup
Puppet::FileServing::Content.indirection.terminus_class = :file_server
Puppet::FileServing::Metadata.indirection.terminus_class = :file_server

Puppet::FileBucket::File.indirection.terminus_class = :file

# Configure all of the SSL stuff.
if Puppet::SSL::CertificateAuthority.ca?
Puppet::SSL::Host.ca_location = :local
Expand Down
3 changes: 1 addition & 2 deletions lib/puppet/file_bucket/file.rb
Expand Up @@ -8,8 +8,7 @@ class Puppet::FileBucket::File
# There are mechanisms to save and load this file locally and remotely in puppet/indirector/filebucketfile/*
# There is a compatibility class that emulates pre-indirector filebuckets in Puppet::FileBucket::Dipper
extend Puppet::Indirector
require 'puppet/file_bucket/file/indirection_hooks'
indirects :file_bucket_file, :terminus_class => :file, :extend => Puppet::FileBucket::File::IndirectionHooks
indirects :file_bucket_file, :terminus_class => :selector

attr :contents
attr :bucket_path
Expand Down
9 changes: 0 additions & 9 deletions lib/puppet/file_bucket/file/indirection_hooks.rb

This file was deleted.

49 changes: 49 additions & 0 deletions lib/puppet/indirector/file_bucket_file/selector.rb
@@ -0,0 +1,49 @@
require 'puppet/indirector/code'

module Puppet::FileBucketFile
class Selector < Puppet::Indirector::Code
desc "Select the terminus based on the request"

def select(request)
if request.protocol == 'https'
:rest
else
:file
end
end

def get_terminus(request)
indirection.terminus(select(request))
end

def head(request)
get_terminus(request).head(request)
end

def find(request)
get_terminus(request).find(request)
end

def save(request)
get_terminus(request).save(request)
end

def search(request)
get_terminus(request).search(request)
end

def destroy(request)
get_terminus(request).destroy(request)
end

def authorized?(request)
terminus = get_terminus(request)
if terminus.respond_to?(:authorized?)
terminus.authorized?(request)
else
true
end
end
end
end

44 changes: 44 additions & 0 deletions spec/integration/file_bucket/file_spec.rb
@@ -0,0 +1,44 @@
#!/usr/bin/env rspec

require 'spec_helper'

require 'puppet/file_bucket/file'

describe Puppet::FileBucket::File do
describe "#indirection" do
before :each do
# Never connect to the network, no matter what
described_class.indirection.terminus(:rest).class.any_instance.stubs(:find)
end

describe "when running the master application" do
before :each do
Puppet::Application[:master].setup_terminuses
end

{
"md5/d41d8cd98f00b204e9800998ecf8427e" => :file,
"https://puppetmaster:8140/production/file_bucket_file/md5/d41d8cd98f00b204e9800998ecf8427e" => :file,
}.each do |key, terminus|
it "should use the #{terminus} terminus when requesting #{key.inspect}" do
described_class.indirection.terminus(terminus).class.any_instance.expects(:find)

described_class.indirection.find(key)
end
end
end

describe "when running another application" do
{
"md5/d41d8cd98f00b204e9800998ecf8427e" => :file,
"https://puppetmaster:8140/production/file_bucket_file/md5/d41d8cd98f00b204e9800998ecf8427e" => :rest,
}.each do |key, terminus|
it "should use the #{terminus} terminus when requesting #{key.inspect}" do
described_class.indirection.terminus(terminus).class.any_instance.expects(:find)

described_class.indirection.find(key)
end
end
end
end
end
29 changes: 29 additions & 0 deletions spec/unit/indirector/file_bucket_file/selector_spec.rb
@@ -0,0 +1,29 @@
#!/usr/bin/env rspec
require 'spec_helper'

require 'puppet/indirector/file_bucket_file/selector'
require 'puppet/indirector/file_bucket_file/file'
require 'puppet/indirector/file_bucket_file/rest'

describe Puppet::FileBucketFile::Selector do
%w[head find save search destroy].each do |method|
describe "##{method}" do
it "should proxy to rest terminus for https requests" do
request = stub 'request', :protocol => 'https'

Puppet::FileBucketFile::Rest.any_instance.expects(method).with(request)

subject.send(method, request)
end

it "should proxy to file terminus for other requests" do
request = stub 'request', :protocol => 'file'

Puppet::FileBucketFile::File.any_instance.expects(method).with(request)

subject.send(method, request)
end
end
end
end

0 comments on commit e7ef153

Please sign in to comment.