Index: openacs-4/packages/acs-tcl/tcl/http-auth-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-tcl/tcl/http-auth-procs.tcl,v diff -u -N -r1.4.2.1 -r1.4.2.2 --- openacs-4/packages/acs-tcl/tcl/http-auth-procs.tcl 10 Apr 2019 20:49:53 -0000 1.4.2.1 +++ openacs-4/packages/acs-tcl/tcl/http-auth-procs.tcl 8 Oct 2019 16:28:28 -0000 1.4.2.2 @@ -5,34 +5,59 @@ namespace eval http_auth {} +ad_proc -public http_auth::basic_authentication_decode { + authorization +} { + Implements decoding of authorization header as defined in RFC 7617 + "username" containing a colon character is invalid (see RFC 7617, + Section 2). + + @param authorization content of "Authorization:" reply header field, + such as e.g. "Basic 29234k3j49a" + @result dict containing password and user +} { + set decoded [ns_uudecode [lindex [split $authorization " "] 1]] + # + # $decoded should be of the form "user:password". + # + # The pair is invalid at least in the following situations: + # - the username contains a colon + # - the username is empty + # - $decoded contains no colon + # + set delimiterPos [string first : $decoded] + if {$delimiterPos > 0} { + set user [string range $decoded 0 $delimiterPos-1] + set password [string range $decoded $delimiterPos+1 end] + } else { + ns_log warning "protocol-handler: invalid user/password pair provided: $decoded" + set password "" + set user "" + } + return [list password $password user $user] +} + ad_proc http_auth::set_user_id {} { Get the user_id from HTTP authentication headers. NOTE: This should be handled through SSL since plain HTTP auth is easy to decode } { # should be something like "Basic 29234k3j49a" - set a [ns_set get [ns_conn headers] Authorization] - if {[string length $a]} { - ns_log debug "\nTDAV auth_check authentication info $a" - # get the second bit, the base64 encoded bit - set up [lindex [split $a " "] 1] - # after decoding, it should be user:password; get the username - lassign [split [ns_uudecode $up] ":"] user password - ns_log debug "\nACS VERSION [ad_acs_version]" - ns_log debug "\nHTTP authentication" - # check all authorities + set authorization [ns_set iget [ns_conn headers] Authorization] + if {[string length $authorization] > 0} { + set credentials [http_auth::basic_authentication_decode $authorization] foreach authority [auth::authority::get_authority_options] { set authority_id [lindex $authority 1] array set auth [auth::authenticate \ - -username $user \ - -password $password \ + -username [dict get $credentials user] \ + -password [dict get $credentials password] \ -authority_id $authority_id \ -no_cookie] if {$auth(auth_status) ne "ok" } { array set auth [auth::authenticate \ - -email $user \ - -password $password \ + -email [dict get $credentials user] \ + -password [dict get $credentials password] \ -authority_id $authority_id \ -no_cookie] }