Revision 358ec5a3
Added by Dominic Cleal over 11 years ago
- ID 358ec5a3a1b59c098b5c14fcd7a90ca1a6a5dccd
app/controllers/fact_values_controller.rb | ||
---|---|---|
require 'foreman/controller/smart_proxy_auth'
|
||
|
||
class FactValuesController < ApplicationController
|
||
include Foreman::Controller::AutoCompleteSearch
|
||
include Foreman::Controller::SmartProxyAuth
|
||
|
||
skip_before_filter :require_ssl, :only => :create
|
||
skip_before_filter :require_login, :only => :create
|
||
skip_before_filter :authorize, :only => :create
|
||
skip_before_filter :verify_authenticity_token, :only => :create
|
||
skip_before_filter :set_taxonomy, :only => :create
|
||
skip_before_filter :session_expiry, :update_activity_time, :only => :create
|
||
before_filter :set_admin_user, :only => :create
|
||
add_puppetmaster_filters :create
|
||
before_filter :setup_search_options, :only => :index
|
||
|
||
def index
|
app/controllers/hosts_controller.rb | ||
---|---|---|
require 'foreman/controller/host_details'
|
||
require 'foreman/controller/smart_proxy_auth'
|
||
|
||
class HostsController < ApplicationController
|
||
include Foreman::Controller::HostDetails
|
||
include Foreman::Controller::AutoCompleteSearch
|
||
include Foreman::Controller::SmartProxyAuth
|
||
|
||
# actions which don't require authentication and are always treated as the admin user
|
||
ANONYMOUS_ACTIONS=[ :externalNodes, :lookup ]
|
||
PUPPETMASTER_ACTIONS=[ :externalNodes, :lookup ]
|
||
SEARCHABLE_ACTIONS= %w[index active errors out_of_sync pending disabled ]
|
||
AJAX_REQUESTS=%w{compute_resource_selected hostgroup_or_environment_selected current_parameters}
|
||
skip_before_filter :require_login, :only => ANONYMOUS_ACTIONS
|
||
skip_before_filter :require_ssl, :only => ANONYMOUS_ACTIONS
|
||
skip_before_filter :authorize, :only => ANONYMOUS_ACTIONS
|
||
skip_before_filter :set_taxonomy, :only => ANONYMOUS_ACTIONS
|
||
skip_before_filter :session_expiry, :update_activity_time, :only => ANONYMOUS_ACTIONS
|
||
before_filter :set_admin_user, :only => ANONYMOUS_ACTIONS
|
||
|
||
add_puppetmaster_filters PUPPETMASTER_ACTIONS
|
||
before_filter :ajax_request, :only => AJAX_REQUESTS
|
||
before_filter :find_multiple, :only => [:update_multiple_parameters, :multiple_build,
|
||
:select_multiple_hostgroup, :select_multiple_environment, :multiple_parameters, :multiple_destroy,
|
app/controllers/reports_controller.rb | ||
---|---|---|
require 'foreman/controller/smart_proxy_auth'
|
||
|
||
class ReportsController < ApplicationController
|
||
include Foreman::Controller::AutoCompleteSearch
|
||
include Foreman::Controller::SmartProxyAuth
|
||
|
||
skip_before_filter :require_login, :only => :create
|
||
skip_before_filter :require_ssl, :only => :create
|
||
skip_before_filter :authorize, :only => :create
|
||
skip_before_filter :verify_authenticity_token, :only => :create
|
||
skip_before_filter :set_taxonomy, :only => :create
|
||
skip_before_filter :session_expiry, :update_activity_time, :only => :create
|
||
before_filter :set_admin_user, :only => :create
|
||
add_puppetmaster_filters :create
|
||
before_filter :setup_search_options, :only => :index
|
||
|
||
def index
|
lib/foreman/access_permissions.rb | ||
---|---|---|
end
|
||
|
||
map.security_block :hosts do |map|
|
||
map.permission :view_hosts, {:hosts => [:index, :show, :errors, :active, :out_of_sync, :disabled], :dashboard => [:OutOfSync, :errors, :active]}
|
||
map.permission :view_hosts, {:hosts => [:index, :show, :errors, :active, :out_of_sync, :disabled, :externalNodes], :dashboard => [:OutOfSync, :errors, :active]}
|
||
map.permission :create_hosts, {:hosts => [:new, :create, :clone]}
|
||
map.permission :edit_hosts, {:hosts => [:edit, :update, :multiple_actions, :reset_multiple,
|
||
:select_multiple_hostgroup, :select_multiple_environment, :submit_multiple_disable,
|
lib/foreman/controller/smart_proxy_auth.rb | ||
---|---|---|
require 'resolv'
|
||
require 'uri'
|
||
|
||
module Foreman::Controller::SmartProxyAuth
|
||
module ClassMethods
|
||
def add_puppetmaster_filters(actions)
|
||
skip_before_filter :require_login, :only => actions
|
||
skip_before_filter :require_ssl, :only => actions
|
||
skip_before_filter :authorize, :only => actions
|
||
skip_before_filter :verify_authenticity_token, :only => actions
|
||
skip_before_filter :set_taxonomy, :only => actions
|
||
skip_before_filter :session_expiry, :update_activity_time, :only => actions
|
||
before_filter :require_puppetmaster_or_login, :only => actions
|
||
end
|
||
end
|
||
|
||
def self.included(base)
|
||
base.extend(ClassMethods)
|
||
end
|
||
|
||
# Permits registered puppetmasters or a user with permission
|
||
def require_puppetmaster_or_login
|
||
if !Setting[:restrict_registered_puppetmasters] or auth_smart_proxy(SmartProxy.puppet_proxies, Setting[:require_ssl_puppetmasters])
|
||
set_admin_user
|
||
return true
|
||
end
|
||
|
||
require_login
|
||
unless User.current
|
||
render_403
|
||
return false
|
||
end
|
||
authorize
|
||
end
|
||
|
||
# Filter requests to only permit from hosts with a registered smart proxy
|
||
# Uses rDNS of the request to match proxy hostnames
|
||
def auth_smart_proxy(proxies = SmartProxy.all, require_cert = true)
|
||
request_hosts = nil
|
||
if request.ssl?
|
||
if cn = request.env[Setting[:ssl_client_cn_env]]
|
||
if request.env[Setting[:ssl_client_verify_env]] == 'SUCCESS'
|
||
request_hosts = [cn]
|
||
else
|
||
logger.warn "SSL cert for #{cn} has not been verified - request from #{request.ip}"
|
||
end
|
||
elsif require_cert
|
||
logger.warn "No SSL cert with CN supplied - request from #{request.ip}"
|
||
else
|
||
request_hosts = Resolv.new.getnames(request.ip)
|
||
end
|
||
elsif SETTINGS[:require_ssl]
|
||
logger.warn "SSL is required - request from #{request.ip}"
|
||
else
|
||
request_hosts = Resolv.new.getnames(request.ip)
|
||
end
|
||
return false unless request_hosts
|
||
|
||
logger.debug("Verifying request from #{request_hosts} against #{proxies.map {|p| URI.parse(p.url).host}.inspect}")
|
||
unless proxies.detect { |p| request_hosts.include? URI.parse(p.url).host }
|
||
logger.warn "No smart proxy server found on #{request_hosts.inspect}"
|
||
return false
|
||
end
|
||
true
|
||
end
|
||
end
|
lib/foreman/default_settings/loader.rb | ||
---|---|---|
[ set('oauth_active', "Should foreman use OAuth for authorization in API", false),
|
||
set('oauth_consumer_key', "OAuth consumer key", 'katello'),
|
||
set('oauth_consumer_secret', "OAuth consumer secret", 'shhhh'),
|
||
set('oauth_map_users', "Should foreman map users by username in request-header", true)
|
||
set('oauth_map_users', "Should foreman map users by username in request-header", true),
|
||
set('restrict_registered_puppetmasters', 'Only known Smart Proxies with the Puppet feature can access fact/report importers and ENC output', true),
|
||
set('require_ssl_puppetmasters', 'Client SSL certificates are used to identify Smart Proxies accessing fact/report importers and ENC output over HTTPS (:require_ssl should also be enabled)', true),
|
||
set('ssl_client_cn_env', 'Environment variable containing the subject CN from a client SSL certificate', 'SSL_CLIENT_S_DN_CN'),
|
||
set('ssl_client_verify_env', 'Environment variable containing the verification status of a client SSL certificate', 'SSL_CLIENT_VERIFY')
|
||
].compact.each { |s| create s.update(:category => "Auth")}
|
||
end
|
||
true
|
test/fixtures/settings.yml | ||
---|---|---|
category: Provisioning
|
||
default: 0
|
||
description: "Time in minutes installation tokens should be valid for, 0 to disable"
|
||
attribute27:
|
||
name: restrict_registered_puppetmasters
|
||
category: Auth
|
||
default: true
|
||
description: "Only known Smart Proxies with the Puppet feature can access fact/report importers and ENC output"
|
||
attribute28:
|
||
name: require_ssl_puppetmasters
|
||
category: Auth
|
||
default: true
|
||
description: "Client SSL certificates are used to identify Smart Proxies accessing fact/report importers and ENC output over HTTPS (:require_ssl should also be enabled)"
|
||
attribute29:
|
||
name: ssl_client_cn_env
|
||
category: Auth
|
||
default: "SSL_CLIENT_S_DN_CN"
|
||
description: "Environment variable containing the subject CN from a client SSL certificate"
|
||
attribute30:
|
||
name: ssl_client_verify_env
|
||
category: Auth
|
||
default: "SSL_CLIENT_VERIFY"
|
||
description: "Environment variable containing the verification status of a client SSL certificate"
|
test/functional/fact_values_controller_test.rb | ||
---|---|---|
Pathname.new("#{Rails.root}/test/fixtures/brslc022.facts.yaml").read
|
||
end
|
||
|
||
def setup
|
||
User.current = nil
|
||
end
|
||
|
||
fixtures
|
||
|
||
def test_index
|
||
... | ... | |
|
||
def test_create_invalid
|
||
User.current = nil
|
||
post :create, {:facts => fact_fixture[1..-1], :format => "yml"}
|
||
post :create, {:facts => fact_fixture[1..-1], :format => "yml"}, set_session_user
|
||
assert_response :bad_request
|
||
end
|
||
|
||
def test_create_valid_puppet_node_facts_object
|
||
User.current = nil
|
||
post :create, {:facts => fact_fixture, :format => "yml"}
|
||
post :create, {:facts => fact_fixture, :format => "yml"}, set_session_user
|
||
assert_response :success
|
||
end
|
||
|
||
... | ... | |
User.current = nil
|
||
facts = Facter.to_hash
|
||
assert_instance_of Hash, facts
|
||
post :create, {:facts => facts.to_yaml, :format => "yml"}
|
||
post :create, {:facts => facts.to_yaml, :format => "yml"}, set_session_user
|
||
assert_response :success
|
||
end
|
||
|
||
... | ... | |
assert_response :success
|
||
end
|
||
|
||
test 'when ":restrict_registered_puppetmasters" is false, HTTP requests should be able to import facts' do
|
||
Setting[:restrict_registered_puppetmasters] = false
|
||
SETTINGS[:require_ssl] = false
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['else.where'])
|
||
post :create, {:facts => fact_fixture, :format => "yml"}
|
||
assert_response :success
|
||
end
|
||
|
||
test 'hosts with a registered smart proxy on should import facts successfully' do
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = false
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['else.where'])
|
||
post :create, {:facts => fact_fixture, :format => "yml"}
|
||
assert_response :success
|
||
end
|
||
|
||
test 'hosts without a registered smart proxy on should not be able to import facts' do
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = false
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['another.host'])
|
||
post :create, {:facts => fact_fixture, :format => "yml"}
|
||
assert_equal 403, @response.status
|
||
end
|
||
|
||
test 'hosts with a registered smart proxy and SSL cert should import facts successfully' do
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
|
||
@request.env['HTTPS'] = 'on'
|
||
@request.env['SSL_CLIENT_S_DN_CN'] = 'else.where'
|
||
@request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
|
||
post :create, {:facts => fact_fixture, :format => "yml"}
|
||
assert_response :success
|
||
end
|
||
|
||
test 'hosts without a registered smart proxy but with an SSL cert should not be able to import facts' do
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
|
||
@request.env['HTTPS'] = 'on'
|
||
@request.env['SSL_CLIENT_S_DN_CN'] = 'another.host'
|
||
@request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
|
||
post :create, {:facts => fact_fixture, :format => "yml"}
|
||
assert_equal 403, @response.status
|
||
end
|
||
|
||
test 'hosts with an unverified SSL cert should not be able to import facts' do
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
|
||
@request.env['HTTPS'] = 'on'
|
||
@request.env['SSL_CLIENT_S_DN_CN'] = 'secure.host'
|
||
@request.env['SSL_CLIENT_VERIFY'] = 'FAILED'
|
||
post :create, {:facts => fact_fixture, :format => "yml"}
|
||
assert_equal 403, @response.status
|
||
end
|
||
|
||
test 'when "require_ssl_puppetmasters" and "require_ssl" are true, HTTP requests should not be able to import facts' do
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
SETTINGS[:require_ssl] = true
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['else.where'])
|
||
post :create, {:facts => fact_fixture, :format => "yml"}
|
||
assert_equal 403, @response.status
|
||
end
|
||
|
||
test 'when "require_ssl_puppetmasters" is true and "require_ssl" is false, HTTP requests should be able to import facts' do
|
||
# since require_ssl_puppetmasters is only applicable to HTTPS connections, both should be set
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
SETTINGS[:require_ssl] = false
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['else.where'])
|
||
post :create, {:facts => fact_fixture, :format => "yml"}
|
||
assert_response :success
|
||
end
|
||
end
|
test/functional/hosts_controller_test.rb | ||
---|---|---|
end
|
||
|
||
test "externalNodes should render correctly when format text/html is given" do
|
||
get :externalNodes, {:name => @host.name}
|
||
get :externalNodes, {:name => @host.name}, set_session_user
|
||
assert_response :success
|
||
assert_template :text => @host.info.to_yaml.gsub("\n","<br/>")
|
||
end
|
||
... | ... | |
assert flash[:notice] == "Foreman now no longer manages the build cycle for #{@host.name}"
|
||
end
|
||
|
||
test 'when ":restrict_registered_puppetmasters" is false, HTTP requests should be able to get externalNodes' do
|
||
User.current = nil
|
||
Setting[:restrict_registered_puppetmasters] = false
|
||
SETTINGS[:require_ssl] = false
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['else.where'])
|
||
get :externalNodes, {:name => @host.name, :format => "yml"}
|
||
assert_response :success
|
||
end
|
||
|
||
test 'hosts with a registered smart proxy on should get externalNodes successfully' do
|
||
User.current = nil
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = false
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['else.where'])
|
||
get :externalNodes, {:name => @host.name, :format => "yml"}
|
||
assert_response :success
|
||
end
|
||
|
||
test 'hosts without a registered smart proxy on should not be able to get externalNodes' do
|
||
User.current = nil
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = false
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['another.host'])
|
||
get :externalNodes, {:name => @host.name, :format => "yml"}
|
||
assert_equal 403, @response.status
|
||
end
|
||
|
||
test 'hosts with a registered smart proxy and SSL cert should get externalNodes successfully' do
|
||
User.current = nil
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
|
||
@request.env['HTTPS'] = 'on'
|
||
@request.env['SSL_CLIENT_S_DN_CN'] = 'else.where'
|
||
@request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
|
||
Resolv.any_instance.stubs(:getnames).returns(['else.where'])
|
||
get :externalNodes, {:name => @host.name, :format => "yml"}
|
||
assert_response :success
|
||
end
|
||
|
||
test 'hosts without a registered smart proxy but with an SSL cert should not be able to get externalNodes' do
|
||
User.current = nil
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
|
||
@request.env['HTTPS'] = 'on'
|
||
@request.env['SSL_CLIENT_S_DN_CN'] = 'another.host'
|
||
@request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
|
||
get :externalNodes, {:name => @host.name, :format => "yml"}
|
||
assert_equal 403, @response.status
|
||
end
|
||
|
||
test 'hosts with an unverified SSL cert should not be able to get externalNodes' do
|
||
User.current = nil
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
|
||
@request.env['HTTPS'] = 'on'
|
||
@request.env['SSL_CLIENT_S_DN_CN'] = 'else.where'
|
||
@request.env['SSL_CLIENT_VERIFY'] = 'FAILURE'
|
||
get :externalNodes, {:name => @host.name, :format => "yml"}
|
||
assert_equal 403, @response.status
|
||
end
|
||
|
||
test 'when "require_ssl_puppetmasters" and "require_ssl" are true, HTTP requests should not be able to get externalNodes' do
|
||
User.current = nil
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
SETTINGS[:require_ssl] = true
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['else.where'])
|
||
get :externalNodes, {:name => @host.name, :format => "yml"}
|
||
assert_equal 403, @response.status
|
||
end
|
||
|
||
test 'when "require_ssl_puppetmasters" is true and "require_ssl" is false, HTTP requests should be able to get externalNodes' do
|
||
User.current = nil
|
||
# since require_ssl_puppetmasters is only applicable to HTTPS connections, both should be set
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
SETTINGS[:require_ssl] = false
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['else.where'])
|
||
get :externalNodes, {:name => @host.name, :format => "yml"}
|
||
assert_response :success
|
||
end
|
||
|
||
test 'authenticated users over HTTP should be able to get externalNodes' do
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
SETTINGS[:require_ssl] = false
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['users.host'])
|
||
get :externalNodes, {:name => @host.name, :format => "yml"}, set_session_user
|
||
assert_response :success
|
||
end
|
||
|
||
test 'authenticated users over HTTPS should be able to get externalNodes' do
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
SETTINGS[:require_ssl] = false
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['users.host'])
|
||
@request.env['HTTPS'] = 'on'
|
||
get :externalNodes, {:name => @host.name, :format => "yml"}, set_session_user
|
||
assert_response :success
|
||
end
|
||
|
||
private
|
||
def initialize_host
|
||
User.current = users(:admin)
|
test/functional/reports_controller_test.rb | ||
---|---|---|
|
||
def test_create_duplicate
|
||
create_a_puppet_transaction_report
|
||
User.current = nil
|
||
post :create, {:report => @log, :format => "yml"}
|
||
post :create, {:report => @log, :format => "yml"}, set_session_user
|
||
assert_response :success
|
||
post :create, {:report => @log, :format => "yml"}
|
||
post :create, {:report => @log, :format => "yml"}, set_session_user
|
||
assert_response :error
|
||
end
|
||
|
||
def test_create_valid
|
||
create_a_puppet_transaction_report
|
||
User.current = nil
|
||
post :create, {:report => @log, :format => "yml"}
|
||
post :create, {:report => @log, :format => "yml"}, set_session_user
|
||
assert_response :success
|
||
end
|
||
|
||
... | ... | |
get :index, {}, set_session_user
|
||
assert_response :success
|
||
end
|
||
|
||
test 'when ":restrict_registered_puppetmasters" is false, HTTP requests should be able to create a report' do
|
||
User.current = nil
|
||
Setting[:restrict_registered_puppetmasters] = false
|
||
SETTINGS[:require_ssl] = false
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['else.where'])
|
||
post :create, {:report => create_a_puppet_transaction_report, :format => "yml"}
|
||
assert_response :success
|
||
end
|
||
|
||
test 'hosts with a registered smart proxy on should create a report successfully' do
|
||
User.current = nil
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = false
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['else.where'])
|
||
post :create, {:report => create_a_puppet_transaction_report, :format => "yml"}
|
||
assert_response :success
|
||
end
|
||
|
||
test 'hosts without a registered smart proxy on should not be able to create a report' do
|
||
User.current = nil
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = false
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['another.host'])
|
||
post :create, {:report => create_a_puppet_transaction_report, :format => "yml"}
|
||
assert_equal 403, @response.status
|
||
end
|
||
|
||
test 'hosts with a registered smart proxy and SSL cert should create a report successfully' do
|
||
User.current = nil
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
|
||
@request.env['HTTPS'] = 'on'
|
||
@request.env['SSL_CLIENT_S_DN_CN'] = 'else.where'
|
||
@request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
|
||
post :create, {:report => create_a_puppet_transaction_report, :format => "yml"}
|
||
assert_response :success
|
||
end
|
||
|
||
test 'hosts without a registered smart proxy but with an SSL cert should not be able to create a report' do
|
||
User.current = nil
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
|
||
@request.env['HTTPS'] = 'on'
|
||
@request.env['SSL_CLIENT_S_DN_CN'] = 'another.host'
|
||
@request.env['SSL_CLIENT_VERIFY'] = 'SUCCESS'
|
||
post :create, {:report => create_a_puppet_transaction_report, :format => "yml"}
|
||
assert_equal 403, @response.status
|
||
end
|
||
|
||
test 'hosts with an unverified SSL cert should not be able to create a report' do
|
||
User.current = nil
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
|
||
@request.env['HTTPS'] = 'on'
|
||
@request.env['SSL_CLIENT_S_DN_CN'] = 'else.where'
|
||
@request.env['SSL_CLIENT_VERIFY'] = 'FAILED'
|
||
post :create, {:report => create_a_puppet_transaction_report, :format => "yml"}
|
||
assert_equal 403, @response.status
|
||
end
|
||
|
||
test 'when "require_ssl_puppetmasters" and "require_ssl" are true, HTTP requests should not be able to create a report' do
|
||
User.current = nil
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
SETTINGS[:require_ssl] = true
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['else.where'])
|
||
post :create, {:report => create_a_puppet_transaction_report, :format => "yml"}
|
||
assert_equal 403, @response.status
|
||
end
|
||
|
||
test 'when "require_ssl_puppetmasters" is true and "require_ssl" is false, HTTP requests should be able to create reports' do
|
||
User.current = nil
|
||
# since require_ssl_puppetmasters is only applicable to HTTPS connections, both should be set
|
||
Setting[:restrict_registered_puppetmasters] = true
|
||
Setting[:require_ssl_puppetmasters] = true
|
||
SETTINGS[:require_ssl] = false
|
||
|
||
Resolv.any_instance.stubs(:getnames).returns(['else.where'])
|
||
post :create, {:report => create_a_puppet_transaction_report, :format => "yml"}
|
||
assert_response :success
|
||
end
|
||
end
|
Also available in: Unified diff
fixes #2121, #2069 - restrict importers and ENC to puppetmasters and users
CVE-2013-0171: report and fact importers parse YAML directly from the remote
host without authentication. Untrusted YAML can instantiate objects and be
used to exploit Foreman.
CVE-2013-0174: external nodes (ENC) output is available to any source and
could contain sensitive information, e.g. root password.
The restrict_registered_puppetmasters setting (default: on) now only permits
access to the three routes if the remote host has a smart proxy registered
with the Puppet feature.
The require_ssl_puppetmasters setting (default: on) requires a client SSL
certificate on HTTPS requests. The CN is checked against known smart proxies
as above. :require_ssl in settings.yaml is recommended to disable HTTP.
Ensure ENC (node.rb) and report (foreman.rb) scripts are updated to supply
client SSL certificates.