f41b982009-05-07Martin Stjernholm // This is a roxen module. Copyright © 2001 - 2009, Roxen IS.
42cd712001-09-03Martin Nilsson 
2c7f392001-01-19Per Hedbor constant cvs_version =
f41b982009-05-07Martin Stjernholm  "$Id: auth_httpcookie.pike,v 1.13 2009/05/07 14:15:55 mast Exp $";
2c7f392001-01-19Per Hedbor inherit AuthModule; inherit "module"; #define COOKIE "_roxen_cookie_auth"
cf4a902001-01-19Per Hedbor constant name = "cookie";
2c7f392001-01-19Per Hedbor  //<locale-token project="mod_auth_httpcookie">_</locale-token> #define _(X,Y) _DEF_LOCALE("mod_auth_httpcookie",X,Y) #include <module.h>
f0d6942001-01-29Per Hedbor LocaleString module_name =
bc0fa02001-03-08Per Hedbor  _(1,"Authentication: HTTP Cookie");
2c7f392001-01-19Per Hedbor 
f0d6942001-01-29Per Hedbor LocaleString module_doc =
5c1ca72001-01-29Martin Nilsson  _(2,"Authenticate users using a cookie.");
2c7f392001-01-19Per Hedbor 
fc40392008-08-15Martin Stjernholm protected User low_authenticate( RequestID id, string user, string password, UserDB db )
2c7f392001-01-19Per Hedbor { if( User u = db->find_user( user ) ) if( u->password_authenticate( password ) ) return u; }
fc40392008-08-15Martin Stjernholm protected string table;
2c7f392001-01-19Per Hedbor 
fc40392008-08-15Martin Stjernholm protected string encode_pw(string p)
2c7f392001-01-19Per Hedbor { return Gmp.mpz( ~p, 256 )->digits( 9 ); }
fc40392008-08-15Martin Stjernholm protected string decode_pw( string p )
2c7f392001-01-19Per Hedbor { return ~Gmp.mpz( p, 9 )->digits( 256 ); }
fc40392008-08-15Martin Stjernholm protected array(string) low_lookup_cookie( string cookie )
2c7f392001-01-19Per Hedbor { array r =
92a21d2001-08-13Per Hedbor  get_my_sql()->query( "SELECT name,password FROM "+
2c7f392001-01-19Per Hedbor  table+" WHERE cookie=%s", cookie ); if( !sizeof( r ) ) return ({0,0}); return ({ decode_pw(r[0]->password), decode_pw( r[0]->name ) }); }
fc40392008-08-15Martin Stjernholm protected mapping(string:array(string)) cookies = ([]); protected array(string) lookup_cookie( string cookie )
2c7f392001-01-19Per Hedbor { if( cookies[ cookie ] ) return cookies[ cookie ]; cookies[ cookie ] = low_lookup_cookie( cookie ); if( !cookies[cookie][0] ) return m_delete( cookies, cookie ); return cookies[cookie]; }
fc40392008-08-15Martin Stjernholm protected string create_cookie( string u, string p )
2c7f392001-01-19Per Hedbor { int i = (((hash(u) << 32) | hash(p)) << 32) | hash(u+p); string c = i->digits(16);
92a21d2001-08-13Per Hedbor  catch(get_my_sql()->query( "INSERT INTO "+table+" "
2c7f392001-01-19Per Hedbor  "(cookie,name,password) VALUES " "(%s,%s,%s)", c, encode_pw(u), encode_pw(p) )); return c; } User authenticate( RequestID id, UserDB db ) //! Try to authenticate the request with users from the specified user //! database. If no @[db] is specified, all datbases in the current //! configuration are searched in order, then the configuration user //! database. //! //! The return value is the autenticated user. { string password; string user; if( !id->cookies[ COOKIE ] ) return 0; [password,user] = lookup_cookie( id->cookies[ COOKIE ] ); if( !user || !password ) return 0;
cf4a902001-01-19Per Hedbor  NOCACHE();
0764862001-03-16Per Hedbor 
2c7f392001-01-19Per Hedbor  User res; if( !db ) { foreach( id->conf->user_databases(), UserDB db ) if( res = low_authenticate( id, user, password, db ) ) return res; Roxen.remove_cookie( id, COOKIE, "", 0, "/" ); return 0; } res = low_authenticate( id, user, password, db ); if( !res ) Roxen.remove_cookie( id, COOKIE, "", 0, "/" ); return res; } mapping authenticate_throw( RequestID id, string realm, UserDB db ) //! Returns a reply mapping, similar to @[Roxen.http_rxml_reply] with //! friends. If no @[db] is specified, all datbases in the current //! configuration are searched in order, then the configuration user //! database. { string u, p;
cf4a902001-01-19Per Hedbor  NOCACHE();
2c7f392001-01-19Per Hedbor  if( (u=id->variables->_cookie_username) && (p=id->variables->_cookie_password) ) { Roxen.set_cookie( id, COOKIE, create_cookie( u, p ), -1, 0, "/"); return Roxen.http_redirect( id->not_query+"?"+ "netscape=needsthis&"+id->query, id ); } return Roxen.http_rxml_answer( replace( query("user_form"), ({"PWINPUT", "UNINPUT", "REALM"}), ({ "<input size=16 type='password' name='_cookie_password' />", "<input size=16 name='_cookie_username' />", realm }) ), id ); } void start() {
54c6842003-05-13Jonas Wallden #if constant(WS_REPLICATE)
e082212001-08-28Per Hedbor  set_my_db( "replicate" ); #endif
92a21d2001-08-13Per Hedbor  table = get_my_table("", ({ "cookie varchar(40) PRIMARY KEY NOT NULL", "password varchar(40) NOT NULL", "name varchar(40) NOT NULL" }), "Used to store the information nessesary to " "authenticate roxen users" );
2c7f392001-01-19Per Hedbor }
fc40392008-08-15Martin Stjernholm protected void create()
2c7f392001-01-19Per Hedbor { defvar( "user_form", Variable.Text( #" <title>Authentication required for REALM</title> <body alink=\"#000000\" bgcolor=\"#ffffff\" text=\"#000000\"> <form method='POST'> Username: UNINPUT<br /> Password: PWINPUT<br /> <input type=submit value=' Ok ' /> </form></body>",0,
5c1ca72001-01-29Martin Nilsson  _(3,"User form"),_(4,"The user/password request form shown to the user")));
2c7f392001-01-19Per Hedbor }