ssh-allow 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/Gemfile +4 -0
- data/LICENSE.md +24 -0
- data/README.md +70 -0
- data/Rakefile +2 -0
- data/bin/ssh-allow +4 -0
- data/lib/ssh/allow.rb +4 -0
- data/lib/ssh/allow/cli.rb +33 -0
- data/lib/ssh/allow/command.rb +41 -0
- data/lib/ssh/allow/command_line.treetop +104 -0
- data/lib/ssh/allow/rule.rb +97 -0
- data/lib/ssh/allow/rule_set.rb +38 -0
- data/lib/ssh/allow/version.rb +5 -0
- data/spec/acceptance/acceptance_helper.rb +21 -0
- data/spec/acceptance/cli_spec.rb +47 -0
- data/spec/command_line_spec.rb +197 -0
- data/spec/command_spec.rb +72 -0
- data/spec/rule_set_spec.rb +95 -0
- data/spec/rule_spec.rb +219 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/.gitkeep +0 -0
- data/spec/support/cli_helpers.rb +17 -0
- data/spec/support/rule_set_helpers.rb +12 -0
- data/ssh-allow.gemspec +30 -0
- metadata +196 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'aruba/api'
|
3
|
+
|
4
|
+
RSpec.configure do |config|
|
5
|
+
config.include Aruba::Api
|
6
|
+
config.include CLIHelpers
|
7
|
+
|
8
|
+
config.before(:all) do
|
9
|
+
@__aruba_original_paths = (ENV['PATH'] || '').split(File::PATH_SEPARATOR)
|
10
|
+
ENV['PATH'] = ([File.expand_path('bin')] + @__aruba_original_paths).join(File::PATH_SEPARATOR)
|
11
|
+
FileUtils.rm_rf(current_dir)
|
12
|
+
@aruba_io_wait_seconds = 1.5
|
13
|
+
end
|
14
|
+
|
15
|
+
config.after(:all) do
|
16
|
+
ENV['PATH'] = @__aruba_original_paths.join(File::PATH_SEPARATOR)
|
17
|
+
restore_env
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'acceptance/acceptance_helper'
|
2
|
+
|
3
|
+
describe "Executing the ssh-allow CLI" do
|
4
|
+
context "GIVEN: a path-limited 'ls' config file" do
|
5
|
+
before(:each) do
|
6
|
+
@file = 'test.rules'
|
7
|
+
@dir_path = File.expand_path(current_dir + '/../')
|
8
|
+
@allow = %(
|
9
|
+
allow!("ls") do
|
10
|
+
opts "-ld"
|
11
|
+
args "#{@dir_path}/.*"
|
12
|
+
end
|
13
|
+
).gsub(/^ {6}/, '')
|
14
|
+
write_file(@file, @allow)
|
15
|
+
@cmd = "ssh-allow guard --rules=#{File.expand_path(current_dir)}/#{@file} --echo"
|
16
|
+
end
|
17
|
+
|
18
|
+
context "WHEN: we run 'ssh-allow guard --echo' with an allowed path" do
|
19
|
+
before(:each) do
|
20
|
+
@ssh = ssh_command %(ls -ld #{@dir_path}/*)
|
21
|
+
run_simple(@cmd)
|
22
|
+
end
|
23
|
+
|
24
|
+
context "THEN: the output of the run" do
|
25
|
+
it "should contain the remote command" do
|
26
|
+
all_output.should include(@ssh)
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should contain a listing for the 'tmp/aruba' directory" do
|
30
|
+
all_output.should match(/tmp\/aruba$/)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "WHEN: we run 'ssh-allow guard --echo' with an disallowed path" do
|
36
|
+
before(:each) do
|
37
|
+
@ssh = ssh_command %(ls -ld /foo/bar/*)
|
38
|
+
run_simple(@cmd)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "standard error indicates a bad command" do
|
42
|
+
all_stderr.should match(/Remote Command Not Allowed: #{@ssh}/)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,197 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "The CommandLine parser" do
|
4
|
+
before(:each) do
|
5
|
+
@parser = CommandLineParser.new
|
6
|
+
end
|
7
|
+
|
8
|
+
context "with only the command" do
|
9
|
+
before(:each) do
|
10
|
+
@cmd = '/bin/ls'
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when not quoted" do
|
14
|
+
before(:each) do
|
15
|
+
@parsed_cmd = @parser.parse(@cmd)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "parses the command" do
|
19
|
+
@parsed_cmd.name.text_value.should == @cmd
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when quoted" do
|
24
|
+
before(:each) do
|
25
|
+
@parsed_cmd = @parser.parse("\"#{@cmd}\"")
|
26
|
+
end
|
27
|
+
|
28
|
+
it "parses the quoted command" do
|
29
|
+
@parsed_cmd.text_value.should == "\"#{@cmd}\""
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "with just options" do
|
35
|
+
before(:each) do
|
36
|
+
@cmd = 'ls'
|
37
|
+
@opts = []
|
38
|
+
end
|
39
|
+
|
40
|
+
context "one short" do
|
41
|
+
before(:each) do
|
42
|
+
@opts << '-l'
|
43
|
+
@parsed_cmd = @parser.parse("#{@cmd} #{@opts.join(' ')}")
|
44
|
+
end
|
45
|
+
|
46
|
+
it "parses the list of options" do
|
47
|
+
@parsed_cmd.option_list.should == ['l']
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "one long" do
|
52
|
+
before(:each) do
|
53
|
+
@opts << '--long'
|
54
|
+
@parsed_cmd = @parser.parse("#{@cmd} #{@opts.join(' ')}")
|
55
|
+
end
|
56
|
+
|
57
|
+
it "parses the list of options" do
|
58
|
+
@parsed_cmd.option_list.should == ['long']
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "one long and one short" do
|
63
|
+
before(:each) do
|
64
|
+
@opts = ['--long', '-a']
|
65
|
+
@parsed_cmd = @parser.parse("#{@cmd} #{@opts.join(' ')}")
|
66
|
+
end
|
67
|
+
|
68
|
+
it "parses the list of options" do
|
69
|
+
@parsed_cmd.option_list.should == ['long', 'a']
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "one short w/argument" do
|
74
|
+
before(:each) do
|
75
|
+
@opts << '-l=foo/bar'
|
76
|
+
@parsed_cmd = @parser.parse("#{@cmd} #{@opts.join(' ')}")
|
77
|
+
end
|
78
|
+
|
79
|
+
it "parses the list of options" do
|
80
|
+
@parsed_cmd.option_list.should == ['l']
|
81
|
+
end
|
82
|
+
|
83
|
+
it "parses the list of arguments" do
|
84
|
+
@parsed_cmd.argument_list.should == ['foo/bar']
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context "one long w/argument" do
|
89
|
+
before(:each) do
|
90
|
+
@opts << '--long=foo/bar'
|
91
|
+
@parsed_cmd = @parser.parse("#{@cmd} #{@opts.join(' ')}")
|
92
|
+
end
|
93
|
+
|
94
|
+
it "parses the list of options" do
|
95
|
+
@parsed_cmd.option_list.should == ['long']
|
96
|
+
end
|
97
|
+
|
98
|
+
it "parses the list of arguments" do
|
99
|
+
@parsed_cmd.argument_list.should == ['foo/bar']
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
context "one long and one short w/arguments" do
|
104
|
+
before(:each) do
|
105
|
+
@opts = ['--long=foo', '-a=bar']
|
106
|
+
@parsed_cmd = @parser.parse("#{@cmd} #{@opts.join(' ')}")
|
107
|
+
end
|
108
|
+
|
109
|
+
it "parses the list of options" do
|
110
|
+
@parsed_cmd.option_list.should == ['long', 'a']
|
111
|
+
end
|
112
|
+
|
113
|
+
it "parses the list of arguments" do
|
114
|
+
@parsed_cmd.argument_list.should == ['foo', 'bar']
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "with just arguments" do
|
120
|
+
before(:each) do
|
121
|
+
@cmd = 'cp'
|
122
|
+
@args = ['foo']
|
123
|
+
end
|
124
|
+
|
125
|
+
context "one argument" do
|
126
|
+
before(:each) do
|
127
|
+
@parsed_cmd = @parser.parse("#{@cmd} #{@args.join(' ')}")
|
128
|
+
end
|
129
|
+
|
130
|
+
it "parses the list of arguments" do
|
131
|
+
@parsed_cmd.argument_list.should == @args
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "two arguments" do
|
136
|
+
before(:each) do
|
137
|
+
@args << 'bar'
|
138
|
+
@parsed_cmd = @parser.parse("#{@cmd} #{@args.join(' ')}")
|
139
|
+
end
|
140
|
+
|
141
|
+
it "parses the list of arguments" do
|
142
|
+
@parsed_cmd.argument_list.should == @args
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context "with arguments and options" do
|
148
|
+
before(:each) do
|
149
|
+
@cmd = 'cp'
|
150
|
+
@opts = ['r']
|
151
|
+
@args = ['foo', 'bar']
|
152
|
+
end
|
153
|
+
|
154
|
+
context "1 option followed by 2 arguments" do
|
155
|
+
before(:each) do
|
156
|
+
@parsed_cmd = @parser.parse("#{@cmd} -#{@opts} #{@args.join(' ')}")
|
157
|
+
end
|
158
|
+
|
159
|
+
it "parses the option" do
|
160
|
+
@parsed_cmd.option_list.should == @opts
|
161
|
+
end
|
162
|
+
|
163
|
+
it "parses the list of arguments" do
|
164
|
+
@parsed_cmd.argument_list.should == @args
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
context "2 arguments followed by 1 option" do
|
169
|
+
before(:each) do
|
170
|
+
@parsed_cmd = @parser.parse("#{@cmd} -#{@opts} #{@args.join(' ')}")
|
171
|
+
end
|
172
|
+
|
173
|
+
it "parses the option" do
|
174
|
+
@parsed_cmd.option_list.should == @opts
|
175
|
+
end
|
176
|
+
|
177
|
+
it "parses the list of arguments" do
|
178
|
+
@parsed_cmd.argument_list.should == @args
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context "1 argument, 1 option, 1 argument" do
|
183
|
+
before(:each) do
|
184
|
+
@cmd << ' foo -r bar'
|
185
|
+
@parsed_cmd = @parser.parse(@cmd)
|
186
|
+
end
|
187
|
+
|
188
|
+
it "parses the option" do
|
189
|
+
@parsed_cmd.option_list.should == @opts
|
190
|
+
end
|
191
|
+
|
192
|
+
it "parses the list of arguments" do
|
193
|
+
@parsed_cmd.argument_list.should == @args
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SSH::Allow::Command do
|
4
|
+
|
5
|
+
context "for a simple command" do
|
6
|
+
before(:each) do
|
7
|
+
@cmd_text = 'git help'
|
8
|
+
@command = SSH::Allow::Command.new(@cmd_text)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "returns the correct name" do
|
12
|
+
@command.name.should == 'git'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns the array of arguments" do
|
16
|
+
@command.arguments.should == ['help']
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns an empty array for options" do
|
20
|
+
@command.options.should == []
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "for a complex command" do
|
25
|
+
before(:each) do
|
26
|
+
@cmd_text = %(git log --since="6 months ago" Gemfile)
|
27
|
+
@command = SSH::Allow::Command.new(@cmd_text)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns the array of arguments" do
|
31
|
+
@command.arguments.should == ['log', '"6 months ago"', 'Gemfile']
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns the array of options" do
|
35
|
+
@command.options.should == ['since']
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#allowed?" do
|
40
|
+
context "with 1 'allow' rule, each, for cp and mv commands" do
|
41
|
+
before(:each) do
|
42
|
+
@cp = mock(:cp_rule)
|
43
|
+
@mv = mock(:mv_rule)
|
44
|
+
@cp.should_receive(:match?).once.and_return([false, false])
|
45
|
+
@rules = [@cp, @mv]
|
46
|
+
cmd_text = 'mv /foo/bar /baz/bar'
|
47
|
+
@command = SSH::Allow::Command.new(cmd_text)
|
48
|
+
end
|
49
|
+
|
50
|
+
context "when the mv command matches" do
|
51
|
+
before(:each) do
|
52
|
+
@mv.should_receive(:match?).once.and_return([true, true])
|
53
|
+
end
|
54
|
+
|
55
|
+
it "returns true" do
|
56
|
+
@command.should be_allowed(@rules)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when the mv command doesn't match" do
|
61
|
+
before(:each) do
|
62
|
+
@mv.should_receive(:match?).once.and_return([false, false])
|
63
|
+
end
|
64
|
+
|
65
|
+
it "returns false" do
|
66
|
+
@command.should_not be_allowed(@rules)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SSH::Allow::RuleSet do
|
4
|
+
before(:each) do
|
5
|
+
@rule_set = SSH::Allow::RuleSet.new
|
6
|
+
end
|
7
|
+
|
8
|
+
context "#new" do
|
9
|
+
it "has an empty rules array" do
|
10
|
+
@rule_set.rules.should be_empty
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "with a valid rule" do
|
15
|
+
before(:each) do
|
16
|
+
@rule = mock(:rule)
|
17
|
+
@rule_set.should_receive(:get_rule).once.and_return(@rule)
|
18
|
+
end
|
19
|
+
|
20
|
+
context "#allow" do
|
21
|
+
before(:each) do
|
22
|
+
@rule_set.allow(:rule)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "adds the rule" do
|
26
|
+
@rule_set.rules.should == [@rule]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "#allow!" do
|
31
|
+
it "does not raise an error" do
|
32
|
+
lambda { @rule_set.allow!(:rule) }.should_not raise_error
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "with an invalid rule" do
|
38
|
+
before(:each) do
|
39
|
+
@rule_set.should_receive(:get_rule).once.and_return(false)
|
40
|
+
end
|
41
|
+
|
42
|
+
context "#allow" do
|
43
|
+
before(:each) do
|
44
|
+
@allow = @rule_set.allow(:rule)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "returns false" do
|
48
|
+
@allow.should == false
|
49
|
+
end
|
50
|
+
|
51
|
+
it "does not add the rule" do
|
52
|
+
@rule_set.rules.should be_empty
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "#allow!" do
|
57
|
+
it "raises an error" do
|
58
|
+
lambda { @rule_set.allow!(:rule) }.should raise_error(/Invalid rule: "rule"/)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "with a config file with 2 valid rules" do
|
64
|
+
before(:each) do
|
65
|
+
@rule1 = mock(:foo)
|
66
|
+
@rule2 = mock(:bar)
|
67
|
+
@rule_set.should_receive(:get_rule).twice.and_return(@rule1, @rule2)
|
68
|
+
@rule_set.should_receive(:read_rules).once.and_return(sample_rules)
|
69
|
+
end
|
70
|
+
|
71
|
+
context "#read" do
|
72
|
+
before(:each) do
|
73
|
+
@rule_set.read('/my/fake/rules')
|
74
|
+
end
|
75
|
+
|
76
|
+
it "adds 2 rules" do
|
77
|
+
@rule_set.rules.should == [@rule1, @rule2]
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "with a config file with 1 valid and 1 invalid rule" do
|
83
|
+
before(:each) do
|
84
|
+
@rule1 = mock(:foo)
|
85
|
+
@rule_set.should_receive(:get_rule).twice.and_return(@rule1, false)
|
86
|
+
@rule_set.should_receive(:read_rules).once.and_return(sample_rules)
|
87
|
+
end
|
88
|
+
|
89
|
+
context "#read" do
|
90
|
+
it "raises an error on the second rule" do
|
91
|
+
lambda { @rule_set.read('/my/fake/rules') }.should raise_error(/Invalid rule: "bar"/)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/spec/rule_spec.rb
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe SSH::Allow::Rule do
|
4
|
+
|
5
|
+
context "creating an Allow rule, with a single command" do
|
6
|
+
before(:each) do
|
7
|
+
@cmd = "ls"
|
8
|
+
end
|
9
|
+
|
10
|
+
context "when specifying no options or arguments" do
|
11
|
+
before(:each) do
|
12
|
+
@rule = SSH::Allow::Rule.allow(@cmd)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "returns [:none] for options" do
|
16
|
+
@rule.options.should == [:none]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "match_command? matches 'ls'" do
|
20
|
+
@rule.should be_match_command(@cmd)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "match_command? doesn't match 'ln'" do
|
24
|
+
@rule.should_not be_match_command('ln')
|
25
|
+
end
|
26
|
+
|
27
|
+
it "match_options? matches no options" do
|
28
|
+
@rule.should be_match_options([])
|
29
|
+
end
|
30
|
+
|
31
|
+
it "match_options? doesn't match a passed in option" do
|
32
|
+
@rule.should_not be_match_options(['foo'])
|
33
|
+
end
|
34
|
+
|
35
|
+
it "match_arguments? matches no arguments" do
|
36
|
+
@rule.should be_match_arguments([])
|
37
|
+
end
|
38
|
+
|
39
|
+
it "match_arguments? doesn't match a passed in argument" do
|
40
|
+
@rule.should_not be_match_arguments(['foo'])
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context "when specifying :any for options and arguments " do
|
45
|
+
before(:each) do
|
46
|
+
@rule = SSH::Allow::Rule.allow(@cmd)
|
47
|
+
@rule.opts(:any)
|
48
|
+
@rule.args(:any)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "match_options? matches no options" do
|
52
|
+
@rule.should be_match_options([])
|
53
|
+
end
|
54
|
+
|
55
|
+
it "match_options? matches any number of options" do
|
56
|
+
@rule.should be_match_options(['foo', 'bar', 'baz'])
|
57
|
+
end
|
58
|
+
|
59
|
+
it "match_arguments? matches no arguments" do
|
60
|
+
@rule.should be_match_arguments([])
|
61
|
+
end
|
62
|
+
|
63
|
+
it "match_arguments? matches any number of arguments" do
|
64
|
+
@rule.should be_match_arguments(['foo', 'bar', :baz])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "when specifying strings for options and arguments, via a block" do
|
69
|
+
before(:each) do
|
70
|
+
@rule = SSH::Allow::Rule.allow(@cmd) do
|
71
|
+
opts '-ld'
|
72
|
+
args '^\/foo\/bar\/.*'
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "returns \"ld\" for the rule options" do
|
77
|
+
@rule.options.should == ['ld']
|
78
|
+
end
|
79
|
+
|
80
|
+
it "returns the correct pattern for the argument" do
|
81
|
+
@rule.arguments[0].should == Regexp.new('^\/foo\/bar\/.*')
|
82
|
+
end
|
83
|
+
|
84
|
+
it "match_options? matches the correct options" do
|
85
|
+
@rule.should be_match_options(['ld'])
|
86
|
+
end
|
87
|
+
|
88
|
+
it "match_options? doesn't match more than one option" do
|
89
|
+
@rule.should_not be_match_options(['ld', 'foo'])
|
90
|
+
end
|
91
|
+
|
92
|
+
it "match_arguments? matches an argument that starts with '/foo/bar/'" do
|
93
|
+
@rule.should be_match_arguments(['/foo/bar/*'])
|
94
|
+
end
|
95
|
+
|
96
|
+
it "match_arguments? doesn't match an argument that starts with '/foo/baz/'" do
|
97
|
+
@rule.should_not be_match_arguments(['/foo/baz/*'])
|
98
|
+
end
|
99
|
+
|
100
|
+
it "match_arguments? doesn't match more than one argument" do
|
101
|
+
@rule.should_not be_match_arguments(['/foo/bar/*', '/foo/baz/*'])
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "when sending an invalid block" do
|
106
|
+
before(:each) do
|
107
|
+
@rule = SSH::Allow::Rule.allow(@cmd) do
|
108
|
+
opts "-ld"
|
109
|
+
foo "bar"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
it "returns false" do
|
114
|
+
@rule.should be(false)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "creating a Deny rule" do
|
120
|
+
context "with a single command string" do
|
121
|
+
before(:each) do
|
122
|
+
@cmd = "ls"
|
123
|
+
@rule = SSH::Allow::Rule.deny(@cmd)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "returns a Deny rule" do
|
127
|
+
@rule.should be_instance_of(SSH::Allow::Rule::Deny)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe SSH::Allow::Rule::Allow do
|
134
|
+
context "A Command for 'ls -ld /foo/bar/*'" do
|
135
|
+
before(:each) do
|
136
|
+
@cmd = mock(:command)
|
137
|
+
@cmd.should_receive(:name).once.and_return('ls')
|
138
|
+
@cmd.should_receive(:options).once.and_return(['ld'])
|
139
|
+
@cmd.should_receive(:arguments).once.and_return(['/foo/bar/*'])
|
140
|
+
end
|
141
|
+
|
142
|
+
context "matched against an 'ls' rule with no options or arguments" do
|
143
|
+
before(:each) do
|
144
|
+
@rule = SSH::Allow::Rule.allow('ls')
|
145
|
+
@match, @allow = @rule.match?(@cmd)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "is not a match" do
|
149
|
+
@match.should_not be(true)
|
150
|
+
end
|
151
|
+
|
152
|
+
it "would not be allowed" do
|
153
|
+
@allow.should_not be(true)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
context "matched against an 'ls' rule with matching options and arguments" do
|
158
|
+
before(:each) do
|
159
|
+
@rule = SSH::Allow::Rule.allow('ls') do
|
160
|
+
opts '-ld'
|
161
|
+
args '^\/foo\/bar\/.*'
|
162
|
+
end
|
163
|
+
@match, @allow = @rule.match?(@cmd)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "is a match" do
|
167
|
+
@match.should be(true)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "would be allowed" do
|
171
|
+
@allow.should be(true)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
describe SSH::Allow::Rule::Deny do
|
178
|
+
context "A Command for 'mv /foo/bar/file.txt /foo/baz/'" do
|
179
|
+
before(:each) do
|
180
|
+
@cmd = mock(:command)
|
181
|
+
@cmd.should_receive(:name).once.and_return('mv')
|
182
|
+
@cmd.should_receive(:options).once.and_return([])
|
183
|
+
@cmd.should_receive(:arguments).once.and_return(['/foo/bar/file.txt', '/foo/baz/'])
|
184
|
+
end
|
185
|
+
|
186
|
+
context "matched against an 'mv' rule with no options or arguments" do
|
187
|
+
before(:each) do
|
188
|
+
@rule = SSH::Allow::Rule.deny('mv')
|
189
|
+
@match, @allow = @rule.match?(@cmd)
|
190
|
+
end
|
191
|
+
|
192
|
+
it "is not a match" do
|
193
|
+
@match.should_not == true
|
194
|
+
end
|
195
|
+
|
196
|
+
it "would be allowed" do
|
197
|
+
@allow.should == true
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context "matched against an 'mv' rule with matching options and arguments" do
|
202
|
+
before(:each) do
|
203
|
+
@rule = SSH::Allow::Rule.deny('mv') do
|
204
|
+
args '^\/foo\/bar\/.*'
|
205
|
+
args '^\/foo\/baz\/.*'
|
206
|
+
end
|
207
|
+
@match, @allow = @rule.match?(@cmd)
|
208
|
+
end
|
209
|
+
|
210
|
+
it "is a match" do
|
211
|
+
@match.should == true
|
212
|
+
end
|
213
|
+
|
214
|
+
it "would not be allowed" do
|
215
|
+
@allow.should_not == true
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|