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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 9b62b4f6fb99a066fef6c3b066654b3ca6b475bf
4
- data.tar.gz: 7b359dff9c331446fb456ff6179f3374b8090ae4
2
+ SHA256:
3
+ metadata.gz: ab5612bdc60b04a6dd7d8fd5d975ff5a3f76c6725aaa6a5f5b839e18c1220938
4
+ data.tar.gz: e4cf768fa8cbebbe8c0a417cf103916026ca2083291f0bf78391ca23c5164410
5
5
  SHA512:
6
- metadata.gz: 0712410c9cf84ef7cfd5a22d3a3d92670b57681056559b87275797ec015e12798c100b5974a351fafa09186f27a2b8b417071d7fb37572c11690f9e9632f09a6
7
- data.tar.gz: '0826976f613dca3a6abb11228f03f0420740b9599dcf9f62ce0f7c642218d604de4d2bcf74ad97c83b6308384706dabff8daed00c0a1839c513376a4be957ab4'
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. The converters in version 0.2 are:
3
+ InspecTools supplies several CLI tools to convert to and from InSpec format.
4
4
 
5
- * compliance
6
- * summary
7
- * csv2inspec
8
- * inspec2csv
9
- * xccdf2inspec
10
- * inspec2xccdf
11
- * inspec2ckl
12
- * pdf2inspec
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', :git => "https://github.com/mitre/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
- compliance parses an inspec results json to check if the compliance level meets a specified threshold.
59
+ compliance parses an inspec results json to check if the compliance level meets a specified threshold.
67
60
 
68
- If the specified threshold is not met, an error code (1) is returned along with non-compliant elements.
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
- summary parses an inspec results json to create a summary json
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/). 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).
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
- 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.
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
- DISA STIGs are published by DISA IASE, see: https://iase.disa.mil/Pages/privacy_policy.aspx
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
@@ -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
- ckl = InspecTools::Inspec.new(File.read(options[:inspec_json])).to_ckl
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
 
@@ -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
- istig.stig_info = HappyMapperTools::StigChecklist::StigInfo.new
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.type = 'Computing'
160
- @checklist.asset = asset
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
@@ -1,3 +1,3 @@
1
1
  module InspecTools
2
- VERSION = '1.2.2'.freeze
2
+ VERSION = '1.3.0'.freeze
3
3
  end
@@ -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.title
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] = control['desc']
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].split.join(' ')}" if control_clk_status == 'Not_Applicable'
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'], "Red Hat Enterprise Linux 7 Security Technical Implementation Guide")
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.2.2
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-03-11 00:00:00.000000000 Z
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
- rubyforge_project:
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