Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Always use the local file_bucket on master

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...
commit 40ee670c60ed703c38e420462dca78f8ec09d551 1 parent d881b4b
Nick Lewis authored June 22, 2012
2  lib/puppet/application/master.rb
@@ -234,6 +234,8 @@ def setup
234 234
     Puppet::FileServing::Content.indirection.terminus_class = :file_server
235 235
     Puppet::FileServing::Metadata.indirection.terminus_class = :file_server
236 236
 
  237
+    Puppet::FileBucket::File.indirection.terminus_class = :file
  238
+
237 239
     # Configure all of the SSL stuff.
238 240
     if Puppet::SSL::CertificateAuthority.ca?
239 241
       Puppet::SSL::Host.ca_location = :local
3  lib/puppet/file_bucket/file.rb
@@ -8,8 +8,7 @@ class Puppet::FileBucket::File
8 8
   # There are mechanisms to save and load this file locally and remotely in puppet/indirector/filebucketfile/*
9 9
   # There is a compatibility class that emulates pre-indirector filebuckets in Puppet::FileBucket::Dipper
10 10
   extend Puppet::Indirector
11  
-  require 'puppet/file_bucket/file/indirection_hooks'
12  
-  indirects :file_bucket_file, :terminus_class => :file, :extend => Puppet::FileBucket::File::IndirectionHooks
  11
+  indirects :file_bucket_file, :terminus_class => :selector
13 12
 
14 13
   attr :contents
15 14
   attr :bucket_path
9  lib/puppet/file_bucket/file/indirection_hooks.rb
... ...
@@ -1,9 +0,0 @@
1  
-require 'puppet/file_bucket/file'
2  
-
3  
-# This module is used to pick the appropriate terminus
4  
-# in filebucket indirections.
5  
-module Puppet::FileBucket::File::IndirectionHooks
6  
-  def select_terminus(request)
7  
-    return(request.protocol == 'https' ? :rest : Puppet::FileBucket::File.indirection.terminus_class)
8  
-  end
9  
-end
49  lib/puppet/indirector/file_bucket_file/selector.rb
... ...
@@ -0,0 +1,49 @@
  1
+require 'puppet/indirector/code'
  2
+
  3
+module Puppet::FileBucketFile
  4
+  class Selector < Puppet::Indirector::Code
  5
+    desc "Select the terminus based on the request"
  6
+
  7
+    def select(request)
  8
+      if request.protocol == 'https'
  9
+        :rest
  10
+      else
  11
+        :file
  12
+      end
  13
+    end
  14
+
  15
+    def get_terminus(request)
  16
+      indirection.terminus(select(request))
  17
+    end
  18
+
  19
+    def head(request)
  20
+      get_terminus(request).head(request)
  21
+    end
  22
+
  23
+    def find(request)
  24
+      get_terminus(request).find(request)
  25
+    end
  26
+
  27
+    def save(request)
  28
+      get_terminus(request).save(request)
  29
+    end
  30
+
  31
+    def search(request)
  32
+      get_terminus(request).search(request)
  33
+    end
  34
+
  35
+    def destroy(request)
  36
+      get_terminus(request).destroy(request)
  37
+    end
  38
+
  39
+    def authorized?(request)
  40
+      terminus = get_terminus(request)
  41
+      if terminus.respond_to?(:authorized?)
  42
+        terminus.authorized?(request)
  43
+      else
  44
+        true
  45
+      end
  46
+    end
  47
+  end
  48
+end
  49
+
44  spec/integration/file_bucket/file_spec.rb
... ...
@@ -0,0 +1,44 @@
  1
+#!/usr/bin/env rspec
  2
+
  3
+require 'spec_helper'
  4
+
  5
+require 'puppet/file_bucket/file'
  6
+
  7
+describe Puppet::FileBucket::File do
  8
+  describe "#indirection" do
  9
+    before :each do
  10
+      # Never connect to the network, no matter what
  11
+      described_class.indirection.terminus(:rest).class.any_instance.stubs(:find)
  12
+    end
  13
+
  14
+    describe "when running the master application" do
  15
+      before :each do
  16
+        Puppet::Application[:master].setup_terminuses
  17
+      end
  18
+
  19
+      {
  20
+        "md5/d41d8cd98f00b204e9800998ecf8427e" => :file,
  21
+        "https://puppetmaster:8140/production/file_bucket_file/md5/d41d8cd98f00b204e9800998ecf8427e" => :file,
  22
+      }.each do |key, terminus|
  23
+        it "should use the #{terminus} terminus when requesting #{key.inspect}" do
  24
+          described_class.indirection.terminus(terminus).class.any_instance.expects(:find)
  25
+
  26
+          described_class.indirection.find(key)
  27
+        end
  28
+      end
  29
+    end
  30
+
  31
+    describe "when running another application" do
  32
+      {
  33
+        "md5/d41d8cd98f00b204e9800998ecf8427e" => :file,
  34
+        "https://puppetmaster:8140/production/file_bucket_file/md5/d41d8cd98f00b204e9800998ecf8427e" => :rest,
  35
+      }.each do |key, terminus|
  36
+        it "should use the #{terminus} terminus when requesting #{key.inspect}" do
  37
+          described_class.indirection.terminus(terminus).class.any_instance.expects(:find)
  38
+
  39
+          described_class.indirection.find(key)
  40
+        end
  41
+      end
  42
+    end
  43
+  end
  44
+end
29  spec/unit/indirector/file_bucket_file/selector_spec.rb
... ...
@@ -0,0 +1,29 @@
  1
+#!/usr/bin/env rspec
  2
+require 'spec_helper'
  3
+
  4
+require 'puppet/indirector/file_bucket_file/selector'
  5
+require 'puppet/indirector/file_bucket_file/file'
  6
+require 'puppet/indirector/file_bucket_file/rest'
  7
+
  8
+describe Puppet::FileBucketFile::Selector do
  9
+  %w[head find save search destroy].each do |method|
  10
+    describe "##{method}" do
  11
+      it "should proxy to rest terminus for https requests" do
  12
+        request = stub 'request', :protocol => 'https'
  13
+
  14
+        Puppet::FileBucketFile::Rest.any_instance.expects(method).with(request)
  15
+
  16
+        subject.send(method, request)
  17
+      end
  18
+
  19
+      it "should proxy to file terminus for other requests" do
  20
+        request = stub 'request', :protocol => 'file'
  21
+
  22
+        Puppet::FileBucketFile::File.any_instance.expects(method).with(request)
  23
+
  24
+        subject.send(method, request)
  25
+      end
  26
+    end
  27
+  end
  28
+end
  29
+

0 notes on commit 40ee670

Please sign in to comment.
Something went wrong with that request. Please try again.