smart_proxy_openscap 0.10.0 → 0.11.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 02ab6e238370db54d999386c79f2735991d9e1c4b23b3a0e9fc86471e82d238a
4
- data.tar.gz: e75f6b653f970415b622304c9526543d81514488be71e3bf62b077bfe41df427
3
+ metadata.gz: d5b5f74d9ef8cf5528ed8352c5fcf086f066e0b4c287d7af2d793af4aa8ca8f3
4
+ data.tar.gz: 853c160e1bd5bc964cd1254462be6294c745f82903fbfe4527accc8c7b59358f
5
5
  SHA512:
6
- metadata.gz: 42d35a3f634b32d1936e6cee7cfc94d764bf43a856004fe6907f6a3b1097dd4d2175f59f295a89ff06240fb1948bf29fffb1659a0a1633f593c9cb67f0f8ed91
7
- data.tar.gz: 80171b3bcbf413ba40a76875febf710e64faca2b84febf048056cb3b1777ccd7d228aced737a87e51906bffaf163fd60728b1c968117d9edf663442cef18c76a
6
+ metadata.gz: 76183d6d4a6cca39f0214b9de18b642bb939ae018a4374cd642bd94751c57368a40ba8287e515bf2cf49e3700a37f4071f57b2e5132b6e5cdbbf2307ad26a6c6
7
+ data.tar.gz: c83274635c726fe521dcd43441b1abf3d87fbf6322d6fcc2c0cc07a380add1683af520edcc11ac3e254353d2bebaebcc59b8918c81fe70a4634ac8f52ba33df1
@@ -24,8 +24,6 @@ module Proxy::OpenSCAP
24
24
  "api/v2/compliance/policies/:policy_id/content"
25
25
  when :tailoring_file
26
26
  "api/v2/compliance/policies/:policy_id/tailoring"
27
- when :oval_content
28
- "api/v2/compliance/oval_policies/:policy_id/oval_content"
29
27
  end
30
28
  end
31
29
 
@@ -33,13 +31,11 @@ module Proxy::OpenSCAP
33
31
  case @type
34
32
  when :scap_content, :tailoring_file
35
33
  "#{policy_id}_#{digest}.xml"
36
- when :oval_content
37
- "#{digest}.oval.xml.bz2"
38
34
  end
39
35
  end
40
36
 
41
37
  def allowed_types
42
- [:scap_content, :tailoring_file, :oval_content]
38
+ [:scap_content, :tailoring_file]
43
39
  end
44
40
  end
45
41
  end
@@ -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,8 +25,9 @@ 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
- CLIENT_PATHS = Regexp.compile(%r{^(/arf/\d+|/policies/\d+/content/|/policies/\d+/tailoring/|/oval_reports|/oval_policies)})
30
+ CLIENT_PATHS = Regexp.compile(%r{^(/arf/\d+|/policies/\d+/content/|/policies/\d+/tailoring/)})
29
31
 
30
32
  # authorize via trusted hosts but let client paths in without such authorization
31
33
  before do
@@ -33,7 +35,7 @@ module Proxy::OpenSCAP
33
35
  do_authorize_with_trusted_hosts
34
36
  end
35
37
 
36
- before '(/arf/*|/oval_reports/*)' do
38
+ before '/arf/*' do
37
39
  begin
38
40
  @cn = Proxy::OpenSCAP::common_name request
39
41
  rescue Proxy::Error::Unauthorized => e
@@ -44,50 +46,39 @@ module Proxy::OpenSCAP
44
46
 
45
47
  post "/arf/:policy" do
46
48
  policy = params[:policy]
