(file) Return to SessionCookie.class.php CVS log (file) (dir) Up to [Development] / advokit-installer-bak

File: [Development] / advokit-installer-bak / SessionCookie.class.php (download) / (as text)
Revision: 1.2, Wed Aug 11 18:37:22 2004 UTC (6 years ago) by travislow
Branch: MAIN
CVS Tags: r0-9-5, HEAD
Changes since 1.1: +76 -12 lines
C. Scott Ananian's changes to http authentication.

<?
# ======================================================================
# AdvoKit -- a campaign managment tool
# Copyright (C) 2004  OrchidSuites, Inc. (info@orchidsuites.net)
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the AFFERO GENERAL PUBLIC LICENSE
# as published by Affero, Inc.; either version 1
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# AFFERO GENERAL PUBLIC LICENSE for more details.
# 
# You should have received a copy of the AFFERO GENERAL PUBLIC LICENSE
# along with this program; if not, write to Affero, Inc. at
# 510 Third Street - Suite 225, San Francisco, CA 94107, USA
# or visit <http://www.affero.org>.
# ======================================================================

# ======================================================================
# A session cookie stores a nonce, the username, a password hash, and
# a login timestamp (used to distinguish between simultaneous logins
# of the same user).  It can also (de)serialize this information
# to (from) a string.
# ======================================================================
class SessionCookie
{
    var $nonce;
    var $username;
    var $passhash;
    var $timestamp;
    
    #------------------------------------------------------------
    # Constructors and factory methods.
    #------------------------------------------------------------

    #.................................................. SessionCookie
    #
    # Create a session cookie from an enumerated list of its contents.
    # (Used primarily by the more convenient factory methods below.)
    #
    function SessionCookie( $nonce, $username, $passhash, $timestamp )
    {
        $this->nonce = $nonce;
        $this->username = $username;
        $this->passhash = $passhash;
        $this->timestamp = $timestamp;
    }

    #.................................................. fromString
    #
    # Reconstruct a session cookie from a string (which may have been
    # stored in an HTTP cookie, or in the PHP session, or come from
    # a GET request, etc).
    # The string is a the session cookie's parts, separated by
    # underscores, trivially encoded.
    #
    function fromString( &$config, $string )
    {
        # Translation strings for obfuscation of sessionid.
        $from = $config->get( "tr_from" );
        $to =   $config->get( "tr_to" );
        $trsessid = strtr( $string, $to, $from );
        # Parse out info from sessionid
        $parts = split( "_", $trsessid );
        $timestamp = array_pop( $parts );
        $cookiehash = array_pop( $parts );
        $nonce = array_shift( $parts );
        $username = join( "_", $parts );
        return new SessionCookie( $nonce, $username, $cookiehash, $timestamp );
    }

    #.................................................. fromUser
    #
    # Create a new SessionCookie which is valid for the specified
    # user.
    #
    function fromUser( &$user )
    {
        $nonce = md5(uniqid(rand(),true));
        $username = $user->getUsername();
        $salt = $user->config->get( "password_salt" );
        $password = $user->getPassword(); // really already a hash
        $passhash = md5( "$password:$nonce" );
        $timestamp = time();
        return new SessionCookie( $nonce, $username, $passhash, $timestamp );
    }

    #.................................................. fromUser
    #
    # Reconstruct a session cookie from http authentication headers.
    #
    function fromHeaders( &$config )
    {
	// Apache server fix for some broken set ups
	if (isset($_SERVER['PHP_AUTH_USER']) && !isset($_ENV['REMOTE_USER']))
	    $_ENV['REMOTE_USER'] = $_SERVER['PHP_AUTH_USER'];
	if (isset($_SERVER['AUTH_PASSWORD']) && !isset($_ENV['PHP_AUTH_PW']))
	    $_ENV['PHP_AUTH_PW'] = $_SERVER['AUTH_PASSWORD'];
	// check for basic authentication.
	if( isset( $_SERVER['PHP_AUTH_USER'] ) &&
	    isset( $_SERVER['PHP_AUTH_PW'] ) )
	{
	    $nonce = "not used";
	    $username = $_SERVER['PHP_AUTH_USER'];
	    $password = $_SERVER['PHP_AUTH_PW'];
	    $salt = $config->get( "password_salt" );
	    $passhash = md5(md5( "$username:$salt:$password" ).":$nonce");
	    // this won't work without 'login_allow_simultaneous'
	    $timestamp = time();
	    return new SessionCookie($nonce, $username, $passhash, $timestamp);
	}
	// okay, then perhaps digest authentication?
	if( isset($_SERVER['HTTP_AUTHORIZATION']) )
	    $headers['Authorization'] = $_SERVER['HTTP_AUTHORIZATION'];
	if( function_exists('apache_request_headers') )
	    $headers = apache_request_headers();
	$auth = parseAuthorizationHeader( $headers['Authorization'] );
	if ( $auth )
	{
	    // digest authentication.
	    $nonce=NULL;
	    foreach(nonceOptions( $config ) as $n) {
		if ($auth['nonce'] == $n) {
		    $nonce = $n;
		    break;
		}
	    }
	    if ($nonce==NULL) {
		// stale nonce!
		makeAuthenticateHeader( $config, $auth['opaque'], true );
		// this message isn't very friendly, but it should be
		// *VERY* unusual for the user to see it.
		?>
		<h1>Stale authentication</h1>
		<p>The credentials you supplied are stale.</p>
		<?
		exit;
	    }
	    $nc = $auth['nc'];
	    $cnonce = $auth['cnonce'];
	    $qop = $auth['qop'];
	    $method = $_SERVER['REQUEST_METHOD'];
	    $digesturi = $_SERVER['REQUEST_URI'];
	    if ($auth['uri'] != $digesturi) // internet explorer bug!
		list($digesturi,$junk)=explode('?',$digesturi,2);
	    $x = "$nonce:$nc:$cnonce:$qop:".md5("$method:$digesturi");
	    // internet explorer may not return the opaque value, so
	    // login_allow_simultaneous=0 may not work.
	    return new SessionCookie($x, $auth['username'], $auth['response'], $auth['opaque']);
	}
    }

    #------------------------------------------------------------
    # Instance functions
    #------------------------------------------------------------

    #.................................................. toString
    #
    # Serialize a session cookie to a string, which can then be
    # stored in an HTTP cookie, in the PHP session, or be added
    # as part of a GET request, etc.
    # The string is a the session cookie's parts, separated by
    # underscores, trivially encoded.
    #
    function toString( &$config )
    {
        $sessionid = $this->nonce."_".$this->username."_".
            $this->passhash."_".$this->timestamp;
        $from = $config->get( "tr_from" );
        $to =   $config->get( "tr_to" );
        $trsessionid = strtr( $sessionid, $from, $to );
        return $trsessionid;
    }
}
?>

cvsadmin@voter2voter.org
CVS Snapshots (updated daily)