inspec_tools 1.2.2 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +69 -41
- data/lib/inspec_tools/cli.rb +13 -2
- data/lib/inspec_tools/inspec.rb +80 -4
- data/lib/inspec_tools/version.rb +1 -1
- data/lib/inspec_tools/xccdf.rb +20 -6
- data/lib/utilities/inspec_util.rb +64 -14
- data/test/unit/inspec_tools/xccdf_test.rb +1 -1
- metadata +9 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ab5612bdc60b04a6dd7d8fd5d975ff5a3f76c6725aaa6a5f5b839e18c1220938
|
4
|
+
data.tar.gz: e4cf768fa8cbebbe8c0a417cf103916026ca2083291f0bf78391ca23c5164410
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cbd6887370c90566a49dbcb9a954dd530fdb196017fe3b164dd5dcb2bb49549eb6ce840cb17093411dc8bab9a3201b4fe2e8f9a1083785584fb5134fdbeeec97
|
7
|
+
data.tar.gz: 0db929f5f420127940b1ed1f90b37d9ea2dea25960d903eb56b65e707b960d6152d4eaeb95764d1c699ba7e0998d83c5bdded9798e6679ae6085a2fac98f50b0
|
data/README.md
CHANGED
@@ -1,36 +1,30 @@
|
|
1
1
|
# InspecTools
|
2
2
|
|
3
|
-
InspecTools supplies several CLI tools to convert to and from InSpec format.
|
3
|
+
InspecTools supplies several CLI tools to convert to and from InSpec format.
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
The inspec_tools support the following modules:
|
6
|
+
|
7
|
+
- compliance
|
8
|
+
- summary
|
9
|
+
- csv2inspec
|
10
|
+
- inspec2csv
|
11
|
+
- xccdf2inspec
|
12
|
+
- inspec2xccdf
|
13
|
+
- inspec2ckl
|
14
|
+
- pdf2inspec
|
13
15
|
|
14
16
|
It also includes an API that can be used in a ruby application. The Ruby API is defined in lib/inspec_tools/inspec.rb
|
15
17
|
|
16
18
|
# Installation
|
17
19
|
|
18
|
-
Ensure happymapper is not installed, as it will take precedence over nokogiri-happymapper
|
20
|
+
Ensure `happymapper` is not installed, as it will take precedence over `nokogiri-happymapper`.
|
19
21
|
|
20
22
|
Add this line to your application's Gemfile:
|
21
23
|
|
22
24
|
```
|
23
|
-
gem 'inspec_tools'
|
25
|
+
gem 'inspec_tools'
|
24
26
|
```
|
25
27
|
|
26
|
-
And then execute:
|
27
|
-
|
28
|
-
$ bundle
|
29
|
-
|
30
|
-
Clone the repo and install it yourself as:
|
31
|
-
|
32
|
-
$ gem install inspec_tools
|
33
|
-
|
34
28
|
# Usage
|
35
29
|
|
36
30
|
## Ruby Usage
|
@@ -60,12 +54,11 @@ xccdf_results = tool.to_xccdf(attribs_json)
|
|
60
54
|
On the Command Line, `inspec_tools help` will print a listing of all the command with a short description.
|
61
55
|
For detailed help on any command, run `inspec_tools help [COMMAND]`. Help can also be called with the `-h, --help` flags after any command, like `inspec_tools xccdf2inspec -h`.
|
62
56
|
|
63
|
-
|
64
57
|
## compliance
|
65
58
|
|
66
|
-
|
59
|
+
compliance parses an inspec results json to check if the compliance level meets a specified threshold.
|
67
60
|
|
68
|
-
|
61
|
+
If the specified threshold is not met, an error code (1) is returned along with non-compliant elements.
|
69
62
|
|
70
63
|
```
|
71
64
|
USAGE: inspec_tools compliance [OPTIONS] -j <inspec-json> -i <threshold-inline>
|
@@ -81,9 +74,9 @@ Examples:
|
|
81
74
|
inspec_tools compliance -j examples/sample_json/rhel-simp.json -f examples/sample_yaml/threshold.yaml
|
82
75
|
```
|
83
76
|
|
84
|
-
|
85
77
|
##### Possible In-line and yaml file threshold definition styles:
|
86
|
-
|
78
|
+
|
79
|
+
```
|
87
80
|
failed:
|
88
81
|
critical:
|
89
82
|
max: 0
|
@@ -91,8 +84,8 @@ failed:
|
|
91
84
|
max: 1
|
92
85
|
compliance:
|
93
86
|
min: 81
|
94
|
-
|
95
87
|
```
|
88
|
+
|
96
89
|
```
|
97
90
|
{compliance: {min: 80}, failed: {critical: {max: 0}, high: {max: 0}}}
|
98
91
|
```
|
@@ -100,6 +93,7 @@ compliance:
|
|
100
93
|
```
|
101
94
|
{compliance.min: 81, failed.critical.max: 10, failed.high.max: 0}
|
102
95
|
```
|
96
|
+
|
103
97
|
```
|
104
98
|
compliance.min: 81
|
105
99
|
failed.critical.max: 10
|
@@ -108,8 +102,8 @@ failed.high.max: 1
|
|
108
102
|
|
109
103
|
## summary
|
110
104
|
|
111
|
-
|
112
|
-
|
105
|
+
summary parses an inspec results json to create a summary json
|
106
|
+
|
113
107
|
```
|
114
108
|
USAGE: inspec_tools summary [OPTIONS] -j <inspec-json> -o <summary-csv>
|
115
109
|
|
@@ -122,10 +116,10 @@ Examples:
|
|
122
116
|
inspec_tools summary -j examples/sample_json/rhel-simp.json -o summary.json
|
123
117
|
```
|
124
118
|
|
125
|
-
|
126
119
|
## xccdf2inspec
|
127
120
|
|
128
121
|
xccdf2inspec translates an xccdf file to an InSpec profile in one or many files
|
122
|
+
|
129
123
|
```
|
130
124
|
USAGE: inspec_tools xccdf2inspec [OPTIONS] -x <xccdf-file>
|
131
125
|
|
@@ -143,6 +137,7 @@ example: inspec_tools xccdf2inspec -x xccdf_file.xml -a attributes.yml -o myprof
|
|
143
137
|
## inspec2xccdf
|
144
138
|
|
145
139
|
inspec2xccdf converts an InSpec profile in json format to a STIG XCCDF Document
|
140
|
+
|
146
141
|
```
|
147
142
|
USAGE: inspec_tools inspec2xccdf [OPTIONS] -j <inspec-json> -a <xccdf-attr-yml> -o <xccdf-xml>
|
148
143
|
|
@@ -158,6 +153,7 @@ example: inspec_tools inspec2xccdf -j example.json -a attributes.yml -o xccdf.xm
|
|
158
153
|
## csv2inspec
|
159
154
|
|
160
155
|
Convert a csv export of STIG controls to an InSpec profile
|
156
|
+
|
161
157
|
```
|
162
158
|
USAGE: inspec_tools csv2inspec [OPTIONS] -c <stig-csv> -m <map-yml>
|
163
159
|
|
@@ -175,6 +171,7 @@ example: inspec_tools csv2inspec -c stig.csv -m map.yml -o mydir -f ruby -s true
|
|
175
171
|
### generate_map
|
176
172
|
|
177
173
|
This command will generate a `mapping.xml` file that can be passed in to the `csv2inspec` command with the `--m` option.
|
174
|
+
|
178
175
|
```
|
179
176
|
USAGE: inspec_tools generate_map
|
180
177
|
```
|
@@ -182,6 +179,7 @@ USAGE: inspec_tools generate_map
|
|
182
179
|
## inspec2csv
|
183
180
|
|
184
181
|
Convert an InSpec json to a csv file
|
182
|
+
|
185
183
|
```
|
186
184
|
USAGE: inspec_tools inspec2csv [OPTIONS] -j <inspec-json> -o <profile-csv>
|
187
185
|
|
@@ -225,7 +223,7 @@ FLAGS:
|
|
225
223
|
example: inspec_tools pdf2inspec -p benchmark.pdf -o /path/to/myprofile -f ruby -s true
|
226
224
|
```
|
227
225
|
|
228
|
-
## version
|
226
|
+
## version
|
229
227
|
|
230
228
|
Prints out the gem version
|
231
229
|
|
@@ -233,30 +231,60 @@ Prints out the gem version
|
|
233
231
|
USAGE: inspec_tools version
|
234
232
|
```
|
235
233
|
|
236
|
-
# Development
|
234
|
+
# Development / PR process
|
235
|
+
|
237
236
|
This gem was developed using the [CLI Template](https://github.com/tongueroo/cli-template), a generator tool that builds a starter CLI project.
|
238
237
|
|
238
|
+
## A complete PR should include 7 core elements:
|
239
|
+
|
240
|
+
- A signed PR ( aka `git commit -a -s` )
|
241
|
+
- Code for the new functionality
|
242
|
+
- Updates to the CLI
|
243
|
+
- New unit tests for the functionality
|
244
|
+
- Updates to the docs and examples in `README.md` and `./docs/*`
|
245
|
+
- (if needed) Example / Template files ( `metadata.yml`,`example.yml`, etc )
|
246
|
+
- Scripts / Scaffolding code for the Example / Template files ( `generate_map` is an example )
|
247
|
+
- Example Output of the new functionality if it produces an artifact
|
248
|
+
|
249
|
+
1. open an issue on the main inspec_tools website noting the issues your PR will address
|
250
|
+
2. fork the repo
|
251
|
+
3. checkout your repo
|
252
|
+
4. cd to the repo
|
253
|
+
5. git co -b `<your_branch>`
|
254
|
+
6. bundle install
|
255
|
+
7. `hack as you will`
|
256
|
+
8. test via rake
|
257
|
+
9. ensure unit tests still function and add unit tests for your new feature
|
258
|
+
10. add new docs to the `README.md` and to `./docs/examples`
|
259
|
+
11. update the CLI as needed and add in `usage` example
|
260
|
+
12. (if needed) create and document any example or templates
|
261
|
+
13. (if needed) create any supporing scripts
|
262
|
+
14. (opt) gem build inspec_tools.gemspec
|
263
|
+
15. (opt) gem install inspec_tools
|
264
|
+
16. (opt) test via the installed gem
|
265
|
+
17. git commit -a -s `<your_branch>`
|
266
|
+
18. Open a PRs aginst the MITRE inspec_tools repo
|
267
|
+
|
268
|
+
# Testing
|
269
|
+
|
239
270
|
There are a set of unit tests. Run `rake test` to run the tests.
|
240
271
|
|
241
|
-
To release a new version, update the version number in `version.rb` according to the [Semantic Versioning Policy](https://semver.org/).
|
272
|
+
To release a new version, update the version number in `version.rb` according to the [Semantic Versioning Policy](https://semver.org/).
|
273
|
+
|
274
|
+
Then, run `bundle exec rake release` which will create a git tag for the specified version, push git commits and tags, and push the `.gem` file to [github.com](https://github.com/mitre/inspec_tools).
|
242
275
|
|
243
276
|
### NOTICE
|
244
277
|
|
245
278
|
© 2018 The MITRE Corporation.
|
246
279
|
|
247
|
-
Approved for Public Release; Distribution Unlimited. Case Number 18-3678.
|
280
|
+
Approved for Public Release; Distribution Unlimited. Case Number 18-3678.
|
248
281
|
|
249
282
|
## NOTICE
|
250
|
-
MITRE hereby grants express written permission to use, reproduce, distribute, modify, and otherwise leverage this software to the extent permitted by the licensed terms provided in the LICENSE.md file included with this project.
|
251
|
-
|
252
|
-
### NOTICE
|
253
|
-
|
254
|
-
This software was produced for the U. S. Government under Contract Number HHSM-500-2012-00008I, and is subject to Federal Acquisition Regulation Clause 52.227-14, Rights in Data-General.
|
255
283
|
|
256
|
-
|
257
|
-
|
258
|
-
For further information, please contact The MITRE Corporation, Contracts Management Office, 7515 Colshire Drive, McLean, VA 22102-7539, (703) 983-6000.
|
284
|
+
MITRE hereby grants express written permission to use, reproduce, distribute, modify, and otherwise leverage this software to the extent permitted by the licensed terms provided in the LICENSE.md file included with this project.
|
259
285
|
|
260
286
|
### NOTICE
|
261
287
|
|
262
|
-
|
288
|
+
This software was produced for the U. S. Government under Contract Number HHSM-500-2012-00008I, and is subject to Federal Acquisition Regulation Clause 52.227-14, Rights in Data-General.
|
289
|
+
|
290
|
+
No other use other than that granted to the U. S. Government, or to those acting on behalf of the U. S. Government under that Clause is authorized without the express written permission of The MITRE Corporation.DISA STIGs are published by DISA IASE, see: https://iase.disa.mil/Pages/privacy_policy.aspx
|
data/lib/inspec_tools/cli.rb
CHANGED
@@ -15,9 +15,15 @@ module InspecTools
|
|
15
15
|
option :format, required: false, aliases: '-f', enum: %w{ruby hash}, default: 'ruby'
|
16
16
|
option :separate_files, required: false, type: :boolean, default: true, aliases: '-s'
|
17
17
|
option :replace_tags, required: false, aliases: '-r'
|
18
|
+
option :metadata, required: false, aliases: '-m'
|
18
19
|
def xccdf2inspec
|
19
|
-
xccdf = XCCDF.new(File.read(options[:xccdf]))
|
20
|
+
xccdf = XCCDF.new(File.read(options[:xccdf]), options[:replace_tags])
|
20
21
|
profile = xccdf.to_inspec
|
22
|
+
|
23
|
+
if !options[:metadata].nil?
|
24
|
+
xccdf.inject_metadata(File.read(options[:metadata]))
|
25
|
+
end
|
26
|
+
|
21
27
|
Utils::InspecUtil.unpack_inspec_json(options[:output], profile, options[:separate_files], options[:format])
|
22
28
|
if !options[:attributes].nil?
|
23
29
|
attributes = xccdf.to_attributes
|
@@ -68,8 +74,13 @@ module InspecTools
|
|
68
74
|
option :inspec_json, required: true, aliases: '-j'
|
69
75
|
option :output, required: true, aliases: '-o'
|
70
76
|
option :verbose, type: :boolean, aliases: '-V'
|
77
|
+
option :metadata, required: false, aliases: '-m'
|
71
78
|
def inspec2ckl
|
72
|
-
|
79
|
+
metadata = '{}'
|
80
|
+
if !options[:metadata].nil?
|
81
|
+
metadata = File.read(options[:metadata])
|
82
|
+
end
|
83
|
+
ckl = InspecTools::Inspec.new(File.read(options[:inspec_json]), metadata).to_ckl
|
73
84
|
File.write(options[:output], ckl)
|
74
85
|
end
|
75
86
|
|
data/lib/inspec_tools/inspec.rb
CHANGED
@@ -3,6 +3,7 @@ require 'json'
|
|
3
3
|
require 'cgi'
|
4
4
|
require 'csv'
|
5
5
|
require 'yaml'
|
6
|
+
require 'pp'
|
6
7
|
require_relative '../happy_mapper_tools/stig_attributes'
|
7
8
|
require_relative '../happy_mapper_tools/stig_checklist'
|
8
9
|
require_relative '../happy_mapper_tools/benchmark'
|
@@ -16,12 +17,14 @@ require_relative 'csv'
|
|
16
17
|
|
17
18
|
module InspecTools
|
18
19
|
class Inspec
|
19
|
-
def initialize(inspec_json)
|
20
|
+
def initialize(inspec_json, metadata = '{}')
|
20
21
|
@json = JSON.parse(inspec_json)
|
22
|
+
@metadata = JSON.parse(metadata)
|
21
23
|
end
|
22
24
|
|
23
25
|
def to_ckl(title = nil, date = nil, cklist = nil)
|
24
26
|
@data = Utils::InspecUtil.parse_data_for_ckl(@json)
|
27
|
+
@platform = Utils::InspecUtil.get_platform(@json)
|
25
28
|
@title = generate_title title, @json, date
|
26
29
|
@cklist = cklist
|
27
30
|
@checklist = HappyMapperTools::StigChecklist::Checklist.new
|
@@ -147,17 +150,90 @@ module InspecTools
|
|
147
150
|
def generate_ckl
|
148
151
|
stigs = HappyMapperTools::StigChecklist::Stigs.new
|
149
152
|
istig = HappyMapperTools::StigChecklist::IStig.new
|
153
|
+
|
150
154
|
vuln_list = []
|
151
155
|
@data.keys.each do |control_id|
|
152
156
|
vuln_list.push(generate_vuln_data(@data[control_id]))
|
153
157
|
end
|
154
|
-
|
158
|
+
|
159
|
+
si_data = HappyMapperTools::StigChecklist::SiData.new
|
160
|
+
si_data.name = 'stigid'
|
161
|
+
si_data.data = ''
|
162
|
+
if !@metadata['stigid'].nil?
|
163
|
+
si_data.data = @metadata['stigid']
|
164
|
+
end
|
165
|
+
|
166
|
+
stig_info = HappyMapperTools::StigChecklist::StigInfo.new
|
167
|
+
stig_info.si_data = si_data
|
168
|
+
istig.stig_info = stig_info
|
169
|
+
|
155
170
|
istig.vuln = vuln_list
|
156
171
|
stigs.istig = istig
|
157
172
|
@checklist.stig = stigs
|
173
|
+
|
174
|
+
@checklist.asset = generate_asset
|
175
|
+
end
|
176
|
+
|
177
|
+
def generate_asset
|
158
178
|
asset = HappyMapperTools::StigChecklist::Asset.new
|
159
|
-
asset.
|
160
|
-
|
179
|
+
asset.role = !@metadata['role'].nil? ? @metadata['role'] : 'Workstation'
|
180
|
+
asset.type = !@metadata['type'].nil? ? @metadata['type'] : 'Computing'
|
181
|
+
asset.host_name = generate_hostname
|
182
|
+
asset.host_ip = generate_ip
|
183
|
+
asset.host_mac = generate_mac
|
184
|
+
asset.host_fqdn = generate_fqdn
|
185
|
+
asset.tech_area = !@metadata['tech_area'].nil? ? @metadata['tech_area'] : ''
|
186
|
+
asset.target_key = !@metadata['target_key'].nil? ? @metadata['target_key'] : ''
|
187
|
+
asset.web_or_database = !@metadata['web_or_databae'].nil? ? @metadata['web_or_database'] : '0'
|
188
|
+
asset.web_db_site = !@metadata['web_db_site'].nil? ? @metadata['web_db_site'] : ''
|
189
|
+
asset.web_db_instance = !@metadata['web_db_instance'].nil? ? @metadata['web_db_instance'] : ''
|
190
|
+
asset
|
191
|
+
end
|
192
|
+
|
193
|
+
def generate_hostname
|
194
|
+
hostname = @metadata['hostname']
|
195
|
+
if hostname.nil? && @platform.nil?
|
196
|
+
hostname = ''
|
197
|
+
elsif hostname.nil?
|
198
|
+
hostname = @platform[:hostname]
|
199
|
+
end
|
200
|
+
hostname
|
201
|
+
end
|
202
|
+
|
203
|
+
def generate_mac
|
204
|
+
mac = @metadata['mac']
|
205
|
+
if mac.nil?
|
206
|
+
nics = @platform.nil? ? [] : @platform[:network]
|
207
|
+
nics_macs = []
|
208
|
+
nics.each do |nic|
|
209
|
+
nics_macs.push(nic[:mac])
|
210
|
+
end
|
211
|
+
mac = nics_macs.join(',')
|
212
|
+
end
|
213
|
+
mac
|
214
|
+
end
|
215
|
+
|
216
|
+
def generate_fqdn
|
217
|
+
fqdn = @metadata['fqdn']
|
218
|
+
if fqdn.nil? && @platform.nil?
|
219
|
+
fqdn = ''
|
220
|
+
elsif fqdn.nil?
|
221
|
+
fqdn = @platform[:fqdn]
|
222
|
+
end
|
223
|
+
fqdn
|
224
|
+
end
|
225
|
+
|
226
|
+
def generate_ip
|
227
|
+
ip = @metadata['ip']
|
228
|
+
if ip.nil?
|
229
|
+
nics = @platform.nil? ? [] : @platform[:network]
|
230
|
+
nics_ips = []
|
231
|
+
nics.each do |nic|
|
232
|
+
nics_ips.push(*nic[:ip])
|
233
|
+
end
|
234
|
+
ip = nics_ips.join(',')
|
235
|
+
end
|
236
|
+
ip
|
161
237
|
end
|
162
238
|
|
163
239
|
def populate_header
|
data/lib/inspec_tools/version.rb
CHANGED
data/lib/inspec_tools/xccdf.rb
CHANGED
@@ -3,6 +3,7 @@ require_relative '../happy_mapper_tools/cci_attributes'
|
|
3
3
|
require_relative '../utilities/inspec_util'
|
4
4
|
|
5
5
|
require 'digest'
|
6
|
+
require 'json'
|
6
7
|
|
7
8
|
module InspecTools
|
8
9
|
# rubocop:disable Metrics/ClassLength
|
@@ -79,6 +80,13 @@ module InspecTools
|
|
79
80
|
@benchmark.release_date.release_date
|
80
81
|
end
|
81
82
|
|
83
|
+
def inject_metadata(metadata = '{}')
|
84
|
+
json_metadata = JSON.parse(metadata)
|
85
|
+
json_metadata.each do |key, value|
|
86
|
+
@profile[key] = value
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
82
90
|
private
|
83
91
|
|
84
92
|
def replace_tags_in_xccdf(replace_tags, xccdf_xml)
|
@@ -89,20 +97,25 @@ module InspecTools
|
|
89
97
|
end
|
90
98
|
|
91
99
|
def insert_json_metadata
|
92
|
-
@profile['name'] = @benchmark.
|
100
|
+
@profile['name'] = @benchmark.id
|
93
101
|
@profile['title'] = @benchmark.title
|
94
|
-
@profile['maintainer'] = 'The Authors'
|
95
|
-
@profile['copyright'] = 'The Authors'
|
96
|
-
@profile['copyright_email'] = 'you@example.com'
|
97
|
-
@profile['license'] = 'Apache-2.0'
|
102
|
+
@profile['maintainer'] = 'The Authors' if @profile['maintainer'].nil?
|
103
|
+
@profile['copyright'] = 'The Authors' if @profile['copyright'].nil?
|
104
|
+
@profile['copyright_email'] = 'you@example.com' if @profile['copyright_email'].nil?
|
105
|
+
@profile['license'] = 'Apache-2.0' if @profile['license'].nil?
|
98
106
|
@profile['summary'] = "\"#{@benchmark.description.gsub('\\', '\\\\\\').gsub('"', '\"')}\""
|
99
|
-
@profile['version'] = '0.1.0'
|
107
|
+
@profile['version'] = '0.1.0' if @profile['version'].nil?
|
100
108
|
@profile['supports'] = []
|
101
109
|
@profile['attributes'] = []
|
102
110
|
@profile['generator'] = {
|
103
111
|
'name': 'inspec',
|
104
112
|
'version': Gem.loaded_specs['inspec'].version
|
105
113
|
}
|
114
|
+
@profile['plaintext'] = @benchmark.plaintext.plaintext
|
115
|
+
@profile['status'] = "#{@benchmark.status} on #{@benchmark.release_date.release_date}"
|
116
|
+
@profile['reference_href'] = @benchmark.reference.href
|
117
|
+
@profile['reference_publisher'] = @benchmark.reference.dc_publisher
|
118
|
+
@profile['reference_source'] = @benchmark.reference.dc_source
|
106
119
|
end
|
107
120
|
|
108
121
|
def insert_controls
|
@@ -133,6 +146,7 @@ module InspecTools
|
|
133
146
|
control['tags']['ia_controls'] = group.rule.description.ia_controls if group.rule.description.ia_controls != ''
|
134
147
|
control['tags']['check'] = group.rule.check.content
|
135
148
|
control['tags']['fix'] = group.rule.fixtext
|
149
|
+
control['tags']['severity'] = group.rule.severity
|
136
150
|
@controls << control
|
137
151
|
end
|
138
152
|
@profile['controls'] = @controls
|
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'inspec/objects'
|
2
2
|
require 'word_wrap'
|
3
3
|
require 'pp'
|
4
|
+
require 'uri'
|
5
|
+
require 'net/http'
|
4
6
|
|
5
7
|
# rubocop:disable Metrics/ClassLength
|
6
8
|
# rubocop:disable Metrics/AbcSize
|
@@ -94,19 +96,23 @@ module Utils
|
|
94
96
|
if control.key?('results')
|
95
97
|
control['results'].each do |result|
|
96
98
|
data[c_id][:status].push(result['status'])
|
97
|
-
data[c_id][:message].push(result['skip_message']) if result['status'] == 'skipped'
|
99
|
+
data[c_id][:message].push("SKIPPED -- Test: #{result['code_desc']}\nMessage: #{result['skip_message']}\n") if result['status'] == 'skipped'
|
98
100
|
data[c_id][:message].push("FAILED -- Test: #{result['code_desc']}\nMessage: #{result['message']}\n") if result['status'] == 'failed'
|
99
101
|
data[c_id][:message].push("PASS -- #{result['code_desc']}\n") if result['status'] == 'passed'
|
100
102
|
end
|
101
103
|
end
|
102
104
|
if data[c_id][:impact].to_f.zero?
|
103
|
-
data[c_id][:message]
|
105
|
+
data[c_id][:message].unshift("NOT_APPLICABLE -- Description: #{control['desc']}\n\n")
|
104
106
|
end
|
105
107
|
end
|
106
108
|
end
|
107
109
|
data
|
108
110
|
end
|
109
111
|
|
112
|
+
def self.get_platform(json)
|
113
|
+
json['profiles'].find { |profile| !profile[:platform].nil? }
|
114
|
+
end
|
115
|
+
|
110
116
|
def self.to_dotted_hash(hash, recursive_key = '')
|
111
117
|
hash.each_with_object({}) do |(k, v), ret|
|
112
118
|
key = recursive_key + k.to_s
|
@@ -127,7 +133,8 @@ module Utils
|
|
127
133
|
elsif status_list.include?('passed')
|
128
134
|
result = 'NotAFinding'
|
129
135
|
else
|
130
|
-
result = 'Not_Tested'
|
136
|
+
# result = 'Not_Tested' ## STIGViewer does not allow Not_Tested as a possible status.
|
137
|
+
result = 'Not_Reviewed'
|
131
138
|
end
|
132
139
|
if control[:impact].to_f.zero?
|
133
140
|
result = 'Not_Applicable'
|
@@ -139,7 +146,7 @@ module Utils
|
|
139
146
|
result = "One or more of the automated tests failed or was inconclusive for the control \n\n #{control[:message].sort.join}" if control_clk_status == 'Open'
|
140
147
|
result = "All Automated tests passed for the control \n\n #{control[:message].join}" if control_clk_status == 'NotAFinding'
|
141
148
|
result = "Automated test skipped due to known accepted condition in the control : \n\n#{control[:message].join}" if control_clk_status == 'Not_Reviewed'
|
142
|
-
result = "Justification: \n #{control[:message].
|
149
|
+
result = "Justification: \n #{control[:message].join}" if control_clk_status == 'Not_Applicable'
|
143
150
|
result = 'No test available for this control' if control_clk_status == 'Not_Tested'
|
144
151
|
result
|
145
152
|
end
|
@@ -170,9 +177,14 @@ module Utils
|
|
170
177
|
end
|
171
178
|
|
172
179
|
def self.unpack_inspec_json(directory, inspec_json, separated, output_format)
|
180
|
+
if directory == 'id'
|
181
|
+
directory = inspec_json['name']
|
182
|
+
end
|
173
183
|
controls = generate_controls(inspec_json)
|
174
184
|
unpack_profile(directory || 'profile', controls, separated, output_format || 'json')
|
175
185
|
create_inspec_yml(directory || 'profile', inspec_json)
|
186
|
+
create_license(directory || 'profile', inspec_json)
|
187
|
+
create_readme_md(directory || 'profile', inspec_json)
|
176
188
|
end
|
177
189
|
|
178
190
|
private_class_method def self.wrap(str, width = WIDTH)
|
@@ -195,6 +207,7 @@ module Utils
|
|
195
207
|
control.id = json_control['id']
|
196
208
|
control.title = json_control['title']
|
197
209
|
control.impact = get_impact(json_control['impact'])
|
210
|
+
control.add_tag(Inspec::Tag.new('severity', json_control['tags']['severity']))
|
198
211
|
control.add_tag(Inspec::Tag.new('gtitle', json_control['tags']['gtitle']))
|
199
212
|
control.add_tag(Inspec::Tag.new('satisfies', json_control['tags']['satisfies'])) if json_control['tags']['satisfies']
|
200
213
|
control.add_tag(Inspec::Tag.new('gid', json_control['tags']['gid']))
|
@@ -226,26 +239,63 @@ module Utils
|
|
226
239
|
#
|
227
240
|
private_class_method def self.create_inspec_yml(directory, inspec_json)
|
228
241
|
benchmark_info =
|
229
|
-
"name: #{inspec_json['name']}
|
230
|
-
title: #{inspec_json['title']}
|
231
|
-
maintainer: #{inspec_json['maintainer']}
|
232
|
-
copyright: #{inspec_json['copyright']}
|
233
|
-
copyright_email: #{inspec_json['copyright_email']}
|
234
|
-
license: #{inspec_json['license']}
|
235
|
-
summary: #{inspec_json['summary']}
|
236
|
-
version: #{inspec_json['version']}"
|
242
|
+
"name: #{inspec_json['name']}\n" \
|
243
|
+
"title: #{inspec_json['title']}\n" \
|
244
|
+
"maintainer: #{inspec_json['maintainer']}\n" \
|
245
|
+
"copyright: #{inspec_json['copyright']}\n" \
|
246
|
+
"copyright_email: #{inspec_json['copyright_email']}\n" \
|
247
|
+
"license: #{inspec_json['license']}\n" \
|
248
|
+
"summary: #{inspec_json['summary']}\n" \
|
249
|
+
"version: #{inspec_json['version']}\n"
|
237
250
|
|
238
251
|
myfile = File.new("#{directory}/inspec.yml", 'w')
|
239
252
|
myfile.puts benchmark_info
|
240
253
|
end
|
241
254
|
|
255
|
+
private_class_method def self.create_license(directory, inspec_json)
|
256
|
+
license_content = ''
|
257
|
+
if !inspec_json['license'].nil?
|
258
|
+
begin
|
259
|
+
response = Net::HTTP.get_response(URI(inspec_json['license']))
|
260
|
+
if response.code == '200'
|
261
|
+
license_content = response.body
|
262
|
+
else
|
263
|
+
license_content = inspec_json['license']
|
264
|
+
end
|
265
|
+
rescue StandardError => e
|
266
|
+
license_content = inspec_json['license']
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
myfile = File.new("#{directory}/LICENSE", 'w')
|
271
|
+
myfile.puts license_content
|
272
|
+
end
|
273
|
+
|
274
|
+
private_class_method def self.create_readme_md(directory, inspec_json)
|
275
|
+
readme_contents =
|
276
|
+
"\# #{inspec_json['title']}\n" \
|
277
|
+
"#{inspec_json['summary']}\n" \
|
278
|
+
"---\n" \
|
279
|
+
"Name: #{inspec_json['name']}\n" \
|
280
|
+
"Author: #{inspec_json['maintainer']}\n" \
|
281
|
+
"Status: #{inspec_json['status']}\n" \
|
282
|
+
"Copyright: #{inspec_json['copyright']}\n" \
|
283
|
+
"Copyright Email: #{inspec_json['copyright_email']}\n" \
|
284
|
+
"Version: #{inspec_json['version']}\n" \
|
285
|
+
"#{inspec_json['plaintext']}\n" \
|
286
|
+
"Reference: #{inspec_json['reference_href']}\n" \
|
287
|
+
"Reference by: #{inspec_json['reference_publisher']}\n" \
|
288
|
+
"Reference source: #{inspec_json['reference_source']}\n"
|
289
|
+
|
290
|
+
myfile = File.new("#{directory}/README.md", 'w')
|
291
|
+
myfile.puts readme_contents
|
292
|
+
end
|
293
|
+
|
242
294
|
private_class_method def self.unpack_profile(directory, controls, separated, output_format)
|
243
295
|
FileUtils.rm_rf(directory) if Dir.exist?(directory)
|
244
296
|
Dir.mkdir directory unless Dir.exist?(directory)
|
245
297
|
Dir.mkdir "#{directory}/controls" unless Dir.exist?("#{directory}/controls")
|
246
298
|
Dir.mkdir "#{directory}/libraries" unless Dir.exist?("#{directory}/libraries")
|
247
|
-
myfile = File.new("#{directory}/README.md", 'w')
|
248
|
-
myfile.puts "# Example InSpec Profile\n\nthis example shows the implementation of an InSpec profile."
|
249
299
|
if separated
|
250
300
|
if output_format == 'ruby'
|
251
301
|
controls.each do |control|
|
@@ -29,7 +29,7 @@ class XCCDFTest < Minitest::Test
|
|
29
29
|
def test_to_inspec_metadata
|
30
30
|
xccdf = InspecTools::XCCDF.new(File.read('examples/xccdf2inspec/data/U_Red_Hat_Enterprise_Linux_7_STIG_V1R4_Manual-xccdf.xml'))
|
31
31
|
inspec_json = xccdf.to_inspec
|
32
|
-
assert_equal(inspec_json['name'], "
|
32
|
+
assert_equal(inspec_json['name'], "RHEL_7_STIG")
|
33
33
|
assert_equal(inspec_json['title'], "Red Hat Enterprise Linux 7 Security Technical Implementation Guide")
|
34
34
|
assert_equal(inspec_json['maintainer'], "The Authors")
|
35
35
|
assert_equal(inspec_json['copyright'], "The Authors")
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inspec_tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Thew
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: exe
|
13
13
|
cert_chain: []
|
14
|
-
date: 2019-
|
14
|
+
date: 2019-04-17 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: colorize
|
@@ -87,22 +87,22 @@ dependencies:
|
|
87
87
|
name: pdf-reader
|
88
88
|
requirement: !ruby/object:Gem::Requirement
|
89
89
|
requirements:
|
90
|
-
- - "~>"
|
91
|
-
- !ruby/object:Gem::Version
|
92
|
-
version: '2.1'
|
93
90
|
- - ">="
|
94
91
|
- !ruby/object:Gem::Version
|
95
92
|
version: 2.1.0
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '2.1'
|
96
96
|
type: :runtime
|
97
97
|
prerelease: false
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
|
-
- - "~>"
|
101
|
-
- !ruby/object:Gem::Version
|
102
|
-
version: '2.1'
|
103
100
|
- - ">="
|
104
101
|
- !ruby/object:Gem::Version
|
105
102
|
version: 2.1.0
|
103
|
+
- - "~>"
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '2.1'
|
106
106
|
- !ruby/object:Gem::Dependency
|
107
107
|
name: roo
|
108
108
|
requirement: !ruby/object:Gem::Requirement
|
@@ -288,8 +288,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
288
288
|
- !ruby/object:Gem::Version
|
289
289
|
version: '0'
|
290
290
|
requirements: []
|
291
|
-
|
292
|
-
rubygems_version: 2.6.14
|
291
|
+
rubygems_version: 3.0.1
|
293
292
|
signing_key:
|
294
293
|
specification_version: 4
|
295
294
|
summary: Converter utils for Inspec
|