smart_proxy_openscap 0.11.0 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- 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 +3 -7
- data/lib/smart_proxy_openscap/helpers.rb +33 -0
- data/lib/smart_proxy_openscap/openscap_api.rb +38 -30
- 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/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 -37
- 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: d64e75accfab154207646ea78d608d37877d3c293d38c3aa0fc0d4b7547b5ac0
|
4
|
+
data.tar.gz: dc18e3c41aaf4515abcc90ed7ec312a52705477bbc20372e9bd32c18203a479e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e4aa8c10499016653a8b7ef9151013ba3e23fb5ac0c1c12c40fa79bb3694135a4c6e33f765c53adaed9e83dd37dde090056dbe355ca4e1bcda626bea9c582fa
|
7
|
+
data.tar.gz: 5b40ab6cf91ecd6a5ffe87c9274714422deaf5b78e35c03c19ec304dda1ed2ec21275e0fb00836e42f5ef1dd4d60a9aedf47c0f224182ecd2b18568f104129c6
|
@@ -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: libopenscap8
|
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,17 +13,13 @@ 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
25
|
rules = arf_file.benchmark.rules.reduce({}) do |memo, rule|
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# lib/helpers.rb
|
2
|
+
|
3
|
+
module Proxy::OpenSCAP
|
4
|
+
module Helpers
|
5
|
+
if Process.respond_to?(:fork)
|
6
|
+
def forked_response
|
7
|
+
r, w = IO.pipe
|
8
|
+
if child_id = Process.fork
|
9
|
+
w.close
|
10
|
+
data = r.read
|
11
|
+
r.close
|
12
|
+
Process.wait(child_id)
|
13
|
+
JSON.parse(data)
|
14
|
+
else
|
15
|
+
r.close
|
16
|
+
begin
|
17
|
+
body, code = yield
|
18
|
+
w.write({ code: code, body: body }.to_json)
|
19
|
+
rescue Exception => e
|
20
|
+
w.write({ code: 500, body: e.message }.to_json)
|
21
|
+
end
|
22
|
+
w.close
|
23
|
+
Process.exit!
|
24
|
+
end
|
25
|
+
end
|
26
|
+
else
|
27
|
+
def forked_response
|
28
|
+
body, code = yield
|
29
|
+
{ code: code, body: body }
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -8,6 +8,7 @@
|
|
8
8
|
# along with this software; if not, see http://www.gnu.org/licenses/gpl.txt
|
9
9
|
#
|
10
10
|
require 'smart_proxy_openscap/openscap_lib'
|
11
|
+
require 'smart_proxy_openscap/helpers'
|
11
12
|
|
12
13
|
module Proxy::OpenSCAP
|
13
14
|
HTTP_ERRORS = [
|
@@ -24,6 +25,7 @@ module Proxy::OpenSCAP
|
|
24
25
|
class Api < ::Sinatra::Base
|
25
26
|
include ::Proxy::Log
|
26
27
|
helpers ::Proxy::Helpers
|
28
|
+
helpers ::Proxy::OpenSCAP::Helpers
|
27
29
|
authorize_with_ssl_client
|
28
30
|
CLIENT_PATHS = Regexp.compile(%r{^(/arf/\d+|/policies/\d+/content/|/policies/\d+/tailoring/)})
|
29
31
|
|
@@ -44,32 +46,37 @@ module Proxy::OpenSCAP
|
|
44
46
|
|
45
47
|
post "/arf/:policy" do
|
46
48
|
policy = params[:policy]
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
49
|
+
response = forked_response do
|
50
|
+
begin
|
51
|
+
post_to_foreman = ForemanArfForwarder.new.post_report(@cn, policy, @reported_at, request.body.string, Proxy::OpenSCAP::Plugin.settings.timeout)
|
52
|
+
Proxy::OpenSCAP::StorageFs.new(Proxy::OpenSCAP::Plugin.settings.reportsdir, @cn, post_to_foreman['id'], @reported_at).store_archive(request.body.string)
|
53
|
+
post_to_foreman.to_json
|
54
|
+
rescue Proxy::OpenSCAP::StoreReportError => e
|
55
|
+
Proxy::OpenSCAP::StorageFs.new(Proxy::OpenSCAP::Plugin.settings.failed_dir, @cn, post_to_foreman['id'], @reported_at).store_failed(request.body.string)
|
56
|
+
logger.error "Failed to save Report in reports directory (#{Proxy::OpenSCAP::Plugin.settings.reportsdir}). Failed with: #{e.message}.
|
57
|
+
Saving file in #{Proxy::OpenSCAP::Plugin.settings.failed_dir}. Please copy manually to #{Proxy::OpenSCAP::Plugin.settings.reportsdir}"
|
58
|
+
{ :result => 'Storage failure on proxy, see proxy logs for details' }.to_json
|
59
|
+
rescue Nokogiri::XML::SyntaxError => e
|
60
|
+
error = "Failed to parse Arf Report, moving to #{Proxy::OpenSCAP::Plugin.settings.corrupted_dir}"
|
61
|
+
logger.error error
|
62
|
+
Proxy::OpenSCAP::StorageFs.new(Proxy::OpenSCAP::Plugin.settings.corrupted_dir, @cn, policy, @reported_at).store_corrupted(request.body.string)
|
63
|
+
{ :result => (error << ' on proxy') }.to_json
|
64
|
+
rescue *HTTP_ERRORS => e
|
65
|
+
### If the upload to foreman fails then store it in the spooldir
|
66
|
+
msg = "Failed to upload to Foreman, saving in spool. Failed with: #{e.message}"
|
67
|
+
logger.error msg
|
68
|
+
Proxy::OpenSCAP::StorageFs.new(Proxy::OpenSCAP::Plugin.settings.spooldir, @cn, policy, @reported_at).store_spool(request.body.string)
|
69
|
+
{ :result => msg }.to_json
|
70
|
+
rescue Proxy::OpenSCAP::StoreSpoolError => e
|
71
|
+
[e.message, 500]
|
72
|
+
rescue Proxy::OpenSCAP::ReportUploadError, Proxy::OpenSCAP::ReportDecompressError => e
|
73
|
+
{ :result => e.message }.to_json
|
74
|
+
end
|
72
75
|
end
|
76
|
+
if code = response['code']
|
77
|
+
log_halt code, response['body']
|
78
|
+
end
|
79
|
+
response['body']
|
73
80
|
end
|
74
81
|
|
75
82
|
get "/arf/:id/:cname/:date/:digest/xml" do
|
@@ -91,11 +98,11 @@ module Proxy::OpenSCAP
|
|
91
98
|
|
92
99
|
get "/arf/:id/:cname/:date/:digest/html" do
|
93
100
|
begin
|
94
|
-
Proxy::OpenSCAP::
|
101
|
+
Proxy::OpenSCAP::ArfHtml.new.generate(params[:cname], params[:id], params[:date], params[:digest])
|
95
102
|
rescue FileNotFound => e
|
96
103
|
log_halt 500, "Could not find requested file, #{e.message}"
|
97
|
-
rescue
|
98
|
-
log_halt 500,
|
104
|
+
rescue ReportDecompressError => e
|
105
|
+
log_halt 500, e.message
|
99
106
|
end
|
100
107
|
end
|
101
108
|
|
@@ -155,10 +162,11 @@ module Proxy::OpenSCAP
|
|
155
162
|
|
156
163
|
post "/scap_content/guide/?:policy?" do
|
157
164
|
begin
|
158
|
-
Proxy::OpenSCAP::
|
165
|
+
html = Proxy::OpenSCAP::PolicyGuide.new.generate_guide(request.body.string, params[:policy])
|
166
|
+
{ :html => html }.to_json
|
159
167
|
rescue *HTTP_ERRORS => e
|
160
168
|
log_halt 500, e.message
|
161
|
-
rescue StandardError => e
|
169
|
+
rescue StandardError, OpenSCAPException => e
|
162
170
|
log_halt 500, "Error occurred: #{e.message}"
|
163
171
|
end
|
164
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
|
@@ -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,7 +1,7 @@
|
|
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.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Šimon Lukašík
|
@@ -10,78 +10,64 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2024-
|
13
|
+
date: 2024-12-03 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rake
|
17
17
|
requirement: !ruby/object:Gem::Requirement
|
18
18
|
requirements:
|
19
|
-
- - "
|
19
|
+
- - "~>"
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: '0'
|
21
|
+
version: '13.0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
|
-
- - "
|
26
|
+
- - "~>"
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: '0'
|
28
|
+
version: '13.0'
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: rack-test
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
|
-
- - "
|
33
|
+
- - "~>"
|
34
34
|
- !ruby/object:Gem::Version
|
35
35
|
version: '0'
|
36
36
|
type: :development
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
|
-
- - "
|
40
|
+
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: '0'
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: mocha
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- - "
|
47
|
+
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: '
|
49
|
+
version: '1'
|
50
50
|
type: :development
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
|
-
- - "
|
54
|
+
- - "~>"
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version: '
|
56
|
+
version: '1'
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
58
|
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
59
|
requirement: !ruby/object:Gem::Requirement
|
74
60
|
requirements:
|
75
61
|
- - "~>"
|
76
62
|
- !ruby/object:Gem::Version
|
77
|
-
version:
|
78
|
-
type: :
|
63
|
+
version: '3'
|
64
|
+
type: :development
|
79
65
|
prerelease: false
|
80
66
|
version_requirements: !ruby/object:Gem::Requirement
|
81
67
|
requirements:
|
82
68
|
- - "~>"
|
83
69
|
- !ruby/object:Gem::Version
|
84
|
-
version:
|
70
|
+
version: '3'
|
85
71
|
- !ruby/object:Gem::Dependency
|
86
72
|
name: openscap_parser
|
87
73
|
requirement: !ruby/object:Gem::Requirement
|
@@ -105,6 +91,7 @@ executables:
|
|
105
91
|
extensions: []
|
106
92
|
extra_rdoc_files: []
|
107
93
|
files:
|
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
|
@@ -125,6 +110,7 @@ files:
|
|
125
110
|
- lib/smart_proxy_openscap/fetch_scap_file.rb
|
126
111
|
- lib/smart_proxy_openscap/foreman_arf_forwarder.rb
|
127
112
|
- lib/smart_proxy_openscap/foreman_forwarder.rb
|
113
|
+
- lib/smart_proxy_openscap/helpers.rb
|
128
114
|
- lib/smart_proxy_openscap/http_config.ru
|
129
115
|
- lib/smart_proxy_openscap/openscap_api.rb
|
130
116
|
- lib/smart_proxy_openscap/openscap_exception.rb
|
@@ -133,16 +119,16 @@ files:
|
|
133
119
|
- lib/smart_proxy_openscap/openscap_lib.rb
|
134
120
|
- lib/smart_proxy_openscap/openscap_plugin.rb
|
135
121
|
- lib/smart_proxy_openscap/policy_guide.rb
|
136
|
-
- lib/smart_proxy_openscap/policy_parser.rb
|
137
122
|
- lib/smart_proxy_openscap/profiles_parser.rb
|
138
|
-
- lib/smart_proxy_openscap/shell_wrapper.rb
|
139
123
|
- lib/smart_proxy_openscap/spool_forwarder.rb
|
140
124
|
- lib/smart_proxy_openscap/storage.rb
|
141
125
|
- lib/smart_proxy_openscap/storage_fs.rb
|
142
126
|
- lib/smart_proxy_openscap/storage_fs_common.rb
|
127
|
+
- lib/smart_proxy_openscap/validate_settings.rb
|
143
128
|
- lib/smart_proxy_openscap/version.rb
|
144
129
|
- settings.d/openscap.yml.example
|
145
130
|
- smart_proxy_openscap.gemspec
|
131
|
+
- test/arf_html_test.rb
|
146
132
|
- test/data/arf_report
|
147
133
|
- test/data/corrupted_arf_report
|
148
134
|
- test/data/oval-results.xml.bz2
|
@@ -158,9 +144,9 @@ files:
|
|
158
144
|
- test/fetch_scap_api_test.rb
|
159
145
|
- test/fetch_tailoring_api_test.rb
|
160
146
|
- test/get_report_xml_html_test.rb
|
147
|
+
- test/policy_guide_test.rb
|
161
148
|
- test/post_report_api_test.rb
|
162
149
|
- test/scap_content_parser_api_test.rb
|
163
|
-
- test/script_class_test.rb
|
164
150
|
- test/spool_forwarder_test.rb
|
165
151
|
- test/test_helper.rb
|
166
152
|
homepage: https://github.com/theforeman/smart_proxy_openscap
|
@@ -175,15 +161,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
175
161
|
requirements:
|
176
162
|
- - ">="
|
177
163
|
- !ruby/object:Gem::Version
|
178
|
-
version: '
|
164
|
+
version: '2.7'
|
165
|
+
- - "<"
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '4'
|
179
168
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
180
169
|
requirements:
|
181
170
|
- - ">="
|
182
171
|
- !ruby/object:Gem::Version
|
183
172
|
version: '0'
|
184
173
|
requirements:
|
185
|
-
-
|
186
|
-
rubygems_version: 3.
|
174
|
+
- oscap
|
175
|
+
rubygems_version: 3.2.33
|
187
176
|
signing_key:
|
188
177
|
specification_version: 4
|
189
178
|
summary: OpenSCAP plug-in for Foreman's smart-proxy.
|
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
|