inspec-core 4.3.2 → 4.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +37 -21
- data/etc/deprecations.json +10 -0
- data/etc/plugin_filters.json +8 -0
- data/lib/bundles/inspec-compliance/api.rb +1 -1
- data/lib/bundles/inspec-compliance/configuration.rb +1 -1
- data/lib/bundles/inspec-compliance/http.rb +1 -1
- data/lib/bundles/inspec-compliance/support.rb +1 -1
- data/lib/bundles/inspec-compliance/target.rb +1 -1
- data/lib/bundles/inspec-supermarket.rb +3 -7
- data/lib/bundles/inspec-supermarket/api.rb +10 -13
- data/lib/bundles/inspec-supermarket/cli.rb +12 -15
- data/lib/bundles/inspec-supermarket/target.rb +7 -11
- data/lib/fetchers/git.rb +14 -15
- data/lib/fetchers/local.rb +6 -10
- data/lib/fetchers/mock.rb +3 -5
- data/lib/fetchers/url.rb +42 -44
- data/lib/inspec.rb +23 -24
- data/lib/inspec/archive/tar.rb +2 -6
- data/lib/inspec/archive/zip.rb +3 -7
- data/lib/inspec/backend.rb +8 -9
- data/lib/inspec/base_cli.rb +64 -65
- data/lib/inspec/cached_fetcher.rb +2 -3
- data/lib/inspec/cli.rb +136 -97
- data/lib/inspec/config.rb +71 -61
- data/lib/inspec/control_eval_context.rb +22 -18
- data/lib/inspec/dependencies/cache.rb +2 -3
- data/lib/inspec/dependencies/dependency_set.rb +2 -3
- data/lib/inspec/dependencies/lockfile.rb +8 -9
- data/lib/inspec/dependencies/requirement.rb +7 -8
- data/lib/inspec/dependencies/resolver.rb +5 -7
- data/lib/inspec/describe.rb +2 -6
- data/lib/inspec/dist.rb +20 -0
- data/lib/inspec/dsl.rb +4 -7
- data/lib/inspec/dsl_shared.rb +1 -2
- data/lib/inspec/env_printer.rb +11 -12
- data/lib/inspec/errors.rb +0 -4
- data/lib/inspec/exceptions.rb +0 -1
- data/lib/inspec/expect.rb +5 -8
- data/lib/inspec/fetcher.rb +7 -10
- data/lib/inspec/file_provider.rb +24 -24
- data/lib/inspec/formatters.rb +3 -3
- data/lib/inspec/formatters/base.rb +8 -8
- data/lib/inspec/globals.rb +2 -2
- data/lib/inspec/impact.rb +5 -7
- data/lib/inspec/input_registry.rb +84 -33
- data/lib/inspec/library_eval_context.rb +3 -6
- data/lib/inspec/log.rb +1 -5
- data/lib/inspec/metadata.rb +17 -16
- data/lib/inspec/method_source.rb +5 -9
- data/lib/inspec/objects.rb +10 -12
- data/lib/inspec/objects/control.rb +7 -9
- data/lib/inspec/objects/describe.rb +9 -11
- data/lib/inspec/objects/each_loop.rb +1 -3
- data/lib/inspec/objects/input.rb +24 -26
- data/lib/inspec/objects/list.rb +4 -6
- data/lib/inspec/objects/or_test.rb +2 -4
- data/lib/inspec/objects/ruby_helper.rb +3 -5
- data/lib/inspec/objects/tag.rb +0 -2
- data/lib/inspec/objects/test.rb +9 -11
- data/lib/inspec/objects/value.rb +3 -5
- data/lib/inspec/plugin/v1.rb +2 -2
- data/lib/inspec/plugin/v1/plugin_types/cli.rb +1 -5
- data/lib/inspec/plugin/v1/plugin_types/fetcher.rb +2 -5
- data/lib/inspec/plugin/v1/plugin_types/resource.rb +4 -6
- data/lib/inspec/plugin/v1/plugin_types/secret.rb +1 -5
- data/lib/inspec/plugin/v1/plugin_types/source_reader.rb +1 -5
- data/lib/inspec/plugin/v1/plugins.rb +15 -19
- data/lib/inspec/plugin/v1/registry.rb +0 -4
- data/lib/inspec/plugin/v2.rb +8 -8
- data/lib/inspec/plugin/v2/activator.rb +1 -1
- data/lib/inspec/plugin/v2/config_file.rb +6 -6
- data/lib/inspec/plugin/v2/filter.rb +13 -13
- data/lib/inspec/plugin/v2/installer.rb +36 -24
- data/lib/inspec/plugin/v2/loader.rb +28 -28
- data/lib/inspec/plugin/v2/plugin_base.rb +15 -2
- data/lib/inspec/plugin/v2/plugin_types/cli.rb +5 -5
- data/lib/inspec/plugin/v2/plugin_types/input.rb +34 -0
- data/lib/inspec/plugin/v2/plugin_types/mock.rb +1 -1
- data/lib/inspec/plugin/v2/registry.rb +7 -7
- data/lib/inspec/polyfill.rb +0 -3
- data/lib/inspec/profile.rb +55 -63
- data/lib/inspec/profile_context.rb +27 -30
- data/lib/inspec/profile_vendor.rb +6 -9
- data/lib/inspec/reporters.rb +24 -24
- data/lib/inspec/reporters/automate.rb +17 -19
- data/lib/inspec/reporters/base.rb +1 -1
- data/lib/inspec/reporters/cli.rb +88 -91
- data/lib/inspec/reporters/json.rb +2 -4
- data/lib/inspec/reporters/json_automate.rb +1 -3
- data/lib/inspec/reporters/json_min.rb +1 -3
- data/lib/inspec/reporters/junit.rb +26 -28
- data/lib/inspec/reporters/yaml.rb +1 -3
- data/lib/inspec/require_loader.rb +0 -4
- data/lib/inspec/resource.rb +4 -125
- data/lib/inspec/resources.rb +121 -0
- data/lib/{resources → inspec/resources}/aide_conf.rb +24 -25
- data/lib/{resources → inspec/resources}/apache.rb +13 -14
- data/lib/{resources → inspec/resources}/apache_conf.rb +16 -17
- data/lib/{resources → inspec/resources}/apt.rb +17 -17
- data/lib/{resources → inspec/resources}/audit_policy.rb +7 -6
- data/lib/{resources → inspec/resources}/auditd.rb +62 -64
- data/lib/{resources → inspec/resources}/auditd_conf.rb +7 -8
- data/lib/{resources → inspec/resources}/bash.rb +6 -8
- data/lib/{resources → inspec/resources}/bond.rb +15 -14
- data/lib/{resources → inspec/resources}/bridge.rb +8 -8
- data/lib/{resources → inspec/resources}/chocolatey_package.rb +10 -8
- data/lib/{resources → inspec/resources}/command.rb +11 -10
- data/lib/{resources → inspec/resources}/cpan.rb +12 -12
- data/lib/{resources → inspec/resources}/cran.rb +9 -9
- data/lib/{resources → inspec/resources}/crontab.rb +47 -48
- data/lib/{resources → inspec/resources}/csv.rb +5 -5
- data/lib/{resources → inspec/resources}/dh_params.rb +5 -7
- data/lib/{resources → inspec/resources}/directory.rb +5 -7
- data/lib/{resources → inspec/resources}/docker.rb +63 -63
- data/lib/{resources → inspec/resources}/docker_container.rb +6 -6
- data/lib/{resources → inspec/resources}/docker_image.rb +9 -9
- data/lib/{resources → inspec/resources}/docker_object.rb +8 -13
- data/lib/{resources → inspec/resources}/docker_plugin.rb +6 -6
- data/lib/{resources → inspec/resources}/docker_service.rb +7 -7
- data/lib/{resources → inspec/resources}/elasticsearch.rb +40 -42
- data/lib/{resources → inspec/resources}/etc_fstab.rb +23 -24
- data/lib/{resources → inspec/resources}/etc_group.rb +26 -27
- data/lib/{resources → inspec/resources}/etc_hosts.rb +11 -13
- data/lib/{resources → inspec/resources}/etc_hosts_allow_deny.rb +25 -27
- data/lib/{resources → inspec/resources}/file.rb +80 -79
- data/lib/{resources → inspec/resources}/filesystem.rb +20 -15
- data/lib/{resources → inspec/resources}/firewalld.rb +26 -26
- data/lib/{resources → inspec/resources}/gem.rb +12 -12
- data/lib/{resources → inspec/resources}/groups.rb +28 -27
- data/lib/{resources → inspec/resources}/grub_conf.rb +46 -48
- data/lib/{resources → inspec/resources}/host.rb +31 -29
- data/lib/{resources → inspec/resources}/http.rb +24 -24
- data/lib/{resources → inspec/resources}/iis_app.rb +6 -7
- data/lib/{resources → inspec/resources}/iis_app_pool.rb +21 -19
- data/lib/{resources → inspec/resources}/iis_site.rb +17 -15
- data/lib/{resources → inspec/resources}/inetd_conf.rb +9 -10
- data/lib/{resources → inspec/resources}/ini.rb +7 -8
- data/lib/{resources → inspec/resources}/interface.rb +30 -30
- data/lib/{resources → inspec/resources}/iptables.rb +8 -8
- data/lib/{resources → inspec/resources}/json.rb +8 -10
- data/lib/{resources → inspec/resources}/kernel_module.rb +15 -15
- data/lib/{resources → inspec/resources}/kernel_parameter.rb +8 -8
- data/lib/{resources → inspec/resources}/key_rsa.rb +8 -10
- data/lib/{resources → inspec/resources}/ksh.rb +6 -8
- data/lib/{resources → inspec/resources}/limits_conf.rb +8 -9
- data/lib/{resources/login_def.rb → inspec/resources/login_defs.rb} +9 -10
- data/lib/{resources → inspec/resources}/mount.rb +6 -8
- data/lib/{resources → inspec/resources}/mssql_session.rb +16 -18
- data/lib/inspec/resources/mysql.rb +81 -0
- data/lib/{resources → inspec/resources}/mysql_conf.rb +13 -14
- data/lib/{resources → inspec/resources}/mysql_session.rb +16 -16
- data/lib/{resources → inspec/resources}/nginx.rb +16 -17
- data/lib/{resources → inspec/resources}/nginx_conf.rb +26 -27
- data/lib/{resources → inspec/resources}/npm.rb +9 -10
- data/lib/{resources → inspec/resources}/ntp_conf.rb +9 -10
- data/lib/{resources → inspec/resources}/oneget.rb +8 -8
- data/lib/{resources → inspec/resources}/oracledb_session.rb +33 -34
- data/lib/{resources → inspec/resources}/os.rb +6 -8
- data/lib/{resources → inspec/resources}/os_env.rb +11 -12
- data/lib/{resources → inspec/resources}/package.rb +66 -65
- data/lib/{resources → inspec/resources}/packages.rb +13 -13
- data/lib/{resources → inspec/resources}/parse_config.rb +8 -8
- data/lib/{resources → inspec/resources}/passwd.rb +18 -19
- data/lib/{resources → inspec/resources}/pip.rb +19 -19
- data/lib/{resources → inspec/resources}/platform.rb +9 -11
- data/lib/{resources → inspec/resources}/port.rb +134 -136
- data/lib/{resources → inspec/resources}/postgres.rb +40 -32
- data/lib/{resources → inspec/resources}/postgres_conf.rb +17 -17
- data/lib/{resources → inspec/resources}/postgres_hba_conf.rb +21 -23
- data/lib/{resources → inspec/resources}/postgres_ident_conf.rb +12 -14
- data/lib/{resources → inspec/resources}/postgres_session.rb +8 -9
- data/lib/{resources → inspec/resources}/powershell.rb +17 -13
- data/lib/{resources → inspec/resources}/processes.rb +29 -29
- data/lib/{resources/rabbitmq_conf.rb → inspec/resources/rabbitmq_config.rb} +10 -11
- data/lib/{resources → inspec/resources}/registry_key.rb +14 -14
- data/lib/inspec/resources/script.rb +1 -0
- data/lib/{resources → inspec/resources}/security_identifier.rb +11 -10
- data/lib/{resources → inspec/resources}/security_policy.rb +59 -58
- data/lib/{resources → inspec/resources}/service.rb +74 -75
- data/lib/{resources → inspec/resources}/shadow.rb +44 -45
- data/lib/{resources/ssh_conf.rb → inspec/resources/ssh_config.rb} +16 -17
- data/lib/{resources → inspec/resources}/ssl.rb +28 -29
- data/lib/inspec/resources/sys_info.rb +30 -0
- data/lib/{resources → inspec/resources}/toml.rb +5 -7
- data/lib/{resources → inspec/resources}/users.rb +65 -65
- data/lib/{resources → inspec/resources}/vbscript.rb +8 -9
- data/lib/{resources → inspec/resources}/virtualization.rb +60 -62
- data/lib/{resources → inspec/resources}/windows_feature.rb +9 -9
- data/lib/{resources → inspec/resources}/windows_hotfix.rb +5 -5
- data/lib/{resources → inspec/resources}/windows_task.rb +16 -15
- data/lib/{resources → inspec/resources}/wmi.rb +7 -8
- data/lib/{resources → inspec/resources}/x509_certificate.rb +9 -11
- data/lib/{resources/xinetd.rb → inspec/resources/xinetd_conf.rb} +27 -29
- data/lib/{resources → inspec/resources}/xml.rb +7 -7
- data/lib/{resources → inspec/resources}/yaml.rb +5 -6
- data/lib/{resources → inspec/resources}/yum.rb +10 -10
- data/lib/{resources → inspec/resources}/zfs_dataset.rb +6 -6
- data/lib/{resources → inspec/resources}/zfs_pool.rb +4 -4
- data/lib/inspec/rspec_extensions.rb +24 -8
- data/lib/inspec/rule.rb +14 -15
- data/lib/inspec/runner.rb +28 -28
- data/lib/inspec/runner_mock.rb +1 -5
- data/lib/inspec/runner_rspec.rb +18 -20
- data/lib/inspec/runtime_profile.rb +2 -5
- data/lib/inspec/schema.rb +142 -143
- data/lib/inspec/secrets.rb +3 -7
- data/lib/inspec/secrets/yaml.rb +3 -5
- data/lib/inspec/shell.rb +11 -15
- data/lib/inspec/shell_detector.rb +6 -7
- data/lib/inspec/source_reader.rb +4 -8
- data/lib/inspec/ui.rb +33 -39
- data/lib/inspec/ui_table_helper.rb +12 -0
- data/lib/{utils → inspec/utils}/command_wrapper.rb +4 -8
- data/lib/{utils → inspec/utils}/convert.rb +0 -4
- data/lib/{utils → inspec/utils}/database_helpers.rb +4 -8
- data/lib/inspec/utils/deprecation.rb +6 -0
- data/lib/{utils → inspec/utils}/deprecation/config_file.rb +19 -19
- data/lib/{utils → inspec/utils}/deprecation/deprecator.rb +12 -12
- data/lib/{utils → inspec/utils}/deprecation/errors.rb +1 -1
- data/lib/{utils → inspec/utils}/deprecation/global_method.rb +2 -2
- data/lib/{utils → inspec/utils}/enumerable_delegation.rb +0 -2
- data/lib/{utils → inspec/utils}/erlang_parser.rb +61 -65
- data/lib/{utils → inspec/utils}/file_reader.rb +1 -2
- data/lib/{utils → inspec/utils}/filter.rb +30 -33
- data/lib/{utils → inspec/utils}/filter_array.rb +0 -2
- data/lib/{utils → inspec/utils}/find_files.rb +9 -12
- data/lib/{utils → inspec/utils}/hash.rb +1 -5
- data/lib/inspec/utils/json_log.rb +15 -0
- data/lib/inspec/utils/latest_version.rb +13 -0
- data/lib/{utils → inspec/utils}/modulator.rb +0 -3
- data/lib/{utils → inspec/utils}/nginx_parser.rb +31 -35
- data/lib/{utils → inspec/utils}/object_traversal.rb +0 -3
- data/lib/{utils → inspec/utils}/parser.rb +45 -45
- data/lib/{utils → inspec/utils}/pkey_reader.rb +4 -2
- data/lib/{utils → inspec/utils}/simpleconfig.rb +8 -10
- data/lib/{utils → inspec/utils}/spdx.rb +1 -4
- data/lib/{utils → inspec/utils}/spdx.txt +0 -0
- data/lib/inspec/utils/telemetry.rb +3 -3
- data/lib/inspec/utils/telemetry/collector.rb +30 -9
- data/lib/inspec/utils/telemetry/data_series.rb +3 -1
- data/lib/inspec/utils/telemetry/global_methods.rb +1 -1
- data/lib/inspec/version.rb +1 -1
- data/lib/matchers/matchers.rb +22 -25
- data/lib/plugins/inspec-artifact/lib/inspec-artifact.rb +1 -1
- data/lib/plugins/inspec-artifact/lib/inspec-artifact/base.rb +52 -45
- data/lib/plugins/inspec-artifact/lib/inspec-artifact/cli.rb +18 -16
- data/lib/plugins/inspec-compliance/lib/inspec-compliance.rb +1 -1
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb +73 -73
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/api/login.rb +66 -62
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +59 -57
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/configuration.rb +11 -11
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/http.rb +20 -22
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/support.rb +2 -4
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/target.rb +30 -27
- data/lib/plugins/inspec-habitat/Berksfile +2 -2
- data/lib/plugins/inspec-habitat/lib/inspec-habitat.rb +1 -1
- data/lib/plugins/inspec-habitat/lib/inspec-habitat/cli.rb +15 -13
- data/lib/plugins/inspec-habitat/lib/inspec-habitat/profile.rb +64 -63
- data/lib/plugins/inspec-habitat/templates/habitat/hooks/run.erb +3 -3
- data/lib/plugins/inspec-habitat/templates/habitat/plan.sh.erb +11 -11
- data/lib/plugins/inspec-init/lib/inspec-init.rb +1 -1
- data/lib/plugins/inspec-init/lib/inspec-init/cli.rb +6 -8
- data/lib/plugins/inspec-init/lib/inspec-init/cli_plugin.rb +72 -74
- data/lib/plugins/inspec-init/lib/inspec-init/cli_profile.rb +9 -11
- data/lib/plugins/inspec-init/lib/inspec-init/renderer.rb +4 -4
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/Gemfile +0 -1
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/inspec-plugin-template.gemspec +0 -2
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template.rb +0 -2
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/cli_command.rb +0 -2
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/plugin.rb +0 -2
- data/lib/plugins/inspec-init/templates/plugins/inspec-plugin-template/lib/inspec-plugin-template/version.rb +0 -2
- data/lib/plugins/inspec-init/templates/profiles/os/controls/example.rb +6 -7
- data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli.rb +1 -2
- data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/cli_command.rb +72 -70
- data/lib/plugins/inspec-plugin-manager-cli/lib/inspec-plugin-manager-cli/plugin.rb +1 -1
- data/lib/plugins/shared/core_plugin_test_helper.rb +43 -38
- data/lib/source_readers/flat.rb +6 -10
- data/lib/source_readers/inspec.rb +8 -12
- metadata +139 -140
- data/lib/resources/mysql.rb +0 -82
- data/lib/resources/sys_info.rb +0 -28
- data/lib/utils/deprecation.rb +0 -6
- data/lib/utils/json_log.rb +0 -18
- data/lib/utils/latest_version.rb +0 -22
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# copyright: 2015, Vulcano Security GmbH
|
3
2
|
|
4
3
|
# Usage example:
|
@@ -10,14 +9,15 @@
|
|
10
9
|
# }
|
11
10
|
# describe parse_config(audit, options ) do
|
12
11
|
|
13
|
-
require
|
12
|
+
require "inspec/utils/file_reader"
|
13
|
+
require "inspec/utils/simpleconfig"
|
14
14
|
|
15
15
|
module Inspec::Resources
|
16
16
|
class PConfig < Inspec.resource(1)
|
17
|
-
name
|
18
|
-
supports platform:
|
19
|
-
supports platform:
|
20
|
-
desc
|
17
|
+
name "parse_config"
|
18
|
+
supports platform: "unix"
|
19
|
+
supports platform: "windows"
|
20
|
+
desc "Use the parse_config InSpec audit resource to test arbitrary configuration files."
|
21
21
|
example <<~EXAMPLE
|
22
22
|
output = command('some-command').stdout
|
23
23
|
describe parse_config(output, { data_config_option: value } ) do
|
@@ -92,8 +92,8 @@ module Inspec::Resources
|
|
92
92
|
end
|
93
93
|
|
94
94
|
class PConfigFile < PConfig
|
95
|
-
name
|
96
|
-
desc
|
95
|
+
name "parse_config_file"
|
96
|
+
desc "Use the parse_config_file InSpec resource to test arbitrary configuration files. It works identically to parse_config. Instead of using a command output, this resource works with files."
|
97
97
|
example <<~EXAMPLE
|
98
98
|
describe parse_config_file('/path/to/file') do
|
99
99
|
its('setting') { should eq 1 }
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# copyright: 2015, Vulcano Security GmbH
|
3
2
|
|
4
3
|
# The file format consists of
|
@@ -10,15 +9,15 @@
|
|
10
9
|
# - home directory
|
11
10
|
# - command
|
12
11
|
|
13
|
-
require
|
14
|
-
require
|
15
|
-
require
|
12
|
+
require "inspec/utils/parser"
|
13
|
+
require "inspec/utils/filter"
|
14
|
+
require "inspec/utils/file_reader"
|
16
15
|
|
17
16
|
module Inspec::Resources
|
18
17
|
class Passwd < Inspec.resource(1)
|
19
|
-
name
|
20
|
-
supports platform:
|
21
|
-
desc
|
18
|
+
name "passwd"
|
19
|
+
supports platform: "unix"
|
20
|
+
desc "Use the passwd InSpec audit resource to test the contents of /etc/passwd, which contains the following information for users that may log into the system and/or as users that own running processes."
|
22
21
|
example <<~EXAMPLE
|
23
22
|
describe passwd do
|
24
23
|
its('users') { should_not include 'forbidden_user' }
|
@@ -43,32 +42,32 @@ module Inspec::Resources
|
|
43
42
|
|
44
43
|
def initialize(path = nil, opts = nil)
|
45
44
|
opts ||= {}
|
46
|
-
@path = path ||
|
45
|
+
@path = path || "/etc/passwd"
|
47
46
|
@content = opts[:content] || read_file_content(@path, allow_empty: true)
|
48
47
|
@lines = @content.to_s.split("\n")
|
49
48
|
@params = parse_passwd(@content)
|
50
49
|
end
|
51
50
|
|
52
51
|
filter = FilterTable.create
|
53
|
-
filter.register_column(:users, field:
|
54
|
-
.register_column(:passwords, field:
|
55
|
-
.register_column(:uids, field:
|
56
|
-
.register_column(:gids, field:
|
57
|
-
.register_column(:descs, field:
|
58
|
-
.register_column(:homes, field:
|
59
|
-
.register_column(:shells, field:
|
52
|
+
filter.register_column(:users, field: "user")
|
53
|
+
.register_column(:passwords, field: "password")
|
54
|
+
.register_column(:uids, field: "uid")
|
55
|
+
.register_column(:gids, field: "gid")
|
56
|
+
.register_column(:descs, field: "desc")
|
57
|
+
.register_column(:homes, field: "home")
|
58
|
+
.register_column(:shells, field: "shell")
|
60
59
|
|
61
60
|
# rebuild the passwd line from raw content
|
62
|
-
filter.register_custom_property(:content)
|
61
|
+
filter.register_custom_property(:content) do |t, _|
|
63
62
|
t.entries.map do |e|
|
64
|
-
[e.user, e.password, e.uid, e.gid, e.desc, e.home, e.shell].join(
|
63
|
+
[e.user, e.password, e.uid, e.gid, e.desc, e.home, e.shell].join(":")
|
65
64
|
end.join("\n")
|
66
|
-
|
65
|
+
end
|
67
66
|
|
68
67
|
filter.install_filter_methods_on_resource(self, :params)
|
69
68
|
|
70
69
|
def to_s
|
71
|
-
|
70
|
+
"/etc/passwd"
|
72
71
|
end
|
73
72
|
end
|
74
73
|
end
|
@@ -1,17 +1,17 @@
|
|
1
|
-
|
1
|
+
require "inspec/resources/command"
|
2
|
+
require "inspec/utils/simpleconfig"
|
2
3
|
|
3
4
|
# Usage:
|
4
5
|
# describe pip('Jinja2') do
|
5
6
|
# it { should be_installed }
|
6
7
|
# end
|
7
|
-
#
|
8
8
|
|
9
9
|
module Inspec::Resources
|
10
10
|
class PipPackage < Inspec.resource(1)
|
11
|
-
name
|
12
|
-
supports platform:
|
13
|
-
supports platform:
|
14
|
-
desc
|
11
|
+
name "pip"
|
12
|
+
supports platform: "unix"
|
13
|
+
supports platform: "windows"
|
14
|
+
desc "Use the pip InSpec audit resource to test packages that are installed using the pip installer."
|
15
15
|
example <<~EXAMPLE
|
16
16
|
describe pip('Jinja2') do
|
17
17
|
it { should be_installed }
|
@@ -27,23 +27,23 @@ module Inspec::Resources
|
|
27
27
|
@package_name = package_name
|
28
28
|
@pip_cmd = pip_path || default_pip_path
|
29
29
|
|
30
|
-
return skip_resource
|
30
|
+
return skip_resource "pip not found" if @pip_cmd.nil?
|
31
31
|
end
|
32
32
|
|
33
33
|
def info
|
34
34
|
return @info if defined?(@info)
|
35
35
|
|
36
36
|
@info = {}
|
37
|
-
@info[:type] =
|
37
|
+
@info[:type] = "pip"
|
38
38
|
return @info unless cmd_successful?
|
39
39
|
|
40
40
|
params = SimpleConfig.new(
|
41
41
|
cmd.stdout,
|
42
42
|
assignment_regex: /^\s*([^:]*?)\s*:\s*(.*?)\s*$/,
|
43
|
-
multiple_values: false
|
43
|
+
multiple_values: false
|
44
44
|
).params
|
45
|
-
@info[:name] = params[
|
46
|
-
@info[:version] = params[
|
45
|
+
@info[:name] = params["Name"]
|
46
|
+
@info[:version] = params["Version"]
|
47
47
|
@info[:installed] = true
|
48
48
|
@info
|
49
49
|
end
|
@@ -92,7 +92,7 @@ module Inspec::Resources
|
|
92
92
|
'New-Object -Type PSObject |
|
93
93
|
Add-Member -MemberType NoteProperty -Name Pip -Value (Invoke-Command -ScriptBlock {where.exe pip}) -PassThru |
|
94
94
|
Add-Member -MemberType NoteProperty -Name Python -Value (Invoke-Command -ScriptBlock {where.exe python}) -PassThru |
|
95
|
-
ConvertTo-Json'
|
95
|
+
ConvertTo-Json'
|
96
96
|
)
|
97
97
|
|
98
98
|
@__windows_paths = JSON.parse(cmd.stdout)
|
@@ -102,23 +102,23 @@ module Inspec::Resources
|
|
102
102
|
#
|
103
103
|
# @return [String] of python pip path
|
104
104
|
def default_pip_path
|
105
|
-
return
|
105
|
+
return "pip" unless inspec.os.windows?
|
106
106
|
|
107
107
|
# If python is not found, return with skip_resource
|
108
|
-
return skip_resource
|
108
|
+
return skip_resource "python not found" if windows_paths["Python"].nil?
|
109
109
|
|
110
110
|
# Pip is not on the default path for Windows, therefore we do some logic
|
111
111
|
# to find the binary on Windows
|
112
112
|
begin
|
113
113
|
# use pip if it on system path
|
114
|
-
pipcmd = windows_paths[
|
114
|
+
pipcmd = windows_paths["Pip"]
|
115
115
|
# calculate path on windows
|
116
|
-
if defined?(windows_paths[
|
117
|
-
return nil if windows_paths[
|
118
|
-
pipdir = windows_paths[
|
116
|
+
if defined?(windows_paths["Python"]) && pipcmd.nil?
|
117
|
+
return nil if windows_paths["Pip"].nil?
|
118
|
+
pipdir = windows_paths["Python"].split('\\')
|
119
119
|
# remove python.exe
|
120
120
|
pipdir.pop
|
121
|
-
pipcmd = pipdir.push(
|
121
|
+
pipcmd = pipdir.push("Scripts").push("pip.exe").join("/")
|
122
122
|
end
|
123
123
|
rescue JSON::ParserError => _e
|
124
124
|
return nil
|
@@ -1,9 +1,7 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
module Inspec::Resources
|
4
2
|
class PlatformResource < Inspec.resource(1)
|
5
|
-
name
|
6
|
-
desc
|
3
|
+
name "platform"
|
4
|
+
desc "Use the platform InSpec resource to test the platform on which the system is running."
|
7
5
|
example <<~EXAMPLE
|
8
6
|
describe platform do
|
9
7
|
its('name') { should eq 'redhat' }
|
@@ -58,7 +56,7 @@ module Inspec::Resources
|
|
58
56
|
}
|
59
57
|
|
60
58
|
# Avoid adding Arch for APIs (not applicable)
|
61
|
-
unless in_family?(
|
59
|
+
unless in_family?("api")
|
62
60
|
h[:arch] = arch
|
63
61
|
end
|
64
62
|
|
@@ -71,11 +69,11 @@ module Inspec::Resources
|
|
71
69
|
status = true
|
72
70
|
supports.each do |s|
|
73
71
|
s.each do |k, v|
|
74
|
-
if %i
|
72
|
+
if %i{os_family os-family platform_family platform-family}.include?(k)
|
75
73
|
status = in_family?(v)
|
76
|
-
elsif %i
|
74
|
+
elsif %i{os platform}.include?(k)
|
77
75
|
status = platform?(v)
|
78
|
-
elsif %i
|
76
|
+
elsif %i{os_name os-name platform_name platform-name}.include?(k)
|
79
77
|
status = name == v
|
80
78
|
elsif k == :release
|
81
79
|
status = check_release(v)
|
@@ -91,15 +89,15 @@ module Inspec::Resources
|
|
91
89
|
end
|
92
90
|
|
93
91
|
def to_s
|
94
|
-
|
92
|
+
"Platform Detection"
|
95
93
|
end
|
96
94
|
|
97
95
|
private
|
98
96
|
|
99
97
|
def check_release(value)
|
100
98
|
# allow wild card matching
|
101
|
-
if value.include?(
|
102
|
-
cleaned = Regexp.escape(value).gsub('\*',
|
99
|
+
if value.include?("*")
|
100
|
+
cleaned = Regexp.escape(value).gsub('\*', ".*?")
|
103
101
|
!(release =~ /#{cleaned}/).nil?
|
104
102
|
else
|
105
103
|
release == value
|
@@ -1,16 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require 'utils/filter'
|
5
|
-
require 'ipaddr'
|
1
|
+
require "inspec/utils/parser"
|
2
|
+
require "inspec/utils/filter"
|
3
|
+
require "ipaddr"
|
6
4
|
|
7
5
|
# TODO: currently we return local ip only
|
8
6
|
# TODO: improve handling of same port on multiple interfaces
|
9
7
|
module Inspec::Resources
|
10
8
|
class Port < Inspec.resource(1)
|
11
|
-
name
|
12
|
-
supports platform:
|
13
|
-
supports platform:
|
9
|
+
name "port"
|
10
|
+
supports platform: "unix"
|
11
|
+
supports platform: "windows"
|
14
12
|
desc "Use the port InSpec audit resource to test basic port properties, such as port, process, if it's listening."
|
15
13
|
example <<~EXAMPLE
|
16
14
|
describe port(80) do
|
@@ -35,15 +33,15 @@ module Inspec::Resources
|
|
35
33
|
|
36
34
|
@cache = nil
|
37
35
|
@port_manager = port_manager_for_os
|
38
|
-
return skip_resource
|
36
|
+
return skip_resource "The `port` resource is not supported on your OS yet." if @port_manager.nil?
|
39
37
|
end
|
40
38
|
|
41
39
|
filter = FilterTable.create
|
42
|
-
filter.register_column(:ports, field:
|
43
|
-
.register_column(:addresses, field:
|
44
|
-
.register_column(:protocols, field:
|
45
|
-
.register_column(:processes, field:
|
46
|
-
.register_column(:pids, field:
|
40
|
+
filter.register_column(:ports, field: "port", style: :simple)
|
41
|
+
.register_column(:addresses, field: "address", style: :simple)
|
42
|
+
.register_column(:protocols, field: "protocol", style: :simple)
|
43
|
+
.register_column(:processes, field: "process", style: :simple)
|
44
|
+
.register_column(:pids, field: "pid", style: :simple)
|
47
45
|
.register_custom_matcher(:listening?) { |x| !x.entries.empty? }
|
48
46
|
filter.install_filter_methods_on_resource(self, :info)
|
49
47
|
|
@@ -83,8 +81,8 @@ module Inspec::Resources
|
|
83
81
|
return @cache = [] if @port_manager.nil?
|
84
82
|
# query ports
|
85
83
|
cache = @port_manager.info || []
|
86
|
-
cache.select! { |x| x[
|
87
|
-
cache.select! { |x| x[
|
84
|
+
cache.select! { |x| x["port"] == @port } unless @port.nil?
|
85
|
+
cache.select! { |x| x["address"] == @ip } unless @ip.nil?
|
88
86
|
@cache = cache
|
89
87
|
end
|
90
88
|
end
|
@@ -121,21 +119,21 @@ module Inspec::Resources
|
|
121
119
|
private
|
122
120
|
|
123
121
|
def powershell_info
|
124
|
-
cmd = inspec.command(
|
122
|
+
cmd = inspec.command("Get-NetTCPConnection -state Listen | Select-Object -Property State, Caption, Description, LocalAddress, LocalPort, RemoteAddress, RemotePort, DisplayName, Status | ConvertTo-Json")
|
125
123
|
return nil if cmd.exit_status != 0
|
126
124
|
|
127
125
|
entries = JSON.parse(cmd.stdout)
|
128
126
|
return nil if entries.nil?
|
129
127
|
|
130
|
-
entries.map
|
128
|
+
entries.map do |x|
|
131
129
|
{
|
132
|
-
|
133
|
-
|
134
|
-
|
130
|
+
"port" => x["LocalPort"],
|
131
|
+
"address" => x["LocalAddress"],
|
132
|
+
"protocol" => "tcp",
|
135
133
|
}
|
136
|
-
|
134
|
+
end
|
137
135
|
rescue JSON::ParserError => _e
|
138
|
-
|
136
|
+
nil
|
139
137
|
end
|
140
138
|
|
141
139
|
def netstat_info
|
@@ -146,14 +144,14 @@ module Inspec::Resources
|
|
146
144
|
lines = cmd.stdout.scan(/^>\s*(tcp\S*|udp\S*)\s+(\S+):(\d+)\s+(\S+)\s+(\S*)\s+(\d+)\s+(.+)/i)
|
147
145
|
lines.map do |line|
|
148
146
|
pid = line[5].to_i
|
149
|
-
process = line[6].delete(
|
150
|
-
process =
|
147
|
+
process = line[6].delete("[").delete("]").strip
|
148
|
+
process = "System" if process == "Can not obtain ownership information" && pid == 4
|
151
149
|
{
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
150
|
+
"port" => line[2].to_i,
|
151
|
+
"address" => line[1].delete("[").delete("]"),
|
152
|
+
"protocol" => line[0].downcase,
|
153
|
+
"pid" => pid,
|
154
|
+
"process" => process,
|
157
155
|
}
|
158
156
|
end
|
159
157
|
end
|
@@ -164,7 +162,7 @@ module Inspec::Resources
|
|
164
162
|
attr_reader :lsof
|
165
163
|
|
166
164
|
def initialize(inspec, lsofpath = nil)
|
167
|
-
@lsof = lsofpath ||
|
165
|
+
@lsof = lsofpath || "lsof"
|
168
166
|
super(inspec)
|
169
167
|
end
|
170
168
|
|
@@ -172,7 +170,7 @@ module Inspec::Resources
|
|
172
170
|
ports = []
|
173
171
|
|
174
172
|
# check that lsof is available, otherwise fail
|
175
|
-
raise
|
173
|
+
raise "Please ensure `lsof` is available on the machine." if !inspec.command(@lsof.to_s).exist?
|
176
174
|
|
177
175
|
# -F p=pid, c=command, P=protocol name, t=type, n=internet addresses
|
178
176
|
# see 'OUTPUT FOR OTHER PROGRAMS' in LSOF(8)
|
@@ -181,15 +179,15 @@ module Inspec::Resources
|
|
181
179
|
|
182
180
|
# map to desired return struct
|
183
181
|
lsof_parser(lsof_cmd).each do |process, port_ids|
|
184
|
-
pid, cmd = process.split(
|
182
|
+
pid, cmd = process.split(":")
|
185
183
|
port_ids.each do |port_str|
|
186
184
|
# should not break on ipv6 addresses
|
187
|
-
ipv, proto, port, host = port_str.split(
|
188
|
-
ports.push({
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
185
|
+
ipv, proto, port, host = port_str.split(":", 4)
|
186
|
+
ports.push({ "port" => port.to_i,
|
187
|
+
"address" => host,
|
188
|
+
"protocol" => ipv == "ipv6" ? proto + "6" : proto,
|
189
|
+
"process" => cmd,
|
190
|
+
"pid" => pid.to_i })
|
193
191
|
end
|
194
192
|
end
|
195
193
|
|
@@ -218,17 +216,17 @@ module Inspec::Resources
|
|
218
216
|
line.chomp!
|
219
217
|
key = line.slice!(0)
|
220
218
|
case key
|
221
|
-
when
|
219
|
+
when "p"
|
222
220
|
proc_id = line
|
223
221
|
port_id = nil
|
224
|
-
when
|
225
|
-
proc_id +=
|
226
|
-
when
|
222
|
+
when "c"
|
223
|
+
proc_id += ":" + line
|
224
|
+
when "t"
|
227
225
|
port_id = line.downcase
|
228
|
-
when
|
229
|
-
port_id +=
|
230
|
-
when
|
231
|
-
src, dst = line.split(
|
226
|
+
when "P"
|
227
|
+
port_id += ":" + line.downcase
|
228
|
+
when "n"
|
229
|
+
src, dst = line.split("->")
|
232
230
|
|
233
231
|
# skip active comm streams
|
234
232
|
next if dst
|
@@ -236,13 +234,13 @@ module Inspec::Resources
|
|
236
234
|
host, port = /^(\S+):(\d+|\*)$/.match(src)[1, 2]
|
237
235
|
|
238
236
|
# skip channels from port 0 - what does this mean?
|
239
|
-
next if port ==
|
237
|
+
next if port == "*"
|
240
238
|
|
241
239
|
# create new array stub if !exist?
|
242
240
|
procs[proc_id] = [] unless procs.key?(proc_id)
|
243
241
|
|
244
242
|
# change address '*' to zero
|
245
|
-
host = port_id =~ /^ipv6:/ ?
|
243
|
+
host = port_id =~ /^ipv6:/ ? "[::]" : "0.0.0.0" if host == "*"
|
246
244
|
# entrust URI to scrub the host and port
|
247
245
|
begin
|
248
246
|
uri = URI("addr://#{host}:#{port}")
|
@@ -254,7 +252,7 @@ module Inspec::Resources
|
|
254
252
|
|
255
253
|
# e.g. 'ipv4:tcp:22:127.0.0.1'
|
256
254
|
# strip ipv6 squares for inspec
|
257
|
-
port_id +=
|
255
|
+
port_id += ":" + port + ":" + host.gsub(/^\[|\]$/, "")
|
258
256
|
|
259
257
|
# lsof will give us another port unless it's done
|
260
258
|
procs[proc_id] << port_id
|
@@ -271,15 +269,15 @@ module Inspec::Resources
|
|
271
269
|
end
|
272
270
|
|
273
271
|
def ports_via_lsof
|
274
|
-
return nil unless inspec.command(
|
272
|
+
return nil unless inspec.command("lsof").exist?
|
275
273
|
LsofPorts.new(inspec).info
|
276
274
|
end
|
277
275
|
|
278
276
|
def ports_via_netstat
|
279
|
-
return nil unless inspec.command(
|
277
|
+
return nil unless inspec.command("netstat").exist?
|
280
278
|
|
281
|
-
cmd = inspec.command(
|
282
|
-
return nil unless cmd.exit_status.to_i
|
279
|
+
cmd = inspec.command("netstat -Aan | grep LISTEN")
|
280
|
+
return nil unless cmd.exit_status.to_i == 0
|
283
281
|
|
284
282
|
ports = []
|
285
283
|
# parse all lines
|
@@ -287,7 +285,7 @@ module Inspec::Resources
|
|
287
285
|
port_info = parse_netstat_line(line)
|
288
286
|
|
289
287
|
# only push protocols we are interested in
|
290
|
-
next unless %w{tcp tcp6 udp udp6}.include?(port_info[
|
288
|
+
next unless %w{tcp tcp6 udp udp6}.include?(port_info["protocol"])
|
291
289
|
ports.push(port_info)
|
292
290
|
end
|
293
291
|
|
@@ -304,7 +302,7 @@ module Inspec::Resources
|
|
304
302
|
protocol = parsed[2].downcase
|
305
303
|
|
306
304
|
# detect protocol if not provided
|
307
|
-
protocol +=
|
305
|
+
protocol += "6" if parsed[5].count(":") > 1 && %w{tcp udp}.include?(protocol)
|
308
306
|
protocol.chop! if %w{tcp4 upd4}.include?(protocol)
|
309
307
|
|
310
308
|
# extract host and port information
|
@@ -320,29 +318,29 @@ module Inspec::Resources
|
|
320
318
|
pid = pid.to_i if pid =~ /^\d+$/
|
321
319
|
|
322
320
|
{
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
321
|
+
"port" => port,
|
322
|
+
"address" => host,
|
323
|
+
"protocol" => protocol,
|
324
|
+
"process" => process,
|
325
|
+
"pid" => pid,
|
328
326
|
}
|
329
327
|
end
|
330
328
|
|
331
329
|
def parse_net_address(net_addr, protocol)
|
332
330
|
# local/foreign addresses on AIX use a '.' to separate the addresss
|
333
331
|
# from the port
|
334
|
-
address, _sep, port = net_addr.rpartition(
|
335
|
-
if protocol.eql?(
|
332
|
+
address, _sep, port = net_addr.rpartition(".")
|
333
|
+
if protocol.eql?("tcp6") || protocol.eql?("udp6")
|
336
334
|
ip6addr = address
|
337
335
|
# AIX uses the wildcard character for ipv6 addresses listening on
|
338
336
|
# all interfaces.
|
339
|
-
ip6addr =
|
337
|
+
ip6addr = "::" if ip6addr =~ /^\*$/
|
340
338
|
|
341
339
|
# v6 addresses need to end in a double-colon when using
|
342
340
|
# shorthand notation. netstat ends with a single colon.
|
343
341
|
# IPAddr will fail to properly parse an address unless it
|
344
342
|
# uses a double-colon for short-hand notation.
|
345
|
-
ip6addr +=
|
343
|
+
ip6addr += ":" if ip6addr =~ /\w:$/
|
346
344
|
|
347
345
|
begin
|
348
346
|
ip_parser = IPAddr.new(ip6addr)
|
@@ -366,12 +364,12 @@ module Inspec::Resources
|
|
366
364
|
host = ip_addr.host
|
367
365
|
else
|
368
366
|
ip_addr = URI("addr://[#{ip6addr}]:#{port}")
|
369
|
-
host = ip_addr.host[1..ip_addr.host.size-2]
|
367
|
+
host = ip_addr.host[1..ip_addr.host.size - 2]
|
370
368
|
end
|
371
369
|
else
|
372
370
|
ip4addr = address
|
373
371
|
# In AIX the wildcard character is used to match all interfaces
|
374
|
-
ip4addr =
|
372
|
+
ip4addr = "0.0.0.0" if ip4addr =~ /^\*$/
|
375
373
|
ip_addr = URI("addr://#{ip4addr}:#{port}")
|
376
374
|
host = ip_addr.host
|
377
375
|
end
|
@@ -389,10 +387,10 @@ module Inspec::Resources
|
|
389
387
|
end
|
390
388
|
|
391
389
|
def ports_via_ss
|
392
|
-
return nil unless inspec.command(
|
390
|
+
return nil unless inspec.command("ss").exist?
|
393
391
|
|
394
|
-
cmd = inspec.command(
|
395
|
-
return nil unless cmd.exit_status.to_i
|
392
|
+
cmd = inspec.command("ss -tulpen")
|
393
|
+
return nil unless cmd.exit_status.to_i == 0
|
396
394
|
|
397
395
|
ports = []
|
398
396
|
|
@@ -405,10 +403,10 @@ module Inspec::Resources
|
|
405
403
|
end
|
406
404
|
|
407
405
|
def ports_via_netstat
|
408
|
-
return nil unless inspec.command(
|
406
|
+
return nil unless inspec.command("netstat").exist?
|
409
407
|
|
410
|
-
cmd = inspec.command(
|
411
|
-
return nil unless cmd.exit_status.to_i
|
408
|
+
cmd = inspec.command("netstat -tulpen")
|
409
|
+
return nil unless cmd.exit_status.to_i == 0
|
412
410
|
|
413
411
|
ports = []
|
414
412
|
# parse all lines
|
@@ -416,24 +414,24 @@ module Inspec::Resources
|
|
416
414
|
port_info = parse_netstat_line(line)
|
417
415
|
|
418
416
|
# only push protocols we are interested in
|
419
|
-
next unless %w{tcp tcp6 udp udp6}.include?(port_info[
|
417
|
+
next unless %w{tcp tcp6 udp udp6}.include?(port_info["protocol"])
|
420
418
|
ports.push(port_info)
|
421
419
|
end
|
422
420
|
ports
|
423
421
|
end
|
424
422
|
|
425
423
|
def parse_net_address(net_addr, protocol)
|
426
|
-
if protocol.eql?(
|
424
|
+
if protocol.eql?("tcp6") || protocol.eql?("udp6")
|
427
425
|
# prep for URI parsing, parse ip6 port
|
428
426
|
ip6 = /^(\S+):(\d+)$/.match(net_addr)
|
429
427
|
ip6addr = ip6[1]
|
430
|
-
ip6addr =
|
428
|
+
ip6addr = "::" if ip6addr =~ /^:::$/
|
431
429
|
|
432
430
|
# v6 addresses need to end in a double-colon when using
|
433
431
|
# shorthand notation. netstat ends with a single colon.
|
434
432
|
# IPAddr will fail to properly parse an address unless it
|
435
433
|
# uses a double-colon for short-hand notation.
|
436
|
-
ip6addr +=
|
434
|
+
ip6addr += ":" if ip6addr =~ /\w:$/
|
437
435
|
|
438
436
|
begin
|
439
437
|
ip_parser = IPAddr.new(ip6addr)
|
@@ -458,10 +456,10 @@ module Inspec::Resources
|
|
458
456
|
else
|
459
457
|
ip_addr = URI("addr://[#{ip6addr}]:#{ip6[2]}")
|
460
458
|
# strip []
|
461
|
-
host = ip_addr.host[1..ip_addr.host.size-2]
|
459
|
+
host = ip_addr.host[1..ip_addr.host.size - 2]
|
462
460
|
end
|
463
461
|
else
|
464
|
-
ip_addr = URI(
|
462
|
+
ip_addr = URI("addr://" + net_addr)
|
465
463
|
host = ip_addr.host
|
466
464
|
end
|
467
465
|
|
@@ -487,24 +485,24 @@ module Inspec::Resources
|
|
487
485
|
protocol = parsed[:proto].downcase
|
488
486
|
|
489
487
|
# detect protocol if not provided
|
490
|
-
protocol +=
|
488
|
+
protocol += "6" if parsed[:local_addr].count(":") > 1 && %w{tcp udp}.include?(protocol)
|
491
489
|
|
492
490
|
# extract host and port information
|
493
491
|
host, port = parse_net_address(parsed[:local_addr], protocol)
|
494
492
|
return {} if host.nil?
|
495
493
|
|
496
494
|
# extract PID
|
497
|
-
process = parsed[:pid_prog].split(
|
495
|
+
process = parsed[:pid_prog].split("/")
|
498
496
|
pid = process[0]
|
499
497
|
pid = pid.to_i if pid =~ /^\d+$/
|
500
498
|
process = process[1]
|
501
499
|
|
502
500
|
{
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
501
|
+
"port" => port,
|
502
|
+
"address" => host,
|
503
|
+
"protocol" => protocol,
|
504
|
+
"process" => process,
|
505
|
+
"pid" => pid,
|
508
506
|
}
|
509
507
|
end
|
510
508
|
|
@@ -544,7 +542,7 @@ module Inspec::Resources
|
|
544
542
|
# entry.
|
545
543
|
process_info = parsed[:process_info]
|
546
544
|
protocol = parsed[:netid]
|
547
|
-
protocol +=
|
545
|
+
protocol += "6" if process_info.include?("v6only:1")
|
548
546
|
return nil unless ALLOWED_PROTOCOLS.include?(protocol)
|
549
547
|
|
550
548
|
# parse the Local Address:Port
|
@@ -567,20 +565,20 @@ module Inspec::Resources
|
|
567
565
|
# for those "v4-but-listed-in-v6" entries, strip off the
|
568
566
|
# leading IPv6 value at the beginning
|
569
567
|
# example: ::ffff:10.0.2.15:9200
|
570
|
-
host.delete!(
|
568
|
+
host.delete!("::ffff:") if host.start_with?("::ffff:")
|
571
569
|
|
572
570
|
# To remove brackets that might surround the IPv6 address
|
573
571
|
# example: [::] and [fe80::dc11:b9b6:514b:134]%eth0:123
|
574
|
-
host = host.tr(
|
572
|
+
host = host.tr("[]", "")
|
575
573
|
|
576
574
|
# if there's an interface name in the local address, which is common for
|
577
575
|
# IPv6 listeners, strip that out too.
|
578
576
|
# example: fe80::a00:27ff:fe32:ed09%enp0s3
|
579
|
-
host = host.split(
|
577
|
+
host = host.split("%").first
|
580
578
|
|
581
579
|
# if host is "*", replace with "0.0.0.0" to maintain backward compatibility with
|
582
580
|
# the netstat-provided data
|
583
|
-
host =
|
581
|
+
host = "0.0.0.0" if host == "*"
|
584
582
|
|
585
583
|
# in case process list parsing is not successfull
|
586
584
|
process = nil
|
@@ -596,7 +594,7 @@ module Inspec::Resources
|
|
596
594
|
# list entires are seperated by "," the braces can also be removed
|
597
595
|
# input: \"nginx\",pid=583,fd=8),(\"nginx\",pid=582,fd=8),(\"nginx\",pid=580,fd=8),(\"nginx\",pid=579,fd=8
|
598
596
|
# res: ["\"nginx\",pid=583,fd=8", "\"nginx\",pid=582,fd=8", "\"nginx\",pid=580,fd=8", "\"nginx\",pid=579,fd=8"]
|
599
|
-
process_list = process_list_match[1].split(
|
597
|
+
process_list = process_list_match[1].split("),(")
|
600
598
|
# To stay backwards compatible with netstat we need to select
|
601
599
|
# the last element in the resulting array.
|
602
600
|
# res: "\"nginx\",pid=579,fd=8"
|
@@ -611,11 +609,11 @@ module Inspec::Resources
|
|
611
609
|
end
|
612
610
|
|
613
611
|
{
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
612
|
+
"port" => port,
|
613
|
+
"address" => host,
|
614
|
+
"protocol" => protocol,
|
615
|
+
"process" => process,
|
616
|
+
"pid" => pid,
|
619
617
|
}
|
620
618
|
end
|
621
619
|
end
|
@@ -623,7 +621,7 @@ module Inspec::Resources
|
|
623
621
|
# extracts information from sockstat
|
624
622
|
class FreeBsdPorts < PortsInfo
|
625
623
|
def info
|
626
|
-
cmd = inspec.command(
|
624
|
+
cmd = inspec.command("sockstat -46l")
|
627
625
|
return nil if cmd.exit_status.to_i != 0
|
628
626
|
|
629
627
|
ports = []
|
@@ -632,7 +630,7 @@ module Inspec::Resources
|
|
632
630
|
port_info = parse_sockstat_line(line)
|
633
631
|
|
634
632
|
# push data, if not headerfile
|
635
|
-
next unless %w{tcp tcp6 udp udp6}.include?(port_info[
|
633
|
+
next unless %w{tcp tcp6 udp udp6}.include?(port_info["protocol"])
|
636
634
|
ports.push(port_info)
|
637
635
|
end
|
638
636
|
ports
|
@@ -640,22 +638,22 @@ module Inspec::Resources
|
|
640
638
|
|
641
639
|
def parse_net_address(net_addr, protocol)
|
642
640
|
case protocol
|
643
|
-
when
|
641
|
+
when "tcp4", "udp4", "tcp", "udp"
|
644
642
|
# replace * with 0.0.0.0
|
645
|
-
net_addr = net_addr.gsub(/^\*:/,
|
646
|
-
ip_addr = URI(
|
643
|
+
net_addr = net_addr.gsub(/^\*:/, "0.0.0.0:") if net_addr =~ /^*:(\d+)$/
|
644
|
+
ip_addr = URI("addr://" + net_addr)
|
647
645
|
host = ip_addr.host
|
648
646
|
port = ip_addr.port
|
649
|
-
when
|
650
|
-
return [] if net_addr ==
|
647
|
+
when "tcp6", "udp6"
|
648
|
+
return [] if net_addr == "*:*" # abort for now
|
651
649
|
# replace * with 0:0:0:0:0:0:0:0
|
652
|
-
net_addr = net_addr.gsub(/^\*:/,
|
650
|
+
net_addr = net_addr.gsub(/^\*:/, "0:0:0:0:0:0:0:0:") if net_addr =~ /^*:(\d+)$/
|
653
651
|
# extract port
|
654
652
|
ip6 = /^(\S+):(\d+)$/.match(net_addr)
|
655
653
|
ip6addr = ip6[1]
|
656
654
|
ip_addr = URI("addr://[#{ip6addr}]:#{ip6[2]}")
|
657
655
|
# replace []
|
658
|
-
host = ip_addr.host[1..ip_addr.host.size-2]
|
656
|
+
host = ip_addr.host[1..ip_addr.host.size - 2]
|
659
657
|
port = ip_addr.port
|
660
658
|
end
|
661
659
|
[host, port]
|
@@ -672,7 +670,7 @@ module Inspec::Resources
|
|
672
670
|
# extract ip information
|
673
671
|
protocol = parsed[5].downcase
|
674
672
|
host, port = parse_net_address(parsed[6], protocol)
|
675
|
-
return {} if host.nil?
|
673
|
+
return {} if host.nil? || port.nil?
|
676
674
|
|
677
675
|
# extract process
|
678
676
|
process = parsed[2]
|
@@ -682,15 +680,15 @@ module Inspec::Resources
|
|
682
680
|
pid = pid.to_i if pid =~ /^\d+$/
|
683
681
|
|
684
682
|
# map tcp4 and udp4
|
685
|
-
protocol =
|
686
|
-
protocol =
|
683
|
+
protocol = "tcp" if protocol.eql?("tcp4")
|
684
|
+
protocol = "udp" if protocol.eql?("udp4")
|
687
685
|
|
688
686
|
{
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
687
|
+
"port" => port,
|
688
|
+
"address" => host,
|
689
|
+
"protocol" => protocol,
|
690
|
+
"process" => process,
|
691
|
+
"pid" => pid,
|
694
692
|
}
|
695
693
|
end
|
696
694
|
end
|
@@ -700,36 +698,36 @@ module Inspec::Resources
|
|
700
698
|
|
701
699
|
def info
|
702
700
|
# extract all port info
|
703
|
-
cmd = inspec.command(
|
701
|
+
cmd = inspec.command("netstat -an -f inet -f inet6")
|
704
702
|
return nil if cmd.exit_status.to_i != 0
|
705
703
|
|
706
704
|
# parse the content
|
707
705
|
netstat_ports = parse_netstat(cmd.stdout)
|
708
706
|
|
709
707
|
# filter all ports, where we `listen`
|
710
|
-
listen = netstat_ports.select
|
711
|
-
!val[
|
712
|
-
|
708
|
+
listen = netstat_ports.select do |val|
|
709
|
+
!val["state"].nil? && "listen".casecmp(val["state"]) == 0
|
710
|
+
end
|
713
711
|
|
714
712
|
# map the data
|
715
|
-
ports = listen.map
|
716
|
-
protocol = val[
|
717
|
-
local_addr = val[
|
713
|
+
ports = listen.map do |val|
|
714
|
+
protocol = val["protocol"]
|
715
|
+
local_addr = val["local-address"]
|
718
716
|
|
719
717
|
# solaris uses 127.0.0.1.57455 instead 127.0.0.1:57455, lets convert the
|
720
718
|
# the last . to :
|
721
|
-
local_addr[local_addr.rindex(
|
719
|
+
local_addr[local_addr.rindex(".")] = ":"
|
722
720
|
host, port = parse_net_address(local_addr, protocol)
|
723
721
|
if host.nil?
|
724
722
|
nil
|
725
723
|
else
|
726
724
|
{
|
727
|
-
|
728
|
-
|
729
|
-
|
725
|
+
"port" => port,
|
726
|
+
"address" => host,
|
727
|
+
"protocol" => protocol,
|
730
728
|
}
|
731
729
|
end
|
732
|
-
|
730
|
+
end
|
733
731
|
ports.compact
|
734
732
|
end
|
735
733
|
end
|
@@ -738,20 +736,20 @@ module Inspec::Resources
|
|
738
736
|
class HpuxPorts < FreeBsdPorts
|
739
737
|
def info
|
740
738
|
## Can't use 'netstat -an -f inet -f inet6' as the latter -f option overrides the former one and return only inet ports
|
741
|
-
cmd1 = inspec.command(
|
739
|
+
cmd1 = inspec.command("netstat -an -f inet")
|
742
740
|
return nil if cmd1.exit_status.to_i != 0
|
743
|
-
cmd2 = inspec.command(
|
741
|
+
cmd2 = inspec.command("netstat -an -f inet6")
|
744
742
|
return nil if cmd2.exit_status.to_i != 0
|
745
743
|
cmd = cmd1.stdout + cmd2.stdout
|
746
744
|
ports = []
|
747
745
|
# parse all lines
|
748
746
|
cmd.each_line do |line|
|
749
747
|
port_info = parse_netstat_line(line)
|
750
|
-
next unless %w{tcp tcp6 udp udp6}.include?(port_info[
|
748
|
+
next unless %w{tcp tcp6 udp udp6}.include?(port_info["protocol"])
|
751
749
|
ports.push(port_info)
|
752
750
|
end
|
753
751
|
# select all ports, where we `listen`
|
754
|
-
ports.select { |val| val if
|
752
|
+
ports.select { |val| val if "listen".casecmp(val["state"]) == 0 }
|
755
753
|
end
|
756
754
|
|
757
755
|
def parse_netstat_line(line)
|
@@ -761,18 +759,18 @@ module Inspec::Resources
|
|
761
759
|
|
762
760
|
return {} if parsed.nil? || line.match(/^proto/i) || line.match(/^active/i)
|
763
761
|
protocol = parsed[1].downcase
|
764
|
-
state = parsed[6].nil
|
762
|
+
state = parsed[6].nil? ? " " : parsed[6].downcase
|
765
763
|
local_addr = parsed[4]
|
766
|
-
local_addr[local_addr.rindex(
|
764
|
+
local_addr[local_addr.rindex(".")] = ":"
|
767
765
|
# extract host and port information
|
768
766
|
host, port = parse_net_address(local_addr, protocol)
|
769
767
|
return {} if host.nil?
|
770
768
|
# map data
|
771
769
|
{
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
770
|
+
"port" => port,
|
771
|
+
"address" => host,
|
772
|
+
"protocol" => protocol,
|
773
|
+
"state" => state,
|
776
774
|
}
|
777
775
|
end
|
778
776
|
end
|