smart_proxy_openscap 0.11.1 → 0.12.1
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/.github/workflows/release.yml +20 -0
- data/.github/workflows/test.yml +14 -0
- data/Gemfile +1 -2
- data/lib/smart_proxy_openscap/arf_html.rb +19 -12
- data/lib/smart_proxy_openscap/arf_parser.rb +26 -30
- data/lib/smart_proxy_openscap/openscap_api.rb +6 -5
- data/lib/smart_proxy_openscap/openscap_lib.rb +9 -2
- data/lib/smart_proxy_openscap/openscap_plugin.rb +5 -0
- data/lib/smart_proxy_openscap/policy_guide.rb +18 -15
- data/lib/smart_proxy_openscap/storage_fs.rb +12 -1
- data/lib/smart_proxy_openscap/validate_settings.rb +11 -0
- data/lib/smart_proxy_openscap/version.rb +1 -1
- data/smart_proxy_openscap.gemspec +7 -5
- data/test/arf_html_test.rb +12 -0
- data/test/data/corrupted_arf_report +0 -0
- data/test/policy_guide_test.rb +11 -0
- metadata +26 -40
- data/bin/smart-proxy-arf-html +0 -7
- data/bin/smart-proxy-policy-guide +0 -7
- data/lib/smart_proxy_openscap/policy_parser.rb +0 -33
- data/lib/smart_proxy_openscap/shell_wrapper.rb +0 -77
- data/test/script_class_test.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 404a103b2ff24e1b3ff89bf63f548abd7269386df14b87225034fc52a30626e3
|
4
|
+
data.tar.gz: 1121a51545bdff52152bb63339b0be18b65a22241795e5e2b3423a5495295082
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b2fcf76c1a4742ba1d1d1b2b0883a5e9cc942f6f0bcb5740390f56e7f38ed95b50288cf7a07dc5b75779543821d6a6e7acd3ef0865097b0c083d102b6ddc40f8
|
7
|
+
data.tar.gz: c95f37095c506b144d9573b6f45fbbd540641828ad73762ead1a4845ddc2708ef42c863572e1579016be2118e1e0e870e330c0c9a5bed02b67fbefc1b760005e
|
@@ -0,0 +1,20 @@
|
|
1
|
+
name: Release
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
# Pattern matched against refs/tags
|
6
|
+
tags:
|
7
|
+
- '**'
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
release:
|
11
|
+
name: Release gem
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
environment: release
|
14
|
+
if: github.repository_owner == 'theforeman'
|
15
|
+
|
16
|
+
permissions:
|
17
|
+
id-token: write
|
18
|
+
|
19
|
+
steps:
|
20
|
+
- uses: voxpupuli/ruby-release@v0
|
@@ -0,0 +1,14 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: pull_request
|
4
|
+
|
5
|
+
concurrency:
|
6
|
+
group: ${{ github.ref_name }}-${{ github.workflow }}
|
7
|
+
cancel-in-progress: true
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
test:
|
11
|
+
name: Tests
|
12
|
+
uses: theforeman/actions/.github/workflows/smart_proxy_plugin.yml@v0
|
13
|
+
with:
|
14
|
+
extra_packages: openscap-scanner
|
data/Gemfile
CHANGED
@@ -6,8 +6,7 @@ group :development do
|
|
6
6
|
gem 'pry'
|
7
7
|
gem 'pry-byebug'
|
8
8
|
gem 'rubocop'
|
9
|
-
gem '
|
10
|
-
gem 'smart_proxy', :github => "theforeman/smart-proxy", :branch => 'develop'
|
9
|
+
gem 'smart_proxy', :github => "theforeman/smart-proxy", :branch => ENV.fetch('SMART_PROXY_BRANCH', 'develop')
|
11
10
|
end
|
12
11
|
|
13
12
|
# load local gemfile
|
@@ -1,21 +1,28 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
1
|
+
require 'smart_proxy_openscap/storage_fs'
|
2
|
+
require 'smart_proxy_openscap/openscap_exception'
|
3
3
|
|
4
4
|
module Proxy
|
5
5
|
module OpenSCAP
|
6
6
|
class ArfHtml
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
include ::Proxy::Log
|
8
|
+
|
9
|
+
def generate(cname, id, date, digest)
|
10
|
+
file_path = file_path_in_storage(cname, id, date, digest)
|
11
|
+
as_html file_path
|
12
|
+
end
|
13
|
+
|
14
|
+
def as_html(file_in_storage)
|
15
|
+
Proxy::OpenSCAP.execute!('oscap', 'xccdf', 'generate', 'report', file_in_storage).first
|
16
|
+
rescue => e
|
17
|
+
logger.debug e.message
|
18
|
+
logger.debug e.backtrace.join("\n\t")
|
19
|
+
raise Proxy::OpenSCAP::ReportDecompressError, "Failed to generate report HTML, cause: #{e.message}"
|
12
20
|
end
|
13
21
|
|
14
|
-
def
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
arf_object.html.force_encoding('UTF-8')
|
22
|
+
def file_path_in_storage(cname, id, date, digest)
|
23
|
+
path_to_dir = Proxy::OpenSCAP::Plugin.settings.reportsdir
|
24
|
+
storage = Proxy::OpenSCAP::StorageFs.new(path_to_dir, cname, id, date)
|
25
|
+
storage.get_path(digest)
|
19
26
|
end
|
20
27
|
end
|
21
28
|
end
|
@@ -13,23 +13,16 @@ module Proxy
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def as_json(arf_data)
|
16
|
-
|
17
|
-
file = Tempfile.new
|
16
|
+
decompressed = Tempfile.create do |file|
|
18
17
|
file.write(arf_data)
|
19
|
-
file.
|
20
|
-
|
18
|
+
file.flush
|
19
|
+
Proxy::OpenSCAP.execute!('bunzip2', '-dc', file.path).first
|
21
20
|
rescue => e
|
22
21
|
logger.error e
|
23
22
|
raise Proxy::OpenSCAP::ReportDecompressError, "Failed to decompress received report bzip, cause: #{e.message}"
|
24
|
-
ensure
|
25
|
-
file.close
|
26
|
-
file.unlink
|
27
23
|
end
|
28
24
|
arf_file = ::OpenscapParser::TestResultFile.new(decompressed)
|
29
|
-
rules = arf_file.benchmark.rules.
|
30
|
-
memo[rule.id] = rule
|
31
|
-
memo
|
32
|
-
end
|
25
|
+
rules = arf_file.benchmark.rules.to_h { |rule| [rule.id, rule] }
|
33
26
|
|
34
27
|
arf_digest = Digest::SHA256.hexdigest(arf_data)
|
35
28
|
report = parse_results(rules, arf_file.test_result, arf_digest)
|
@@ -41,18 +34,16 @@ module Proxy
|
|
41
34
|
private
|
42
35
|
|
43
36
|
def parse_results(rules, test_result, arf_digest)
|
44
|
-
results = test_result.rule_results
|
45
37
|
set_values = test_result.set_values
|
46
|
-
report = {}
|
47
|
-
report[:logs] = []
|
48
38
|
passed = 0
|
49
39
|
failed = 0
|
50
40
|
othered = 0
|
51
|
-
|
41
|
+
|
42
|
+
logs = test_result.rule_results.filter_map do |result|
|
52
43
|
next if result.result == 'notapplicable' || result.result == 'notselected'
|
44
|
+
|
53
45
|
# get rules and their results
|
54
46
|
rule_data = rules[result.id]
|
55
|
-
report[:logs] << populate_result_data(result.id, result.result, rule_data, set_values)
|
56
47
|
# create metrics for the results
|
57
48
|
case result.result
|
58
49
|
when 'pass', 'fixed'
|
@@ -62,24 +53,29 @@ module Proxy
|
|
62
53
|
else
|
63
54
|
othered += 1
|
64
55
|
end
|
56
|
+
|
57
|
+
populate_result_data(result.id, result.result, rule_data, set_values)
|
65
58
|
end
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
59
|
+
|
60
|
+
{
|
61
|
+
logs: logs,
|
62
|
+
digest: arf_digest,
|
63
|
+
metrics: { :passed => passed, :failed => failed, :othered => othered },
|
64
|
+
score: test_result.score,
|
65
|
+
}
|
70
66
|
end
|
71
67
|
|
72
68
|
def populate_result_data(result_id, rule_result, rule_data, set_values)
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
69
|
+
{
|
70
|
+
source: result_id,
|
71
|
+
result: rule_result,
|
72
|
+
title: rule_data.title,
|
73
|
+
description: rule_data.description,
|
74
|
+
rationale: rule_data.rationale,
|
75
|
+
references: rule_data.references.map { |ref| { :href => ref.href, :title => ref.label }},
|
76
|
+
fixes: populate_fixes(rule_data.fixes, set_values),
|
77
|
+
severity: rule_data.severity,
|
78
|
+
}
|
83
79
|
end
|
84
80
|
|
85
81
|
def populate_fixes(fixes, set_values)
|
@@ -98,11 +98,11 @@ module Proxy::OpenSCAP
|
|
98
98
|
|
99
99
|
get "/arf/:id/:cname/:date/:digest/html" do
|
100
100
|
begin
|
101
|
-
Proxy::OpenSCAP::
|
101
|
+
Proxy::OpenSCAP::ArfHtml.new.generate(params[:cname], params[:id], params[:date], params[:digest])
|
102
102
|
rescue FileNotFound => e
|
103
103
|
log_halt 500, "Could not find requested file, #{e.message}"
|
104
|
-
rescue
|
105
|
-
log_halt 500,
|
104
|
+
rescue ReportDecompressError => e
|
105
|
+
log_halt 500, e.message
|
106
106
|
end
|
107
107
|
end
|
108
108
|
|
@@ -162,10 +162,11 @@ module Proxy::OpenSCAP
|
|
162
162
|
|
163
163
|
post "/scap_content/guide/?:policy?" do
|
164
164
|
begin
|
165
|
-
Proxy::OpenSCAP::
|
165
|
+
html = Proxy::OpenSCAP::PolicyGuide.new.generate_guide(request.body.string, params[:policy])
|
166
|
+
{ :html => html }.to_json
|
166
167
|
rescue *HTTP_ERRORS => e
|
167
168
|
log_halt 500, e.message
|
168
|
-
rescue StandardError => e
|
169
|
+
rescue StandardError, OpenSCAPException => e
|
169
170
|
log_halt 500, "Error occurred: #{e.message}"
|
170
171
|
end
|
171
172
|
end
|
@@ -14,15 +14,16 @@ require 'pathname'
|
|
14
14
|
require 'json'
|
15
15
|
require 'proxy/error'
|
16
16
|
require 'yaml'
|
17
|
+
require 'open3'
|
17
18
|
require 'ostruct'
|
18
19
|
require 'proxy/request'
|
19
20
|
require 'smart_proxy_openscap/foreman_arf_forwarder'
|
20
21
|
require 'smart_proxy_openscap/content_parser'
|
21
22
|
require 'smart_proxy_openscap/openscap_exception'
|
23
|
+
require 'smart_proxy_openscap/arf_html'
|
22
24
|
require 'smart_proxy_openscap/arf_parser'
|
23
25
|
require 'smart_proxy_openscap/spool_forwarder'
|
24
|
-
require 'smart_proxy_openscap/
|
25
|
-
require 'smart_proxy_openscap/policy_parser'
|
26
|
+
require 'smart_proxy_openscap/policy_guide'
|
26
27
|
require 'smart_proxy_openscap/profiles_parser'
|
27
28
|
require 'smart_proxy_openscap/fetch_scap_file'
|
28
29
|
|
@@ -63,4 +64,10 @@ module Proxy::OpenSCAP
|
|
63
64
|
pathname = Pathname.new(path)
|
64
65
|
pathname.relative? ? pathname.expand_path(Sinatra::Base.root).to_s : path
|
65
66
|
end
|
67
|
+
|
68
|
+
def self.execute!(*cmd)
|
69
|
+
out, err, status = Open3.capture3(*cmd)
|
70
|
+
raise "'#{cmd.join(' ')} exited with #{status.exitstatus}: #{err}" unless status.success?
|
71
|
+
[out, err, status]
|
72
|
+
end
|
66
73
|
end
|
@@ -9,6 +9,8 @@
|
|
9
9
|
#
|
10
10
|
|
11
11
|
require 'smart_proxy_openscap/version'
|
12
|
+
require 'smart_proxy_openscap/validate_settings'
|
13
|
+
require 'smart_proxy_openscap/openscap_exception'
|
12
14
|
|
13
15
|
module Proxy::OpenSCAP
|
14
16
|
class Plugin < ::Proxy::Plugin
|
@@ -23,5 +25,8 @@ module Proxy::OpenSCAP
|
|
23
25
|
:reportsdir => File.join(APP_ROOT, 'openscap/reports'),
|
24
26
|
:failed_dir => File.join(APP_ROOT, 'openscap/failed'),
|
25
27
|
:tailoring_dir => File.join(APP_ROOT, 'openscap/tailoring')
|
28
|
+
|
29
|
+
load_validators :validate_settings => ::Proxy::OpenSCAP::ValidateSettings
|
30
|
+
validate :validate!, :validate_settings => nil
|
26
31
|
end
|
27
32
|
end
|
@@ -1,22 +1,25 @@
|
|
1
|
-
require '
|
2
|
-
require 'openscap/source'
|
3
|
-
require 'openscap/ds/sds'
|
4
|
-
require 'json'
|
1
|
+
require 'smart_proxy_openscap/openscap_exception'
|
5
2
|
|
6
3
|
module Proxy
|
7
4
|
module OpenSCAP
|
8
5
|
class PolicyGuide
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
6
|
+
include ::Proxy::Log
|
7
|
+
|
8
|
+
def generate_guide(file_content, policy_id)
|
9
|
+
Tempfile.create do |file|
|
10
|
+
file.write file_content
|
11
|
+
file.flush
|
12
|
+
command = ['oscap', 'xccdf', 'generate'] + profile_opt(policy_id) + ['guide', file.path]
|
13
|
+
Proxy::OpenSCAP.execute!(*command).first
|
14
|
+
end
|
15
|
+
rescue => e
|
16
|
+
logger.debug e.message
|
17
|
+
logger.debug e.backtrace.join("\n\t")
|
18
|
+
raise OpenSCAPException, "Failed to generate policy guide, cause: #{e.message}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def profile_opt(policy_id)
|
22
|
+
policy_id ? ['--profile', policy_id] : []
|
20
23
|
end
|
21
24
|
end
|
22
25
|
end
|
@@ -27,6 +27,11 @@ module Proxy::OpenSCAP
|
|
27
27
|
move "#{source}/#{digest}", StoreCorruptedError
|
28
28
|
end
|
29
29
|
|
30
|
+
def move_from_spool(digest, spooldir)
|
31
|
+
path = Dir.glob("#{spooldir}/#{@namespace}/#{@cname}/*/#{@date}/#{digest}").first
|
32
|
+
move path, StoreSpoolError
|
33
|
+
end
|
34
|
+
|
30
35
|
def get_arf_xml(digest)
|
31
36
|
get_arf_file(digest)[:xml]
|
32
37
|
end
|
@@ -45,8 +50,14 @@ module Proxy::OpenSCAP
|
|
45
50
|
|
46
51
|
def get_path(digest)
|
47
52
|
full_path = @path + digest
|
48
|
-
|
53
|
+
if !File.file?(full_path) || File.zero?(full_path)
|
54
|
+
logger.info "File not found in storage, trying to get it from spool"
|
55
|
+
path_to_spool = Proxy::OpenSCAP::Plugin.settings.spooldir
|
56
|
+
move_from_spool(digest, path_to_spool)
|
57
|
+
end
|
49
58
|
full_path
|
59
|
+
rescue StoreSpoolError
|
60
|
+
raise FileNotFound, "Can't find path #{full_path}"
|
50
61
|
end
|
51
62
|
|
52
63
|
def spool_errors
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module Proxy::OpenSCAP
|
4
|
+
class ValidateSettings < ::Proxy::PluginValidators::Base
|
5
|
+
def validate!(_settings)
|
6
|
+
_, _, _ = Open3.popen3(['oscap', '--help'])
|
7
|
+
rescue Errno::ENOENT
|
8
|
+
raise FileNotFound.new("'oscap' utility is not available")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -15,11 +15,13 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.files = `git ls-files`.split("\n") - ['.gitignore']
|
16
16
|
s.executables = ['smart-proxy-openscap-send']
|
17
17
|
s.requirements = 'bzip2'
|
18
|
+
s.requirements = 'oscap'
|
18
19
|
|
19
|
-
s.
|
20
|
-
|
21
|
-
s.add_development_dependency('
|
22
|
-
s.add_development_dependency('
|
23
|
-
s.
|
20
|
+
s.required_ruby_version = '>= 2.7', '< 4'
|
21
|
+
|
22
|
+
s.add_development_dependency('rake', '~> 13.0')
|
23
|
+
s.add_development_dependency('rack-test', '~> 0')
|
24
|
+
s.add_development_dependency('mocha', '~> 1')
|
25
|
+
s.add_development_dependency('webmock', '~> 3')
|
24
26
|
s.add_dependency 'openscap_parser', '~> 1.0.2'
|
25
27
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'smart_proxy_openscap/arf_html'
|
3
|
+
|
4
|
+
class ArfHtmlTest < Test::Unit::TestCase
|
5
|
+
def test_html_report
|
6
|
+
obj = Proxy::OpenSCAP::ArfHtml.new
|
7
|
+
obj.stubs(:file_path_in_storage).returns("#{Dir.getwd}/test/data/arf_report")
|
8
|
+
html = obj.generate('consumer-uuid', 5, 523455, 'digest')
|
9
|
+
|
10
|
+
assert html.start_with?('<!DOCTYPE'), "File should be html"
|
11
|
+
end
|
12
|
+
end
|
Binary file
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'smart_proxy_openscap/policy_guide'
|
3
|
+
|
4
|
+
class PolicyGuideTest < Test::Unit::TestCase
|
5
|
+
def test_policy_guide
|
6
|
+
profile = "xccdf_org.ssgproject.content_profile_rht-ccp"
|
7
|
+
policy_data = File.read "#{Dir.getwd}/test/data/ssg-rhel7-ds.xml"
|
8
|
+
guide = Proxy::OpenSCAP::PolicyGuide.new.generate_guide(policy_data, profile)
|
9
|
+
assert guide.start_with?('<!DOCTYPE'), "File should be html"
|
10
|
+
end
|
11
|
+
end
|
metadata
CHANGED
@@ -1,87 +1,72 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smart_proxy_openscap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Šimon Lukašík
|
8
8
|
- Shlomi Zadok
|
9
9
|
- Marek Hulan
|
10
|
-
autorequire:
|
11
10
|
bindir: bin
|
12
11
|
cert_chain: []
|
13
|
-
date:
|
12
|
+
date: 2025-04-09 00:00:00.000000000 Z
|
14
13
|
dependencies:
|
15
14
|
- !ruby/object:Gem::Dependency
|
16
15
|
name: rake
|
17
16
|
requirement: !ruby/object:Gem::Requirement
|
18
17
|
requirements:
|
19
|
-
- - "
|
18
|
+
- - "~>"
|
20
19
|
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
20
|
+
version: '13.0'
|
22
21
|
type: :development
|
23
22
|
prerelease: false
|
24
23
|
version_requirements: !ruby/object:Gem::Requirement
|
25
24
|
requirements:
|
26
|
-
- - "
|
25
|
+
- - "~>"
|
27
26
|
- !ruby/object:Gem::Version
|
28
|
-
version: '0'
|
27
|
+
version: '13.0'
|
29
28
|
- !ruby/object:Gem::Dependency
|
30
29
|
name: rack-test
|
31
30
|
requirement: !ruby/object:Gem::Requirement
|
32
31
|
requirements:
|
33
|
-
- - "
|
32
|
+
- - "~>"
|
34
33
|
- !ruby/object:Gem::Version
|
35
34
|
version: '0'
|
36
35
|
type: :development
|
37
36
|
prerelease: false
|
38
37
|
version_requirements: !ruby/object:Gem::Requirement
|
39
38
|
requirements:
|
40
|
-
- - "
|
39
|
+
- - "~>"
|
41
40
|
- !ruby/object:Gem::Version
|
42
41
|
version: '0'
|
43
42
|
- !ruby/object:Gem::Dependency
|
44
43
|
name: mocha
|
45
44
|
requirement: !ruby/object:Gem::Requirement
|
46
45
|
requirements:
|
47
|
-
- - "
|
46
|
+
- - "~>"
|
48
47
|
- !ruby/object:Gem::Version
|
49
|
-
version: '
|
48
|
+
version: '1'
|
50
49
|
type: :development
|
51
50
|
prerelease: false
|
52
51
|
version_requirements: !ruby/object:Gem::Requirement
|
53
52
|
requirements:
|
54
|
-
- - "
|
53
|
+
- - "~>"
|
55
54
|
- !ruby/object:Gem::Version
|
56
|
-
version: '
|
55
|
+
version: '1'
|
57
56
|
- !ruby/object:Gem::Dependency
|
58
57
|
name: webmock
|
59
|
-
requirement: !ruby/object:Gem::Requirement
|
60
|
-
requirements:
|
61
|
-
- - ">="
|
62
|
-
- !ruby/object:Gem::Version
|
63
|
-
version: '0'
|
64
|
-
type: :development
|
65
|
-
prerelease: false
|
66
|
-
version_requirements: !ruby/object:Gem::Requirement
|
67
|
-
requirements:
|
68
|
-
- - ">="
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
version: '0'
|
71
|
-
- !ruby/object:Gem::Dependency
|
72
|
-
name: openscap
|
73
58
|
requirement: !ruby/object:Gem::Requirement
|
74
59
|
requirements:
|
75
60
|
- - "~>"
|
76
61
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
78
|
-
type: :
|
62
|
+
version: '3'
|
63
|
+
type: :development
|
79
64
|
prerelease: false
|
80
65
|
version_requirements: !ruby/object:Gem::Requirement
|
81
66
|
requirements:
|
82
67
|
- - "~>"
|
83
68
|
- !ruby/object:Gem::Version
|
84
|
-
version:
|
69
|
+
version: '3'
|
85
70
|
- !ruby/object:Gem::Dependency
|
86
71
|
name: openscap_parser
|
87
72
|
requirement: !ruby/object:Gem::Requirement
|
@@ -105,6 +90,8 @@ executables:
|
|
105
90
|
extensions: []
|
106
91
|
extra_rdoc_files: []
|
107
92
|
files:
|
93
|
+
- ".github/workflows/release.yml"
|
94
|
+
- ".github/workflows/test.yml"
|
108
95
|
- ".rubocop.yml"
|
109
96
|
- ".rubocop_todo.yml"
|
110
97
|
- ".travis.yml"
|
@@ -112,9 +99,7 @@ files:
|
|
112
99
|
- Gemfile
|
113
100
|
- README.md
|
114
101
|
- Rakefile
|
115
|
-
- bin/smart-proxy-arf-html
|
116
102
|
- bin/smart-proxy-openscap-send
|
117
|
-
- bin/smart-proxy-policy-guide
|
118
103
|
- bundler.d/openscap.rb
|
119
104
|
- extra/smart-proxy-openscap-send.cron
|
120
105
|
- lib/smart_proxy_openscap.rb
|
@@ -134,16 +119,16 @@ files:
|
|
134
119
|
- lib/smart_proxy_openscap/openscap_lib.rb
|
135
120
|
- lib/smart_proxy_openscap/openscap_plugin.rb
|
136
121
|
- lib/smart_proxy_openscap/policy_guide.rb
|
137
|
-
- lib/smart_proxy_openscap/policy_parser.rb
|
138
122
|
- lib/smart_proxy_openscap/profiles_parser.rb
|
139
|
-
- lib/smart_proxy_openscap/shell_wrapper.rb
|
140
123
|
- lib/smart_proxy_openscap/spool_forwarder.rb
|
141
124
|
- lib/smart_proxy_openscap/storage.rb
|
142
125
|
- lib/smart_proxy_openscap/storage_fs.rb
|
143
126
|
- lib/smart_proxy_openscap/storage_fs_common.rb
|
127
|
+
- lib/smart_proxy_openscap/validate_settings.rb
|
144
128
|
- lib/smart_proxy_openscap/version.rb
|
145
129
|
- settings.d/openscap.yml.example
|
146
130
|
- smart_proxy_openscap.gemspec
|
131
|
+
- test/arf_html_test.rb
|
147
132
|
- test/data/arf_report
|
148
133
|
- test/data/corrupted_arf_report
|
149
134
|
- test/data/oval-results.xml.bz2
|
@@ -159,16 +144,15 @@ files:
|
|
159
144
|
- test/fetch_scap_api_test.rb
|
160
145
|
- test/fetch_tailoring_api_test.rb
|
161
146
|
- test/get_report_xml_html_test.rb
|
147
|
+
- test/policy_guide_test.rb
|
162
148
|
- test/post_report_api_test.rb
|
163
149
|
- test/scap_content_parser_api_test.rb
|
164
|
-
- test/script_class_test.rb
|
165
150
|
- test/spool_forwarder_test.rb
|
166
151
|
- test/test_helper.rb
|
167
152
|
homepage: https://github.com/theforeman/smart_proxy_openscap
|
168
153
|
licenses:
|
169
154
|
- GPL-3.0-or-later
|
170
155
|
metadata: {}
|
171
|
-
post_install_message:
|
172
156
|
rdoc_options: []
|
173
157
|
require_paths:
|
174
158
|
- lib
|
@@ -176,16 +160,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
176
160
|
requirements:
|
177
161
|
- - ">="
|
178
162
|
- !ruby/object:Gem::Version
|
179
|
-
version: '
|
163
|
+
version: '2.7'
|
164
|
+
- - "<"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '4'
|
180
167
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
181
168
|
requirements:
|
182
169
|
- - ">="
|
183
170
|
- !ruby/object:Gem::Version
|
184
171
|
version: '0'
|
185
172
|
requirements:
|
186
|
-
-
|
187
|
-
rubygems_version: 3.
|
188
|
-
signing_key:
|
173
|
+
- oscap
|
174
|
+
rubygems_version: 3.6.2
|
189
175
|
specification_version: 4
|
190
176
|
summary: OpenSCAP plug-in for Foreman's smart-proxy.
|
191
177
|
test_files: []
|
data/bin/smart-proxy-arf-html
DELETED
@@ -1,33 +0,0 @@
|
|
1
|
-
require 'smart_proxy_openscap/shell_wrapper'
|
2
|
-
|
3
|
-
module Proxy
|
4
|
-
module OpenSCAP
|
5
|
-
class PolicyParser < ShellWrapper
|
6
|
-
|
7
|
-
def initialize(policy)
|
8
|
-
@script_name = "smart-proxy-policy-guide"
|
9
|
-
@policy = policy
|
10
|
-
end
|
11
|
-
|
12
|
-
def guide(scap_file)
|
13
|
-
execute_shell_command scap_file
|
14
|
-
end
|
15
|
-
|
16
|
-
def in_filename
|
17
|
-
super
|
18
|
-
end
|
19
|
-
|
20
|
-
def out_filename
|
21
|
-
"#{in_filename}json-"
|
22
|
-
end
|
23
|
-
|
24
|
-
def failure_message
|
25
|
-
"Failure when running script which renders policy guide"
|
26
|
-
end
|
27
|
-
|
28
|
-
def command(in_file, out_file)
|
29
|
-
"#{script_location} #{in_file.path} #{out_file.path} #{@policy}"
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
require 'tempfile'
|
2
|
-
|
3
|
-
module Proxy
|
4
|
-
module OpenSCAP
|
5
|
-
class ShellWrapper
|
6
|
-
include ::Proxy::Log
|
7
|
-
|
8
|
-
attr_reader :script_name
|
9
|
-
|
10
|
-
def script_location
|
11
|
-
raise NotImplementedError, 'Must have @script_name' unless script_name
|
12
|
-
path = File.join(File.dirname(File.expand_path(__FILE__)), '../../bin', script_name)
|
13
|
-
return path if File.exist? path
|
14
|
-
script_name
|
15
|
-
end
|
16
|
-
|
17
|
-
def execute_shell_command(in_file_content = nil)
|
18
|
-
out_file = Tempfile.new(out_filename, "/var/tmp")
|
19
|
-
in_file = prepare_in_file in_file_content
|
20
|
-
comm = command(in_file, out_file)
|
21
|
-
logger.debug "Executing: #{comm}"
|
22
|
-
output = nil
|
23
|
-
begin
|
24
|
-
`#{comm}`
|
25
|
-
output = out_file.read
|
26
|
-
rescue => e
|
27
|
-
logger.debug failure_message
|
28
|
-
logger.debug e.message
|
29
|
-
logger.debug e.backtrace.join("\n\t")
|
30
|
-
ensure
|
31
|
-
close_unlink out_file, in_file
|
32
|
-
end
|
33
|
-
raise OpenSCAPException, exception_message if output.nil? || output.empty?
|
34
|
-
output
|
35
|
-
end
|
36
|
-
|
37
|
-
def close_unlink(*files)
|
38
|
-
files.compact.each do |file|
|
39
|
-
file.close
|
40
|
-
file.unlink
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def prepare_in_file(in_file_content)
|
45
|
-
return unless in_file_content
|
46
|
-
file = Tempfile.new(in_filename, "/var/tmp")
|
47
|
-
file.write in_file_content
|
48
|
-
file.rewind
|
49
|
-
file
|
50
|
-
end
|
51
|
-
|
52
|
-
def in_filename
|
53
|
-
@in_filename ||= unique_filename
|
54
|
-
end
|
55
|
-
|
56
|
-
def out_filename
|
57
|
-
@out_filename ||= unique_filename
|
58
|
-
end
|
59
|
-
|
60
|
-
def unique_filename
|
61
|
-
SecureRandom.uuid
|
62
|
-
end
|
63
|
-
|
64
|
-
def command(in_file, out_file)
|
65
|
-
raise NotImplementedError, "Must be implemented"
|
66
|
-
end
|
67
|
-
|
68
|
-
def failure_message
|
69
|
-
raise NotImplementedError, "Must be implemented"
|
70
|
-
end
|
71
|
-
|
72
|
-
def exception_message
|
73
|
-
failure_message
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
data/test/script_class_test.rb
DELETED
@@ -1,39 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
require 'smart_proxy_openscap/arf_html'
|
3
|
-
require 'smart_proxy_openscap/policy_guide'
|
4
|
-
|
5
|
-
class ScriptClassTest < Test::Unit::TestCase
|
6
|
-
def test_arf_generate_html
|
7
|
-
carry_out do |tmp|
|
8
|
-
Proxy::OpenSCAP::ArfHtml.new.generate_html("#{Dir.getwd}/test/data/arf_report", tmp.path)
|
9
|
-
content = File.read tmp
|
10
|
-
assert content.start_with?('<!DOCTYPE'), "File should be html"
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_policy_guide
|
15
|
-
carry_out do |tmp|
|
16
|
-
profile = "xccdf_org.ssgproject.content_profile_rht-ccp"
|
17
|
-
Proxy::OpenSCAP::PolicyGuide.new.generate_guide("#{Dir.getwd}/test/data/ssg-rhel7-ds.xml", tmp.path, profile)
|
18
|
-
guide = read_json tmp
|
19
|
-
assert guide['html'].start_with?('<!DOCTYPE'), "File should be html"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def carry_out
|
26
|
-
tmp = Tempfile.new('test')
|
27
|
-
begin
|
28
|
-
yield tmp if block_given?
|
29
|
-
ensure
|
30
|
-
tmp.close
|
31
|
-
tmp.unlink
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
def read_json(file)
|
36
|
-
file.flush
|
37
|
-
JSON.parse(File.read file)
|
38
|
-
end
|
39
|
-
end
|