47
-
48
- begin
49
- post_to_foreman = ForemanArfForwarder.new.post_report(@cn, policy, @reported_at, request.body.string, Proxy::OpenSCAP::Plugin.settings.timeout)
50
- Proxy::OpenSCAP::StorageFs.new(Proxy::OpenSCAP::Plugin.settings.reportsdir, @cn, post_to_foreman['id'], @reported_at).store_archive(request.body.string)
51
- post_to_foreman.to_json
52
- rescue Proxy::OpenSCAP::StoreReportError => e
53
- Proxy::OpenSCAP::StorageFs.new(Proxy::OpenSCAP::Plugin.settings.failed_dir, @cn, post_to_foreman['id'], @reported_at).store_failed(request.body.string)
54
- logger.error "Failed to save Report in reports directory (#{Proxy::OpenSCAP::Plugin.settings.reportsdir}). Failed with: #{e.message}.
55
- Saving file in #{Proxy::OpenSCAP::Plugin.settings.failed_dir}. Please copy manually to #{Proxy::OpenSCAP::Plugin.settings.reportsdir}"
56
- { :result => 'Storage failure on proxy, see proxy logs for details' }.to_json
57
- rescue Nokogiri::XML::SyntaxError => e
58
- error = "Failed to parse Arf Report, moving to #{Proxy::OpenSCAP::Plugin.settings.corrupted_dir}"
59
- logger.error error
60
- Proxy::OpenSCAP::StorageFs.new(Proxy::OpenSCAP::Plugin.settings.corrupted_dir, @cn, policy, @reported_at).store_corrupted(request.body.string)
61
- { :result => (error << ' on proxy') }.to_json
62
- rescue *HTTP_ERRORS => e
63
- ### If the upload to foreman fails then store it in the spooldir
64
- msg = "Failed to upload to Foreman, saving in spool. Failed with: #{e.message}"
65
- logger.error msg
66
- Proxy::OpenSCAP::StorageFs.new(Proxy::OpenSCAP::Plugin.settings.spooldir, @cn, policy, @reported_at).store_spool(request.body.string)
67
- { :result => msg }.to_json
68
- rescue Proxy::OpenSCAP::StoreSpoolError => e
69
- log_halt 500, e.message
70
- rescue Proxy::OpenSCAP::ReportUploadError, Proxy::OpenSCAP::ReportDecompressError => e
71
- { :result => e.message }.to_json
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
- post "/oval_reports/:oval_policy_id" do
76
- ForemanOvalForwarder.new.post_report(@cn, params[:oval_policy_id], @reported_at, request.body.string, Plugin.settings.timeout)
77
-
78
- { :reported_at => Time.at(@reported_at) }.to_json
79
- rescue *HTTP_ERRORS => e
80
- msg = "Failed to upload to Foreman, failed with: #{e.message}"
81
- logger.error e
82
- { :result => msg }.to_json
83
- rescue Nokogiri::XML::SyntaxError => e
84
- logger.error e
85
- { :result => 'Failed to parse OVAL report, see proxy logs for details' }.to_json
86
- rescue Proxy::OpenSCAP::ReportUploadError, Proxy::OpenSCAP::ReportDecompressError => e
87
- { :result => e.message }.to_json
88
- end
89
-
90
-
91
82
  get "/arf/:id/:cname/:date/:digest/xml" do
92
83
  content_type 'application/x-bzip2'
93
84
  begin
@@ -139,18 +130,6 @@ module Proxy::OpenSCAP
139
130
  end
140
131
  end
141
132
 
142
- get "/oval_policies/:oval_policy_id/oval_content/:digest" do
143
- content_type 'application/x-bzip2'
144
- begin
145
- Proxy::OpenSCAP::FetchScapFile.new(:oval_content)
146
- .fetch(params[:oval_policy_id], params[:digest], Proxy::OpenSCAP::Plugin.settings.oval_content_dir)
147
- rescue *HTTP => e
148
- log_halt e.response.code.to_i, file_not_found_msg
149
- rescue StandardError => e
150
- log_halt 500, "Error occurred: #{e.message}"
151
- end
152
- end
153
-
154
133
  post "/scap_content/policies" do
155
134
  begin
156
135
  Proxy::OpenSCAP::ProfilesParser.new.profiles('scap_content', request.body.string)
@@ -17,7 +17,6 @@ require 'yaml'
17
17
  require 'ostruct'
18
18
  require 'proxy/request'
19
19
  require 'smart_proxy_openscap/foreman_arf_forwarder'
