(file) Return to auth-utils.inc.php CVS log (file) (dir) Up to [Development] / advokit-installer

File: [Development] / advokit-installer / auth-utils.inc.php (download) / (as text)
Revision: 1.1, Wed Aug 11 18:37:22 2004 UTC (6 years, 1 month ago) by travislow
Branch: MAIN
CVS Tags: r1-x-dev, r0-9-9, r0-9-8, r0-9-5, footag0, HEAD
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>.
# ======================================================================

#.................................................. parseAuthorizationHeader
#
# Parse an HTTP digest authorization header into its component parts.
# Returns an array which maps each header key to its value, or
# NULL if this is not a digest header.
#
function parseAuthorizationHeader( $authorization ) {
    list($authtype,$params) =
	explode(' ', trim($authorization), 2);
    if( strcasecmp($authtype, "Digest") != 0 )
	return NULL; // not a digest authorization header
    $auth=array(); $ptmp=array();
    preg_match_all
	('/\s*(\w+)\s*=\s*(\"(?:[^\"]|\\\\.)*\"|[^\",]*?)\s*(?:,|$)/',
	 $params, $ptmp, PREG_SET_ORDER);
    foreach($ptmp as $match) {
	if(substr($match[2],0,1)=='"')
	    $auth[$match[1]]=stripslashes(substr($match[2],1,-1));
	else
	    $auth[$match[1]]=$match[2];
    }
    return array_change_key_case($auth, CASE_LOWER);
}

#.................................................. nonceOptions
#
# Create 3 nonce values which we will accept, corresponding to the
# previous 3 minutes.
#
function nonceOptions( &$config ) {
    // Return acceptable nonce values
    $time = time();
    $noncekey = $config->get( "noncekey" );
    $nonces = array();
    for ($i=0; $i<3; $i++) { // 3 is 'nonce lifetime'
	$nonces[$i] =
	    md5(// nonce is specific to a particular minute.
		date('Y-m-d H:i',$time-($i*60)).
		// different users get different nonces, sorta
		':'.$_SERVER['HTTP_USER_AGENT'].
		// different (virtual) hosts get different nonces
		':'.$_SERVER['SERVER_SIGNATURE'].
		// this is the real security: admin should make a secret.
		':'.(empty($noncekey)?"insecure":$noncekey));
    }
    return $nonces;
}

#.................................................. makeAuthenticateHeader
#
# Send a WWW-Authenticate header.
#
function makeAuthenticateHeader( &$config, $opaque, $stale=false )
{
    $realm = $config->get( "password_salt" );
    $nonceOptions = nonceOptions( $config );
    $nonce = $nonceOptions[0];
    // don't allow basic authentication unless the connection is secure.
    // also, basic authentication doesn't track the timestamp we need
    // for login_allow_simultanous.
    if ( strtolower( $_SERVER['HTTPS'] ) == "on" &&
	 $config->get( "login_allow_simultaneous" ) )
	header("WWW-Authenticate: Basic realm=\"$realm\"", false, 401);
    // opaque string tracks the timestamp for 'login_allow_simultaneous'
    $opaque = addslashes($opaque);
    // add domain=xxx if you don't want site-wide authentication, or
    //  if you want authentication across multiple servers
    header("WWW-Authenticate: Digest qop=auth, algorithm=MD5, ".
	   "realm=\"$realm\", nonce=\"$nonce\", opaque=\"$opaque\"".
	   ($stale?", stale=true":""), false, 401);
}
?>

cvsadmin@voter2voter.org
CVS Snapshots (updated daily)