Forum OpenACS Q&A: SSL, Login and Cookies

Collapse
Posted by Gilbert Wong on

I am in the process of making the login process onto my site happen over a SSL connection. Here's the process:

  1. go to the non-SSL site and login
  2. the login button sends me over to a SSL connection
  3. I enter my password and the server confirms my identity (still on SSL)
  4. I close my browser
  5. I open my browser and log onto the non-SSL site and it doesn't remember me.

I think I found reason why the server doesn't recognize me when I return to the non-SSL site after closing my browser. The cookie that the server writes has the following lines:

ad_user_login_secure
some encrypted stuff
www.mysite.com/

The cookie info is encrypted and my guess is that the ACS can't read that info. Am I correct? Is there a way I can authenticate the user over a SSL connection and have that information persist even if the user closes and reopens the browser?

Thanks.

Collapse
Posted by Richard Li on
What version of [Open]ACS are you running? The semantics of this were
fixed in ACS 4.0.1 (insecure and secure cookies are both set in SSL).
If you post the "encrypted" stuff, I think it might help in debugging.
Collapse
Posted by Gilbert Wong on
You know what, for some reason I can't get the ad_user_login_secure field anymore.  hmmm...  I'm confused.  Okay, in any case, the server still doesn't remember me.  I'll take a look at the 4.x code to see what the difference is.  Thanks.
Collapse
Posted by Stan Kaufman on
Gilbert, you problem may indeed be related to SSL, but there may be another issue if you're encrypting passwords in the database. Check out bug 783:

https://openacs.org/sdm/one-baf.tcl?baf_id=783

Somehow this prevents persistent login from working even if you've enabled it in your config file. Applying this patch fixes it.

Again, this may not be relevant, and there may be some real issues with SSL (haven't yet worked with it myself), but this *may* be part of your problem.

Collapse
Posted by Gilbert Wong on
Stan, that's not my problem.  That bug should have been fixed by 3.2.5.  I'll check the code to confirm but I'm sure that my login cookies were working before I started using SSL.
Collapse
Posted by Stan Kaufman on
Interesting. It wasn't fixed in my copy of 3.2.5, downloaded from the site here a couple weeks ago. Then again, that's the price I'm paying for not stopping to figure out how to run CVS and stay updated that way.
Collapse
Posted by Gilbert Wong on
Interesting.  Maybe I'm remembering incorrectly.  I'll check it out tonight.  Thanks!
Collapse
Posted by Gilbert Wong on
Stan,

Nope.  That wasn't the problem.  I patched that file the day I upgraded it.  I'm 99% sure it's the SSL.  My development machine runs the same code but doesn't have nsopenssl installed and the dev machine can read the cookies correctly.  I'm going to poke around in the ACS 4.x code.

Collapse
Posted by Gilbert Wong on

Okay. I got the cookies to work. Here's the code that I used in tcl/ad-security.tcl:

ad_proc ad_user_login {
    { -forever f }
    db user_id
} { Logs the user in, forever (via the user_login cookie) if -forever is true. }
 {
    global ad_sec_user_id
    set ad_sec_user_id $user_id

    set user_id_for_update [ad_decode $user_id 0 "null" $user_id]

    sec_generate_session_id_cookie
    ns_db dml $db "
        update sec_sessions
        set user_id = $user_id_for_update
        where session_id = [ad_get_session_id]
    "
    util_memoize_flush "sec_get_session_info [ad_get_session_id]"

    if { $user_id == 0 } {
        ad_set_cookie -replace t -max_age 0 ad_session_id ""
        ad_set_cookie -replace t -max_age 0 ad_secure_token ""
        ad_set_cookie -replace t -max_age 0 ad_user_login ""
        ad_set_cookie -replace t -max_age 0 ad_user_login_secure ""
    }

    if { $forever == "t" && $user_id != 0 } {
        set password [database_to_tcl_string $db "select password from users where user_id = $user_id"]
        if { [ad_secure_conn_p] } {
            ad_set_cookie -expires never -secure f 
                "ad_user_login" "$user_id,[sec_hexify $password]"
            ad_set_cookie -expires never -secure t 
                "ad_user_login_secure" "$user_id,[sec_hexify $password]"
        } else {
            ad_set_cookie -expires never -secure f 
                "ad_user_login" "$user_id,[sec_hexify $password]"
        }
        #if { [ad_secure_conn_p] } {
        #    set secure "t"
        #} else {
        #    set secure "f"
        #}
        #set password [database_to_tcl_string $db "select password from users wh
ere user_id = $user_id"]
        #ad_set_cookie -expires never -secure $secure 
        #       "ad_user_login" "$user_id,[sec_hexify $password]"
    }
}

Then you need to change the www/register/logout.tcl line to:

ns_returnredirect "/cookie-chain.tcl?cookie_name=[ns_urlencode ad_user_login]&cookie_value=expired&expire_state=e&final_page=[ns_urlencode /]"

My only concern is that the password is "hexafied" into the cookie. In the ACS 4.x, [ns_time] is used instead of a hexified password.