Skip to content

Commit

Permalink
Fixes #31049 - Introduce server CA file setting
Browse files Browse the repository at this point in the history
  • Loading branch information
kamils-iRonin committed Dec 15, 2020
1 parent fb285ce commit e49bad1
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 24 deletions.
2 changes: 1 addition & 1 deletion app/models/setting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class Setting < ApplicationRecord
FROZEN_ATTRS = %w{name category}
NONZERO_ATTRS = %w{puppet_interval idle_timeout entries_per_page outofsync_interval}
BLANK_ATTRS = %w{ host_owner trusted_hosts login_delegation_logout_url root_pass default_location default_organization websockets_ssl_key websockets_ssl_cert oauth_consumer_key oauth_consumer_secret login_text oidc_audience oidc_issuer oidc_algorithm
smtp_address smtp_domain smtp_user_name smtp_password smtp_openssl_verify_mode smtp_authentication sendmail_arguments sendmail_location http_proxy http_proxy_except_list default_locale default_timezone ssl_certificate ssl_ca_file ssl_priv_key default_pxe_item_global default_pxe_item_local oidc_jwks_url instance_title }
smtp_address smtp_domain smtp_user_name smtp_password smtp_openssl_verify_mode smtp_authentication sendmail_arguments sendmail_location http_proxy http_proxy_except_list default_locale default_timezone ssl_certificate ssl_ca_file server_ca_file ssl_priv_key default_pxe_item_global default_pxe_item_local oidc_jwks_url instance_title }
ARRAY_HOSTNAMES = %w{trusted_hosts}
URI_ATTRS = %w{foreman_url unattended_url}
URI_BLANK_ATTRS = %w{login_delegation_logout_url}
Expand Down
1 change: 1 addition & 0 deletions app/models/setting/auth.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def self.default_settings
set('ssl_client_dn_env', N_('Environment variable containing the subject DN from a client SSL certificate'), 'SSL_CLIENT_S_DN', N_('SSL client DN env')),
set('ssl_client_verify_env', N_('Environment variable containing the verification status of a client SSL certificate'), 'SSL_CLIENT_VERIFY', N_('SSL client verify env')),
set('ssl_client_cert_env', N_("Environment variable containing a client's SSL certificate"), 'SSL_CLIENT_CERT', N_('SSL client cert env')),
set('server_ca_file', N_("SSL CA file that will be used in templates (to verify the connection to Foreman)"), nil, N_('Server CA file')),
set('websockets_ssl_key', N_("Private key file that Foreman will use to encrypt websockets "), nil, N_('Websockets SSL key')),
set('websockets_ssl_cert', N_("Certificate that Foreman will use to encrypt websockets "), nil, N_('Websockets SSL certificate')),
# websockets_encrypt depends on key/cert when true, so initialize it last
Expand Down
29 changes: 20 additions & 9 deletions lib/foreman/renderer/scope/macros/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -334,20 +334,31 @@ def gem_version_compare(first, second)
Gem::Version.new(first.to_s) <=> Gem::Version.new(second.to_s)
end

apipie :method, "Returns content of 'SSL CA file' configured in Settings > Authentication" do
apipie :method, "Returns a combination of 'Server CA file' and 'SSL CA file' configured in Settings > Authentication" do
example "SSL_CA_CERT=$(mktemp)
cat > $SSL_CA_CERT <<CA_CONTENT
<%= foreman_server_ca_cert %>
CA_CONTENT
curl --cacert $SSL_CA_CERT https://smart-proxy.example.com:8443"
end
def foreman_server_ca_cert
if File.exist?(Setting[:ssl_ca_file])
File.read(Setting[:ssl_ca_file])
else
msg = N_("SSL CA file not found, check the 'SSL CA file' in Settings > Authentication")
raise Foreman::Exception.new(msg)
curl --cacert $SSL_CA_CERT https://foreman.example.com:8443"
end
def foreman_server_ca_cert(server_ca_file_enabled: true, ssl_ca_file_enabled: true)
setting_values = []
setting_values << Setting[:server_ca_file] if server_ca_file_enabled
setting_values << Setting[:ssl_ca_file] if ssl_ca_file_enabled
files_content = setting_values.compact.map do |setting_value|
File.read(setting_value)
rescue StandardError => e
Foreman::Logging.logger('templates').warn("Failed to read CA file: #{e}")

