smart_proxy_openscap 0.4.0 → 0.4.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/lib/smart_proxy_openscap/openscap_api.rb +11 -0
- data/lib/smart_proxy_openscap/openscap_exception.rb +20 -0
- data/lib/smart_proxy_openscap/openscap_lib.rb +56 -2
- data/lib/smart_proxy_openscap/openscap_plugin.rb +2 -1
- data/lib/smart_proxy_openscap/openscap_version.rb +1 -1
- data/settings.d/openscap.yml.example +4 -0
- metadata +6 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: dc0f9e535cc7359af74ea374ced6f071f6af4745
|
|
4
|
+
data.tar.gz: 7d0741cb41875f74908d3383dcfaea081db68366
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 66e1c835c86977103e63102e6764bcd906e659d5ab02df882cef8dca1b58a6ec8de60fd9559e1625ec78aa7124f0abc103cc4e44228034efce0b26b3149d1e87
|
|
7
|
+
data.tar.gz: 30610e832fe4cb4a5c8a9db0203b956b6b090eb67c4f6f86350de8a1cb1b302c25c82a957510aa8ac607a1f13ce02ba21f77346a6acc173b7bb9c5a0ebcd2458
|
|
@@ -43,5 +43,16 @@ module Proxy::OpenSCAP
|
|
|
43
43
|
|
|
44
44
|
{"created" => true}.to_json
|
|
45
45
|
end
|
|
46
|
+
|
|
47
|
+
get "/policies/:policy_id/content" do
|
|
48
|
+
content_type 'application/xml'
|
|
49
|
+
begin
|
|
50
|
+
Proxy::OpenSCAP::get_policy_content(params[:policy_id])
|
|
51
|
+
rescue OpenSCAPException => e
|
|
52
|
+
log_halt e.http_code, "Error fetching xml file: #{e.message}"
|
|
53
|
+
rescue StandardError => e
|
|
54
|
+
log_halt 500, "Error occurred: #{e.message}"
|
|
55
|
+
end
|
|
56
|
+
end
|
|
46
57
|
end
|
|
47
58
|
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Proxy::OpenSCAP
|
|
2
|
+
class OpenSCAPException < Exception
|
|
3
|
+
attr_accessor :response
|
|
4
|
+
attr_accessor :message
|
|
5
|
+
def initialize(response = nil)
|
|
6
|
+
@response = response
|
|
7
|
+
@message = response.message if response
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def http_code
|
|
11
|
+
@response.code || 500
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def http_body
|
|
15
|
+
@response.body if @response
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class FileNotFound < StandardError; end
|
|
20
|
+
end
|
|
@@ -13,10 +13,29 @@ require 'fileutils'
|
|
|
13
13
|
require 'json'
|
|
14
14
|
require 'proxy/error'
|
|
15
15
|
require 'proxy/request'
|
|
16
|
+
require 'smart_proxy_openscap/openscap_exception'
|
|
16
17
|
|
|
17
18
|
module Proxy::OpenSCAP
|
|
18
19
|
extend ::Proxy::Log
|
|
19
20
|
|
|
21
|
+
def self.get_policy_content(policy_id)
|
|
22
|
+
policy_store_dir = File.join(Proxy::OpenSCAP::Plugin.settings.contentdir, policy_id.to_s)
|
|
23
|
+
policy_scap_file = File.join(policy_store_dir, "#{policy_id}_scap_content.xml")
|
|
24
|
+
begin
|
|
25
|
+
FileUtils.mkdir_p(policy_store_dir) # will fail silently if exists
|
|
26
|
+
rescue Errno::EACCES => e
|
|
27
|
+
logger.error "No permission to create directory #{policy_store_dir}"
|
|
28
|
+
raise e
|
|
29
|
+
rescue StandardError => e
|
|
30
|
+
logger.error "Could not create '#{policy_store_dir}' directory: #{e.message}"
|
|
31
|
+
raise e
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
scap_file = policy_content_file(policy_scap_file)
|
|
35
|
+
scap_file ||= save_or_serve_scap_file(policy_id, policy_scap_file)
|
|
36
|
+
scap_file
|
|
37
|
+
end
|
|
38
|
+
|
|
20
39
|
def self.common_name(request)
|
|
21
40
|
client_cert = request.env['SSL_CLIENT_CERT']
|
|
22
41
|
raise Proxy::Error::Unauthorized, "Client certificate required!" if client_cert.to_s.empty?
|
|
@@ -65,6 +84,42 @@ module Proxy::OpenSCAP
|
|
|
65
84
|
end
|
|
66
85
|
end
|
|
67
86
|
|
|
87
|
+
def self.fetch_scap_content_xml(policy_id, policy_scap_file)
|
|
88
|
+
foreman_request = Proxy::HttpRequest::ForemanRequest.new
|
|
89
|
+
policy_content_path = "/api/v2/compliance/policies/#{policy_id}/content"
|
|
90
|
+
req = foreman_request.request_factory.create_get(policy_content_path)
|
|
91
|
+
response = foreman_request.send_request(req)
|
|
92
|
+
unless response.is_a? Net::HTTPSuccess
|
|
93
|
+
raise OpenSCAPException.new(response)
|
|
94
|
+
end
|
|
95
|
+
response.body
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def self.policy_content_file(policy_scap_file)
|
|
100
|
+
return nil if !File.file?(policy_scap_file) || File.zero?(policy_scap_file)
|
|
101
|
+
File.open(policy_scap_file, 'rb').read
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def self.save_or_serve_scap_file(policy_id, policy_scap_file)
|
|
105
|
+
lock = Proxy::FileLock::try_locking(policy_scap_file)
|
|
106
|
+
response = fetch_scap_content_xml(policy_id, policy_scap_file)
|
|
107
|
+
if lock.nil?
|
|
108
|
+
return response
|
|
109
|
+
else
|
|
110
|
+
begin
|
|
111
|
+
File.open(policy_scap_file, 'wb') do |file|
|
|
112
|
+
file << response
|
|
113
|
+
end
|
|
114
|
+
ensure
|
|
115
|
+
Proxy::FileLock::unlock(lock)
|
|
116
|
+
end
|
|
117
|
+
scap_file = policy_content_file(policy_scap_file)
|
|
118
|
+
raise FileNotFound if scap_file.nil?
|
|
119
|
+
return scap_file
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
68
123
|
class ForemanForwarder < Proxy::HttpRequest::ForemanRequest
|
|
69
124
|
def do(arf_dir)
|
|
70
125
|
Dir.foreach(arf_dir) { |cname|
|
|
@@ -116,11 +171,10 @@ module Proxy::OpenSCAP
|
|
|
116
171
|
begin
|
|
117
172
|
data = File.read(arf_file_path)
|
|
118
173
|
response = send_request(foreman_api_path, data)
|
|
174
|
+
# Raise an HTTP error if the response is not 2xx (success).
|
|
119
175
|
response.value
|
|
120
|
-
raise StandardError, "Received #{response.code}: #{response.message}" unless response.code.to_i == 200
|
|
121
176
|
res = JSON.parse(response.body)
|
|
122
177
|
raise StandardError, "Received result: #{res['result']}" unless res['result'] == 'OK'
|
|
123
|
-
raise StandardError, "Sent bytes: #{data.length}, but foreman received: #{res['received']}" unless data.length == res['received']
|
|
124
178
|
File.delete arf_file_path
|
|
125
179
|
rescue StandardError => e
|
|
126
180
|
logger.debug response.body if response
|
|
@@ -18,6 +18,7 @@ module Proxy::OpenSCAP
|
|
|
18
18
|
https_rackup_path File.expand_path("http_config.ru", File.expand_path("../", __FILE__))
|
|
19
19
|
|
|
20
20
|
default_settings :spooldir => '/var/spool/foreman-proxy/openscap',
|
|
21
|
-
:openscap_send_log_file => '/
|
|
21
|
+
:openscap_send_log_file => 'logs/openscap-send.log',
|
|
22
|
+
:contentdir => 'openscap/content'
|
|
22
23
|
end
|
|
23
24
|
end
|
|
@@ -7,3 +7,7 @@
|
|
|
7
7
|
# Directory where OpenSCAP audits are stored
|
|
8
8
|
# before they are forwarded to Foreman
|
|
9
9
|
#:spooldir: /var/spool/foreman-proxy/openscap
|
|
10
|
+
|
|
11
|
+
# Directory where OpenSCAP content XML are stored
|
|
12
|
+
# So we will not request the XML from Foreman each time
|
|
13
|
+
#:contentdir: /var/lib/openscap/content
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: smart_proxy_openscap
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
|
-
-
|
|
7
|
+
- Šimon Lukašík
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2015-
|
|
11
|
+
date: 2015-05-19 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: |-
|
|
14
14
|
A plug-in to the Foreman's smart-proxy which receives
|
|
@@ -28,6 +28,7 @@ files:
|
|
|
28
28
|
- lib/smart_proxy_openscap.rb
|
|
29
29
|
- lib/smart_proxy_openscap/http_config.ru
|
|
30
30
|
- lib/smart_proxy_openscap/openscap_api.rb
|
|
31
|
+
- lib/smart_proxy_openscap/openscap_exception.rb
|
|
31
32
|
- lib/smart_proxy_openscap/openscap_lib.rb
|
|
32
33
|
- lib/smart_proxy_openscap/openscap_plugin.rb
|
|
33
34
|
- lib/smart_proxy_openscap/openscap_version.rb
|
|
@@ -43,12 +44,12 @@ require_paths:
|
|
|
43
44
|
- lib
|
|
44
45
|
required_ruby_version: !ruby/object:Gem::Requirement
|
|
45
46
|
requirements:
|
|
46
|
-
- -
|
|
47
|
+
- - '>='
|
|
47
48
|
- !ruby/object:Gem::Version
|
|
48
49
|
version: '0'
|
|
49
50
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
50
51
|
requirements:
|
|
51
|
-
- -
|
|
52
|
+
- - '>='
|
|
52
53
|
- !ruby/object:Gem::Version
|
|
53
54
|
version: '0'
|
|
54
55
|
requirements: []
|