inspec 0.20.1 → 0.21.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +45 -2
- data/docs/dsl_inspec.rst +2 -2
- data/docs/resources.rst +9 -9
- data/docs/ruby_usage.rst +145 -0
- data/inspec.gemspec +1 -0
- data/lib/bundles/inspec-compliance/cli.rb +15 -2
- data/lib/inspec/cli.rb +23 -10
- data/lib/inspec/dsl.rb +0 -52
- data/lib/inspec/objects/or_test.rb +1 -0
- data/lib/inspec/objects/test.rb +4 -4
- data/lib/inspec/profile.rb +76 -61
- data/lib/inspec/profile_context.rb +12 -11
- data/lib/inspec/rspec_json_formatter.rb +93 -40
- data/lib/inspec/rule.rb +7 -29
- data/lib/inspec/runner.rb +15 -4
- data/lib/inspec/runner_mock.rb +1 -1
- data/lib/inspec/runner_rspec.rb +26 -24
- data/lib/inspec/version.rb +1 -1
- data/lib/matchers/matchers.rb +3 -3
- data/lib/resources/auditd_rules.rb +2 -2
- data/lib/resources/host.rb +1 -1
- data/lib/resources/interface.rb +1 -1
- data/lib/resources/kernel_parameter.rb +1 -1
- data/lib/resources/mount.rb +2 -1
- data/lib/resources/mysql_session.rb +1 -1
- data/lib/resources/os_env.rb +2 -2
- data/lib/resources/passwd.rb +33 -93
- data/lib/resources/port.rb +47 -3
- data/lib/resources/processes.rb +3 -3
- data/lib/resources/service.rb +33 -1
- data/lib/resources/user.rb +15 -15
- data/lib/utils/base_cli.rb +1 -3
- data/lib/utils/filter.rb +30 -7
- data/test/cookbooks/os_prepare/recipes/_upstart_service_centos.rb +4 -0
- data/test/functional/helper.rb +1 -0
- data/test/functional/inheritance_test.rb +1 -1
- data/test/functional/inspec_compliance_test.rb +4 -3
- data/test/functional/inspec_exec_json_test.rb +122 -0
- data/test/functional/inspec_exec_test.rb +23 -117
- data/test/functional/{inspec_json_test.rb → inspec_json_profile_test.rb} +13 -15
- data/test/functional/inspec_test.rb +15 -2
- data/test/helper.rb +5 -1
- data/test/integration/default/auditd_rules_spec.rb +3 -3
- data/test/integration/default/kernel_parameter_spec.rb +6 -6
- data/test/integration/default/service_spec.rb +4 -0
- data/test/resource/command_test.rb +9 -9
- data/test/resource/dsl_test.rb +1 -1
- data/test/resource/file_test.rb +17 -17
- data/test/unit/control_test.rb +1 -1
- data/test/unit/mock/cmd/hpux-netstat-inet +10 -0
- data/test/unit/mock/cmd/hpux-netstat-inet6 +11 -0
- data/test/unit/mock/profiles/skippy-profile-os/controls/one.rb +1 -1
- data/test/unit/profile_context_test.rb +2 -2
- data/test/unit/profile_test.rb +11 -14
- data/test/unit/resources/passwd_test.rb +13 -14
- data/test/unit/resources/port_test.rb +14 -0
- data/test/unit/resources/processes_test.rb +3 -3
- data/test/unit/resources/service_test.rb +103 -39
- data/test/unit/utils/filter_table_test.rb +35 -3
- metadata +25 -4
data/lib/inspec/rule.rb
CHANGED
@@ -12,8 +12,7 @@ module Inspec
|
|
12
12
|
class Rule # rubocop:disable Metrics/ClassLength
|
13
13
|
include ::RSpec::Matchers
|
14
14
|
|
15
|
-
def initialize(id, _opts, &block)
|
16
|
-
@id = id
|
15
|
+
def initialize(id, profile_id, _opts, &block)
|
17
16
|
@impact = nil
|
18
17
|
@title = nil
|
19
18
|
@desc = nil
|
@@ -24,7 +23,8 @@ module Inspec
|
|
24
23
|
@__block = block
|
25
24
|
@__code = __get_block_source(&block)
|
26
25
|
@__source_location = __get_block_source_location(&block)
|
27
|
-
@__rule_id =
|
26
|
+
@__rule_id = id
|
27
|
+
@__profile_id = profile_id
|
28
28
|
@__checks = []
|
29
29
|
@__skip_rule = nil
|
30
30
|
|
@@ -119,6 +119,10 @@ module Inspec
|
|
119
119
|
rule.instance_variable_set(:@__rule_id, value)
|
120
120
|
end
|
121
121
|
|
122
|
+
def self.profile_id(rule)
|
123
|
+
rule.instance_variable_get(:@__profile_id)
|
124
|
+
end
|
125
|
+
|
122
126
|
def self.checks(rule)
|
123
127
|
rule.instance_variable_get(:@__checks)
|
124
128
|
end
|
@@ -167,32 +171,6 @@ module Inspec
|
|
167
171
|
set_skip_rule(dst, sr) unless sr.nil?
|
168
172
|
end
|
169
173
|
|
170
|
-
# Get the full id consisting of profile id + rule id
|
171
|
-
# for the rule. If the rule's profile id is empty,
|
172
|
-
# the given profile_id will be used instead and also
|
173
|
-
# set for the rule.
|
174
|
-
def self.full_id(profile_id, rule)
|
175
|
-
if rule.is_a?(String) or rule.nil?
|
176
|
-
rid = rule
|
177
|
-
else
|
178
|
-
# As the profile context is exclusively pulled with a
|
179
|
-
# profile ID, attach it to the rule if necessary.
|
180
|
-
rid = rule.instance_variable_get(:@id)
|
181
|
-
if rid.nil?
|
182
|
-
# TODO: Message about skipping this rule
|
183
|
-
# due to missing ID
|
184
|
-
return nil
|
185
|
-
end
|
186
|
-
end
|
187
|
-
pid = rule_id(rule)
|
188
|
-
pid = set_rule_id(rule, profile_id) if pid.nil?
|
189
|
-
|
190
|
-
# if we don't have a profile id, just return the rule's ID
|
191
|
-
return rid if pid.nil? or pid.empty?
|
192
|
-
# otherwise combine them
|
193
|
-
"#{pid}/#{rid}"
|
194
|
-
end
|
195
|
-
|
196
174
|
private
|
197
175
|
|
198
176
|
def __add_check(describe_or_expect, values, block)
|
data/lib/inspec/runner.rb
CHANGED
@@ -18,7 +18,6 @@ module Inspec
|
|
18
18
|
attr_reader :backend, :rules
|
19
19
|
def initialize(conf = {})
|
20
20
|
@rules = {}
|
21
|
-
@profile_id = conf[:id]
|
22
21
|
@conf = conf.dup
|
23
22
|
@conf[:logger] ||= Logger.new(nil)
|
24
23
|
|
@@ -74,6 +73,7 @@ module Inspec
|
|
74
73
|
|
75
74
|
@test_collector.add_profile(profile)
|
76
75
|
options[:metadata] = profile.metadata
|
76
|
+
options[:profile] = profile
|
77
77
|
|
78
78
|
libs = profile.libraries.map do |k, v|
|
79
79
|
{ ref: k, content: v }
|
@@ -88,7 +88,10 @@ module Inspec
|
|
88
88
|
end
|
89
89
|
|
90
90
|
def create_context(options = {})
|
91
|
-
|
91
|
+
meta = options['metadata']
|
92
|
+
profile_id = nil
|
93
|
+
profile_id = meta.params[:name] unless meta.nil?
|
94
|
+
Inspec::ProfileContext.new(profile_id, @backend, @conf.merge(options))
|
92
95
|
end
|
93
96
|
|
94
97
|
def add_content(tests, libs, options = {})
|
@@ -101,6 +104,11 @@ module Inspec
|
|
101
104
|
ctx.reload_dsl
|
102
105
|
end
|
103
106
|
|
107
|
+
# hand the context to the profile for further evaluation
|
108
|
+
unless (profile = options['profile']).nil?
|
109
|
+
profile.runner_context = ctx
|
110
|
+
end
|
111
|
+
|
104
112
|
# evaluate the test content
|
105
113
|
tests = [tests] unless tests.is_a? Array
|
106
114
|
tests.each { |t| add_test_to_context(t, ctx) }
|
@@ -124,7 +132,10 @@ module Inspec
|
|
124
132
|
|
125
133
|
def filter_controls(controls_map, include_list)
|
126
134
|
return controls_map if include_list.nil? || include_list.empty?
|
127
|
-
controls_map.select
|
135
|
+
controls_map.select do |_, c|
|
136
|
+
id = ::Inspec::Rule.rule_id(c)
|
137
|
+
include_list.include?(id)
|
138
|
+
end
|
128
139
|
end
|
129
140
|
|
130
141
|
def block_source_info(block)
|
@@ -186,7 +197,7 @@ module Inspec
|
|
186
197
|
# scope.
|
187
198
|
dsl = Inspec::Resource.create_dsl(backend)
|
188
199
|
example.send(:include, dsl)
|
189
|
-
@test_collector.add_test(example,
|
200
|
+
@test_collector.add_test(example, rule)
|
190
201
|
end
|
191
202
|
end
|
192
203
|
end
|
data/lib/inspec/runner_mock.rb
CHANGED
data/lib/inspec/runner_rspec.rb
CHANGED
@@ -7,10 +7,8 @@ require 'rspec/its'
|
|
7
7
|
require 'inspec/rspec_json_formatter'
|
8
8
|
|
9
9
|
# There be dragons!! Or borgs, or something...
|
10
|
-
# This file and all its contents cannot
|
11
|
-
#
|
12
|
-
# To circumvent this, we need functional tests which tackle the RSpec runner
|
13
|
-
# or a separate suite of unit tests to which get along with this.
|
10
|
+
# This file and all its contents cannot be unit-tested. both test-suits
|
11
|
+
# collide and disable all unit tests that have been added.
|
14
12
|
|
15
13
|
module Inspec
|
16
14
|
class RunnerRspec
|
@@ -35,7 +33,7 @@ module Inspec
|
|
35
33
|
# @return [nil]
|
36
34
|
def add_profile(profile)
|
37
35
|
RSpec.configuration.formatters
|
38
|
-
.find_all { |c| c.is_a?
|
36
|
+
.find_all { |c| c.is_a? InspecRspecJson }
|
39
37
|
.each do |fmt|
|
40
38
|
fmt.add_profile(profile)
|
41
39
|
end
|
@@ -46,8 +44,8 @@ module Inspec
|
|
46
44
|
# @param [RSpecExampleGroup] example test
|
47
45
|
# @param [String] rule_id the ID associated with this check
|
48
46
|
# @return [nil]
|
49
|
-
def add_test(example,
|
50
|
-
set_rspec_ids(example,
|
47
|
+
def add_test(example, rule)
|
48
|
+
set_rspec_ids(example, rule)
|
51
49
|
@tests.example_groups.push(example)
|
52
50
|
end
|
53
51
|
|
@@ -83,6 +81,12 @@ module Inspec
|
|
83
81
|
RSpec.configuration.reset
|
84
82
|
end
|
85
83
|
|
84
|
+
FORMATTERS = {
|
85
|
+
'json-min' => 'InspecRspecMiniJson',
|
86
|
+
'json' => 'InspecRspecJson',
|
87
|
+
'json-rspec' => 'InspecRspecVanilla',
|
88
|
+
}.freeze
|
89
|
+
|
86
90
|
# Configure the output formatter and stream to be used with RSpec.
|
87
91
|
#
|
88
92
|
# @return [nil]
|
@@ -93,8 +97,7 @@ module Inspec
|
|
93
97
|
RSpec.configuration.output_stream = @conf['output']
|
94
98
|
end
|
95
99
|
|
96
|
-
format = @conf['format'] || 'progress'
|
97
|
-
format = 'InspecRspecFormatter' if format == 'fulljson'
|
100
|
+
format = FORMATTERS[@conf['format']] || @conf['format'] || 'progress'
|
98
101
|
RSpec.configuration.add_formatter(format)
|
99
102
|
RSpec.configuration.color = @conf['color']
|
100
103
|
|
@@ -111,27 +114,26 @@ module Inspec
|
|
111
114
|
# by the InSpec adjusted json formatter (rspec_json_formatter).
|
112
115
|
#
|
113
116
|
# @param [RSpecExampleGroup] example object which contains a check
|
114
|
-
# @param [Type] id describe id
|
115
117
|
# @return [Type] description of returned object
|
116
|
-
def set_rspec_ids(example,
|
117
|
-
example.metadata
|
118
|
-
example.metadata[:impact] = rule.impact
|
119
|
-
example.metadata[:title] = rule.title
|
120
|
-
example.metadata[:desc] = rule.desc
|
121
|
-
example.metadata[:code] = rule.instance_variable_get(:@__code)
|
122
|
-
example.metadata[:source_location] = rule.instance_variable_get(:@__source_location)
|
118
|
+
def set_rspec_ids(example, rule)
|
119
|
+
assign_rspec_ids(example.metadata, rule)
|
123
120
|
example.filtered_examples.each do |e|
|
124
|
-
e.metadata
|
125
|
-
e.metadata[:impact] = rule.impact
|
126
|
-
e.metadata[:title] = rule.title
|
127
|
-
e.metadata[:desc] = rule.desc
|
128
|
-
e.metadata[:code] = rule.instance_variable_get(:@__code)
|
129
|
-
e.metadata[:source_location] = rule.instance_variable_get(:@__source_location)
|
121
|
+
assign_rspec_ids(e.metadata, rule)
|
130
122
|
end
|
131
123
|
example.children.each do |child|
|
132
|
-
set_rspec_ids(child,
|
124
|
+
set_rspec_ids(child, rule)
|
133
125
|
end
|
134
126
|
end
|
127
|
+
|
128
|
+
def assign_rspec_ids(metadata, rule)
|
129
|
+
metadata[:id] = ::Inspec::Rule.rule_id(rule)
|
130
|
+
metadata[:profile_id] = ::Inspec::Rule.profile_id(rule)
|
131
|
+
metadata[:impact] = rule.impact
|
132
|
+
metadata[:title] = rule.title
|
133
|
+
metadata[:desc] = rule.desc
|
134
|
+
metadata[:code] = rule.instance_variable_get(:@__code)
|
135
|
+
metadata[:source_location] = rule.instance_variable_get(:@__source_location)
|
136
|
+
end
|
135
137
|
end
|
136
138
|
|
137
139
|
class RSpecReporter < RSpec::Core::Formatters::JsonFormatter
|
data/lib/inspec/version.rb
CHANGED
data/lib/matchers/matchers.rb
CHANGED
@@ -106,7 +106,7 @@ RSpec::Matchers.define :be_installed do
|
|
106
106
|
end
|
107
107
|
|
108
108
|
chain :with_version do |version|
|
109
|
-
warn "[DEPRECATION] `with_version` is deprecated. Please use `its(
|
109
|
+
warn "[DEPRECATION] `with_version` is deprecated. Please use `its('version') { should eq '1.4.1' }` instead."
|
110
110
|
@version = version
|
111
111
|
end
|
112
112
|
end
|
@@ -146,7 +146,7 @@ end
|
|
146
146
|
# Deprecated: You should not use this matcher anymore
|
147
147
|
RSpec::Matchers.define :belong_to_group do |compare_group|
|
148
148
|
match do |user|
|
149
|
-
warn "[DEPRECATION] `belong_to_group` is deprecated. Please use `its(
|
149
|
+
warn "[DEPRECATION] `belong_to_group` is deprecated. Please use `its('groups') { should include('root') }` instead."
|
150
150
|
user.groups.include?(compare_group)
|
151
151
|
end
|
152
152
|
|
@@ -159,7 +159,7 @@ end
|
|
159
159
|
# Deprecated: You should not use this matcher anymore
|
160
160
|
RSpec::Matchers.define :belong_to_primary_group do |compare_group|
|
161
161
|
match do |user|
|
162
|
-
warn "[DEPRECATION] `belong_to_primary_group` is deprecated. Please use `its(
|
162
|
+
warn "[DEPRECATION] `belong_to_primary_group` is deprecated. Please use `its('group') { should eq 'root' }` instead."
|
163
163
|
user.group == compare_group
|
164
164
|
end
|
165
165
|
|
@@ -67,11 +67,11 @@ module Inspec::Resources
|
|
67
67
|
end
|
68
68
|
|
69
69
|
describe auditd_rules.key('sshd_config') do
|
70
|
-
its(
|
70
|
+
its('permissions') { should contain_match(/x/) }
|
71
71
|
end
|
72
72
|
|
73
73
|
describe auditd_rules do
|
74
|
-
its(
|
74
|
+
its('lines') { should contain_match(%r{-w /etc/ssh/sshd_config/}) }
|
75
75
|
end
|
76
76
|
"
|
77
77
|
|
data/lib/resources/host.rb
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
# describe host('example.com') do
|
7
7
|
# it { should be_resolvable }
|
8
8
|
# it { should be_reachable }
|
9
|
-
# its(
|
9
|
+
# its('ipaddress') { should include '93.184.216.34' }
|
10
10
|
# end
|
11
11
|
#
|
12
12
|
# To verify a hostname with protocol and port
|
data/lib/resources/interface.rb
CHANGED
@@ -8,7 +8,7 @@ module Inspec::Resources
|
|
8
8
|
desc 'Use the kernel_parameter InSpec audit resource to test kernel parameters on Linux platforms.'
|
9
9
|
example "
|
10
10
|
describe kernel_parameter('net.ipv4.conf.all.forwarding') do
|
11
|
-
its(
|
11
|
+
its('value') { should eq 0 }
|
12
12
|
end
|
13
13
|
"
|
14
14
|
|
data/lib/resources/mount.rb
CHANGED
@@ -11,10 +11,11 @@ module Inspec::Resources
|
|
11
11
|
example "
|
12
12
|
describe mount('/') do
|
13
13
|
it { should be_mounted }
|
14
|
-
its(
|
14
|
+
its('count') { should eq 1 }
|
15
15
|
its('device') { should eq '/dev/mapper/VolGroup-lv_root' }
|
16
16
|
its('type') { should eq 'ext4' }
|
17
17
|
its('options') { should eq ['rw', 'mode=620'] }
|
18
|
+
its('options') { should include 'nodev' }
|
18
19
|
end
|
19
20
|
"
|
20
21
|
include MountParser
|
data/lib/resources/os_env.rb
CHANGED
@@ -7,8 +7,8 @@
|
|
7
7
|
# Usage:
|
8
8
|
#
|
9
9
|
# describe os_env('PATH') do
|
10
|
-
# its(
|
11
|
-
# its(
|
10
|
+
# its('split') { should_not include('') }
|
11
|
+
# its('split') { should_not include('.') }
|
12
12
|
# end
|
13
13
|
|
14
14
|
require 'utils/simpleconfig'
|
data/lib/resources/passwd.rb
CHANGED
@@ -14,9 +14,10 @@
|
|
14
14
|
# - command
|
15
15
|
|
16
16
|
require 'utils/parser'
|
17
|
+
require 'utils/filter'
|
17
18
|
|
18
19
|
module Inspec::Resources
|
19
|
-
class Passwd < Inspec.resource(1)
|
20
|
+
class Passwd < Inspec.resource(1)
|
20
21
|
name 'passwd'
|
21
22
|
desc 'Use the passwd InSpec audit resource to test the contents of /etc/passwd, which contains the following information for users that may log into the system and/or as users that own running processes.'
|
22
23
|
example "
|
@@ -37,7 +38,6 @@ module Inspec::Resources
|
|
37
38
|
|
38
39
|
include PasswdParser
|
39
40
|
|
40
|
-
attr_reader :uid
|
41
41
|
attr_reader :params
|
42
42
|
attr_reader :content
|
43
43
|
attr_reader :lines
|
@@ -47,111 +47,51 @@ module Inspec::Resources
|
|
47
47
|
@path = path || '/etc/passwd'
|
48
48
|
@content = opts[:content] || inspec.file(@path).content
|
49
49
|
@lines = @content.to_s.split("\n")
|
50
|
-
@filters = opts[:filters] || ''
|
51
50
|
@params = parse_passwd(@content)
|
52
51
|
end
|
53
52
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
53
|
+
filter = FilterTable.create
|
54
|
+
filter.add_accessor(:where)
|
55
|
+
.add_accessor(:entries)
|
56
|
+
.add(:users, field: 'user')
|
57
|
+
.add(:passwords, field: 'password')
|
58
|
+
.add(:uids, field: 'uid')
|
59
|
+
.add(:gids, field: 'gid')
|
60
|
+
.add(:descs, field: 'desc')
|
61
|
+
.add(:homes, field: 'home')
|
62
|
+
.add(:shells, field: 'shell')
|
64
63
|
|
65
|
-
|
64
|
+
filter.add(:count) { |t, _|
|
65
|
+
warn '[DEPRECATION] `passwd.count` is deprecated. Please use `passwd.entries.length` instead. It will be removed in version 1.0.0.'
|
66
|
+
t.entries.length
|
67
|
+
}
|
68
|
+
|
69
|
+
filter.add(:usernames) { |t, x|
|
66
70
|
warn '[DEPRECATION] `passwd.usernames` is deprecated. Please use `passwd.users` instead. It will be removed in version 1.0.0.'
|
67
|
-
users
|
68
|
-
|
71
|
+
t.users(x)
|
72
|
+
}
|
69
73
|
|
70
|
-
|
71
|
-
warn '[DEPRECATION] `passwd.
|
72
|
-
users[0]
|
73
|
-
|
74
|
+
filter.add(:username) { |t, x|
|
75
|
+
warn '[DEPRECATION] `passwd.username` is deprecated. Please use `passwd.users` instead. It will be removed in version 1.0.0.'
|
76
|
+
t.users(x)[0]
|
77
|
+
}
|
78
|
+
|
79
|
+
# rebuild the passwd line from raw content
|
80
|
+
filter.add(:content) { |t, _|
|
81
|
+
t.entries.map do |e|
|
82
|
+
[e.user, e.password, e.uid, e.gid, e.desc, e.home, e.shell].join(':')
|
83
|
+
end.join("\n")
|
84
|
+
}
|
74
85
|
|
75
86
|
def uid(x)
|
76
87
|
warn '[DEPRECATION] `passwd.uid(arg)` is deprecated. Please use `passwd.uids(arg)` instead. It will be removed in version 1.0.0.'
|
77
88
|
uids(x)
|
78
89
|
end
|
79
90
|
|
80
|
-
|
81
|
-
name.nil? ? map_data('user') : filter(user: name)
|
82
|
-
end
|
83
|
-
|
84
|
-
def passwords(password = nil)
|
85
|
-
password.nil? ? map_data('password') : filter(password: password)
|
86
|
-
end
|
87
|
-
|
88
|
-
def uids(uid = nil)
|
89
|
-
uid.nil? ? map_data('uid') : filter(uid: uid)
|
90
|
-
end
|
91
|
-
|
92
|
-
def gids(gid = nil)
|
93
|
-
gid.nil? ? map_data('gid') : filter(gid: gid)
|
94
|
-
end
|
95
|
-
|
96
|
-
def homes(home = nil)
|
97
|
-
home.nil? ? map_data('home') : filter(home: home)
|
98
|
-
end
|
99
|
-
|
100
|
-
def shells(shell = nil)
|
101
|
-
shell.nil? ? map_data('shell') : filter(shell: shell)
|
102
|
-
end
|
91
|
+
filter.connect(self, :params)
|
103
92
|
|
104
93
|
def to_s
|
105
|
-
|
106
|
-
"/etc/passwd#{f}"
|
107
|
-
end
|
108
|
-
|
109
|
-
def count
|
110
|
-
@params.length
|
111
|
-
end
|
112
|
-
|
113
|
-
private
|
114
|
-
|
115
|
-
def map_data(id)
|
116
|
-
@params.map { |x| x[id] }
|
117
|
-
end
|
118
|
-
|
119
|
-
def filter_res_line(item, matcher, condition, positive)
|
120
|
-
# TODO: REWORK ALL OF THESE, please don't depend on them except for simple equality!
|
121
|
-
case matcher
|
122
|
-
when '<'
|
123
|
-
item.to_i < condition
|
124
|
-
when '<='
|
125
|
-
item.to_i <= condition
|
126
|
-
when '>'
|
127
|
-
item.to_i > condition
|
128
|
-
when '>='
|
129
|
-
item.to_i >= condition
|
130
|
-
else
|
131
|
-
condition = condition.to_s if condition.is_a? Integer
|
132
|
-
case item
|
133
|
-
when condition
|
134
|
-
positive
|
135
|
-
else
|
136
|
-
!positive
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
def filter_attribute(attr, condition, res, filters)
|
142
|
-
matcher = '=='
|
143
|
-
positive = true
|
144
|
-
if condition.is_a?(Hash) && condition.length == 1
|
145
|
-
matcher = condition.keys[0].to_s
|
146
|
-
condition = condition.values[0]
|
147
|
-
end
|
148
|
-
positive = false if matcher == '!='
|
149
|
-
|
150
|
-
a = res.find_all do |line|
|
151
|
-
filter_res_line(line[attr.to_s], matcher, condition, positive)
|
152
|
-
end
|
153
|
-
b = filters + " #{attr} #{matcher} #{condition.inspect}"
|
154
|
-
[a, b]
|
94
|
+
'/etc/passwd'
|
155
95
|
end
|
156
96
|
end
|
157
97
|
end
|