diff --git a/config/config.example.yml b/config/config.example.yml index 47a17c4f..cf8d9d05 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -562,6 +562,17 @@ log: #enable_single_sign_out: true +##### SERVICES ################################################################# + +# You can restrict what services can authenticate against the CAS server. + +# By default any service can authenticate and a blank white list will also +# allow any service to authenticate. Services are listed on a single line +# separated by a comma. + +#service_whitelist: https://service.one.com,https://service.two.com + + ##### OTHER #################################################################### # You can set various ticket expiry times (specify the value in seconds). diff --git a/lib/casserver/server.rb b/lib/casserver/server.rb index 12d1f756..73880780 100644 --- a/lib/casserver/server.rb +++ b/lib/casserver/server.rb @@ -293,6 +293,7 @@ def self.init_database! require @template_engine @template_engine = @template_engine.to_sym end + @service_whitelist = CASServer::Utils::initialize_service_whitelist(settings.config[:service_whitelist]) end # The #.#.# comments (e.g. "2.1.3") refer to section numbers in the CAS protocol spec @@ -310,7 +311,7 @@ def self.init_database! headers['Expires'] = (Time.now - 1.year).rfc2822 # optional params - @service = clean_service_url(params['service']) + @service = CASServer::Utils::validate_service(clean_service_url(params['service']), @service_whitelist) @renew = params['renew'] @gateway = params['gateway'] == 'true' || params['gateway'] == '1' @@ -400,7 +401,7 @@ def self.init_database! Utils::log_controller_action(self.class, params) # 2.2.1 (optional) - @service = clean_service_url(params['service']) + @service = CASServer::Utils::validate_service(clean_service_url(params['service']), @service_whitelist) # 2.2.2 (required) @username = params['username'] @@ -516,7 +517,7 @@ def self.init_database! # "logout" page, we take the user back to the login page with a "you have been logged out" # message, allowing for an opportunity to immediately log back in. This makes it # easier for the user to log out and log in as someone else. - @service = clean_service_url(params['service'] || params['destination']) + @service = CASServer::Utils::validate_service(clean_service_url(params['service']), @service_whitelist) || clean_service_url(params['destination']) @continue_url = params['url'] @gateway = params['gateway'] == 'true' || params['gateway'] == '1' @@ -607,7 +608,7 @@ def self.init_database! CASServer::Utils::log_controller_action(self.class, params) # required - @service = clean_service_url(params['service']) + @service = CASServer::Utils::validate_service(clean_service_url(params['service']), @service_whitelist) @ticket = params['ticket'] # optional @renew = params['renew'] @@ -630,7 +631,7 @@ def self.init_database! CASServer::Utils::log_controller_action(self.class, params) # required - @service = clean_service_url(params['service']) + @service = CASServer::Utils::validate_service(clean_service_url(params['service']), @service_whitelist) @ticket = params['ticket'] # optional @pgt_url = params['pgtUrl'] @@ -661,7 +662,7 @@ def self.init_database! CASServer::Utils::log_controller_action(self.class, params) # required - @service = clean_service_url(params['service']) + @service = CASServer::Utils::validate_service(clean_service_url(params['service']), @service_whitelist) @ticket = params['ticket'] # optional @pgt_url = params['pgtUrl'] diff --git a/lib/casserver/utils.rb b/lib/casserver/utils.rb index 324db887..1075c3bf 100644 --- a/lib/casserver/utils.rb +++ b/lib/casserver/utils.rb @@ -28,5 +28,22 @@ def log_controller_action(controller, params) $LOG.debug("Processing #{controller}::#{method} #{params2.inspect}") end module_function :log_controller_action + + def initialize_service_whitelist(whitelist) + $LOG.debug("Initializing Service Whitelist") + whitelist = whitelist || '' + whitelist.split(',') + end + module_function :initialize_service_whitelist + + def validate_service(service, whitelist) + $LOG.debug("Validating service \"#{service}\"") + return service if whitelist.empty? + $LOG.debug("Checking service whitelist") + return service if whitelist.include?(service) + $LOG.warn("Service \"#{service}\" is not in service whitelist") + nil + end + module_function :validate_service end end