20
- require 'smart_proxy_openscap/foreman_oval_forwarder'
21
20
  require 'smart_proxy_openscap/content_parser'
22
21
  require 'smart_proxy_openscap/openscap_exception'
23
22
  require 'smart_proxy_openscap/arf_parser'
@@ -25,8 +24,6 @@ require 'smart_proxy_openscap/spool_forwarder'
25
24
  require 'smart_proxy_openscap/openscap_html_generator'
26
25
  require 'smart_proxy_openscap/policy_parser'
27
26
  require 'smart_proxy_openscap/profiles_parser'
28
- require 'smart_proxy_openscap/oval_report_storage_fs'
29
- require 'smart_proxy_openscap/oval_report_parser'
30
27
  require 'smart_proxy_openscap/fetch_scap_file'
31
28
 
32
29
  module Proxy::OpenSCAP
@@ -22,7 +22,6 @@ module Proxy::OpenSCAP
22
22
  :contentdir => File.join(APP_ROOT, 'openscap/content'),
23
23
  :reportsdir => File.join(APP_ROOT, 'openscap/reports'),
24
24
  :failed_dir => File.join(APP_ROOT, 'openscap/failed'),
25
- :tailoring_dir => File.join(APP_ROOT, 'openscap/tailoring'),
26
- :oval_content_dir => File.join(APP_ROOT, 'openscap/oval_content')
25
+ :tailoring_dir => File.join(APP_ROOT, 'openscap/tailoring')
27
26
  end
28
27
  end
@@ -10,6 +10,6 @@
10
10
 
11
11
  module Proxy
12
12
  module OpenSCAP
13
- VERSION = '0.10.0'
13
+ VERSION = '0.11.1'
14
14
  end
15
15
  end
@@ -31,6 +31,3 @@
31
31
  # Affects sending reports to Foreman (directly and from spool) and fetching scap content or tailoring file
32
32
  # for distribution to clients
33
33
  #:timeout: 60
34
-
35
- # Directory where OpenSCAP OVAL content bzipped XML are stored
36
- #:oval_content_dir: /var/lib/openscap/oval_content
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.10.0
4
+ version: 0.11.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Šimon Lukašík
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-05-15 00:00:00.000000000 Z
13
+ date: 2024-07-24 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -125,7 +125,7 @@ files:
125
125
  - lib/smart_proxy_openscap/fetch_scap_file.rb
126
126
  - lib/smart_proxy_openscap/foreman_arf_forwarder.rb
127
127
  - lib/smart_proxy_openscap/foreman_forwarder.rb
128
- - lib/smart_proxy_openscap/foreman_oval_forwarder.rb
128
+ - lib/smart_proxy_openscap/helpers.rb
129
129
  - lib/smart_proxy_openscap/http_config.ru
130
130
  - lib/smart_proxy_openscap/openscap_api.rb
131
131
  - lib/smart_proxy_openscap/openscap_exception.rb
@@ -133,8 +133,6 @@ files:
133
133
  - lib/smart_proxy_openscap/openscap_import_api.rb
134
134
  - lib/smart_proxy_openscap/openscap_lib.rb
135
135
  - lib/smart_proxy_openscap/openscap_plugin.rb
136
- - lib/smart_proxy_openscap/oval_report_parser.rb
137
- - lib/smart_proxy_openscap/oval_report_storage_fs.rb
138
136
  - lib/smart_proxy_openscap/policy_guide.rb
139
137
  - lib/smart_proxy_openscap/policy_parser.rb
140
138
  - lib/smart_proxy_openscap/profiles_parser.rb
@@ -158,12 +156,9 @@ files:
158
156
  - test/data/spool/valid_spool/arf/e20b9695-f655-401a-9dda-8cca7a47a8c0/1/1484313035/fa2f68ffb944c917332a284dc63ec7f8fa76990cb815ddcad3318b5d9457f8a1
159
157
  - test/data/ssg-rhel7-ds.xml
160
158
  - test/data/tailoring.xml
161
- - test/fetch_oval_content_api_test.rb
162
159
  - test/fetch_scap_api_test.rb
