sec_handler (private)
sec_handler
Defined in packages/acs-tcl/tcl/security-procs.tcl
Reads the security cookies, setting fields in ad_conn accordingly.
- Partial Call Graph (max 5 caller/called nodes):
- Testcases:
- No testcase defined.
Source code: ns_log debug "OACS= sec_handler: enter" if {[info exists ::security::log(login_cookie)]} { foreach c [list session_id secure_token user_login user_login_secure] { lappend msg "$c '[ad_get_cookie [security::cookie_name $c]]'" } ns_log notice "OACS [ns_conn url] cookies: $msg" } try { ad_get_signed_cookie [security::cookie_name session_id] } trap {AD_EXCEPTION NO_COOKIE} {errorMsg} { # # We have no session cookie. Maybe we are running under # aa_test. # #if {[nsv_array exists aa_test]} { # ns_log notice "... nsv_array logindata [nsv_get aa_test logindata logindata]" # ns_log notice "... ns_conn peeraddr [ns_conn peeraddr]" # ns_log notice "... dict get $logindata peeraddr [ns_conn peeraddr]" #} if {[nsv_array exists aa_test] && [nsv_get aa_test logindata logindata] && [ns_conn peeraddr] in [list [dict get $logindata peeraddr] 127.0.0.1 ::1] } { #ns_log notice logindata=$logindata if {[dict exists $logindata user_id]} { set user_id [dict get $logindata user_id] ad_conn -set user_id $user_id ad_conn -set untrusted_user_id $user_id ad_conn -set account_status ok ad_conn -set auth_level ok #ad_conn -set session_id [sec_allocate_session] set auth_level ok set untrusted_user_id $user_id aa_test_start } } if {![aa_test_running_p]} { sec_login_handler } } trap {AD_EXCEPTION INVALID_COOKIE} {errorMsg} { # # We have a session cookie, but it fails the cryptographic # checks. Make sure to log the current user out and update # session cookie and ad_conn information. # ad_user_logout sec_login_handler } on ok {session_list} { # # The session cookie exists and is valid. # set session_data [split [lindex $session_list 0] {,}] set session_id [lindex $session_data 0] set session_user_id [lindex $session_data 1] set login_level [lindex $session_data 2] set session_last_renew_time [lindex $session_data 3] if {![string is integer -strict $session_last_renew_time]} { # # This happens only when the session cookie is old style # previous to OpenACS 5.7 and does not have session review # time embedded. Assume cookie expired and force login # handler. # set session_last_renew_time 0 } # # When the session_cookie comes from an authenticated session, # get login cookie as well. # set login_cookie_exists_p 0 set persistent_login_p 0 if {$session_user_id > 0} { set login_info [sec_login_read_cookie] if {[dict get $login_info status] eq "OK"} { set auth_token [dict get $login_info auth_token] # # Verify currently stored user authentication token # against the one on the login cookie. # if {$auth_token ne [sec_get_user_auth_token $session_user_id]} { # # Invalid user auth token in the login # cookie. This happens e.g. when user changed # their password, hence all logins on different # devices must be invalidated. Make sure to log # the current user out and update session cookie # and ad_conn information. # ad_user_logout sec_login_handler } else { set login_cookie_exists_p 1 set persistent_login_p [dict get $login_info forever_p] if {$persistent_login_p eq ""} { set persistent_login_p 0 } } } } ::security::log timeout "login_cookie persistent_login $persistent_login_p [ns_conn url]" set session_expr [expr {$session_last_renew_time + [sec_session_timeout]}] # # Check for persistent logins: If the user requested a # persistent login, don't perform session renewing based on # SessionTimeout. # if {!$persistent_login_p} { ::security::log timeout "SessionTimeout in [expr {$session_expr - [ns_time]}] secs" if {$session_expr < [ns_time]} { ::security::log timeout "SessionTimeout reached, call sec_login_handler" sec_login_handler } } else { ::security::log timeout "SessionTimeout not checked due to persistent login" } set user_id 0 set account_status closed if {$login_level > 0 && [sec_session_id_invalidated_p $session_id]} { # # Check, if the session_id was invalidated (e.g. via # logout). In case, someone might be operating with # stolen cookies. This check required to make sure that # after the logout this sesson_id is not accepted anymore, # even when below sec_session_renew time (default 5min). # ns_log warning "downgrade login_level of user $session_user_id since session_id was invalidated" set login_level 0 } if {$login_level > 0 && !$login_cookie_exists_p} { # # $login_level > 0 requires a login cookie. If we have no # login cookie, somebody tries to hack around. # set login_level 0 ns_log warning "downgrade login_level of user $session_user_id since there is no login cookie provided" } switch -- $login_level { 1 { # # authentication ok # set auth_level ok set user_id $session_user_id set account_status ok } 2 { # # authentication ok, but account closed # set auth_level ok } default { # # login_level 0: none/expired # if { $session_user_id == 0 } { set auth_level none } else { set auth_level expired } } } ::security::log login_cookie "Insecure session OK: session_id $session_id, session_user_id $session_user_id, auth_level $auth_level, user_id $user_id" # # We're okay for the insecure session. Check if it's also # secure. # if { $auth_level eq "ok" && ([security::secure_conn_p] || [ad_conn behind_secure_proxy_p]) } { catch { set sec_token [split [ad_get_signed_cookie [security::cookie_name secure_token]] {,}] if {[lindex $sec_token 0] eq $session_id && [lindex $sec_token 2] eq [ad_conn peeraddr] } { set auth_level secure } } ::security::log login_cookie "Secure session checked: session_id = $session_id, session_user_id = $session_user_id, auth_level = $auth_level, user_id = $user_id" } # Setup ad_conn ad_conn -set session_id $session_id ad_conn -set untrusted_user_id $session_user_id ad_conn -set user_id $user_id ad_conn -set auth_level $auth_level ad_conn -set account_status $account_status # Reissue session cookie so session doesn't expire if the # renewal period has passed. This is a little tricky because # the cookie doesn't know about sec_session_renew; it only # knows about sec_session_timeout. # [sec_session_renew] = SessionTimeout - SessionRenew (see security-init.tcl) # $session_expr = PreviousSessionIssue + SessionTimeout ::security::log timeout "SessionRefresh in [expr {($session_expr - [sec_session_renew]) - [ns_time]}] secs" if { $session_expr - [sec_session_renew] < [ns_time] } { sec_generate_session_id_cookie } } # # Generate a CSRF token. # security::csrf::newGeneric XQL file: packages/acs-tcl/tcl/security-procs.xql
PostgreSQL XQL file: packages/acs-tcl/tcl/security-procs-postgresql.xql
Oracle XQL file: packages/acs-tcl/tcl/security-procs-oracle.xql