~ubuntu-branches/ubuntu/trusty/puppet/trusty

« back to all changes in this revision

Viewing changes to debian/patches/secure-indirector-file-backed-terminus-base-cla.patch

  • Committer: Package Import Robot
  • Author(s): Stig Sandbeck Mathisen
  • Date: 2011-10-22 14:08:22 UTC
  • mfrom: (1.1.25) (3.1.32 sid)
  • Revision ID: package-import@ubuntu.com-20111022140822-odxde5lohc45yhuz
Tags: 2.7.6-1
* New upstream release (CVE-2011-3872)
* Remove cherry-picked "groupadd_aix_warning" patch
* Install all new manpages

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
From a05502f2d8c627c08ae33c2fb49d5dbe36affb16 Mon Sep 17 00:00:00 2001
2
 
From: Daniel Pittman <daniel@puppetlabs.com>
3
 
Date: Wed, 28 Sep 2011 23:59:49 -0700
4
 
Subject: [PATCH] (#9793) "secure" indirector file backed terminus base class.
5
 
 
6
 
The file base class in the indirector trusted the request key directly, which
7
 
made it vulnerable to the same potential for injection attacks as other
8
 
terminus base classes.
9
 
 
10
 
However, this is somewhat mitigated by the fact that base class is entirely
11
 
unused.  We can simple eliminate it from the system, because nothing is more
12
 
secure than code that doesn't exist.
13
 
 
14
 
The only consumer of the code was in the tests, and didn't care what base
15
 
class was used, so that was substituted with a continuing class.
16
 
 
17
 
Signed-off-by: Daniel Pittman <daniel@puppetlabs.com>
18
 
---
19
 
 lib/puppet/indirector/file.rb         |   79 ---------------
20
 
 spec/unit/indirector/file_spec.rb     |  179 ---------------------------------
21
 
 spec/unit/indirector/terminus_spec.rb |    6 +-
22
 
 3 files changed, 3 insertions(+), 261 deletions(-)
23
 
 delete mode 100644 lib/puppet/indirector/file.rb
24
 
 delete mode 100755 spec/unit/indirector/file_spec.rb
25
 
 
26
 
diff --git a/lib/puppet/indirector/file.rb b/lib/puppet/indirector/file.rb
27
 
deleted file mode 100644
28
 
index b3746b7..0000000
29
 
--- a/lib/puppet/indirector/file.rb
30
 
+++ /dev/null
31
 
@@ -1,79 +0,0 @@
32
 
-require 'puppet/indirector/terminus'
33
 
-
34
 
-# Store instances as files, usually serialized using some format.
35
 
-class Puppet::Indirector::File < Puppet::Indirector::Terminus
36
 
-  # Where do we store our data?
37
 
-  def data_directory
38
 
-    name = Puppet.run_mode.master? ? :server_datadir : :client_datadir
39
 
-
40
 
-    File.join(Puppet.settings[name], self.class.indirection_name.to_s)
41
 
-  end
42
 
-
43
 
-  def file_format(path)
44
 
-    path =~ /\.(\w+)$/ and return $1
45
 
-  end
46
 
-
47
 
-  def file_path(request)
48
 
-    File.join(data_directory, request.key + ".#{serialization_format}")
49
 
-  end
50
 
-
51
 
-  def latest_path(request)
52
 
-    files = Dir.glob(File.join(data_directory, request.key + ".*"))
53
 
-    return nil if files.empty?
54
 
-
55
 
-    # Return the newest file.
56
 
-    files.sort { |a, b| File.stat(b).mtime <=> File.stat(a).mtime }[0]
57
 
-  end
58
 
-
59
 
-  def serialization_format
60
 
-    model.default_format
61
 
-  end
62
 
-
63
 
-  # Remove files on disk.
64
 
-  def destroy(request)
65
 
-    begin
66
 
-      removed = false
67
 
-      Dir.glob(File.join(data_directory, request.key.to_s + ".*")).each do |file|
68
 
-        removed = true
69
 
-        File.unlink(file)
70
 
-      end
71
 
-    rescue => detail
72
 
-      raise Puppet::Error, "Could not remove #{request.key}: #{detail}"
73
 
-    end
74
 
-
75
 
-    raise Puppet::Error, "Could not find files for #{request.key} to remove" unless removed
76
 
-  end
77
 
-
78
 
-  # Return a model instance for a given file on disk.
79
 
-  def find(request)
80
 
-    return nil unless path = latest_path(request)
81
 
-    format = file_format(path)
82
 
-
83
 
-    raise ArgumentError, "File format #{format} is not supported by #{self.class.indirection_name}" unless model.support_format?(format)
84
 
-
85
 
-    begin
86
 
-      return model.convert_from(format, File.read(path))
87
 
-    rescue => detail
88
 
-      raise Puppet::Error, "Could not convert path #{path} into a #{self.class.indirection_name}: #{detail}"
89
 
-    end
90
 
-  end
91
 
-
92
 
-  # Save a new file to disk.
93
 
-  def save(request)
94
 
-    path = file_path(request)
95
 
-
96
 
-    dir = File.dirname(path)
97
 
-
98
 
-    raise Puppet::Error.new("Cannot save #{request.key}; parent directory #{dir} does not exist") unless File.directory?(dir)
99
 
-
100
 
-    begin
101
 
-      File.open(path, "w") { |f| f.print request.instance.render(serialization_format) }
102
 
-    rescue => detail
103
 
-      raise Puppet::Error, "Could not write #{request.key}: #{detail}" % [request.key, detail]
104
 
-    end
105
 
-  end
106
 
-
107
 
-  def path(key)
108
 
-    key
109
 
-  end
110
 
-end
111
 
diff --git a/spec/unit/indirector/file_spec.rb b/spec/unit/indirector/file_spec.rb
112
 
deleted file mode 100755
113
 
index b72bf4d..0000000
114
 
--- a/spec/unit/indirector/file_spec.rb
115
 
+++ /dev/null
116
 
@@ -1,179 +0,0 @@
117
 
-#!/usr/bin/env rspec
118
 
-require 'spec_helper'
119
 
-require 'puppet/indirector/file'
120
 
-
121
 
-
122
 
-describe Puppet::Indirector::File do
123
 
-  before :all do
124
 
-    Puppet::Indirector::Terminus.stubs(:register_terminus_class)
125
 
-    @model = mock 'model'
126
 
-    @indirection = stub 'indirection', :name => :mystuff, :register_terminus_type => nil, :model => @model
127
 
-    Puppet::Indirector::Indirection.stubs(:instance).returns(@indirection)
128
 
-
129
 
-    module Testing; end
130
 
-    @file_class = class Testing::MyFile < Puppet::Indirector::File
131
 
-      self
132
 
-    end
133
 
-
134
 
-    @searcher = @file_class.new
135
 
-
136
 
-    @path = "/my/file"
137
 
-    @dir = "/my"
138
 
-
139
 
-    @request = stub 'request', :key => @path
140
 
-  end
141
 
-
142
 
-  describe "when finding files" do
143
 
-    it "should provide a method to return file contents at a specified path" do
144
 
-      @searcher.should respond_to(:find)
145
 
-    end
146
 
-
147
 
-    it "should use the server data directory plus the indirection name if the run_mode is master" do
148
 
-      Puppet.run_mode.expects(:master?).returns true
149
 
-      Puppet.settings.expects(:value).with(:server_datadir).returns "/my/dir"
150
 
-
151
 
-      @searcher.data_directory.should == File.join("/my/dir", "mystuff")
152
 
-    end
153
 
-
154
 
-    it "should use the client data directory plus the indirection name if the run_mode is not master" do
155
 
-      Puppet.run_mode.expects(:master?).returns false
156
 
-      Puppet.settings.expects(:value).with(:client_datadir).returns "/my/dir"
157
 
-
158
 
-      @searcher.data_directory.should == File.join("/my/dir", "mystuff")
159
 
-    end
160
 
-
161
 
-    it "should use the newest file in the data directory matching the indirection key without extension" do
162
 
-      @searcher.expects(:data_directory).returns "/data/dir"
163
 
-      @request.stubs(:key).returns "foo"
164
 
-      Dir.expects(:glob).with("/data/dir/foo.*").returns %w{/data1.stuff /data2.stuff}
165
 
-
166
 
-      stat1 = stub 'data1', :mtime => (Time.now - 5)
167
 
-      stat2 = stub 'data2', :mtime => Time.now
168
 
-      File.expects(:stat).with("/data1.stuff").returns stat1
169
 
-      File.expects(:stat).with("/data2.stuff").returns stat2
170
 
-
171
 
-      @searcher.latest_path(@request).should == "/data2.stuff"
172
 
-    end
173
 
-
174
 
-    it "should return nil when no files are found" do
175
 
-      @searcher.stubs(:latest_path).returns nil
176
 
-
177
 
-      @searcher.find(@request).should be_nil
178
 
-    end
179
 
-
180
 
-    it "should determine the file format from the file extension" do
181
 
-      @searcher.file_format("/data2.pson").should == "pson"
182
 
-    end
183
 
-
184
 
-    it "should fail if the model does not support the file format" do
185
 
-      @searcher.stubs(:latest_path).returns "/my/file.pson"
186
 
-
187
 
-      @model.expects(:support_format?).with("pson").returns false
188
 
-
189
 
-      lambda { @searcher.find(@request) }.should raise_error(ArgumentError)
190
 
-    end
191
 
-  end
192
 
-
193
 
-  describe "when saving files" do
194
 
-    before do
195
 
-      @content = "my content"
196
 
-      @file = stub 'file', :content => @content, :path => @path, :name => @path, :render => "mydata"
197
 
-      @request.stubs(:instance).returns @file
198
 
-    end
199
 
-
200
 
-    it "should provide a method to save file contents at a specified path" do
201
 
-      @searcher.should respond_to(:save)
202
 
-    end
203
 
-
204
 
-    it "should choose the file extension based on the default format of the model" do
205
 
-      @model.expects(:default_format).returns "pson"
206
 
-
207
 
-      @searcher.serialization_format.should == "pson"
208
 
-    end
209
 
-
210
 
-    it "should place the file in the data directory, named after the indirection, key, and format" do
211
 
-      @searcher.stubs(:data_directory).returns "/my/dir"
212
 
-      @searcher.stubs(:serialization_format).returns "pson"
213
 
-
214
 
-      @request.stubs(:key).returns "foo"
215
 
-      @searcher.file_path(@request).should == File.join("/my/dir", "foo.pson")
216
 
-    end
217
 
-
218
 
-    it "should fail intelligently if the file's parent directory does not exist" do
219
 
-      @searcher.stubs(:file_path).returns "/my/dir/file.pson"
220
 
-      @searcher.stubs(:serialization_format).returns "pson"
221
 
-
222
 
-      @request.stubs(:key).returns "foo"
223
 
-      File.expects(:directory?).with(File.join("/my/dir")).returns(false)
224
 
-
225
 
-      proc { @searcher.save(@request) }.should raise_error(Puppet::Error)
226
 
-    end
227
 
-
228
 
-    it "should render the instance using the file format and print it to the file path" do
229
 
-      @searcher.stubs(:file_path).returns "/my/file.pson"
230
 
-      @searcher.stubs(:serialization_format).returns "pson"
231
 
-
232
 
-      File.stubs(:directory?).returns true
233
 
-
234
 
-      @request.instance.expects(:render).with("pson").returns "data"
235
 
-
236
 
-      fh = mock 'filehandle'
237
 
-      File.expects(:open).with("/my/file.pson", "w").yields fh
238
 
-      fh.expects(:print).with("data")
239
 
-
240
 
-      @searcher.save(@request)
241
 
-    end
242
 
-
243
 
-    it "should fail intelligently if a file cannot be written" do
244
 
-      filehandle = mock 'file'
245
 
-      File.stubs(:directory?).returns(true)
246
 
-      File.stubs(:open).yields(filehandle)
247
 
-      filehandle.expects(:print).raises(ArgumentError)
248
 
-
249
 
-      @searcher.stubs(:file_path).returns "/my/file.pson"
250
 
-      @model.stubs(:default_format).returns "pson"
251
 
-
252
 
-      @instance.stubs(:render).returns "stuff"
253
 
-
254
 
-      proc { @searcher.save(@request) }.should raise_error(Puppet::Error)
255
 
-    end
256
 
-  end
257
 
-
258
 
-  describe "when removing files" do
259
 
-    it "should provide a method to remove files" do
260
 
-      @searcher.should respond_to(:destroy)
261
 
-    end
262
 
-
263
 
-    it "should remove files in all formats found in the data directory that match the request key" do
264
 
-      @searcher.stubs(:data_directory).returns "/my/dir"
265
 
-      @request.stubs(:key).returns "me"
266
 
-
267
 
-      Dir.expects(:glob).with(File.join("/my/dir", "me.*")).returns %w{/one /two}
268
 
-
269
 
-      File.expects(:unlink).with("/one")
270
 
-      File.expects(:unlink).with("/two")
271
 
-
272
 
-      @searcher.destroy(@request)
273
 
-    end
274
 
-
275
 
-    it "should throw an exception if no file is found" do
276
 
-      @searcher.stubs(:data_directory).returns "/my/dir"
277
 
-      @request.stubs(:key).returns "me"
278
 
-
279
 
-      Dir.expects(:glob).with(File.join("/my/dir", "me.*")).returns []
280
 
-
281
 
-      proc { @searcher.destroy(@request) }.should raise_error(Puppet::Error)
282
 
-    end
283
 
-
284
 
-    it "should fail intelligently if a file cannot be removed" do
285
 
-      @searcher.stubs(:data_directory).returns "/my/dir"
286
 
-      @request.stubs(:key).returns "me"
287
 
-
288
 
-      Dir.expects(:glob).with(File.join("/my/dir", "me.*")).returns %w{/one}
289
 
-
290
 
-      File.expects(:unlink).with("/one").raises ArgumentError
291
 
-
292
 
-      proc { @searcher.destroy(@request) }.should raise_error(Puppet::Error)
293
 
-    end
294
 
-  end
295
 
-end
296
 
diff --git a/spec/unit/indirector/terminus_spec.rb b/spec/unit/indirector/terminus_spec.rb
297
 
index 2f37c1f..ccd6fd2 100755
298
 
--- a/spec/unit/indirector/terminus_spec.rb
299
 
+++ b/spec/unit/indirector/terminus_spec.rb
300
 
@@ -2,7 +2,7 @@
301
 
 require 'spec_helper'
302
 
 require 'puppet/defaults'
303
 
 require 'puppet/indirector'
304
 
-require 'puppet/indirector/file'
305
 
+require 'puppet/indirector/memory'
306
 
 
307
 
 describe Puppet::Indirector::Terminus, :'fails_on_ruby_1.9.2' => true do
308
 
   before :each do
309
 
@@ -201,14 +201,14 @@ describe Puppet::Indirector::Terminus, " when parsing class constants for indire
310
 
     @subclass.expects(:indirection=).with(:test_ind)
311
 
     @subclass.stubs(:name=)
312
 
     @subclass.stubs(:terminus_type=)
313
 
-    Puppet::Indirector::File.inherited(@subclass)
314
 
+    Puppet::Indirector::Memory.inherited(@subclass)
315
 
   end
316
 
 
317
 
   it "should convert the indirection name to a downcased symbol" do
318
 
     @subclass.expects(:indirection=).with(:test_ind)
319
 
     @subclass.stubs(:name=)
320
 
     @subclass.stubs(:terminus_type=)
321
 
-    Puppet::Indirector::File.inherited(@subclass)
322
 
+    Puppet::Indirector::Memory.inherited(@subclass)
323
 
   end
324
 
 
325
 
   it "should convert camel case to lower case with underscores as word separators" do
326
 
1.7.6.4
327