163
160
  - test/fetch_tailoring_api_test.rb
164
161
  - test/get_report_xml_html_test.rb
165
- - test/oval_report_parser_test.rb
166
- - test/post_oval_report_api_test.rb
167
162
  - test/post_report_api_test.rb
168
163
  - test/scap_content_parser_api_test.rb
169
164
  - test/script_class_test.rb
@@ -189,7 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
189
184
  version: '0'
190
185
  requirements:
191
186
  - bzip2
192
- rubygems_version: 3.5.9
187
+ rubygems_version: 3.3.26
193
188
  signing_key:
194
189
  specification_version: 4
195
190
  summary: OpenSCAP plug-in for Foreman's smart-proxy.
@@ -1,19 +0,0 @@
1
- require 'smart_proxy_openscap/foreman_forwarder'
2
-
3
- module Proxy::OpenSCAP
4
- class ForemanOvalForwarder < ForemanForwarder
5
- private
6
-
7
- def parse_report(cname, policy_id, date, report_data)
8
- {
9
- :oval_results => OvalReportParser.new.parse_cves(report_data),
10
- :oval_policy_id => policy_id,
11
- :cname => cname
12
- }.to_json
13
- end
14
-
15
- def report_upload_path(cname, policy_id, date)
16
- upload_path "oval_reports", cname, policy_id, date
17
- end
18
- end
19
- end
@@ -1,54 +0,0 @@
1
- require 'smart_proxy_openscap/openscap_exception'
2
- require 'openscap_parser/oval_report'
3
-
4
- module Proxy::OpenSCAP
5
- class OvalReportParser
6
- include Proxy::Log
7
-
8
- def parse_cves(report_data)
9
- report = oval_report report_data
10
- results = report.definition_results.reduce({}) do |memo, result|
11
- memo.tap { |acc| acc[result.definition_id] = parse_cve_res result }
12
- end
13
-
14
- report.definitions.map do |definition|
15
- results[definition.id].merge(parse_cve_def definition)
16
- end
17
- end
18
-
19
- private
20
-
21
- def parse_cve_def(definition)
22
- refs = definition.references.reduce([]) do |memo, ref|
23
- memo.tap { |acc| acc << { :ref_id => ref.ref_id, :ref_url => ref.ref_url } }
24
- end
25
-
26
- { :references => refs, :definition_id => definition.id }
27
- end
28
-
29
- def parse_cve_res(result)
30
- { :result => result.result }
31
- end
32
-
33
- def oval_report(report_data)
34
- decompressed = decompress report_data
35
- ::OpenscapParser::OvalReport.new(decompressed)
36
- end
37
-
38
- def decompress(report_data)
39
- begin
40
- file = Tempfile.new
41
- file.write report_data
42
- file.rewind
43
- decompressed = `bunzip2 -dc #{file.path}`
44
- rescue => e
45
- logger.error e
46
- raise Proxy::OpenSCAP::ReportDecompressError, "Failed to decompress received report bzip, cause: #{e.message}"
47
- ensure
48
- file.close
49
- file.unlink
50
- end
51
- decompressed
52
- end
53
- end
54
- end
@@ -1,26 +0,0 @@
1
- require 'smart_proxy_openscap/storage_fs_common'
2
- require 'smart_proxy_openscap/openscap_exception'
3
-
4
- module Proxy::OpenSCAP
5
- class OvalReportStorageFs
6
- include StorageFsCommon
7
-
8
- def initialize(path_to_dir, oval_policy_id, cname, reported_at)
9
- @namespace = 'oval'
10
- @reported_at = reported_at
11
- @path = "#{path_to_dir}/#{@namespace}/#{oval_policy_id}/#{cname}/"
12
- end
13
-
14
- def store_report(report_data)
15
- store(report_data, StoreReportError)
16
- end
17
-
18
- private
19
-
20
- def store_file(path_to_store, report_data)
21
- target_path = "#{path_to_store}#{@reported_at}"
22
- File.open(target_path, 'w') { |f| f.write(report_data) }
23
- target_path
24
- end
25
- end
26
- end
@@ -1,38 +0,0 @@
1
- require 'test_helper'
2
- require 'smart_proxy_openscap'
3
- require 'smart_proxy_openscap/openscap_api'
4
-
5
- ENV['RACK_ENV'] = 'test'
6
-
7
- class FetchOvalContentApiTest < Test::Unit::TestCase
8
- include Rack::Test::Methods
9
-
10
- def setup
11
- @foreman_url = 'https://foreman.example.com'
12
- @fixture_path = "/test/data/rhel-7-including-unpatched.oval.xml.bz2"
13
- @fixture_full_path = File.join(Dir.getwd, @fixture_path)
14
- Proxy::SETTINGS.stubs(:foreman_url).returns(@foreman_url)
15
- @results_path = ("#{Dir.getwd}/test/test_run_files")
16
- FileUtils.mkdir_p(@results_path)
17
- Proxy::OpenSCAP::Plugin.settings.stubs(:oval_content_dir).returns(@results_path)
18
- @oval_content = File.new(@fixture_full_path).read
19
- @digest = Digest::SHA256.hexdigest @oval_content
20
- @policy_id = 1
21
- end
22
-
23
- def teardown
24
- FileUtils.rm_rf(Dir.glob("#{@results_path}/*"))
25
- end
26
-
27
- def app
28
- ::Proxy::OpenSCAP::Api.new
29
- end
30
-
31
- def test_get_oval_content_from_file
32
- FileUtils.mkdir("#{@results_path}/#{@policy_id}")
33
- FileUtils.cp(@fixture_full_path, "#{@results_path}/#{@policy_id}/#{@digest}.oval.xml.bz2")
34
- get "/oval_policies/#{@policy_id}/oval_content/#{@digest}"
35
- assert_equal("application/x-bzip2", last_response.header["Content-Type"], "Response header should be application/x-bzip2")
36
- assert(last_response.successful?, "Response should be success")
37
- end
38
- end
@@ -1,14 +0,0 @@
1
- require 'test_helper'
2
- require 'smart_proxy_openscap'
3
- require 'smart_proxy_openscap/oval_report_parser'
4
-
5
- class OvalReportParserTest < Test::Unit::TestCase
6
-
7
- def test_oval_report_parsing
8
- oval_report = File.open("#{Dir.getwd}/test/data/oval-results.xml.bz2").read
9
- res = Proxy::OpenSCAP::OvalReportParser.new.parse_cves oval_report
10
- refute res.empty?
11
- assert res.first[:result]
12
- refute res.first[:references].empty?
13
- end
14
- end
@@ -1,30 +0,0 @@
1
- require 'test_helper'
2
- require 'smart_proxy_openscap'
3
- require 'smart_proxy_openscap/openscap_api'
4
-
5
- ENV['RACK_ENV'] = 'test'
6
-
7
- class PostOvalReportApiTest < Test::Unit::TestCase
8
- include Rack::Test::Methods
9
-
10
- setup do
11
- @foreman_url = 'https://foreman.example.com'
12
- Proxy::SETTINGS.stubs(:foreman_url).returns(@foreman_url)
13
- @oval_report = File.open("#{Dir.getwd}/test/data/oval-results.xml.bz2").read
14
- @cname = 'node.example.org'
15
- @date = Time.now.to_i
16
- @policy_id = 1
17
- Proxy::OpenSCAP.stubs(:common_name).returns(@cname)
18
- end
19
-
20
- def app
21
- ::Proxy::OpenSCAP::Api.new
22
- end
23
-
24
- def test_post_oval_report_to_foreman
25
- stub_request(:post, "#{@foreman_url}/api/v2/compliance/oval_reports/#{@cname}/#{@policy_id}/#{@date}")
26
- .to_return(:status => 200, :body => '{ "result": "ok" }')
27
- post "/oval_reports/#{@policy_id}", @oval_report, 'CONTENT_TYPE' => 'text/xml', 'CONTENT_ENCODING' => 'x-bzip2'
28
- assert(last_response.successful?, "Should be a success")
29
- end
30
- end