inspec 1.2.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +47 -2
- data/README.md +14 -24
- data/docs/resources/file.md.erb +5 -5
- data/docs/resources/iis_site.md.erb +1 -1
- data/docs/resources/parse_config_file.md.erb +1 -1
- data/docs/resources/registry_key.md.erb +3 -4
- data/docs/shared/matcher_cmp.md.erb +0 -2
- data/examples/profile/README.md +1 -1
- data/lib/bundles/inspec-artifact.rb +7 -0
- data/lib/bundles/inspec-artifact/README.md +1 -0
- data/lib/bundles/inspec-artifact/cli.rb +284 -0
- data/lib/bundles/inspec-supermarket/api.rb +3 -3
- data/lib/inspec/objects/attribute.rb +21 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/matchers/matchers.rb +1 -1
- data/lib/resources/file.rb +76 -24
- data/lib/resources/inetd_conf.rb +6 -0
- data/lib/resources/package.rb +1 -1
- data/lib/resources/processes.rb +9 -11
- data/lib/resources/ssl.rb +2 -2
- metadata +6 -10
- data/examples/profile/inspec.lock +0 -3
- data/examples/ssh/README.md +0 -3
- data/examples/ssh/controls/example.rb +0 -9
- data/examples/ssh/inspec.lock +0 -3
- data/examples/ssh/inspec.yml +0 -8
- data/examples/ssh/libraries/.gitkeep +0 -0
- data/examples/ssh/libraries/habitat.rb +0 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bc80c218f1945dc66bf6d693530077e66212968a
|
|
4
|
+
data.tar.gz: b54754846a031670396d5069a43f7434113e7fde
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 60442e056460a6c14ed1c7587b499f75f40f942f4064f43275ac11943ddb881968edcae4d5c49f49a37b551330d72aa89289438418e6cc24c5d992024365f102
|
|
7
|
+
data.tar.gz: fa8866e5fc94fc087908b6bd313d50295077b436757e70b49e1c4e7c1caed27c344908c548183f0c73096bb1c574b91bebcbd9d67d11b81cf235060ba7a29b66
|
data/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,52 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
-
## [1.
|
|
4
|
-
[Full Changelog](https://github.com/chef/inspec/compare/v1.2.
|
|
3
|
+
## [1.3.0](https://github.com/chef/inspec/tree/1.3.0) (2016-10-28)
|
|
4
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v1.2.1...1.3.0)
|
|
5
|
+
|
|
6
|
+
**Implemented enhancements:**
|
|
7
|
+
|
|
8
|
+
- extend the attributes object with helper methods [\#1220](https://github.com/chef/inspec/pull/1220) ([chris-rock](https://github.com/chris-rock))
|
|
9
|
+
|
|
10
|
+
**Fixed bugs:**
|
|
11
|
+
|
|
12
|
+
- inetd\_conf resource error [\#1253](https://github.com/chef/inspec/issues/1253)
|
|
13
|
+
- Process user should eq \["longusername"\]: usernames get truncated with a '+' at the end [\#995](https://github.com/chef/inspec/issues/995)
|
|
14
|
+
- Remove wildcard from windows package detection [\#1259](https://github.com/chef/inspec/pull/1259) ([chris-rock](https://github.com/chris-rock))
|
|
15
|
+
- Fix nil timeout and retries [\#1256](https://github.com/chef/inspec/pull/1256) ([alexpop](https://github.com/alexpop))
|
|
16
|
+
- Supermarket tools get and filter by tool\_type [\#1254](https://github.com/chef/inspec/pull/1254) ([alexpop](https://github.com/alexpop))
|
|
17
|
+
- Fix processes resource user and command truncation [\#1225](https://github.com/chef/inspec/pull/1225) ([alexpop](https://github.com/alexpop))
|
|
18
|
+
|
|
19
|
+
**Closed issues:**
|
|
20
|
+
|
|
21
|
+
- inetd and xinetd resources inconsistencies [\#1252](https://github.com/chef/inspec/issues/1252)
|
|
22
|
+
- TestKitchen - Duplicate testing when verifier specified in suite definition [\#1240](https://github.com/chef/inspec/issues/1240)
|
|
23
|
+
- Document new DCO process in contributing.md [\#1223](https://github.com/chef/inspec/issues/1223)
|
|
24
|
+
- Move InSpec Community to https://community-slack.chef.io/ [\#1222](https://github.com/chef/inspec/issues/1222)
|
|
25
|
+
- Export Docker package for InSpec from Habitat [\#1212](https://github.com/chef/inspec/issues/1212)
|
|
26
|
+
- Test verify action on Windows 2012 fails - \[no implicit conversion of nil into Array\] on default-windows-2012r2 [\#1193](https://github.com/chef/inspec/issues/1193)
|
|
27
|
+
- Add InSpec habitat plan [\#843](https://github.com/chef/inspec/issues/843)
|
|
28
|
+
|
|
29
|
+
**Merged pull requests:**
|
|
30
|
+
|
|
31
|
+
- Use Slack Badge instead of Gitter badge [\#1262](https://github.com/chef/inspec/pull/1262) ([chris-rock](https://github.com/chris-rock))
|
|
32
|
+
- remove accidentally added file [\#1260](https://github.com/chef/inspec/pull/1260) ([chris-rock](https://github.com/chris-rock))
|
|
33
|
+
- overwrite exec for inetd because respec its is executing `exec` [\#1257](https://github.com/chef/inspec/pull/1257) ([chris-rock](https://github.com/chris-rock))
|
|
34
|
+
- Use include instead of match in the error message [\#1248](https://github.com/chef/inspec/pull/1248) ([artem-sidorenko](https://github.com/artem-sidorenko))
|
|
35
|
+
- Code-block directive is not needed here [\#1247](https://github.com/chef/inspec/pull/1247) ([artem-sidorenko](https://github.com/artem-sidorenko))
|
|
36
|
+
- Set the global message to display again [\#1246](https://github.com/chef/inspec/pull/1246) ([ryankeairns](https://github.com/ryankeairns))
|
|
37
|
+
- Ignore RVM files [\#1245](https://github.com/chef/inspec/pull/1245) ([artem-sidorenko](https://github.com/artem-sidorenko))
|
|
38
|
+
- Change global message regarding 10/25 webinar [\#1244](https://github.com/chef/inspec/pull/1244) ([ryankeairns](https://github.com/ryankeairns))
|
|
39
|
+
- Fix issue with registry\_key example [\#1243](https://github.com/chef/inspec/pull/1243) ([seththoenen](https://github.com/seththoenen))
|
|
40
|
+
- Accessing nested mappings in a yam file [\#1242](https://github.com/chef/inspec/pull/1242) ([chriswessells](https://github.com/chriswessells))
|
|
41
|
+
- Fix broken link in README.md [\#1233](https://github.com/chef/inspec/pull/1233) ([swalberg](https://github.com/swalberg))
|
|
42
|
+
- DOCS: fix commit amend dash [\#1232](https://github.com/chef/inspec/pull/1232) ([alexpop](https://github.com/alexpop))
|
|
43
|
+
- Headers and list elements that include more than one `\_` character we… [\#1231](https://github.com/chef/inspec/pull/1231) ([nathenharvey](https://github.com/nathenharvey))
|
|
44
|
+
- Implements profile signing and verification \[Experimental\] [\#1228](https://github.com/chef/inspec/pull/1228) ([metadave](https://github.com/metadave))
|
|
45
|
+
- Document new DCO process [\#1224](https://github.com/chef/inspec/pull/1224) ([chris-rock](https://github.com/chris-rock))
|
|
46
|
+
- adding by\_user permissions support for windows [\#1215](https://github.com/chef/inspec/pull/1215) ([jeremymv2](https://github.com/jeremymv2))
|
|
47
|
+
|
|
48
|
+
## [v1.2.1](https://github.com/chef/inspec/tree/v1.2.1) (2016-10-15)
|
|
49
|
+
[Full Changelog](https://github.com/chef/inspec/compare/v1.2.0...v1.2.1)
|
|
5
50
|
|
|
6
51
|
**Implemented enhancements:**
|
|
7
52
|
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# InSpec: Inspect Your Infrastructure
|
|
2
2
|
|
|
3
|
-
[](https://community-slack.chef.io/)
|
|
4
4
|
[](https://travis-ci.org/chef/inspec)
|
|
5
5
|
[](https://ci.appveyor.com/project/Chef/inspec/branch/master)
|
|
6
6
|
|
|
@@ -45,6 +45,10 @@ inspec exec test.rb -t docker://container_id
|
|
|
45
45
|
|
|
46
46
|
InSpec requires Ruby ( >1.9 ).
|
|
47
47
|
|
|
48
|
+
### Install as package
|
|
49
|
+
|
|
50
|
+
The InSpec package is available for MacOS, RedHat, Ubuntu and Windows. Download the latest package at [InSpec Downloads](https://downloads.chef.io/inspec).
|
|
51
|
+
|
|
48
52
|
### Install it via rubygems.org
|
|
49
53
|
|
|
50
54
|
When installing from source, gem dependencies may require ruby build tools to be installed.
|
|
@@ -114,7 +118,7 @@ On Windows, you need to install [Ruby](http://rubyinstaller.org/downloads/) with
|
|
|
114
118
|
|
|
115
119
|
Currently, this method of installation only supports Linux. See the [Habitat site](https://www.habitat.sh/) for more information.
|
|
116
120
|
|
|
117
|
-
Download the `hab` binary from the [Habitat](https://www.habitat.sh/docs/get-habitat/) site.
|
|
121
|
+
Download the `hab` binary from the [Habitat](https://www.habitat.sh/docs/get-habitat/) site.
|
|
118
122
|
|
|
119
123
|
```bash
|
|
120
124
|
hab pkg install chef/inspec
|
|
@@ -169,11 +173,12 @@ describe sshd_config do
|
|
|
169
173
|
end
|
|
170
174
|
```
|
|
171
175
|
|
|
172
|
-
* Test your `kitchen.yml` file to verify that only Vagrant is configured as the driver.
|
|
176
|
+
* Test your `kitchen.yml` file to verify that only Vagrant is configured as the driver. The %w() formatting will
|
|
177
|
+
pass rubocop lintng and allow you to access nested mappings.
|
|
173
178
|
|
|
174
179
|
```ruby
|
|
175
180
|
describe yaml('.kitchen.yml') do
|
|
176
|
-
its(
|
|
181
|
+
its(%w(driver name)) { should eq('vagrant') }
|
|
177
182
|
end
|
|
178
183
|
```
|
|
179
184
|
|
|
@@ -284,28 +289,13 @@ Windows | 2012+
|
|
|
284
289
|
|
|
285
290
|
Documentation
|
|
286
291
|
|
|
292
|
+
* http://inspec.io/docs/
|
|
293
|
+
* http://inspec.io/docs/reference/resources/
|
|
287
294
|
* https://github.com/chef/inspec/tree/master/docs
|
|
288
295
|
|
|
289
|
-
Blogs:
|
|
290
|
-
|
|
291
|
-
*
|
|
292
|
-
* [Introduction to InSpec](http://tfitch.com/automation-tools-bootcamp/inspec.html)
|
|
293
|
-
* [InSpec Tutorial: Day 1 - Hello World](http://www.anniehedgie.com/inspec-basics-1)
|
|
294
|
-
* [InSpec Tutorial: Day 2 - Command Resource Blog Logo](http://www.anniehedgie.com/inspec-basics-2)
|
|
295
|
-
* [InSpec Tutorial: Day 3 - File Resource](http://www.anniehedgie.com/inspec-basics-3)
|
|
296
|
-
* [InSpec Tutorial: Day 4 - Custom Matchers](http://www.anniehedgie.com/inspec-basics-4)
|
|
297
|
-
* [InSpec Tutorial: Day 5 - Creating a Profile](http://www.anniehedgie.com/inspec-basics-5)
|
|
298
|
-
* [InSpec Tutorial: Day 6 - Ways to Run It and Places to Store It](http://www.anniehedgie.com/inspec-basics-6)
|
|
299
|
-
* [InSpec Tutorial: Day 7 - How to Inherit a Profile from Chef Compliance Server](http://www.anniehedgie.com/inspec-basics-7)
|
|
300
|
-
* [Windows infrastructure testing using InSpec – Part I](http://datatomix.com/?p=236)
|
|
301
|
-
* [Windows infrastructure testing using InSpec and Profiles – Part II](http://datatomix.com/?p=238)
|
|
302
|
-
* [Testing Ansible with Inspec](http://scienceofficersblog.blogspot.de/2016/02/testing-ansible-with-inspec.html)
|
|
303
|
-
* [Operating Chef/InSpec in an air gapped environment](https://github.com/jeremymv2/chef-intranet-scaffolding/blob/master/README.md)
|
|
304
|
-
|
|
305
|
-
Podcasts:
|
|
306
|
-
|
|
307
|
-
* [InSpec Foodfight](http://foodfightshow.org/2016/02/inspec.html)
|
|
308
|
-
* [Test Driven Infrastructure With Arthur Maltson And Michael Goetz](https://www.arresteddevops.com/tdi/)
|
|
296
|
+
Tutorials/Blogs/Podcasts:
|
|
297
|
+
|
|
298
|
+
* http://inspec.io/tutorials/
|
|
309
299
|
|
|
310
300
|
## Share your Profiles
|
|
311
301
|
|
data/docs/resources/file.md.erb
CHANGED
|
@@ -29,13 +29,13 @@ This InSpec audit resource has the following matchers:
|
|
|
29
29
|
|
|
30
30
|
<%= partial "/shared/matcher_be" %>
|
|
31
31
|
|
|
32
|
-
###
|
|
32
|
+
### be\_block\_device
|
|
33
33
|
|
|
34
34
|
The `be_block_device` matcher tests if the file exists as a block device, such as `/dev/disk0` or `/dev/disk0s9`:
|
|
35
35
|
|
|
36
36
|
it { should be_block_device }
|
|
37
37
|
|
|
38
|
-
###
|
|
38
|
+
### be\_character\_device
|
|
39
39
|
|
|
40
40
|
The `be_character_device` matcher tests if the file exists as a character device (that corresponds to a block device), such as `/dev/rdisk0` or `/dev/rdisk0s9`:
|
|
41
41
|
|
|
@@ -71,7 +71,7 @@ The `be_file` matcher tests if the file exists as a file. This can be useful wit
|
|
|
71
71
|
|
|
72
72
|
it { should be_file }
|
|
73
73
|
|
|
74
|
-
###
|
|
74
|
+
### be\_grouped\_into
|
|
75
75
|
|
|
76
76
|
The `be_grouped_into` matcher tests if the file exists as part of the named group:
|
|
77
77
|
|
|
@@ -83,7 +83,7 @@ The `be_immutable` matcher tests if the file is immutable, i.e. "cannot be chang
|
|
|
83
83
|
|
|
84
84
|
it { should be_immutable }
|
|
85
85
|
|
|
86
|
-
###
|
|
86
|
+
### be\_linked\_to
|
|
87
87
|
|
|
88
88
|
The `be_linked_to` matcher tests if the file is linked to the named target:
|
|
89
89
|
|
|
@@ -95,7 +95,7 @@ The `be_mounted` matcher tests if the file is accessible from the file system:
|
|
|
95
95
|
|
|
96
96
|
it { should be_mounted }
|
|
97
97
|
|
|
98
|
-
###
|
|
98
|
+
### be\_owned\_by
|
|
99
99
|
|
|
100
100
|
The `be_owned_by` matcher tests if the file is owned by the named user, such as `root`:
|
|
101
101
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
title: About the parse_config_file Resource
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
#
|
|
5
|
+
# parse\_config\_file
|
|
6
6
|
|
|
7
7
|
Use the `parse_config_file` InSpec audit resource to test arbitrary configuration files. It works in the same way as `parse_config`. Instead of using a command output, this resource works with files.
|
|
8
8
|
|
|
@@ -73,9 +73,8 @@ For example, to get all child items for a registry key:
|
|
|
73
73
|
The following example shows how find a property that may exist against multiple registry keys, and then test that property for every registry key in which that property is located:
|
|
74
74
|
|
|
75
75
|
describe registry_key({
|
|
76
|
-
hive: HKEY_USERS
|
|
77
|
-
}).children(/^S-1-5-21-[0-9]+-[0-9]+-[0-9]+-[0-9]{3,}\\Software\\Policies\\Microsoft\\Windows\\Installer/).each
|
|
78
|
-
{ |key|
|
|
76
|
+
hive: 'HKEY_USERS'
|
|
77
|
+
}).children(/^S-1-5-21-[0-9]+-[0-9]+-[0-9]+-[0-9]{3,}\\Software\\Policies\\Microsoft\\Windows\\Installer/).each { |key|
|
|
79
78
|
describe registry_key(key) do
|
|
80
79
|
its('AlwaysInstallElevated') { should eq 'value' }
|
|
81
80
|
end
|
|
@@ -101,7 +100,7 @@ The `have_property` matcher tests if a property exists for a registry key:
|
|
|
101
100
|
|
|
102
101
|
it { should have_property 'value' }
|
|
103
102
|
|
|
104
|
-
###
|
|
103
|
+
### have\_property\_value
|
|
105
104
|
|
|
106
105
|
The `have_property_value` matcher tests if a property value exists for a registry key:
|
|
107
106
|
|
data/examples/profile/README.md
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# TODO
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
require 'base64'
|
|
4
|
+
require 'openssl'
|
|
5
|
+
require 'pathname'
|
|
6
|
+
require 'set'
|
|
7
|
+
require 'tempfile'
|
|
8
|
+
require 'yaml'
|
|
9
|
+
|
|
10
|
+
# Notes:
|
|
11
|
+
#
|
|
12
|
+
# Generate keys
|
|
13
|
+
# The initial implementation uses 2048 bit RSA key pairs (public + private).
|
|
14
|
+
# Public keys must be available for a customer to install and verify an artifact.
|
|
15
|
+
# Private keys should be stored in a secure location and NOT be distributed.
|
|
16
|
+
# (They're only for creating artifacts).
|
|
17
|
+
#
|
|
18
|
+
#
|
|
19
|
+
# .IAF file format
|
|
20
|
+
# .iaf = "Inspec Artifact File", easy to rename if you'd like something more appropriate.
|
|
21
|
+
# The iaf file wraps a binary artifact with some metadata. The first implementation
|
|
22
|
+
# looks like this:
|
|
23
|
+
#
|
|
24
|
+
# INSPEC-PROFILE-1
|
|
25
|
+
# name_of_signing_key
|
|
26
|
+
# algorithm
|
|
27
|
+
# signature
|
|
28
|
+
# <empty line>
|
|
29
|
+
# binary-blob
|
|
30
|
+
# <eof>
|
|
31
|
+
#
|
|
32
|
+
# Let's look at each line:
|
|
33
|
+
# INSPEC-PROFILE-1:
|
|
34
|
+
# This is the artifact version descriptor. It should't change unless the
|
|
35
|
+
# format of the archive changes.
|
|
36
|
+
#
|
|
37
|
+
# name_of_signing_key
|
|
38
|
+
# The name of the public key that can be used to verify an artifact
|
|
39
|
+
#
|
|
40
|
+
# algorithm
|
|
41
|
+
# The digest used to sign, I picked SHA512 to start with.
|
|
42
|
+
# If we support multiple digests, we'll need to have the verify() method
|
|
43
|
+
# support each digest.
|
|
44
|
+
#
|
|
45
|
+
# signature
|
|
46
|
+
# The result of passing the binary artifact through the digest algorithm above.
|
|
47
|
+
# Result is base64 encoded.
|
|
48
|
+
#
|
|
49
|
+
# <empty line>
|
|
50
|
+
# We use an empty line to separate artifact header from artifact body (binary blob).
|
|
51
|
+
# The artifact body can be anything you like.
|
|
52
|
+
#
|
|
53
|
+
# binary-blob
|
|
54
|
+
# A binary blob, most likely a .tar.gz or tar.xz file. We'll need to pick one and
|
|
55
|
+
# stick with it as part of the "INSPEC-PROFILE-1" artifact version. If we change block
|
|
56
|
+
# format, the artifact version descriptor must be incremented, and the sign()
|
|
57
|
+
# and verify() methods must be updated to support a newer version.
|
|
58
|
+
#
|
|
59
|
+
#
|
|
60
|
+
# Key revocation
|
|
61
|
+
# This implementation doesn't support key revocation. However, a customer
|
|
62
|
+
# can remove the public cert file before installation, and artifacts will then
|
|
63
|
+
# fail verification.
|
|
64
|
+
#
|
|
65
|
+
# Key locations
|
|
66
|
+
# This implementation uses the current working directory to find public and
|
|
67
|
+
# private keys. We should establish a common key directory (similar to /hab/cache/keys
|
|
68
|
+
# or ~/.hab/cache/keys in Habitat).
|
|
69
|
+
#
|
|
70
|
+
# Extracting artifacts outside of Inspec
|
|
71
|
+
# As in Habitat, the artifact format for Inspec allows the use of common
|
|
72
|
+
# Unix tools to read the header and body of an artifact.
|
|
73
|
+
# To extract the header from a .iaf:
|
|
74
|
+
# sed '/^$/q' foo.iaf
|
|
75
|
+
# To extract the raw content from a .iaf:
|
|
76
|
+
# sed '1,/^$/d' foo.iaf
|
|
77
|
+
|
|
78
|
+
module Artifact
|
|
79
|
+
KEY_BITS=2048
|
|
80
|
+
KEY_ALG=OpenSSL::PKey::RSA
|
|
81
|
+
|
|
82
|
+
INSPEC_PROFILE_VERSION_1='INSPEC-PROFILE-1'.freeze
|
|
83
|
+
INSPEC_REPORT_VERSION_1='INSPEC-REPORT-1'.freeze
|
|
84
|
+
|
|
85
|
+
ARTIFACT_DIGEST=OpenSSL::Digest::SHA512
|
|
86
|
+
ARTIFACT_DIGEST_NAME='SHA512'.freeze
|
|
87
|
+
|
|
88
|
+
VALID_PROFILE_VERSIONS=Set.new [INSPEC_PROFILE_VERSION_1]
|
|
89
|
+
VALID_PROFILE_DIGESTS=Set.new [ARTIFACT_DIGEST_NAME]
|
|
90
|
+
|
|
91
|
+
SIGNED_PROFILE_SUFFIX='iaf'.freeze
|
|
92
|
+
SIGNED_REPORT_SUFFIX='iar'.freeze
|
|
93
|
+
|
|
94
|
+
# rubocop:disable Metrics/ClassLength
|
|
95
|
+
class CLI < Inspec::BaseCLI
|
|
96
|
+
namespace 'artifact'
|
|
97
|
+
|
|
98
|
+
# TODO: find another solution, once https://github.com/erikhuda/thor/issues/261 is fixed
|
|
99
|
+
def self.banner(command, _namespace = nil, _subcommand = false)
|
|
100
|
+
"#{basename} #{subcommand_prefix} #{command.usage}"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def self.subcommand_prefix
|
|
104
|
+
namespace
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
desc 'generate', 'Generate a RSA key pair for signing and verification'
|
|
108
|
+
option :keyname, type: :string, required: true,
|
|
109
|
+
desc: 'Desriptive name of key'
|
|
110
|
+
option :keydir, type: :string, default: './',
|
|
111
|
+
desc: 'Directory to search for keys'
|
|
112
|
+
def generate_keys
|
|
113
|
+
puts 'Generating keys'
|
|
114
|
+
keygen
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
desc 'sign-profile', 'Create a signed .iaf artifact'
|
|
118
|
+
option :profile, type: :string, required: true,
|
|
119
|
+
desc: 'Path to profile directory'
|
|
120
|
+
option :keyname, type: :string, required: true,
|
|
121
|
+
desc: 'Desriptive name of key'
|
|
122
|
+
def sign_profile
|
|
123
|
+
profile_sign
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
desc 'verify-profile', 'Verify a signed .iaf artifact'
|
|
127
|
+
option :infile, type: :string, required: true,
|
|
128
|
+
desc: '.iaf file to verify'
|
|
129
|
+
def verify_profile
|
|
130
|
+
profile_verify
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
desc 'install-profile', 'Verify and install a signed .iaf artifact'
|
|
134
|
+
option :infile, type: :string, required: true,
|
|
135
|
+
desc: '.iaf file to install'
|
|
136
|
+
option :destdir, type: :string, required: true,
|
|
137
|
+
desc: 'Installation directory'
|
|
138
|
+
def install_profile
|
|
139
|
+
profile_install
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
private
|
|
143
|
+
|
|
144
|
+
def keygen
|
|
145
|
+
key = KEY_ALG.new KEY_BITS
|
|
146
|
+
puts 'Generating private key'
|
|
147
|
+
open "#{options['keyname']}.pem.key", 'w' do |io| io.write key.to_pem end
|
|
148
|
+
puts 'Generating public key'
|
|
149
|
+
open "#{options['keyname']}.pem.pub", 'w' do |io| io.write key.public_key.to_pem end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def read_profile_metadata(path_to_profile)
|
|
153
|
+
begin
|
|
154
|
+
p = Pathname.new(path_to_profile)
|
|
155
|
+
p = p.join('inspec.yml')
|
|
156
|
+
if not p.exist?
|
|
157
|
+
fail "#{path_to_profile} doesn't appear to be a valid Inspec profile"
|
|
158
|
+
end
|
|
159
|
+
yaml = YAML.load_file(p.to_s)
|
|
160
|
+
yaml = yaml.to_hash
|
|
161
|
+
|
|
162
|
+
if not yaml.key? 'name'
|
|
163
|
+
fail 'Profile is invalid, name is not defined'
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
if not yaml.key? 'version'
|
|
167
|
+
fail 'Profile is invalid, version is not defined'
|
|
168
|
+
end
|
|
169
|
+
rescue => e
|
|
170
|
+
# rewrap it and pass it up to the CLI
|
|
171
|
+
raise "Error reading Inspec profile metadata: #{e}"
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
yaml
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def profile_compress(path_to_profile, profile_md, workdir)
|
|
178
|
+
profile_name = profile_md['name']
|
|
179
|
+
profile_version = profile_md['version']
|
|
180
|
+
outfile_name = "#{workdir}/#{profile_name}-#{profile_version}.tar.gz"
|
|
181
|
+
`tar czf #{outfile_name} -C #{path_to_profile} .`
|
|
182
|
+
outfile_name
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def profile_sign
|
|
186
|
+
Dir.mktmpdir do |workdir|
|
|
187
|
+
puts "Signing #{options['profile']} with key #{options['keyname']}"
|
|
188
|
+
path_to_profile = options['profile']
|
|
189
|
+
profile_md = read_profile_metadata(path_to_profile)
|
|
190
|
+
artifact_filename = "#{profile_md['name']}-#{profile_md['version']}.#{SIGNED_PROFILE_SUFFIX}"
|
|
191
|
+
tarfile = profile_compress(path_to_profile, profile_md, workdir)
|
|
192
|
+
content = IO.binread(tarfile)
|
|
193
|
+
signing_key = KEY_ALG.new File.read "#{options['keyname']}.pem.key"
|
|
194
|
+
sha = ARTIFACT_DIGEST.new
|
|
195
|
+
signature = signing_key.sign sha, content
|
|
196
|
+
# convert the signature to Base64
|
|
197
|
+
signature_base64 = Base64.encode64(signature)
|
|
198
|
+
tar_content = IO.binread(tarfile)
|
|
199
|
+
File.open(artifact_filename, 'wb') do |f|
|
|
200
|
+
f.puts(INSPEC_PROFILE_VERSION_1)
|
|
201
|
+
f.puts(options['keyname'])
|
|
202
|
+
f.puts(ARTIFACT_DIGEST_NAME)
|
|
203
|
+
f.puts(signature_base64)
|
|
204
|
+
f.puts('') # newline separates artifact header with body
|
|
205
|
+
f.write(tar_content)
|
|
206
|
+
end
|
|
207
|
+
puts "Successfully generated #{artifact_filename}"
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def valid_header?(file_alg, file_version, file_keyname)
|
|
212
|
+
public_keyfile = "#{file_keyname}.pem.pub"
|
|
213
|
+
puts "Looking for #{public_keyfile} to verify artifact"
|
|
214
|
+
if not File.exist? public_keyfile
|
|
215
|
+
fail "Can't find #{public_keyfile}"
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
if not VALID_PROFILE_DIGESTS.member? file_alg
|
|
219
|
+
fail 'Invalid artifact digest algorithm detected'
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
if not VALID_PROFILE_VERSIONS.member? file_version
|
|
223
|
+
fail 'Invalid artifact version detected'
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def verify(file_to_verifiy, &content_block)
|
|
228
|
+
f = File.open(file_to_verifiy, 'r')
|
|
229
|
+
file_version = f.readline.strip!
|
|
230
|
+
file_keyname = f.readline.strip!
|
|
231
|
+
file_alg = f.readline.strip!
|
|
232
|
+
|
|
233
|
+
file_sig = ''
|
|
234
|
+
# the signature is multi-line
|
|
235
|
+
while (line = f.readline) != "\n"
|
|
236
|
+
file_sig += line
|
|
237
|
+
end
|
|
238
|
+
file_sig.strip!
|
|
239
|
+
f.close
|
|
240
|
+
|
|
241
|
+
valid_header?(file_alg, file_version, file_keyname)
|
|
242
|
+
|
|
243
|
+
public_keyfile = "#{file_keyname}.pem.pub"
|
|
244
|
+
verification_key = KEY_ALG.new File.read public_keyfile
|
|
245
|
+
|
|
246
|
+
f = File.open(file_to_verifiy, 'r')
|
|
247
|
+
while f.readline != "\n" do end
|
|
248
|
+
content = f.read
|
|
249
|
+
|
|
250
|
+
signature = Base64.decode64(file_sig)
|
|
251
|
+
digest = ARTIFACT_DIGEST.new
|
|
252
|
+
if verification_key.verify digest, signature, content
|
|
253
|
+
content_block.yield(content)
|
|
254
|
+
else
|
|
255
|
+
puts 'Artifact is invalid'
|
|
256
|
+
end
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def profile_verify
|
|
260
|
+
file_to_verifiy = options['infile']
|
|
261
|
+
puts "Verifying #{file_to_verifiy}"
|
|
262
|
+
verify(file_to_verifiy) do ||
|
|
263
|
+
puts 'Artifact is valid'
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
def profile_install
|
|
268
|
+
puts 'Installing profile'
|
|
269
|
+
file_to_verifiy = options['infile']
|
|
270
|
+
dest_dir = options['destdir']
|
|
271
|
+
verify(file_to_verifiy) do |content|
|
|
272
|
+
Dir.mktmpdir do |workdir|
|
|
273
|
+
tmpfile = Pathname.new(workdir).join('artifact_to_install.tar.gz')
|
|
274
|
+
File.write(tmpfile, content)
|
|
275
|
+
puts "Installing to #{dest_dir}"
|
|
276
|
+
`tar xzf #{tmpfile} -C #{dest_dir}`
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
# register the subcommand to Inspec CLI registry
|
|
283
|
+
Inspec::Plugins::CLI.add_subcommand(Artifact::CLI, 'artifact', 'artifact SUBCOMMAND ...', 'Sign, verify and install artifacts', {})
|
|
284
|
+
end
|
|
@@ -11,11 +11,11 @@ module Supermarket
|
|
|
11
11
|
|
|
12
12
|
# displays a list of profiles
|
|
13
13
|
def self.profiles(supermarket_url = SUPERMARKET_URL)
|
|
14
|
-
url = "#{supermarket_url}/api/v1/tools
|
|
15
|
-
_success, data = get(url, {
|
|
14
|
+
url = "#{supermarket_url}/api/v1/tools"
|
|
15
|
+
_success, data = get(url, { start: 0, items: 100, order: 'recently_added' })
|
|
16
16
|
if !data.nil?
|
|
17
17
|
profiles = JSON.parse(data)
|
|
18
|
-
profiles['items'].map { |x|
|
|
18
|
+
profiles['items'].select { |p| p['tool_type'] == 'compliance_profile' }.map { |x|
|
|
19
19
|
m = %r{^#{supermarket_url}/api/v1/tools/(?<slug>[\w-]+)(/)?$}.match(x['tool'])
|
|
20
20
|
x['slug'] = m[:slug]
|
|
21
21
|
x
|
|
@@ -21,6 +21,18 @@ module Inspec
|
|
|
21
21
|
@opts[:default]
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
def title
|
|
25
|
+
@opts[:title]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def description
|
|
29
|
+
@opts[:description]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def ruby_var_identifier
|
|
33
|
+
'attr_' + @name.downcase.strip.gsub(/\s+/, '-').gsub(/[^\w-]/, '')
|
|
34
|
+
end
|
|
35
|
+
|
|
24
36
|
def to_hash
|
|
25
37
|
{
|
|
26
38
|
name: @name,
|
|
@@ -28,6 +40,15 @@ module Inspec
|
|
|
28
40
|
}
|
|
29
41
|
end
|
|
30
42
|
|
|
43
|
+
def to_ruby
|
|
44
|
+
res = ["#{ruby_var_identifier} = attribute('#{@name}',{"]
|
|
45
|
+
res.push " title: '#{title}'," unless title.to_s.empty?
|
|
46
|
+
res.push " default: '#{default}'," unless default.to_s.empty?
|
|
47
|
+
res.push " description: '#{description}'," unless description.to_s.empty?
|
|
48
|
+
res.push '})'
|
|
49
|
+
res.join("\n")
|
|
50
|
+
end
|
|
51
|
+
|
|
31
52
|
def to_s
|
|
32
53
|
"Attribute #{@name} with #{@value}"
|
|
33
54
|
end
|
data/lib/inspec/version.rb
CHANGED
data/lib/matchers/matchers.rb
CHANGED
|
@@ -219,7 +219,7 @@ end
|
|
|
219
219
|
# unsupported
|
|
220
220
|
RSpec::Matchers.define :contain do |_rule|
|
|
221
221
|
match do |_resource|
|
|
222
|
-
fail "[UNSUPPORTED] `contain` matcher. Please use the following syntax `its('content') { should
|
|
222
|
+
fail "[UNSUPPORTED] `contain` matcher. Please use the following syntax `its('content') { should include('value') }`."
|
|
223
223
|
end
|
|
224
224
|
end
|
|
225
225
|
|
data/lib/resources/file.rb
CHANGED
|
@@ -7,7 +7,20 @@
|
|
|
7
7
|
require 'shellwords'
|
|
8
8
|
|
|
9
9
|
module Inspec::Resources
|
|
10
|
+
module FilePermissionsSelector
|
|
11
|
+
def select_file_perms_style(os)
|
|
12
|
+
if os.unix?
|
|
13
|
+
UnixFilePermissions.new(inspec)
|
|
14
|
+
elsif os.windows?
|
|
15
|
+
WindowsFilePermissions.new(inspec)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
10
20
|
class FileResource < Inspec.resource(1) # rubocop:disable Metrics/ClassLength
|
|
21
|
+
include FilePermissionsSelector
|
|
22
|
+
include MountParser
|
|
23
|
+
|
|
11
24
|
name 'file'
|
|
12
25
|
desc 'Use the file InSpec audit resource to test all system file types, including files, directories, symbolic links, named pipes, sockets, character devices, block devices, and doors.'
|
|
13
26
|
example "
|
|
@@ -16,14 +29,16 @@ module Inspec::Resources
|
|
|
16
29
|
it { should be_file }
|
|
17
30
|
it { should be_readable }
|
|
18
31
|
it { should be_writable }
|
|
32
|
+
it { should be_executable.by_user('root') }
|
|
19
33
|
it { should be_owned_by 'root' }
|
|
20
34
|
its('mode') { should cmp '0644' }
|
|
21
35
|
end
|
|
22
36
|
"
|
|
23
|
-
include MountParser
|
|
24
37
|
|
|
25
38
|
attr_reader :file, :mount_options
|
|
26
39
|
def initialize(path)
|
|
40
|
+
# select permissions style
|
|
41
|
+
@perms_provider = select_file_perms_style(inspec.os)
|
|
27
42
|
@file = inspec.backend.file(path)
|
|
28
43
|
end
|
|
29
44
|
|
|
@@ -51,20 +66,23 @@ module Inspec::Resources
|
|
|
51
66
|
|
|
52
67
|
def readable?(by_usergroup, by_specific_user)
|
|
53
68
|
return false unless exist?
|
|
69
|
+
return skip_resource '`readable?` is not supported on your OS yet.' if @perms_provider.nil?
|
|
54
70
|
|
|
55
|
-
file_permission_granted?('
|
|
71
|
+
file_permission_granted?('read', by_usergroup, by_specific_user)
|
|
56
72
|
end
|
|
57
73
|
|
|
58
74
|
def writable?(by_usergroup, by_specific_user)
|
|
59
75
|
return false unless exist?
|
|
76
|
+
return skip_resource '`writable?` is not supported on your OS yet.' if @perms_provider.nil?
|
|
60
77
|
|
|
61
|
-
file_permission_granted?('
|
|
78
|
+
file_permission_granted?('write', by_usergroup, by_specific_user)
|
|
62
79
|
end
|
|
63
80
|
|
|
64
81
|
def executable?(by_usergroup, by_specific_user)
|
|
65
82
|
return false unless exist?
|
|
83
|
+
return skip_resource '`executable?` is not supported on your OS yet.' if @perms_provider.nil?
|
|
66
84
|
|
|
67
|
-
file_permission_granted?('
|
|
85
|
+
file_permission_granted?('execute', by_usergroup, by_specific_user)
|
|
68
86
|
end
|
|
69
87
|
|
|
70
88
|
def mounted?(expected_options = nil, identical = false)
|
|
@@ -109,16 +127,14 @@ module Inspec::Resources
|
|
|
109
127
|
|
|
110
128
|
private
|
|
111
129
|
|
|
112
|
-
def file_permission_granted?(
|
|
113
|
-
|
|
114
|
-
fail 'Checking file permissions is not supported on your os'
|
|
115
|
-
end
|
|
116
|
-
|
|
130
|
+
def file_permission_granted?(access, by_usergroup, by_specific_user)
|
|
131
|
+
fail '`file_permission_granted?` is not supported on your OS' if @perms_provider.nil?
|
|
117
132
|
if by_specific_user.nil? || by_specific_user.empty?
|
|
133
|
+
fail '`check_file_permission_by_mask` is not supported on your OS' unless inspec.os.unix?
|
|
118
134
|
usergroup = usergroup_for(by_usergroup, by_specific_user)
|
|
119
|
-
check_file_permission_by_mask(usergroup,
|
|
135
|
+
check_file_permission_by_mask(usergroup, access)
|
|
120
136
|
else
|
|
121
|
-
check_file_permission_by_user(by_specific_user,
|
|
137
|
+
@perms_provider.check_file_permission_by_user(by_specific_user, access, source_path)
|
|
122
138
|
end
|
|
123
139
|
end
|
|
124
140
|
|
|
@@ -129,15 +145,44 @@ module Inspec::Resources
|
|
|
129
145
|
(file.mode & mask) != 0
|
|
130
146
|
end
|
|
131
147
|
|
|
132
|
-
def
|
|
148
|
+
def usergroup_for(usergroup, specific_user)
|
|
149
|
+
if usergroup == 'others'
|
|
150
|
+
'other'
|
|
151
|
+
elsif (usergroup.nil? || usergroup.empty?) && specific_user.nil?
|
|
152
|
+
'all'
|
|
153
|
+
else
|
|
154
|
+
usergroup
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
class FilePermissions
|
|
160
|
+
attr_reader :inspec
|
|
161
|
+
def initialize(inspec)
|
|
162
|
+
@inspec = inspec
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
class UnixFilePermissions < FilePermissions
|
|
167
|
+
def check_file_permission_by_user(user, access_type, path)
|
|
168
|
+
flag = case access_type
|
|
169
|
+
when 'read'
|
|
170
|
+
'r'
|
|
171
|
+
when 'write'
|
|
172
|
+
'w'
|
|
173
|
+
when 'execute'
|
|
174
|
+
'x'
|
|
175
|
+
else
|
|
176
|
+
fail 'Invalid access_type provided'
|
|
177
|
+
end
|
|
133
178
|
if inspec.os.linux?
|
|
134
|
-
perm_cmd = "su -s /bin/sh -c \"test -#{flag} #{
|
|
179
|
+
perm_cmd = "su -s /bin/sh -c \"test -#{flag} #{path}\" #{user}"
|
|
135
180
|
elsif inspec.os.bsd? || inspec.os.solaris?
|
|
136
|
-
perm_cmd = "sudo -u #{user} test -#{flag} #{
|
|
181
|
+
perm_cmd = "sudo -u #{user} test -#{flag} #{path}"
|
|
137
182
|
elsif inspec.os.aix?
|
|
138
|
-
perm_cmd = "su #{user} -c test -#{flag} #{
|
|
183
|
+
perm_cmd = "su #{user} -c test -#{flag} #{path}"
|
|
139
184
|
elsif inspec.os.hpux?
|
|
140
|
-
perm_cmd = "su #{user} -c \"test -#{flag} #{
|
|
185
|
+
perm_cmd = "su #{user} -c \"test -#{flag} #{path}\""
|
|
141
186
|
else
|
|
142
187
|
return skip_resource 'The `file` resource does not support `by_user` on your OS.'
|
|
143
188
|
end
|
|
@@ -145,15 +190,22 @@ module Inspec::Resources
|
|
|
145
190
|
cmd = inspec.command(perm_cmd)
|
|
146
191
|
cmd.exit_status == 0 ? true : false
|
|
147
192
|
end
|
|
193
|
+
end
|
|
148
194
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
195
|
+
class WindowsFilePermissions < FilePermissions
|
|
196
|
+
def check_file_permission_by_user(user, access_type, path)
|
|
197
|
+
access_rule = case access_type
|
|
198
|
+
when 'read'
|
|
199
|
+
'@(\'FullControl\', \'Modify\', \'ReadAndExecute\', \'Read\', \'ListDirectory\')'
|
|
200
|
+
when 'write'
|
|
201
|
+
'@(\'FullControl\', \'Modify\', \'Write\')'
|
|
202
|
+
when 'execute'
|
|
203
|
+
'@(\'FullControl\', \'Modify\', \'ReadAndExecute\', \'ExecuteFile\')'
|
|
204
|
+
else
|
|
205
|
+
fail 'Invalid access_type provided'
|
|
206
|
+
end
|
|
207
|
+
cmd = inspec.command("@(@((Get-Acl '#{path}').access | Where-Object {$_.AccessControlType -eq 'Allow' -and $_.IdentityReference -eq '#{user}' }) | Where-Object {($_.FileSystemRights.ToString().Split(',') | % {$_.trim()} | ? {#{access_rule} -contains $_}) -ne $null}) | measure | % { $_.Count }")
|
|
208
|
+
cmd.stdout.chomp == '0' ? false : true
|
|
157
209
|
end
|
|
158
210
|
end
|
|
159
211
|
end
|
data/lib/resources/inetd_conf.rb
CHANGED
|
@@ -22,6 +22,12 @@ module Inspec::Resources
|
|
|
22
22
|
@conf_path = path || '/etc/inetd.conf'
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
# overwrite exec to ensure it works with its
|
|
26
|
+
# TODO: this needs to be fixed in RSpec
|
|
27
|
+
def exec
|
|
28
|
+
read_params['exec']
|
|
29
|
+
end
|
|
30
|
+
|
|
25
31
|
def method_missing(name)
|
|
26
32
|
read_params[name.to_s]
|
|
27
33
|
end
|
data/lib/resources/package.rb
CHANGED
|
@@ -204,7 +204,7 @@ module Inspec::Resources
|
|
|
204
204
|
# Find the package
|
|
205
205
|
cmd = inspec.command <<-EOF.gsub(/^\s*/, '')
|
|
206
206
|
Get-ItemProperty (@("#{search_paths.join('", "')}") | Where-Object { Test-Path $_ }) |
|
|
207
|
-
Where-Object { $_.DisplayName -like "#{package_name}
|
|
207
|
+
Where-Object { $_.DisplayName -like "#{package_name}" -or $_.PSChildName -like "#{package_name}" } |
|
|
208
208
|
Select-Object -Property DisplayName,DisplayVersion | ConvertTo-Json
|
|
209
209
|
EOF
|
|
210
210
|
|
data/lib/resources/processes.rb
CHANGED
|
@@ -26,7 +26,7 @@ module Inspec::Resources
|
|
|
26
26
|
grep = '(/[^/]*)*'+grep if grep[0] != '/'
|
|
27
27
|
grep = Regexp.new('^' + grep + '(\s|$)')
|
|
28
28
|
end
|
|
29
|
-
all_cmds =
|
|
29
|
+
all_cmds = ps_axo
|
|
30
30
|
@list = all_cmds.find_all do |hm|
|
|
31
31
|
hm[:command] =~ grep
|
|
32
32
|
end
|
|
@@ -43,39 +43,37 @@ module Inspec::Resources
|
|
|
43
43
|
|
|
44
44
|
private
|
|
45
45
|
|
|
46
|
-
def
|
|
46
|
+
def ps_axo
|
|
47
47
|
os = inspec.os
|
|
48
48
|
|
|
49
49
|
if os.linux?
|
|
50
|
-
command = 'ps
|
|
50
|
+
command = 'ps axo label,pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user:32,command'
|
|
51
51
|
regex = /^([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+(.*)$/
|
|
52
52
|
else
|
|
53
|
-
command = 'ps
|
|
54
|
-
regex =
|
|
53
|
+
command = 'ps axo pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user,command'
|
|
54
|
+
regex = /^\s*([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+(.*)$/
|
|
55
55
|
end
|
|
56
56
|
build_process_list(command, regex, os)
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
Process = Struct.new(:label, :
|
|
59
|
+
Process = Struct.new(:label, :pid,
|
|
60
60
|
:cpu, :mem, :vsz,
|
|
61
61
|
:rss, :tty, :stat,
|
|
62
|
-
:start, :time, :command)
|
|
62
|
+
:start, :time, :user, :command)
|
|
63
63
|
|
|
64
64
|
def build_process_list(command, regex, os)
|
|
65
65
|
cmd = inspec.command(command)
|
|
66
66
|
all = cmd.stdout.split("\n")[1..-1]
|
|
67
67
|
return [] if all.nil?
|
|
68
|
-
|
|
69
68
|
lines = all.map do |line|
|
|
70
69
|
line.match(regex)
|
|
71
70
|
end.compact
|
|
72
|
-
|
|
73
71
|
lines.map do |m|
|
|
74
72
|
a = m.to_a[1..-1] # grab all matching groups
|
|
75
73
|
a.unshift(nil) unless os.linux?
|
|
76
|
-
a[
|
|
74
|
+
a[1] = a[1].to_i
|
|
75
|
+
a[4] = a[4].to_i
|
|
77
76
|
a[5] = a[5].to_i
|
|
78
|
-
a[6] = a[6].to_i
|
|
79
77
|
Process.new(*a)
|
|
80
78
|
end
|
|
81
79
|
end
|
data/lib/resources/ssl.rb
CHANGED
|
@@ -41,7 +41,7 @@ class SSL < Inspec.resource(1)
|
|
|
41
41
|
'tls1.2',
|
|
42
42
|
].freeze
|
|
43
43
|
|
|
44
|
-
attr_reader :host, :port
|
|
44
|
+
attr_reader :host, :port, :timeout, :retries
|
|
45
45
|
|
|
46
46
|
def initialize(opts = {})
|
|
47
47
|
@host = opts[:host]
|
|
@@ -71,7 +71,7 @@ class SSL < Inspec.resource(1)
|
|
|
71
71
|
res = Parallel.map(groups, in_threads: 8) do |proto, e|
|
|
72
72
|
[proto, SSLShake.hello(x.resource.host, port: x.resource.port,
|
|
73
73
|
protocol: proto, ciphers: e.map(&:cipher),
|
|
74
|
-
timeout:
|
|
74
|
+
timeout: x.resource.timeout, retries: x.resource.retries)]
|
|
75
75
|
end
|
|
76
76
|
Hash[res]
|
|
77
77
|
}
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: inspec
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dominik Richter
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2016-10-
|
|
11
|
+
date: 2016-10-28 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: train
|
|
@@ -344,17 +344,13 @@ files:
|
|
|
344
344
|
- examples/profile/controls/example.rb
|
|
345
345
|
- examples/profile/controls/gordon.rb
|
|
346
346
|
- examples/profile/controls/meta.rb
|
|
347
|
-
- examples/profile/inspec.lock
|
|
348
347
|
- examples/profile/inspec.yml
|
|
349
348
|
- examples/profile/libraries/gordon_config.rb
|
|
350
|
-
- examples/ssh/README.md
|
|
351
|
-
- examples/ssh/controls/example.rb
|
|
352
|
-
- examples/ssh/inspec.lock
|
|
353
|
-
- examples/ssh/inspec.yml
|
|
354
|
-
- examples/ssh/libraries/.gitkeep
|
|
355
|
-
- examples/ssh/libraries/habitat.rb
|
|
356
349
|
- inspec.gemspec
|
|
357
350
|
- lib/bundles/README.md
|
|
351
|
+
- lib/bundles/inspec-artifact.rb
|
|
352
|
+
- lib/bundles/inspec-artifact/README.md
|
|
353
|
+
- lib/bundles/inspec-artifact/cli.rb
|
|
358
354
|
- lib/bundles/inspec-compliance.rb
|
|
359
355
|
- lib/bundles/inspec-compliance/.kitchen.yml
|
|
360
356
|
- lib/bundles/inspec-compliance/README.md
|
|
@@ -537,7 +533,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
537
533
|
version: '0'
|
|
538
534
|
requirements: []
|
|
539
535
|
rubyforge_project:
|
|
540
|
-
rubygems_version: 2.
|
|
536
|
+
rubygems_version: 2.4.6
|
|
541
537
|
signing_key:
|
|
542
538
|
specification_version: 4
|
|
543
539
|
summary: Infrastructure and compliance testing.
|
data/examples/ssh/README.md
DELETED
data/examples/ssh/inspec.lock
DELETED
data/examples/ssh/inspec.yml
DELETED
|
File without changes
|