inspec 2.0.32 → 2.0.45
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/.rubocop.yml +101 -101
- data/CHANGELOG.md +2991 -2970
- data/Gemfile +55 -55
- data/LICENSE +14 -14
- data/MAINTAINERS.md +33 -33
- data/MAINTAINERS.toml +52 -52
- data/README.md +446 -437
- data/Rakefile +322 -322
- data/bin/inspec +12 -12
- data/docs/.gitignore +2 -2
- data/docs/README.md +40 -40
- data/docs/dsl_inspec.md +258 -258
- data/docs/dsl_resource.md +93 -93
- data/docs/glossary.md +99 -99
- data/docs/habitat.md +191 -191
- data/docs/inspec_and_friends.md +107 -107
- data/docs/matchers.md +169 -168
- data/docs/migration.md +293 -293
- data/docs/platforms.md +118 -118
- data/docs/plugin_kitchen_inspec.md +49 -49
- data/docs/profiles.md +370 -370
- data/docs/reporters.md +105 -105
- data/docs/resources/aide_conf.md.erb +75 -75
- data/docs/resources/apache.md.erb +67 -67
- data/docs/resources/apache_conf.md.erb +68 -68
- data/docs/resources/apt.md.erb +71 -71
- data/docs/resources/audit_policy.md.erb +47 -47
- data/docs/resources/auditd.md.erb +79 -79
- data/docs/resources/auditd_conf.md.erb +68 -68
- data/docs/resources/aws_cloudtrail_trail.md.erb +140 -140
- data/docs/resources/aws_cloudtrail_trails.md.erb +81 -81
- data/docs/resources/aws_cloudwatch_alarm.md.erb +86 -86
- data/docs/resources/aws_cloudwatch_log_metric_filter.md.erb +151 -151
- data/docs/resources/aws_config_recorder.md.erb +71 -71
- data/docs/resources/aws_ec2_instance.md.erb +106 -106
- data/docs/resources/aws_iam_access_key.md.erb +123 -123
- data/docs/resources/aws_iam_access_keys.md.erb +198 -198
- data/docs/resources/aws_iam_group.md.erb +46 -46
- data/docs/resources/aws_iam_groups.md.erb +43 -43
- data/docs/resources/aws_iam_password_policy.md.erb +76 -76
- data/docs/resources/aws_iam_policies.md.erb +82 -82
- data/docs/resources/aws_iam_policy.md.erb +144 -144
- data/docs/resources/aws_iam_role.md.erb +63 -63
- data/docs/resources/aws_iam_root_user.md.erb +58 -58
- data/docs/resources/aws_iam_user.md.erb +64 -64
- data/docs/resources/aws_iam_users.md.erb +89 -89
- data/docs/resources/aws_kms_keys.md.erb +84 -84
- data/docs/resources/aws_route_table.md.erb +47 -47
- data/docs/resources/aws_s3_bucket.md.erb +134 -134
- data/docs/resources/aws_security_group.md.erb +151 -151
- data/docs/resources/aws_security_groups.md.erb +91 -91
- data/docs/resources/aws_sns_topic.md.erb +63 -63
- data/docs/resources/aws_subnet.md.erb +133 -133
- data/docs/resources/aws_subnets.md.erb +126 -126
- data/docs/resources/aws_vpc.md.erb +120 -120
- data/docs/resources/aws_vpcs.md.erb +48 -48
- data/docs/resources/azure_generic_resource.md.erb +170 -170
- data/docs/resources/azure_resource_group.md.erb +284 -284
- data/docs/resources/azure_virtual_machine.md.erb +347 -347
- data/docs/resources/azure_virtual_machine_data_disk.md.erb +224 -224
- data/docs/resources/bash.md.erb +75 -75
- data/docs/resources/bond.md.erb +90 -90
- data/docs/resources/bridge.md.erb +57 -57
- data/docs/resources/bsd_service.md.erb +67 -67
- data/docs/resources/command.md.erb +138 -138
- data/docs/resources/cpan.md.erb +79 -79
- data/docs/resources/cran.md.erb +64 -64
- data/docs/resources/crontab.md.erb +89 -89
- data/docs/resources/csv.md.erb +54 -54
- data/docs/resources/dh_params.md.erb +205 -205
- data/docs/resources/directory.md.erb +30 -30
- data/docs/resources/docker.md.erb +219 -219
- data/docs/resources/docker_container.md.erb +104 -104
- data/docs/resources/docker_image.md.erb +94 -94
- data/docs/resources/docker_service.md.erb +114 -114
- data/docs/resources/elasticsearch.md.erb +242 -242
- data/docs/resources/etc_fstab.md.erb +125 -125
- data/docs/resources/etc_group.md.erb +75 -75
- data/docs/resources/etc_hosts.md.erb +78 -78
- data/docs/resources/etc_hosts_allow.md.erb +74 -74
- data/docs/resources/etc_hosts_deny.md.erb +74 -74
- data/docs/resources/file.md.erb +526 -515
- data/docs/resources/filesystem.md.erb +41 -41
- data/docs/resources/firewalld.md.erb +107 -107
- data/docs/resources/gem.md.erb +79 -79
- data/docs/resources/group.md.erb +61 -61
- data/docs/resources/grub_conf.md.erb +101 -101
- data/docs/resources/host.md.erb +86 -86
- data/docs/resources/http.md.erb +196 -196
- data/docs/resources/iis_app.md.erb +122 -122
- data/docs/resources/iis_site.md.erb +135 -135
- data/docs/resources/inetd_conf.md.erb +94 -94
- data/docs/resources/ini.md.erb +76 -76
- data/docs/resources/interface.md.erb +58 -58
- data/docs/resources/iptables.md.erb +64 -64
- data/docs/resources/json.md.erb +63 -63
- data/docs/resources/kernel_module.md.erb +120 -120
- data/docs/resources/kernel_parameter.md.erb +53 -53
- data/docs/resources/key_rsa.md.erb +85 -85
- data/docs/resources/launchd_service.md.erb +57 -57
- data/docs/resources/limits_conf.md.erb +75 -75
- data/docs/resources/login_def.md.erb +71 -71
- data/docs/resources/mount.md.erb +69 -69
- data/docs/resources/mssql_session.md.erb +60 -60
- data/docs/resources/mysql_conf.md.erb +99 -99
- data/docs/resources/mysql_session.md.erb +74 -74
- data/docs/resources/nginx.md.erb +79 -79
- data/docs/resources/nginx_conf.md.erb +128 -128
- data/docs/resources/npm.md.erb +60 -60
- data/docs/resources/ntp_conf.md.erb +60 -60
- data/docs/resources/oneget.md.erb +53 -53
- data/docs/resources/oracledb_session.md.erb +52 -52
- data/docs/resources/os.md.erb +141 -141
- data/docs/resources/os_env.md.erb +78 -78
- data/docs/resources/package.md.erb +120 -120
- data/docs/resources/packages.md.erb +67 -67
- data/docs/resources/parse_config.md.erb +103 -103
- data/docs/resources/parse_config_file.md.erb +138 -138
- data/docs/resources/passwd.md.erb +141 -141
- data/docs/resources/pip.md.erb +67 -67
- data/docs/resources/port.md.erb +137 -137
- data/docs/resources/postgres_conf.md.erb +79 -79
- data/docs/resources/postgres_hba_conf.md.erb +93 -93
- data/docs/resources/postgres_ident_conf.md.erb +76 -76
- data/docs/resources/postgres_session.md.erb +69 -69
- data/docs/resources/powershell.md.erb +102 -102
- data/docs/resources/processes.md.erb +109 -109
- data/docs/resources/rabbitmq_config.md.erb +41 -41
- data/docs/resources/registry_key.md.erb +158 -158
- data/docs/resources/runit_service.md.erb +57 -57
- data/docs/resources/security_policy.md.erb +47 -47
- data/docs/resources/service.md.erb +121 -121
- data/docs/resources/shadow.md.erb +146 -144
- data/docs/resources/ssh_config.md.erb +80 -80
- data/docs/resources/sshd_config.md.erb +83 -83
- data/docs/resources/ssl.md.erb +119 -119
- data/docs/resources/sys_info.md.erb +42 -42
- data/docs/resources/systemd_service.md.erb +57 -57
- data/docs/resources/sysv_service.md.erb +57 -57
- data/docs/resources/upstart_service.md.erb +57 -57
- data/docs/resources/user.md.erb +140 -140
- data/docs/resources/users.md.erb +127 -127
- data/docs/resources/vbscript.md.erb +55 -55
- data/docs/resources/virtualization.md.erb +57 -57
- data/docs/resources/windows_feature.md.erb +47 -47
- data/docs/resources/windows_hotfix.md.erb +53 -53
- data/docs/resources/windows_task.md.erb +95 -95
- data/docs/resources/wmi.md.erb +81 -81
- data/docs/resources/x509_certificate.md.erb +151 -151
- data/docs/resources/xinetd_conf.md.erb +156 -156
- data/docs/resources/xml.md.erb +85 -85
- data/docs/resources/yaml.md.erb +69 -69
- data/docs/resources/yum.md.erb +98 -98
- data/docs/resources/zfs_dataset.md.erb +53 -53
- data/docs/resources/zfs_pool.md.erb +47 -47
- data/docs/ruby_usage.md +203 -203
- data/docs/shared/matcher_be.md.erb +1 -1
- data/docs/shared/matcher_cmp.md.erb +43 -43
- data/docs/shared/matcher_eq.md.erb +3 -3
- data/docs/shared/matcher_include.md.erb +1 -1
- data/docs/shared/matcher_match.md.erb +1 -1
- data/docs/shell.md +215 -215
- data/examples/README.md +8 -8
- data/examples/inheritance/README.md +65 -65
- data/examples/inheritance/controls/example.rb +14 -14
- data/examples/inheritance/inspec.yml +15 -15
- data/examples/kitchen-ansible/.kitchen.yml +25 -25
- data/examples/kitchen-ansible/Gemfile +19 -19
- data/examples/kitchen-ansible/README.md +53 -53
- data/examples/kitchen-ansible/files/nginx.repo +6 -6
- data/examples/kitchen-ansible/tasks/main.yml +16 -16
- data/examples/kitchen-ansible/test/integration/default/default.yml +5 -5
- data/examples/kitchen-ansible/test/integration/default/web_spec.rb +28 -28
- data/examples/kitchen-chef/.kitchen.yml +20 -20
- data/examples/kitchen-chef/Berksfile +3 -3
- data/examples/kitchen-chef/Gemfile +19 -19
- data/examples/kitchen-chef/README.md +27 -27
- data/examples/kitchen-chef/metadata.rb +7 -7
- data/examples/kitchen-chef/recipes/default.rb +6 -6
- data/examples/kitchen-chef/recipes/nginx.rb +30 -30
- data/examples/kitchen-chef/test/integration/default/web_spec.rb +28 -28
- data/examples/kitchen-puppet/.kitchen.yml +22 -22
- data/examples/kitchen-puppet/Gemfile +20 -20
- data/examples/kitchen-puppet/Puppetfile +25 -25
- data/examples/kitchen-puppet/README.md +53 -53
- data/examples/kitchen-puppet/manifests/site.pp +33 -33
- data/examples/kitchen-puppet/metadata.json +11 -11
- data/examples/kitchen-puppet/test/integration/default/web_spec.rb +28 -28
- data/examples/meta-profile/README.md +37 -37
- data/examples/meta-profile/controls/example.rb +13 -13
- data/examples/meta-profile/inspec.yml +13 -13
- data/examples/profile-attribute.yml +2 -2
- data/examples/profile-attribute/README.md +14 -14
- data/examples/profile-attribute/controls/example.rb +11 -11
- data/examples/profile-attribute/inspec.yml +8 -8
- data/examples/profile-aws/controls/iam_password_policy_expiration.rb +8 -8
- data/examples/profile-aws/controls/iam_password_policy_max_age.rb +8 -8
- data/examples/profile-aws/controls/iam_root_user_mfa.rb +8 -8
- data/examples/profile-aws/controls/iam_users_access_key_age.rb +8 -8
- data/examples/profile-aws/controls/iam_users_console_users_mfa.rb +8 -8
- data/examples/profile-aws/inspec.yml +11 -11
- data/examples/profile-azure/controls/azure_resource_group_example.rb +24 -24
- data/examples/profile-azure/controls/azure_vm_example.rb +29 -29
- data/examples/profile-azure/inspec.yml +11 -11
- data/examples/profile-sensitive/README.md +29 -29
- data/examples/profile-sensitive/controls/sensitive-failures.rb +9 -9
- data/examples/profile-sensitive/controls/sensitive.rb +9 -9
- data/examples/profile-sensitive/inspec.yml +8 -8
- data/examples/profile/README.md +48 -48
- data/examples/profile/controls/example.rb +23 -23
- data/examples/profile/controls/gordon.rb +36 -36
- data/examples/profile/controls/meta.rb +34 -34
- data/examples/profile/inspec.yml +10 -10
- data/examples/profile/libraries/gordon_config.rb +53 -53
- data/inspec.gemspec +47 -47
- data/lib/bundles/README.md +3 -3
- data/lib/bundles/inspec-artifact.rb +7 -7
- data/lib/bundles/inspec-artifact/README.md +1 -1
- data/lib/bundles/inspec-artifact/cli.rb +277 -277
- data/lib/bundles/inspec-compliance.rb +16 -16
- data/lib/bundles/inspec-compliance/.kitchen.yml +20 -20
- data/lib/bundles/inspec-compliance/README.md +185 -185
- data/lib/bundles/inspec-compliance/api.rb +316 -316
- data/lib/bundles/inspec-compliance/api/login.rb +152 -152
- data/lib/bundles/inspec-compliance/bootstrap.sh +41 -41
- data/lib/bundles/inspec-compliance/cli.rb +254 -254
- data/lib/bundles/inspec-compliance/configuration.rb +103 -103
- data/lib/bundles/inspec-compliance/http.rb +86 -86
- data/lib/bundles/inspec-compliance/support.rb +36 -36
- data/lib/bundles/inspec-compliance/target.rb +98 -98
- data/lib/bundles/inspec-compliance/test/integration/default/cli.rb +93 -93
- data/lib/bundles/inspec-habitat.rb +12 -12
- data/lib/bundles/inspec-habitat/cli.rb +36 -36
- data/lib/bundles/inspec-habitat/log.rb +10 -10
- data/lib/bundles/inspec-habitat/profile.rb +390 -390
- data/lib/bundles/inspec-init.rb +8 -8
- data/lib/bundles/inspec-init/README.md +31 -31
- data/lib/bundles/inspec-init/cli.rb +97 -97
- data/lib/bundles/inspec-init/templates/profile/README.md +3 -3
- data/lib/bundles/inspec-init/templates/profile/controls/example.rb +19 -19
- data/lib/bundles/inspec-init/templates/profile/inspec.yml +8 -8
- data/lib/bundles/inspec-supermarket.rb +13 -13
- data/lib/bundles/inspec-supermarket/README.md +45 -45
- data/lib/bundles/inspec-supermarket/api.rb +84 -84
- data/lib/bundles/inspec-supermarket/cli.rb +73 -73
- data/lib/bundles/inspec-supermarket/target.rb +34 -34
- data/lib/fetchers/git.rb +163 -163
- data/lib/fetchers/local.rb +74 -74
- data/lib/fetchers/mock.rb +35 -35
- data/lib/fetchers/url.rb +204 -204
- data/lib/inspec.rb +24 -24
- data/lib/inspec/archive/tar.rb +29 -29
- data/lib/inspec/archive/zip.rb +19 -19
- data/lib/inspec/backend.rb +92 -92
- data/lib/inspec/base_cli.rb +355 -350
- data/lib/inspec/cached_fetcher.rb +66 -66
- data/lib/inspec/cli.rb +292 -292
- data/lib/inspec/completions/bash.sh.erb +45 -45
- data/lib/inspec/completions/fish.sh.erb +34 -34
- data/lib/inspec/completions/zsh.sh.erb +61 -61
- data/lib/inspec/control_eval_context.rb +179 -179
- data/lib/inspec/dependencies/cache.rb +72 -72
- data/lib/inspec/dependencies/dependency_set.rb +92 -92
- data/lib/inspec/dependencies/lockfile.rb +115 -115
- data/lib/inspec/dependencies/requirement.rb +123 -123
- data/lib/inspec/dependencies/resolver.rb +86 -86
- data/lib/inspec/describe.rb +27 -27
- data/lib/inspec/dsl.rb +66 -66
- data/lib/inspec/dsl_shared.rb +33 -33
- data/lib/inspec/env_printer.rb +157 -157
- data/lib/inspec/errors.rb +13 -13
- data/lib/inspec/exceptions.rb +12 -12
- data/lib/inspec/expect.rb +45 -45
- data/lib/inspec/fetcher.rb +45 -45
- data/lib/inspec/file_provider.rb +275 -275
- data/lib/inspec/formatters.rb +3 -3
- data/lib/inspec/formatters/base.rb +250 -250
- data/lib/inspec/formatters/json_rspec.rb +20 -20
- data/lib/inspec/formatters/show_progress.rb +12 -12
- data/lib/inspec/library_eval_context.rb +58 -58
- data/lib/inspec/log.rb +11 -11
- data/lib/inspec/metadata.rb +247 -247
- data/lib/inspec/method_source.rb +24 -24
- data/lib/inspec/objects.rb +14 -14
- data/lib/inspec/objects/attribute.rb +65 -65
- data/lib/inspec/objects/control.rb +61 -61
- data/lib/inspec/objects/describe.rb +92 -92
- data/lib/inspec/objects/each_loop.rb +36 -36
- data/lib/inspec/objects/list.rb +15 -15
- data/lib/inspec/objects/or_test.rb +40 -40
- data/lib/inspec/objects/ruby_helper.rb +15 -15
- data/lib/inspec/objects/tag.rb +27 -27
- data/lib/inspec/objects/test.rb +87 -87
- data/lib/inspec/objects/value.rb +27 -27
- data/lib/inspec/plugins.rb +60 -60
- data/lib/inspec/plugins/cli.rb +24 -24
- data/lib/inspec/plugins/fetcher.rb +86 -86
- data/lib/inspec/plugins/resource.rb +135 -135
- data/lib/inspec/plugins/secret.rb +15 -15
- data/lib/inspec/plugins/source_reader.rb +40 -40
- data/lib/inspec/polyfill.rb +12 -12
- data/lib/inspec/profile.rb +510 -510
- data/lib/inspec/profile_context.rb +207 -207
- data/lib/inspec/profile_vendor.rb +66 -66
- data/lib/inspec/reporters.rb +54 -50
- data/lib/inspec/reporters/base.rb +24 -24
- data/lib/inspec/reporters/cli.rb +356 -356
- data/lib/inspec/reporters/json.rb +116 -116
- data/lib/inspec/reporters/json_min.rb +48 -48
- data/lib/inspec/reporters/junit.rb +77 -77
- data/lib/inspec/require_loader.rb +33 -33
- data/lib/inspec/resource.rb +186 -186
- data/lib/inspec/rule.rb +266 -266
- data/lib/inspec/runner.rb +345 -345
- data/lib/inspec/runner_mock.rb +41 -41
- data/lib/inspec/runner_rspec.rb +175 -175
- data/lib/inspec/runtime_profile.rb +26 -26
- data/lib/inspec/schema.rb +213 -213
- data/lib/inspec/secrets.rb +19 -19
- data/lib/inspec/secrets/yaml.rb +30 -30
- data/lib/inspec/shell.rb +220 -220
- data/lib/inspec/shell_detector.rb +90 -90
- data/lib/inspec/source_reader.rb +29 -29
- data/lib/inspec/version.rb +8 -8
- data/lib/matchers/matchers.rb +339 -339
- data/lib/resource_support/aws.rb +41 -41
- data/lib/resource_support/aws/aws_backend_base.rb +12 -12
- data/lib/resource_support/aws/aws_backend_factory_mixin.rb +12 -12
- data/lib/resource_support/aws/aws_plural_resource_mixin.rb +21 -21
- data/lib/resource_support/aws/aws_resource_mixin.rb +66 -66
- data/lib/resource_support/aws/aws_singular_resource_mixin.rb +24 -24
- data/lib/resources/aide_conf.rb +159 -160
- data/lib/resources/apache.rb +48 -48
- data/lib/resources/apache_conf.rb +156 -156
- data/lib/resources/apt.rb +149 -149
- data/lib/resources/audit_policy.rb +63 -63
- data/lib/resources/auditd.rb +231 -231
- data/lib/resources/auditd_conf.rb +55 -55
- data/lib/resources/aws/aws_cloudtrail_trail.rb +77 -77
- data/lib/resources/aws/aws_cloudtrail_trails.rb +47 -47
- data/lib/resources/aws/aws_cloudwatch_alarm.rb +62 -62
- data/lib/resources/aws/aws_cloudwatch_log_metric_filter.rb +100 -100
- data/lib/resources/aws/aws_config_recorder.rb +98 -98
- data/lib/resources/aws/aws_ec2_instance.rb +157 -157
- data/lib/resources/aws/aws_iam_access_key.rb +106 -106
- data/lib/resources/aws/aws_iam_access_keys.rb +149 -144
- data/lib/resources/aws/aws_iam_group.rb +56 -56
- data/lib/resources/aws/aws_iam_groups.rb +52 -45
- data/lib/resources/aws/aws_iam_password_policy.rb +116 -116
- data/lib/resources/aws/aws_iam_policies.rb +53 -46
- data/lib/resources/aws/aws_iam_policy.rb +125 -119
- data/lib/resources/aws/aws_iam_role.rb +51 -51
- data/lib/resources/aws/aws_iam_root_user.rb +60 -60
- data/lib/resources/aws/aws_iam_user.rb +111 -111
- data/lib/resources/aws/aws_iam_users.rb +108 -96
- data/lib/resources/aws/aws_kms_keys.rb +53 -46
- data/lib/resources/aws/aws_route_table.rb +61 -61
- data/lib/resources/aws/aws_s3_bucket.rb +115 -115
- data/lib/resources/aws/aws_security_group.rb +93 -93
- data/lib/resources/aws/aws_security_groups.rb +68 -68
- data/lib/resources/aws/aws_sns_topic.rb +53 -53
- data/lib/resources/aws/aws_subnet.rb +88 -88
- data/lib/resources/aws/aws_subnets.rb +53 -53
- data/lib/resources/aws/aws_vpc.rb +69 -69
- data/lib/resources/aws/aws_vpcs.rb +45 -45
- data/lib/resources/azure/azure_backend.rb +377 -377
- data/lib/resources/azure/azure_generic_resource.rb +59 -59
- data/lib/resources/azure/azure_resource_group.rb +152 -152
- data/lib/resources/azure/azure_virtual_machine.rb +264 -264
- data/lib/resources/azure/azure_virtual_machine_data_disk.rb +136 -136
- data/lib/resources/bash.rb +35 -35
- data/lib/resources/bond.rb +68 -68
- data/lib/resources/bridge.rb +122 -122
- data/lib/resources/command.rb +73 -69
- data/lib/resources/cpan.rb +58 -58
- data/lib/resources/cran.rb +64 -64
- data/lib/resources/crontab.rb +169 -170
- data/lib/resources/csv.rb +60 -60
- data/lib/resources/dh_params.rb +82 -82
- data/lib/resources/directory.rb +25 -25
- data/lib/resources/docker.rb +236 -236
- data/lib/resources/docker_container.rb +89 -89
- data/lib/resources/docker_image.rb +83 -83
- data/lib/resources/docker_object.rb +57 -57
- data/lib/resources/docker_service.rb +90 -90
- data/lib/resources/elasticsearch.rb +169 -169
- data/lib/resources/etc_fstab.rb +101 -102
- data/lib/resources/etc_group.rb +152 -156
- data/lib/resources/etc_hosts.rb +82 -81
- data/lib/resources/etc_hosts_allow_deny.rb +122 -123
- data/lib/resources/file.rb +298 -298
- data/lib/resources/filesystem.rb +31 -31
- data/lib/resources/firewalld.rb +143 -144
- data/lib/resources/gem.rb +70 -70
- data/lib/resources/groups.rb +215 -215
- data/lib/resources/grub_conf.rb +237 -237
- data/lib/resources/host.rb +306 -300
- data/lib/resources/http.rb +251 -250
- data/lib/resources/iis_app.rb +101 -104
- data/lib/resources/iis_site.rb +148 -148
- data/lib/resources/inetd_conf.rb +62 -62
- data/lib/resources/ini.rb +29 -29
- data/lib/resources/interface.rb +129 -129
- data/lib/resources/iptables.rb +80 -69
- data/lib/resources/json.rb +117 -117
- data/lib/resources/kernel_module.rb +107 -107
- data/lib/resources/kernel_parameter.rb +58 -58
- data/lib/resources/key_rsa.rb +67 -67
- data/lib/resources/limits_conf.rb +55 -55
- data/lib/resources/login_def.rb +66 -66
- data/lib/resources/mount.rb +88 -88
- data/lib/resources/mssql_session.rb +101 -101
- data/lib/resources/mysql.rb +81 -81
- data/lib/resources/mysql_conf.rb +134 -134
- data/lib/resources/mysql_session.rb +71 -71
- data/lib/resources/nginx.rb +96 -96
- data/lib/resources/nginx_conf.rb +227 -227
- data/lib/resources/npm.rb +48 -48
- data/lib/resources/ntp_conf.rb +58 -58
- data/lib/resources/oneget.rb +71 -71
- data/lib/resources/oracledb_session.rb +139 -139
- data/lib/resources/os.rb +36 -36
- data/lib/resources/os_env.rb +76 -76
- data/lib/resources/package.rb +370 -370
- data/lib/resources/packages.rb +111 -111
- data/lib/resources/parse_config.rb +116 -116
- data/lib/resources/passwd.rb +74 -74
- data/lib/resources/pip.rb +89 -89
- data/lib/resources/platform.rb +109 -109
- data/lib/resources/port.rb +771 -771
- data/lib/resources/postgres.rb +130 -130
- data/lib/resources/postgres_conf.rb +121 -121
- data/lib/resources/postgres_hba_conf.rb +99 -100
- data/lib/resources/postgres_ident_conf.rb +76 -78
- data/lib/resources/postgres_session.rb +71 -71
- data/lib/resources/powershell.rb +53 -57
- data/lib/resources/processes.rb +204 -204
- data/lib/resources/rabbitmq_conf.rb +52 -52
- data/lib/resources/registry_key.rb +296 -296
- data/lib/resources/security_policy.rb +180 -180
- data/lib/resources/service.rb +789 -789
- data/lib/resources/shadow.rb +146 -140
- data/lib/resources/ssh_conf.rb +102 -102
- data/lib/resources/ssl.rb +99 -99
- data/lib/resources/sys_info.rb +28 -28
- data/lib/resources/toml.rb +32 -32
- data/lib/resources/users.rb +654 -654
- data/lib/resources/vbscript.rb +68 -69
- data/lib/resources/virtualization.rb +247 -247
- data/lib/resources/windows_feature.rb +84 -84
- data/lib/resources/windows_hotfix.rb +35 -35
- data/lib/resources/windows_task.rb +102 -105
- data/lib/resources/wmi.rb +110 -113
- data/lib/resources/x509_certificate.rb +143 -143
- data/lib/resources/xinetd.rb +111 -111
- data/lib/resources/xml.rb +46 -46
- data/lib/resources/yaml.rb +47 -47
- data/lib/resources/yum.rb +180 -180
- data/lib/resources/zfs_dataset.rb +60 -60
- data/lib/resources/zfs_pool.rb +49 -49
- data/lib/source_readers/flat.rb +39 -39
- data/lib/source_readers/inspec.rb +75 -75
- data/lib/utils/command_wrapper.rb +27 -27
- data/lib/utils/convert.rb +12 -12
- data/lib/utils/database_helpers.rb +77 -77
- data/lib/utils/erlang_parser.rb +192 -192
- data/lib/utils/filter.rb +272 -272
- data/lib/utils/filter_array.rb +27 -27
- data/lib/utils/find_files.rb +44 -44
- data/lib/utils/hash.rb +41 -41
- data/lib/utils/json_log.rb +18 -18
- data/lib/utils/latest_version.rb +22 -22
- data/lib/utils/modulator.rb +12 -12
- data/lib/utils/nginx_parser.rb +85 -85
- data/lib/utils/object_traversal.rb +49 -49
- data/lib/utils/parser.rb +274 -274
- data/lib/utils/plugin_registry.rb +93 -93
- data/lib/utils/simpleconfig.rb +120 -120
- data/lib/utils/spdx.rb +13 -13
- data/lib/utils/spdx.txt +343 -343
- metadata +2 -2
data/lib/resources/groups.rb
CHANGED
|
@@ -1,215 +1,215 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'utils/filter'
|
|
4
|
-
|
|
5
|
-
module Inspec::Resources
|
|
6
|
-
# This file contains two resources, the `group` and `groups` resource.
|
|
7
|
-
# The `group` resource is optimized for requests that verify specific groups
|
|
8
|
-
# that you know upfront for testing. If you need to query all groups or search
|
|
9
|
-
# specific groups with certain properties, use the `groups` resource.
|
|
10
|
-
module GroupManagementSelector
|
|
11
|
-
# select group provider based on the operating system
|
|
12
|
-
# returns nil, if no group manager was found for the operating system
|
|
13
|
-
def select_group_manager(os)
|
|
14
|
-
@group_provider = if os.darwin?
|
|
15
|
-
DarwinGroup.new(inspec)
|
|
16
|
-
elsif os.unix?
|
|
17
|
-
UnixGroup.new(inspec)
|
|
18
|
-
elsif os.windows?
|
|
19
|
-
WindowsGroup.new(inspec)
|
|
20
|
-
end
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
class Groups < Inspec.resource(1)
|
|
25
|
-
include GroupManagementSelector
|
|
26
|
-
|
|
27
|
-
name 'groups'
|
|
28
|
-
supports platform: 'unix'
|
|
29
|
-
supports platform: 'windows'
|
|
30
|
-
desc 'Use the group InSpec audit resource to test groups on the system. Groups can be filtered.'
|
|
31
|
-
example "
|
|
32
|
-
describe groups.where { name == 'root'} do
|
|
33
|
-
its('names') { should eq ['root'] }
|
|
34
|
-
its('gids') { should eq [0] }
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
describe groups.where { name == 'Administrators'} do
|
|
38
|
-
its('names') { should eq ['Administrators'] }
|
|
39
|
-
its('gids') { should eq ['S-1-5-32-544'] }
|
|
40
|
-
end
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
def initialize
|
|
44
|
-
# select group manager
|
|
45
|
-
@group_provider = select_group_manager(inspec.os)
|
|
46
|
-
return skip_resource 'The `groups` resource is not supported on your OS yet.' if @group_provider.nil?
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
filter = FilterTable.create
|
|
50
|
-
filter.add_accessor(:where)
|
|
51
|
-
.add_accessor(:entries)
|
|
52
|
-
.add(:names, field: 'name')
|
|
53
|
-
.add(:gids, field: 'gid')
|
|
54
|
-
.add(:domains, field: 'domain')
|
|
55
|
-
.add(:exists?) { |x| !x.entries.empty? }
|
|
56
|
-
filter.connect(self, :collect_group_details)
|
|
57
|
-
|
|
58
|
-
def to_s
|
|
59
|
-
'Groups'
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
private
|
|
63
|
-
|
|
64
|
-
# collects information about every group
|
|
65
|
-
def collect_group_details
|
|
66
|
-
return @groups_cache ||= @group_provider.groups unless @group_provider.nil?
|
|
67
|
-
[]
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
# Usage:
|
|
72
|
-
# describe group('root') do
|
|
73
|
-
# it { should exist }
|
|
74
|
-
# its('gid') { should eq 0 }
|
|
75
|
-
# end
|
|
76
|
-
#
|
|
77
|
-
# deprecated has matcher
|
|
78
|
-
# describe group('root') do
|
|
79
|
-
# it { should have_gid 0 }
|
|
80
|
-
# end
|
|
81
|
-
class Group < Inspec.resource(1)
|
|
82
|
-
include GroupManagementSelector
|
|
83
|
-
|
|
84
|
-
name 'group'
|
|
85
|
-
supports platform: 'unix'
|
|
86
|
-
supports platform: 'windows'
|
|
87
|
-
desc 'Use the group InSpec audit resource to test groups on the system.'
|
|
88
|
-
example "
|
|
89
|
-
describe group('root') do
|
|
90
|
-
it { should exist }
|
|
91
|
-
its('gid') { should eq 0 }
|
|
92
|
-
end
|
|
93
|
-
"
|
|
94
|
-
|
|
95
|
-
def initialize(groupname)
|
|
96
|
-
@group = groupname
|
|
97
|
-
|
|
98
|
-
# select group manager
|
|
99
|
-
@group_provider = select_group_manager(inspec.os)
|
|
100
|
-
return skip_resource 'The `group` resource is not supported on your OS yet.' if @group_provider.nil?
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# verifies if a group exists
|
|
104
|
-
def exists?
|
|
105
|
-
!group_info.entries.empty?
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def gid
|
|
109
|
-
gids = group_info.gids
|
|
110
|
-
if gids.empty?
|
|
111
|
-
nil
|
|
112
|
-
# the default case should be one group
|
|
113
|
-
elsif gids.size == 1
|
|
114
|
-
gids.entries[0]
|
|
115
|
-
else
|
|
116
|
-
raise 'found more than one group with the same name, please use `groups` resource'
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
# implements rspec has matcher, to be compatible with serverspec
|
|
121
|
-
def has_gid?(compare_gid)
|
|
122
|
-
gid == compare_gid
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
def local
|
|
126
|
-
# at this point the implementation only returns local groups
|
|
127
|
-
true
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def to_s
|
|
131
|
-
"Group #{@group}"
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
private
|
|
135
|
-
|
|
136
|
-
def group_info
|
|
137
|
-
# we need a local copy for the block
|
|
138
|
-
group = @group.dup
|
|
139
|
-
@groups_cache ||= inspec.groups.where { name == group }
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
class GroupInfo
|
|
144
|
-
attr_reader :inspec
|
|
145
|
-
def initialize(inspec)
|
|
146
|
-
@inspec = inspec
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
def groups
|
|
150
|
-
raise 'group provider must implement the `groups` method'
|
|
151
|
-
end
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
# implements generic unix groups via /etc/group
|
|
155
|
-
class UnixGroup < GroupInfo
|
|
156
|
-
def groups
|
|
157
|
-
inspec.etc_group.entries
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
# OSX uses opendirectory for groups, so `/etc/group` may not be fully accurate
|
|
162
|
-
# This uses `dscacheutil` to get the group info instead of `etc_group`
|
|
163
|
-
class DarwinGroup < GroupInfo
|
|
164
|
-
def groups
|
|
165
|
-
group_info = inspec.command('dscacheutil -q group').stdout.split("\n\n")
|
|
166
|
-
|
|
167
|
-
groups = []
|
|
168
|
-
regex = /^([^:]*?)\s*:\s(.*?)\s*$/
|
|
169
|
-
group_info.each do |data|
|
|
170
|
-
groups << inspec.parse_config(data, assignment_regex: regex).params
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
# Convert the `dscacheutil` groups to match `inspec.etc_group.entries`
|
|
174
|
-
groups.each { |g| g['gid'] = g['gid'].to_i }
|
|
175
|
-
groups.each do |g|
|
|
176
|
-
next if g['users'].nil?
|
|
177
|
-
g['members'] = g.delete('users')
|
|
178
|
-
g['members'].tr!(' ', ',')
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
class WindowsGroup < GroupInfo
|
|
184
|
-
# returns all local groups
|
|
185
|
-
def groups
|
|
186
|
-
script = <<~EOH
|
|
187
|
-
Function ConvertTo-SID { Param([byte[]]$BinarySID)
|
|
188
|
-
(New-Object System.Security.Principal.SecurityIdentifier($BinarySID,0)).Value
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
$Computername = $Env:Computername
|
|
192
|
-
$adsi = [ADSI]"WinNT://$Computername"
|
|
193
|
-
$groups = $adsi.Children | where {$_.SchemaClassName -eq 'group'} | ForEach {
|
|
194
|
-
$name = $_.Name[0]
|
|
195
|
-
$sid = ConvertTo-SID -BinarySID $_.ObjectSID[0]
|
|
196
|
-
$group =[ADSI]$_.Path
|
|
197
|
-
new-object psobject -property @{name = $group.Name[0]; gid = $sid; domain=$Computername}
|
|
198
|
-
}
|
|
199
|
-
$groups | ConvertTo-Json -Depth 3
|
|
200
|
-
EOH
|
|
201
|
-
cmd = inspec.powershell(script)
|
|
202
|
-
# cannot rely on exit code for now, successful command returns exit code 1
|
|
203
|
-
# return nil if cmd.exit_status != 0, try to parse json
|
|
204
|
-
begin
|
|
205
|
-
groups = JSON.parse(cmd.stdout)
|
|
206
|
-
rescue JSON::ParserError => _e
|
|
207
|
-
return []
|
|
208
|
-
end
|
|
209
|
-
|
|
210
|
-
# ensure we have an array of groups
|
|
211
|
-
groups = [groups] if !groups.is_a?(Array)
|
|
212
|
-
groups
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
end
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'utils/filter'
|
|
4
|
+
|
|
5
|
+
module Inspec::Resources
|
|
6
|
+
# This file contains two resources, the `group` and `groups` resource.
|
|
7
|
+
# The `group` resource is optimized for requests that verify specific groups
|
|
8
|
+
# that you know upfront for testing. If you need to query all groups or search
|
|
9
|
+
# specific groups with certain properties, use the `groups` resource.
|
|
10
|
+
module GroupManagementSelector
|
|
11
|
+
# select group provider based on the operating system
|
|
12
|
+
# returns nil, if no group manager was found for the operating system
|
|
13
|
+
def select_group_manager(os)
|
|
14
|
+
@group_provider = if os.darwin?
|
|
15
|
+
DarwinGroup.new(inspec)
|
|
16
|
+
elsif os.unix?
|
|
17
|
+
UnixGroup.new(inspec)
|
|
18
|
+
elsif os.windows?
|
|
19
|
+
WindowsGroup.new(inspec)
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class Groups < Inspec.resource(1)
|
|
25
|
+
include GroupManagementSelector
|
|
26
|
+
|
|
27
|
+
name 'groups'
|
|
28
|
+
supports platform: 'unix'
|
|
29
|
+
supports platform: 'windows'
|
|
30
|
+
desc 'Use the group InSpec audit resource to test groups on the system. Groups can be filtered.'
|
|
31
|
+
example "
|
|
32
|
+
describe groups.where { name == 'root'} do
|
|
33
|
+
its('names') { should eq ['root'] }
|
|
34
|
+
its('gids') { should eq [0] }
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe groups.where { name == 'Administrators'} do
|
|
38
|
+
its('names') { should eq ['Administrators'] }
|
|
39
|
+
its('gids') { should eq ['S-1-5-32-544'] }
|
|
40
|
+
end
|
|
41
|
+
"
|
|
42
|
+
|
|
43
|
+
def initialize
|
|
44
|
+
# select group manager
|
|
45
|
+
@group_provider = select_group_manager(inspec.os)
|
|
46
|
+
return skip_resource 'The `groups` resource is not supported on your OS yet.' if @group_provider.nil?
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
filter = FilterTable.create
|
|
50
|
+
filter.add_accessor(:where)
|
|
51
|
+
.add_accessor(:entries)
|
|
52
|
+
.add(:names, field: 'name')
|
|
53
|
+
.add(:gids, field: 'gid')
|
|
54
|
+
.add(:domains, field: 'domain')
|
|
55
|
+
.add(:exists?) { |x| !x.entries.empty? }
|
|
56
|
+
filter.connect(self, :collect_group_details)
|
|
57
|
+
|
|
58
|
+
def to_s
|
|
59
|
+
'Groups'
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
# collects information about every group
|
|
65
|
+
def collect_group_details
|
|
66
|
+
return @groups_cache ||= @group_provider.groups unless @group_provider.nil?
|
|
67
|
+
[]
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Usage:
|
|
72
|
+
# describe group('root') do
|
|
73
|
+
# it { should exist }
|
|
74
|
+
# its('gid') { should eq 0 }
|
|
75
|
+
# end
|
|
76
|
+
#
|
|
77
|
+
# deprecated has matcher
|
|
78
|
+
# describe group('root') do
|
|
79
|
+
# it { should have_gid 0 }
|
|
80
|
+
# end
|
|
81
|
+
class Group < Inspec.resource(1)
|
|
82
|
+
include GroupManagementSelector
|
|
83
|
+
|
|
84
|
+
name 'group'
|
|
85
|
+
supports platform: 'unix'
|
|
86
|
+
supports platform: 'windows'
|
|
87
|
+
desc 'Use the group InSpec audit resource to test groups on the system.'
|
|
88
|
+
example "
|
|
89
|
+
describe group('root') do
|
|
90
|
+
it { should exist }
|
|
91
|
+
its('gid') { should eq 0 }
|
|
92
|
+
end
|
|
93
|
+
"
|
|
94
|
+
|
|
95
|
+
def initialize(groupname)
|
|
96
|
+
@group = groupname
|
|
97
|
+
|
|
98
|
+
# select group manager
|
|
99
|
+
@group_provider = select_group_manager(inspec.os)
|
|
100
|
+
return skip_resource 'The `group` resource is not supported on your OS yet.' if @group_provider.nil?
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# verifies if a group exists
|
|
104
|
+
def exists?
|
|
105
|
+
!group_info.entries.empty?
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def gid
|
|
109
|
+
gids = group_info.gids
|
|
110
|
+
if gids.empty?
|
|
111
|
+
nil
|
|
112
|
+
# the default case should be one group
|
|
113
|
+
elsif gids.size == 1
|
|
114
|
+
gids.entries[0]
|
|
115
|
+
else
|
|
116
|
+
raise 'found more than one group with the same name, please use `groups` resource'
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# implements rspec has matcher, to be compatible with serverspec
|
|
121
|
+
def has_gid?(compare_gid)
|
|
122
|
+
gid == compare_gid
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def local
|
|
126
|
+
# at this point the implementation only returns local groups
|
|
127
|
+
true
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def to_s
|
|
131
|
+
"Group #{@group}"
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
private
|
|
135
|
+
|
|
136
|
+
def group_info
|
|
137
|
+
# we need a local copy for the block
|
|
138
|
+
group = @group.dup
|
|
139
|
+
@groups_cache ||= inspec.groups.where { name == group }
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
class GroupInfo
|
|
144
|
+
attr_reader :inspec
|
|
145
|
+
def initialize(inspec)
|
|
146
|
+
@inspec = inspec
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def groups
|
|
150
|
+
raise 'group provider must implement the `groups` method'
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# implements generic unix groups via /etc/group
|
|
155
|
+
class UnixGroup < GroupInfo
|
|
156
|
+
def groups
|
|
157
|
+
inspec.etc_group.entries
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# OSX uses opendirectory for groups, so `/etc/group` may not be fully accurate
|
|
162
|
+
# This uses `dscacheutil` to get the group info instead of `etc_group`
|
|
163
|
+
class DarwinGroup < GroupInfo
|
|
164
|
+
def groups
|
|
165
|
+
group_info = inspec.command('dscacheutil -q group').stdout.split("\n\n")
|
|
166
|
+
|
|
167
|
+
groups = []
|
|
168
|
+
regex = /^([^:]*?)\s*:\s(.*?)\s*$/
|
|
169
|
+
group_info.each do |data|
|
|
170
|
+
groups << inspec.parse_config(data, assignment_regex: regex).params
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Convert the `dscacheutil` groups to match `inspec.etc_group.entries`
|
|
174
|
+
groups.each { |g| g['gid'] = g['gid'].to_i }
|
|
175
|
+
groups.each do |g|
|
|
176
|
+
next if g['users'].nil?
|
|
177
|
+
g['members'] = g.delete('users')
|
|
178
|
+
g['members'].tr!(' ', ',')
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
class WindowsGroup < GroupInfo
|
|
184
|
+
# returns all local groups
|
|
185
|
+
def groups
|
|
186
|
+
script = <<~EOH
|
|
187
|
+
Function ConvertTo-SID { Param([byte[]]$BinarySID)
|
|
188
|
+
(New-Object System.Security.Principal.SecurityIdentifier($BinarySID,0)).Value
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
$Computername = $Env:Computername
|
|
192
|
+
$adsi = [ADSI]"WinNT://$Computername"
|
|
193
|
+
$groups = $adsi.Children | where {$_.SchemaClassName -eq 'group'} | ForEach {
|
|
194
|
+
$name = $_.Name[0]
|
|
195
|
+
$sid = ConvertTo-SID -BinarySID $_.ObjectSID[0]
|
|
196
|
+
$group =[ADSI]$_.Path
|
|
197
|
+
new-object psobject -property @{name = $group.Name[0]; gid = $sid; domain=$Computername}
|
|
198
|
+
}
|
|
199
|
+
$groups | ConvertTo-Json -Depth 3
|
|
200
|
+
EOH
|
|
201
|
+
cmd = inspec.powershell(script)
|
|
202
|
+
# cannot rely on exit code for now, successful command returns exit code 1
|
|
203
|
+
# return nil if cmd.exit_status != 0, try to parse json
|
|
204
|
+
begin
|
|
205
|
+
groups = JSON.parse(cmd.stdout)
|
|
206
|
+
rescue JSON::ParserError => _e
|
|
207
|
+
return []
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# ensure we have an array of groups
|
|
211
|
+
groups = [groups] if !groups.is_a?(Array)
|
|
212
|
+
groups
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
data/lib/resources/grub_conf.rb
CHANGED
|
@@ -1,237 +1,237 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
|
|
3
|
-
require 'utils/simpleconfig'
|
|
4
|
-
|
|
5
|
-
class GrubConfig < Inspec.resource(1)
|
|
6
|
-
name 'grub_conf'
|
|
7
|
-
supports platform: 'unix'
|
|
8
|
-
desc 'Use the grub_conf InSpec audit resource to test the boot config of Linux systems that use Grub.'
|
|
9
|
-
example "
|
|
10
|
-
describe grub_conf('/etc/grub.conf', 'default') do
|
|
11
|
-
its('kernel') { should include '/vmlinuz-2.6.32-573.7.1.el6.x86_64' }
|
|
12
|
-
its('initrd') { should include '/initramfs-2.6.32-573.el6.x86_64.img=1' }
|
|
13
|
-
its('default') { should_not eq '1' }
|
|
14
|
-
its('timeout') { should eq '5' }
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
also check specific kernels
|
|
18
|
-
describe grub_conf('/etc/grub.conf', 'CentOS (2.6.32-573.12.1.el6.x86_64)') do
|
|
19
|
-
its('kernel') { should include 'audit=1' }
|
|
20
|
-
end
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
class UnknownGrubConfig < StandardError; end
|
|
24
|
-
|
|
25
|
-
def initialize(path = nil, kernel = nil)
|
|
26
|
-
config_for_platform(path)
|
|
27
|
-
@kernel = kernel || 'default'
|
|
28
|
-
rescue UnknownGrubConfig
|
|
29
|
-
return skip_resource 'The `grub_config` resource is not supported on your OS yet.'
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def config_for_platform(path)
|
|
33
|
-
os = inspec.os
|
|
34
|
-
if os.redhat? || os[:name] == 'fedora'
|
|
35
|
-
config_for_redhatish(path)
|
|
36
|
-
elsif os.debian?
|
|
37
|
-
@conf_path = path || '/boot/grub/grub.cfg'
|
|
38
|
-
@defaults_path = '/etc/default/grub'
|
|
39
|
-
@grubenv_path = '/boot/grub2/grubenv'
|
|
40
|
-
@version = 'grub2'
|
|
41
|
-
elsif os[:name] == 'amazon'
|
|
42
|
-
@conf_path = path || '/etc/grub.conf'
|
|
43
|
-
@version = 'legacy'
|
|
44
|
-
else
|
|
45
|
-
raise UnknownGrubConfig
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def config_for_redhatish(path)
|
|
50
|
-
if inspec.os[:release].to_f < 7
|
|
51
|
-
@conf_path = path || '/etc/grub.conf'
|
|
52
|
-
@version = 'legacy'
|
|
53
|
-
else
|
|
54
|
-
@conf_path = path || '/boot/grub2/grub.cfg'
|
|
55
|
-
@defaults_path = '/etc/default/grub'
|
|
56
|
-
@grubenv_path = '/boot/grub2/grubenv'
|
|
57
|
-
@version = 'grub2'
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def method_missing(name)
|
|
62
|
-
read_params[name.to_s]
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def to_s
|
|
66
|
-
'Grub Config'
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
private
|
|
70
|
-
|
|
71
|
-
######################################################################
|
|
72
|
-
# Grub2 This is used by all supported versions of Ubuntu and Rhel 7+ #
|
|
73
|
-
######################################################################
|
|
74
|
-
|
|
75
|
-
def grub2_parse_kernel_lines(content, conf)
|
|
76
|
-
menu_entries = extract_menu_entries(content)
|
|
77
|
-
|
|
78
|
-
if @kernel == 'default'
|
|
79
|
-
default_menu_entry(menu_entries, conf['GRUB_DEFAULT'])
|
|
80
|
-
else
|
|
81
|
-
menu_entries.find { |entry| entry['name'] == @kernel }
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def extract_menu_entries(content)
|
|
86
|
-
menu_entries = []
|
|
87
|
-
|
|
88
|
-
lines = content.split("\n")
|
|
89
|
-
lines.each_with_index do |line, index|
|
|
90
|
-
next unless line =~ /^menuentry\s+.*/
|
|
91
|
-
entry = {}
|
|
92
|
-
entry['insmod'] = []
|
|
93
|
-
|
|
94
|
-
# Extract name from menuentry line
|
|
95
|
-
capture_data = line.match(/(?:^|\s+).*menuentry\s*['|"](.*)['|"]\s*--/)
|
|
96
|
-
if capture_data.nil? || capture_data.captures[0].nil?
|
|
97
|
-
raise Inspec::Exceptions::ResourceFailed "Failed to extract menuentry name from #{line}"
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
entry['name'] = capture_data.captures[0]
|
|
101
|
-
|
|
102
|
-
# Begin processing from index forward until a `}` line is met
|
|
103
|
-
lines.drop(index+1).each do |mline|
|
|
104
|
-
break if mline =~ /^\s*}\s*$/
|
|
105
|
-
case mline
|
|
106
|
-
when /(?:^|\s*)initrd.*/
|
|
107
|
-
entry['initrd'] = mline.split(' ')[1]
|
|
108
|
-
when /(?:^|\s*)linux.*/
|
|
109
|
-
entry['kernel'] = mline.split
|
|
110
|
-
when /(?:^|\s*)set root=.*/
|
|
111
|
-
entry['root'] = mline.split('=')[1].tr('\'', '')
|
|
112
|
-
when /(?:^|\s*)insmod.*/
|
|
113
|
-
entry['insmod'] << mline.split(' ')[1]
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
menu_entries << entry
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
menu_entries
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def default_menu_entry(menu_entries, default)
|
|
124
|
-
# If the default entry isn't `saved` then a number is used as an index.
|
|
125
|
-
# By default this is `0`, which would be the first item in the list.
|
|
126
|
-
return menu_entries[default.to_i] unless default == 'saved'
|
|
127
|
-
|
|
128
|
-
grubenv_contents = inspec.file(@grubenv_path).content
|
|
129
|
-
|
|
130
|
-
# The location of the grubenv file is not guaranteed. In the case that
|
|
131
|
-
# the file does not exist this will return the 0th entry. This will also
|
|
132
|
-
# return the 0th entry if InSpec lacks permission to read the file. Both
|
|
133
|
-
# of these reflect the default Grub2 behavior.
|
|
134
|
-
return menu_entries[0] if grubenv_contents.nil?
|
|
135
|
-
|
|
136
|
-
default_name = SimpleConfig.new(grubenv_contents).params['saved_entry']
|
|
137
|
-
default_entry = menu_entries.select { |k| k['name'] == default_name }[0]
|
|
138
|
-
return default_entry unless default_entry.nil?
|
|
139
|
-
|
|
140
|
-
# It is possible for the saved entry to not be valid . For example, grubenv
|
|
141
|
-
# not being up to date. If so, the 0th entry is the default.
|
|
142
|
-
menu_entries[0]
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
###################################################################
|
|
146
|
-
# Grub1 aka legacy-grub config. Primarily used by Centos/Rhel 6.x #
|
|
147
|
-
###################################################################
|
|
148
|
-
|
|
149
|
-
def parse_kernel_lines(content, conf)
|
|
150
|
-
# Find all "title" lines and then parse them into arrays
|
|
151
|
-
menu_entry = 0
|
|
152
|
-
lines = content.split("\n")
|
|
153
|
-
kernel_opts = {}
|
|
154
|
-
lines.each_with_index do |file_line, index|
|
|
155
|
-
next unless file_line =~ /^title.*/
|
|
156
|
-
current_kernel = file_line.split(' ', 2)[1]
|
|
157
|
-
lines.drop(index+1).each do |kernel_line|
|
|
158
|
-
if kernel_line =~ /^\s.*/
|
|
159
|
-
option_type = kernel_line.split(' ')[0]
|
|
160
|
-
line_options = kernel_line.split(' ').drop(1)
|
|
161
|
-
if (menu_entry == conf['default'].to_i && @kernel == 'default') || current_kernel == @kernel
|
|
162
|
-
if option_type == 'kernel'
|
|
163
|
-
kernel_opts['kernel'] = line_options
|
|
164
|
-
else
|
|
165
|
-
kernel_opts[option_type] = line_options[0]
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
|
-
else
|
|
169
|
-
menu_entry += 1
|
|
170
|
-
break
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
kernel_opts
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
def read_file(config_file)
|
|
178
|
-
file = inspec.file(config_file)
|
|
179
|
-
|
|
180
|
-
if !file.file? && !file.symlink?
|
|
181
|
-
skip_resource "Can't find file '#{@conf_path}'"
|
|
182
|
-
return @params = {}
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
content = file.content
|
|
186
|
-
|
|
187
|
-
if content.empty? && !file.empty?
|
|
188
|
-
skip_resource "Can't read file '#{@conf_path}'"
|
|
189
|
-
return @params = {}
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
content
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
def read_params
|
|
196
|
-
return @params if defined?(@params)
|
|
197
|
-
|
|
198
|
-
content = read_file(@conf_path)
|
|
199
|
-
|
|
200
|
-
if @version == 'legacy'
|
|
201
|
-
# parse the file
|
|
202
|
-
conf = SimpleConfig.new(
|
|
203
|
-
content,
|
|
204
|
-
multiple_values: true,
|
|
205
|
-
).params
|
|
206
|
-
# convert single entry arrays into strings
|
|
207
|
-
conf.each do |key, value|
|
|
208
|
-
if value.size == 1
|
|
209
|
-
conf[key] = conf[key][0].to_s
|
|
210
|
-
end
|
|
211
|
-
end
|
|
212
|
-
kernel_opts = parse_kernel_lines(content, conf)
|
|
213
|
-
@params = conf.merge(kernel_opts)
|
|
214
|
-
end
|
|
215
|
-
|
|
216
|
-
if @version == 'grub2'
|
|
217
|
-
# read defaults
|
|
218
|
-
defaults = read_file(@defaults_path)
|
|
219
|
-
|
|
220
|
-
conf = SimpleConfig.new(
|
|
221
|
-
defaults,
|
|
222
|
-
multiple_values: true,
|
|
223
|
-
).params
|
|
224
|
-
|
|
225
|
-
# convert single entry arrays into strings
|
|
226
|
-
conf.each do |key, value|
|
|
227
|
-
if value.size == 1
|
|
228
|
-
conf[key] = conf[key][0].to_s
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
|
|
232
|
-
kernel_opts = grub2_parse_kernel_lines(content, conf)
|
|
233
|
-
@params = conf.merge(kernel_opts)
|
|
234
|
-
end
|
|
235
|
-
@params
|
|
236
|
-
end
|
|
237
|
-
end
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
|
|
3
|
+
require 'utils/simpleconfig'
|
|
4
|
+
|
|
5
|
+
class GrubConfig < Inspec.resource(1)
|
|
6
|
+
name 'grub_conf'
|
|
7
|
+
supports platform: 'unix'
|
|
8
|
+
desc 'Use the grub_conf InSpec audit resource to test the boot config of Linux systems that use Grub.'
|
|
9
|
+
example "
|
|
10
|
+
describe grub_conf('/etc/grub.conf', 'default') do
|
|
11
|
+
its('kernel') { should include '/vmlinuz-2.6.32-573.7.1.el6.x86_64' }
|
|
12
|
+
its('initrd') { should include '/initramfs-2.6.32-573.el6.x86_64.img=1' }
|
|
13
|
+
its('default') { should_not eq '1' }
|
|
14
|
+
its('timeout') { should eq '5' }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
also check specific kernels
|
|
18
|
+
describe grub_conf('/etc/grub.conf', 'CentOS (2.6.32-573.12.1.el6.x86_64)') do
|
|
19
|
+
its('kernel') { should include 'audit=1' }
|
|
20
|
+
end
|
|
21
|
+
"
|
|
22
|
+
|
|
23
|
+
class UnknownGrubConfig < StandardError; end
|
|
24
|
+
|
|
25
|
+
def initialize(path = nil, kernel = nil)
|
|
26
|
+
config_for_platform(path)
|
|
27
|
+
@kernel = kernel || 'default'
|
|
28
|
+
rescue UnknownGrubConfig
|
|
29
|
+
return skip_resource 'The `grub_config` resource is not supported on your OS yet.'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def config_for_platform(path)
|
|
33
|
+
os = inspec.os
|
|
34
|
+
if os.redhat? || os[:name] == 'fedora'
|
|
35
|
+
config_for_redhatish(path)
|
|
36
|
+
elsif os.debian?
|
|
37
|
+
@conf_path = path || '/boot/grub/grub.cfg'
|
|
38
|
+
@defaults_path = '/etc/default/grub'
|
|
39
|
+
@grubenv_path = '/boot/grub2/grubenv'
|
|
40
|
+
@version = 'grub2'
|
|
41
|
+
elsif os[:name] == 'amazon'
|
|
42
|
+
@conf_path = path || '/etc/grub.conf'
|
|
43
|
+
@version = 'legacy'
|
|
44
|
+
else
|
|
45
|
+
raise UnknownGrubConfig
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def config_for_redhatish(path)
|
|
50
|
+
if inspec.os[:release].to_f < 7
|
|
51
|
+
@conf_path = path || '/etc/grub.conf'
|
|
52
|
+
@version = 'legacy'
|
|
53
|
+
else
|
|
54
|
+
@conf_path = path || '/boot/grub2/grub.cfg'
|
|
55
|
+
@defaults_path = '/etc/default/grub'
|
|
56
|
+
@grubenv_path = '/boot/grub2/grubenv'
|
|
57
|
+
@version = 'grub2'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def method_missing(name)
|
|
62
|
+
read_params[name.to_s]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def to_s
|
|
66
|
+
'Grub Config'
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
######################################################################
|
|
72
|
+
# Grub2 This is used by all supported versions of Ubuntu and Rhel 7+ #
|
|
73
|
+
######################################################################
|
|
74
|
+
|
|
75
|
+
def grub2_parse_kernel_lines(content, conf)
|
|
76
|
+
menu_entries = extract_menu_entries(content)
|
|
77
|
+
|
|
78
|
+
if @kernel == 'default'
|
|
79
|
+
default_menu_entry(menu_entries, conf['GRUB_DEFAULT'])
|
|
80
|
+
else
|
|
81
|
+
menu_entries.find { |entry| entry['name'] == @kernel }
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def extract_menu_entries(content)
|
|
86
|
+
menu_entries = []
|
|
87
|
+
|
|
88
|
+
lines = content.split("\n")
|
|
89
|
+
lines.each_with_index do |line, index|
|
|
90
|
+
next unless line =~ /^menuentry\s+.*/
|
|
91
|
+
entry = {}
|
|
92
|
+
entry['insmod'] = []
|
|
93
|
+
|
|
94
|
+
# Extract name from menuentry line
|
|
95
|
+
capture_data = line.match(/(?:^|\s+).*menuentry\s*['|"](.*)['|"]\s*--/)
|
|
96
|
+
if capture_data.nil? || capture_data.captures[0].nil?
|
|
97
|
+
raise Inspec::Exceptions::ResourceFailed "Failed to extract menuentry name from #{line}"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
entry['name'] = capture_data.captures[0]
|
|
101
|
+
|
|
102
|
+
# Begin processing from index forward until a `}` line is met
|
|
103
|
+
lines.drop(index+1).each do |mline|
|
|
104
|
+
break if mline =~ /^\s*}\s*$/
|
|
105
|
+
case mline
|
|
106
|
+
when /(?:^|\s*)initrd.*/
|
|
107
|
+
entry['initrd'] = mline.split(' ')[1]
|
|
108
|
+
when /(?:^|\s*)linux.*/
|
|
109
|
+
entry['kernel'] = mline.split
|
|
110
|
+
when /(?:^|\s*)set root=.*/
|
|
111
|
+
entry['root'] = mline.split('=')[1].tr('\'', '')
|
|
112
|
+
when /(?:^|\s*)insmod.*/
|
|
113
|
+
entry['insmod'] << mline.split(' ')[1]
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
menu_entries << entry
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
menu_entries
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def default_menu_entry(menu_entries, default)
|
|
124
|
+
# If the default entry isn't `saved` then a number is used as an index.
|
|
125
|
+
# By default this is `0`, which would be the first item in the list.
|
|
126
|
+
return menu_entries[default.to_i] unless default == 'saved'
|
|
127
|
+
|
|
128
|
+
grubenv_contents = inspec.file(@grubenv_path).content
|
|
129
|
+
|
|
130
|
+
# The location of the grubenv file is not guaranteed. In the case that
|
|
131
|
+
# the file does not exist this will return the 0th entry. This will also
|
|
132
|
+
# return the 0th entry if InSpec lacks permission to read the file. Both
|
|
133
|
+
# of these reflect the default Grub2 behavior.
|
|
134
|
+
return menu_entries[0] if grubenv_contents.nil?
|
|
135
|
+
|
|
136
|
+
default_name = SimpleConfig.new(grubenv_contents).params['saved_entry']
|
|
137
|
+
default_entry = menu_entries.select { |k| k['name'] == default_name }[0]
|
|
138
|
+
return default_entry unless default_entry.nil?
|
|
139
|
+
|
|
140
|
+
# It is possible for the saved entry to not be valid . For example, grubenv
|
|
141
|
+
# not being up to date. If so, the 0th entry is the default.
|
|
142
|
+
menu_entries[0]
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
###################################################################
|
|
146
|
+
# Grub1 aka legacy-grub config. Primarily used by Centos/Rhel 6.x #
|
|
147
|
+
###################################################################
|
|
148
|
+
|
|
149
|
+
def parse_kernel_lines(content, conf)
|
|
150
|
+
# Find all "title" lines and then parse them into arrays
|
|
151
|
+
menu_entry = 0
|
|
152
|
+
lines = content.split("\n")
|
|
153
|
+
kernel_opts = {}
|
|
154
|
+
lines.each_with_index do |file_line, index|
|
|
155
|
+
next unless file_line =~ /^title.*/
|
|
156
|
+
current_kernel = file_line.split(' ', 2)[1]
|
|
157
|
+
lines.drop(index+1).each do |kernel_line|
|
|
158
|
+
if kernel_line =~ /^\s.*/
|
|
159
|
+
option_type = kernel_line.split(' ')[0]
|
|
160
|
+
line_options = kernel_line.split(' ').drop(1)
|
|
161
|
+
if (menu_entry == conf['default'].to_i && @kernel == 'default') || current_kernel == @kernel
|
|
162
|
+
if option_type == 'kernel'
|
|
163
|
+
kernel_opts['kernel'] = line_options
|
|
164
|
+
else
|
|
165
|
+
kernel_opts[option_type] = line_options[0]
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
else
|
|
169
|
+
menu_entry += 1
|
|
170
|
+
break
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
kernel_opts
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def read_file(config_file)
|
|
178
|
+
file = inspec.file(config_file)
|
|
179
|
+
|
|
180
|
+
if !file.file? && !file.symlink?
|
|
181
|
+
skip_resource "Can't find file '#{@conf_path}'"
|
|
182
|
+
return @params = {}
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
content = file.content
|
|
186
|
+
|
|
187
|
+
if content.empty? && !file.empty?
|
|
188
|
+
skip_resource "Can't read file '#{@conf_path}'"
|
|
189
|
+
return @params = {}
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
content
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def read_params
|
|
196
|
+
return @params if defined?(@params)
|
|
197
|
+
|
|
198
|
+
content = read_file(@conf_path)
|
|
199
|
+
|
|
200
|
+
if @version == 'legacy'
|
|
201
|
+
# parse the file
|
|
202
|
+
conf = SimpleConfig.new(
|
|
203
|
+
content,
|
|
204
|
+
multiple_values: true,
|
|
205
|
+
).params
|
|
206
|
+
# convert single entry arrays into strings
|
|
207
|
+
conf.each do |key, value|
|
|
208
|
+
if value.size == 1
|
|
209
|
+
conf[key] = conf[key][0].to_s
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
kernel_opts = parse_kernel_lines(content, conf)
|
|
213
|
+
@params = conf.merge(kernel_opts)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
if @version == 'grub2'
|
|
217
|
+
# read defaults
|
|
218
|
+
defaults = read_file(@defaults_path)
|
|
219
|
+
|
|
220
|
+
conf = SimpleConfig.new(
|
|
221
|
+
defaults,
|
|
222
|
+
multiple_values: true,
|
|
223
|
+
).params
|
|
224
|
+
|
|
225
|
+
# convert single entry arrays into strings
|
|
226
|
+
conf.each do |key, value|
|
|
227
|
+
if value.size == 1
|
|
228
|
+
conf[key] = conf[key][0].to_s
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
kernel_opts = grub2_parse_kernel_lines(content, conf)
|
|
233
|
+
@params = conf.merge(kernel_opts)
|
|
234
|
+
end
|
|
235
|
+
@params
|
|
236
|
+
end
|
|
237
|
+
end
|