nil
end

result = files_content.compact.join("\n")

msg = N_("SSL CA file not found, check the 'Server CA file' and 'SSL CA file' in Settings > Authentication")
raise Foreman::Exception.new(msg) unless result.present?

result
end

private
Expand Down
11 changes: 8 additions & 3 deletions test/fixtures/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,17 @@ attributes4:
description: Enable safe mode config templates rendinging(recommended)
attributes5:
name: ssl_certificate
category: Setting::Provisioning
category: Setting::Auth
default: /var/lib/puppet/ssl/certs/some.host.fqdn
description: SSL Certificate path that foreman would use to communicate with its proxies
attributes6:
name: ssl_ca_file
category: Setting::Provisioning
category: Setting::Auth
default: /var/lib/puppet/ssl/certs/ca.pem
description: SSL CA file that foreman would use to communicate with its proxies
attributes7:
name: ssl_priv_key
category: Setting::Provisioning
category: Setting::Auth
default: /var/lib/puppet/ssl/private_keys/super.some.host.fqdn.pem
description: SSL Private Key file that foreman would use to communicate with its proxies
attributes8:
Expand Down Expand Up @@ -428,3 +428,8 @@ attribute94:
category: Setting::Provisioning
default: 'Global Registration'
description: "Default Global registration template"
attributes95:
name: server_ca_file
category: Setting::Auth
default: /var/lib/puppet/ssl/certs/ca.pem
description: SSL CA file that will be used in templates (to verify the connection to Foreman)
72 changes: 61 additions & 11 deletions test/unit/foreman/renderer/renderers_shared_tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,18 +205,68 @@ module RenderersSharedTests
assert_equal(renderer.render(source, @scope), '-1')
end

test "foreman_server_ca_cert - existing file" do
cert_path = Rails.root.join('test/static_fixtures/certificates/example.com.crt')
Setting[:ssl_ca_file] = cert_path
source = OpenStruct.new(content: '<%= foreman_server_ca_cert %>')
assert_equal(renderer.render(source, @scope), File.read(cert_path))
end
describe '#foreman_server_ca_cert' do
subject { renderer.render(source, @scope) }

test "foreman_server_ca_cert - not existing file" do
Setting[:ssl_ca_file] = 'not-existing-file'
source = OpenStruct.new(content: '<%= foreman_server_ca_cert %>')
assert_raise Foreman::Exception do
renderer.render(source, @scope)
let(:source) { OpenStruct.new(content: '<%= foreman_server_ca_cert %>') }
let(:cert_path) { Rails.root.join('test/static_fixtures/certificates/example.com.crt') }
let(:cert_file_content) { File.read(cert_path) }

test "load server_ca_file" do
Setting[:server_ca_file] = cert_path
Setting[:ssl_ca_file] = 'not-existing-file'

assert_equal subject, cert_file_content
end

test "load ssl_ca_file" do
Setting[:server_ca_file] = 'not-existing-file'
Setting[:ssl_ca_file] = cert_path

assert_equal subject, cert_file_content
end

test "load server_ca_file and ssl_ca_file" do
Setting[:server_ca_file] = cert_path
Setting[:ssl_ca_file] = cert_path

expeced = "#{cert_file_content}\n#{cert_file_content}"
assert_equal subject, expeced
end

test "do not load any files and raise exception" do
Setting[:server_ca_file] = 'not-existing-file'
Setting[:ssl_ca_file] = 'not-existing-file'

assert_raise Foreman::Exception do
subject
end
end

context 'when server_ca_file is disabled' do
let(:source) { OpenStruct.new(content: '<%= foreman_server_ca_cert(server_ca_file_enabled: false) %>') }

test "do not load server_ca_file and raise exception" do
Setting[:server_ca_file] = cert_path
Setting[:ssl_ca_file] = 'not-existing-file'

assert_raise Foreman::Exception do
subject
end
end
end

context 'when ssl_ca_file is disabled' do
let(:source) { OpenStruct.new(content: '<%= foreman_server_ca_cert(ssl_ca_file_enabled: false) %>') }

test "do not load ssl_ca_file and raise exception" do
Setting[:server_ca_file] = 'not-existing-file'
Setting[:ssl_ca_file] = cert_path

assert_raise Foreman::Exception do
subject
end
end
end
end

Expand Down

0 comments on commit e49bad1

Please sign in to comment.