2011-06-23 15:04:32 +00:00
< ? php
// PLEASE DO NOT EDIT THIS FILE UNLESS YOU KNOW WHAT YOU ARE DOING!
/**
* phpMyID - A standalone , single user , OpenID Identity Provider
*
* @ package phpMyID
* @ author CJ Niemira < siege ( at ) siege ( dot ) org >
* @ copyright 2006 - 2008
* @ license http :// www . gnu . org / licenses / gpl . html GNU Public License
* @ url http :// siege . org / projects / phpMyID
* @ version 0.9
*/
/**
* Set a constant to indicate that phpMyID is running
*/
define ( 'PHPMYID_STARTED' , true );
/**
* List the known types and modes
* @ name $known
* @ global array $GLOBALS [ 'known' ]
*/
$GLOBALS [ 'known' ] = array (
'assoc_types' => array ( 'HMAC-SHA1' ),
'openid_modes' => array ( 'accept' ,
'associate' ,
'authorize' ,
'cancel' ,
'checkid_immediate' ,
'checkid_setup' ,
'check_authentication' ,
'error' ,
'id_res' ,
'login' ,
'logout' ,
'test' ),
'session_types' => array ( '' ,
'DH-SHA1' ),
'bigmath_types' => array ( 'DH-SHA1' ),
);
/**
* Defined by OpenID spec
* @ name $g
* @ global integer $GLOBALS [ 'g' ]
*/
$GLOBALS [ 'g' ] = 2 ;
/**
* Defined by OpenID spec
* @ name $p
* @ global integer $GLOBALS [ 'p' ]
*/
$GLOBALS [ 'p' ] = '155172898181473697471232257763715539915724801966915404479707' .
'7953140576293785419175806512274236981889937278161526466314385615958256881888' .
'8995127215884267541995034125870655654980358010487053768147672651325574704076' .
'5857479291291572334510643245094715007229621094194349783925984760375594985848' .
'253359305585439638443' ;
// Runmode functions
/**
* Allow the user to accept trust on a URL
* @ global array $profile
*/
function accept_mode () {
global $profile ;
// this is a user session
user_session ();
// the user needs refresh urls in their session to access this mode
if ( ! isset ( $_SESSION [ 'post_accept_url' ]) || ! isset ( $_SESSION [ 'cancel_accept_url' ]) || ! isset ( $_SESSION [ 'unaccepted_url' ]))
error_500 ( 'You may not access this mode directly.' );
// has the user accepted the trust_root?
$accepted = @ strlen ( $_REQUEST [ 'accepted' ])
? $_REQUEST [ 'accepted' ]
: null ;
// if so, refresh back to post_accept_url
if ( $accepted === 'yes' ) {
$_SESSION [ 'accepted_url' ] = $_SESSION [ 'unaccepted_url' ];
wrap_redirect ( $_SESSION [ 'post_accept_url' ]);
// if they rejected it, return to the client
} elseif ( $accepted === 'no' ) {
wrap_redirect ( $_SESSION [ 'cancel_accept_url' ]);
}
// if neither, offer the trust request
$q = strpos ( $profile [ 'req_url' ], '?' ) ? '&' : '?' ;
$yes = $profile [ 'req_url' ] . $q . 'accepted=yes' ;
$no = $profile [ 'req_url' ] . $q . 'accepted=no' ;
wrap_html ( 'The client site you are attempting to log into has requested that you trust the following URL:<br/><b>' . $_SESSION [ 'unaccepted_url' ] . '</b><br/><br/>Do you wish to continue?<br/><a href="' . $yes . '">Yes</a> | <a href="' . $no . '">No</a>' );
}
/** * Perform an association with a consumer
* @ global array $known
* @ global array $profile
* @ global integer $g
* @ global integer $p
*/
function associate_mode () {
global $g , $known , $p , $profile ;
// Validate the request
if ( ! isset ( $_REQUEST [ 'openid_mode' ]) || $_REQUEST [ 'openid_mode' ] != 'associate' )
error_400 ();
// Get the request options, using defaults as necessary
$assoc_type = ( @ strlen ( $_REQUEST [ 'openid_assoc_type' ])
&& in_array ( $_REQUEST [ 'openid_assoc_type' ], $known [ 'assoc_types' ]))
? $_REQUEST [ 'openid_assoc_type' ]
: 'HMAC-SHA1' ;
$session_type = ( @ strlen ( $_REQUEST [ 'openid_session_type' ])
&& in_array ( $_REQUEST [ 'openid_session_type' ], $known [ 'session_types' ]))
? $_REQUEST [ 'openid_session_type' ]
: '' ;
$dh_modulus = ( @ strlen ( $_REQUEST [ 'openid_dh_modulus' ]))
? long ( base64_decode ( $_REQUEST [ 'openid_dh_modulus' ]))
: ( $session_type == 'DH-SHA1'
? $p
: null );
$dh_gen = ( @ strlen ( $_REQUEST [ 'openid_dh_gen' ]))
? long ( base64_decode ( $_REQUEST [ 'openid_dh_gen' ]))
: ( $session_type == 'DH-SHA1'
? $g
: null );
$dh_consumer_public = ( @ strlen ( $_REQUEST [ 'openid_dh_consumer_public' ]))
? $_REQUEST [ 'openid_dh_consumer_public' ]
: ( $session_type == 'DH-SHA1'
? error_post ( 'dh_consumer_public was not specified' )
: null );
$lifetime = time () + $profile [ 'lifetime' ];
// Create standard keys
$keys = array (
'assoc_type' => $assoc_type ,
'expires_in' => $profile [ 'lifetime' ]
);
// If I can't handle bigmath, default to plaintext sessions
if ( in_array ( $session_type , $known [ 'bigmath_types' ]) && $profile [ 'use_bigmath' ] === false )
$session_type = null ;
// Add response keys based on the session type
switch ( $session_type ) {
case 'DH-SHA1' :
// Create the associate id and shared secret now
list ( $assoc_handle , $shared_secret ) = new_assoc ( $lifetime );
// Compute the Diffie-Hellman stuff
$private_key = random ( $dh_modulus );
$public_key = bmpowmod ( $dh_gen , $private_key , $dh_modulus );
$remote_key = long ( base64_decode ( $dh_consumer_public ));
$ss = bmpowmod ( $remote_key , $private_key , $dh_modulus );
$keys [ 'assoc_handle' ] = $assoc_handle ;
$keys [ 'session_type' ] = $session_type ;
$keys [ 'dh_server_public' ] = base64_encode ( bin ( $public_key ));
$keys [ 'enc_mac_key' ] = base64_encode ( x_or ( sha1_20 ( bin ( $ss )), $shared_secret ));
break ;
default :
// Create the associate id and shared secret now
list ( $assoc_handle , $shared_secret ) = new_assoc ( $lifetime );
$keys [ 'assoc_handle' ] = $assoc_handle ;
$keys [ 'mac_key' ] = base64_encode ( $shared_secret );
}
// Return the keys
wrap_kv ( $keys );
}
/**
* Perform a user authorization
* @ global array $profile
*/
function authorize_mode () {
global $profile ;
global $USERNAME ;
2011-06-24 20:07:26 +00:00
global $IDENTITY ;
2011-06-23 15:04:32 +00:00
// this is a user session
// the user needs refresh urls in their session to access this mode
if ( ! isset ( $_SESSION [ 'post_auth_url' ]) || ! isset ( $_SESSION [ 'cancel_auth_url' ]))
error_500 ( 'You may not access this mode directly.' );
2011-06-24 20:07:26 +00:00
$profile [ 'idp_url' ] = $IDENTITY ;
2011-06-23 15:04:32 +00:00
if ( isset ( $_SERVER [ 'PHP_AUTH_USER' ]) && $profile [ 'authorized' ] === false && $_SERVER [ 'PHP_AUTH_USER' ] == $USERNAME ) {
2011-07-29 19:36:03 +00:00
if ( OC_User :: checkPassword ( $USERNAME , $_SERVER [ 'PHP_AUTH_PW' ])) { // successful login!
2011-06-23 15:04:32 +00:00
// return to the refresh url if they get in
$_SESSION [ 'openid_auth' ] = true ;
$_SESSION [ 'openid_user' ] = $USERNAME ;
wrap_redirect ( $_SESSION [ 'post_auth_url' ]);
// failed login
} else {
$_SESSION [ 'failures' ] ++ ;
debug ( 'Login failed' );
debug ( 'Fail count: ' . $_SESSION [ 'failures' ]);
}
}
// if we get this far the user is not authorized, so send the headers
$uid = uniqid ( mt_rand ( 1 , 9 ));
$_SESSION [ 'uniqid' ] = $uid ;
// debug('Prompting user to log in. Stale? ' . $stale);
header ( 'HTTP/1.0 401 Unauthorized' );
// header(sprintf('WWW-Authenticate: Digest qop="auth-int, auth", realm="%s", domain="%s", nonce="%s", opaque="%s", stale="%s", algorithm="MD5"', $profile['auth_realm'], $profile['auth_domain'], $uid, md5($profile['auth_realm']), $stale ? 'true' : 'false'));
header ( 'WWW-Authenticate: Basic realm="ownCloud"' );
$q = strpos ( $_SESSION [ 'cancel_auth_url' ], '?' ) ? '&' : '?' ;
wrap_refresh ( $_SESSION [ 'cancel_auth_url' ] . $q . 'openid.mode=cancel' );
// die('401 Unauthorized');
}
/**
* Handle a consumer ' s request for cancellation .
*/
function cancel_mode () {
wrap_html ( 'Request cancelled.' );
}
/**
* Handle a consumer ' s request to see if the user is authenticated
*/
function check_authentication_mode () {
// Validate the request
if ( ! isset ( $_REQUEST [ 'openid_mode' ]) || $_REQUEST [ 'openid_mode' ] != 'check_authentication' )
error_400 ();
$assoc_handle = @ strlen ( $_REQUEST [ 'openid_assoc_handle' ])
? $_REQUEST [ 'openid_assoc_handle' ]
: error_post ( 'Missing assoc_handle' );
$sig = @ strlen ( $_REQUEST [ 'openid_sig' ])
? $_REQUEST [ 'openid_sig' ]
: error_post ( 'Missing sig' );
$signed = @ strlen ( $_REQUEST [ 'openid_signed' ])
? $_REQUEST [ 'openid_signed' ]
: error_post ( 'Missing signed' );
// Prepare the return keys
$keys = array (
'openid.mode' => 'id_res'
);
// Invalidate the assoc handle if we need to
if ( @ strlen ( $_REQUEST [ 'openid_invalidate_handle' ])) {
destroy_assoc_handle ( $_REQUEST [ 'openid_invalidate_handle' ]);
$keys [ 'invalidate_handle' ] = $_REQUEST [ 'openid_invalidate_handle' ];
}
// Validate the sig by recreating the kv pair and signing
$_REQUEST [ 'openid_mode' ] = 'id_res' ;
$tokens = '' ;
foreach ( explode ( ',' , $signed ) as $param ) {
$post = preg_replace ( '/\./' , '_' , $param );
$tokens .= sprintf ( " %s:%s \n " , $param , $_REQUEST [ 'openid_' . $post ]);
}
// Add the sreg stuff, if we've got it
if ( isset ( $sreg_required )) {
foreach ( explode ( ',' , $sreg_required ) as $key ) {
if ( ! isset ( $sreg [ $key ]))
continue ;
$skey = 'sreg.' . $key ;
$tokens .= sprintf ( " %s:%s \n " , $skey , $sreg [ $key ]);
$keys [ $skey ] = $sreg [ $key ];
$fields [] = $skey ;
}
}
// Look up the consumer's shared_secret and timeout
list ( $shared_secret , $expires ) = secret ( $assoc_handle );
// if I can't verify the assoc_handle, or if it's expired
if ( $shared_secret == false || ( is_numeric ( $expires ) && $expires < time ())) {
$keys [ 'is_valid' ] = 'false' ;
} else {
$ok = base64_encode ( hmac ( $shared_secret , $tokens ));
$keys [ 'is_valid' ] = ( $sig == $ok ) ? 'true' : 'false' ;
}
// Return the keys
wrap_kv ( $keys );
}
/**
* Handle a consumer ' s request to see if the end user is logged in
* @ global array $known
* @ global array $profile
* @ global array $sreg
*/
function checkid ( $wait ) {
global $known , $profile , $sreg ;
global $USERNAME ;
// This is a user session
user_session ();
// Get the options, use defaults as necessary
2011-07-28 18:12:07 +00:00
$return_to = isset ( $_REQUEST [ 'openid_return_to' ])
2011-06-23 15:04:32 +00:00
? $_REQUEST [ 'openid_return_to' ]
2011-07-28 18:12:07 +00:00
: error_400 ( 'Missing return_to' );
2011-06-23 15:04:32 +00:00
2011-07-28 18:12:07 +00:00
$identity = isset ( $_REQUEST [ 'openid_identity' ])
2011-06-23 15:04:32 +00:00
? $_REQUEST [ 'openid_identity' ]
: error_get ( $return_to , 'Missing identity' );
2011-07-28 18:12:07 +00:00
$assoc_handle = isset ( $_REQUEST [ 'openid_assoc_handle' ])
2011-07-19 22:53:55 +00:00
? $_REQUEST [ 'openid_assoc_handle' ]
2011-06-23 15:04:32 +00:00
: null ;
2011-07-28 18:12:07 +00:00
$trust_root = isset ( $_REQUEST [ 'openid_trust_root' ])
2011-06-23 15:04:32 +00:00
? $_REQUEST [ 'openid_trust_root' ]
: $return_to ;
2011-07-28 18:12:07 +00:00
$sreg_required = isset ( $_REQUEST [ 'openid_sreg_required' ])
2011-06-23 15:04:32 +00:00
? $_REQUEST [ 'openid_sreg.required' ]
: '' ;
2011-07-28 18:12:07 +00:00
$sreg_optional = isset ( $_REQUEST [ 'openid_sreg_optional' ])
2011-06-23 15:04:32 +00:00
? $_REQUEST [ 'openid_sreg.optional' ]
: '' ;
// determine the cancel url
$q = strpos ( $return_to , '?' ) ? '&' : '?' ;
$cancel_url = $return_to . $q . 'openid.mode=cancel' ;
// required and optional make no difference to us
$sreg_required .= ',' . $sreg_optional ;
// do the trust_root analysis
if ( $trust_root != $return_to ) {
// the urls are not the same, be sure return decends from trust
if ( ! url_descends ( $return_to , $trust_root ))
error_500 ( 'Invalid trust_root: "' . $trust_root . '"' );
}
// transfer the user to the url accept mode if they're paranoid
2011-06-24 20:07:26 +00:00
if ( $wait == 1 && isset ( $profile [ 'paranoid' ]) && $profile [ 'paranoid' ] === true && ( ! isset ( $_SESSION [ 'accepted_url' ]) || $_SESSION [ 'accepted_url' ] != $trust_root )) {
2011-06-23 15:04:32 +00:00
$_SESSION [ 'cancel_accept_url' ] = $cancel_url ;
$_SESSION [ 'post_accept_url' ] = $profile [ 'req_url' ];
$_SESSION [ 'unaccepted_url' ] = $trust_root ;
debug ( 'Transferring to acceptance mode.' );
debug ( 'Cancel URL: ' . $_SESSION [ 'cancel_accept_url' ]);
debug ( 'Post URL: ' . $_SESSION [ 'post_accept_url' ]);
$q = strpos ( $profile [ 'idp_url' ], '?' ) ? '&' : '?' ;
wrap_redirect ( $profile [ 'idp_url' ] . $q . 'openid.mode=accept' );
}
// make sure i am this identifier
2011-06-24 20:07:26 +00:00
// if ($identity != $profile['idp_url']) {
// debug("Invalid identity: $identity");
// debug("IdP URL: " . $profile['idp_url']);
// error_get($return_to, "Invalid identity: '$identity'");
// }
2011-06-23 15:04:32 +00:00
// begin setting up return keys
$keys = array (
'mode' => 'id_res'
);
// if the user is not logged in, transfer to the authorization mode
2011-06-24 20:07:26 +00:00
if ( $USERNAME == '' || $_SESSION [ 'openid_auth' ] === false || $USERNAME != $_SESSION [ 'openid_user' ]) {
2011-06-23 15:04:32 +00:00
// users can only be logged in to one url at a time
2011-06-24 20:07:26 +00:00
$_SESSION [ 'openid_user' ] = null ;
2011-06-23 15:04:32 +00:00
$_SESSION [ 'auth_url' ] = null ;
if ( $wait ) {
unset ( $_SESSION [ 'uniqid' ]);
$_SESSION [ 'cancel_auth_url' ] = $cancel_url ;
$_SESSION [ 'post_auth_url' ] = $profile [ 'req_url' ];
debug ( 'Transferring to authorization mode.' );
debug ( 'Cancel URL: ' . $_SESSION [ 'cancel_auth_url' ]);
debug ( 'Post URL: ' . $_SESSION [ 'post_auth_url' ]);
$q = strpos ( $profile [ 'idp_url' ], '?' ) ? '&' : '?' ;
wrap_redirect ( $profile [ 'idp_url' ] . $q . 'openid.mode=authorize' );
} else {
$keys [ 'user_setup_url' ] = $profile [ 'idp_url' ];
}
// the user is logged in
} else {
// remove the refresh URLs if set
unset ( $_SESSION [ 'cancel_auth_url' ]);
unset ( $_SESSION [ 'post_auth_url' ]);
// check the assoc handle
list ( $shared_secret , $expires ) = secret ( $assoc_handle );
// if I can't verify the assoc_handle, or if it's expired
if ( $shared_secret == false || ( is_numeric ( $expires ) && $expires < time ())) {
debug ( " Session expired or missing key: $expires < " . time ());
if ( $assoc_handle != null ) {
$keys [ 'invalidate_handle' ] = $assoc_handle ;
destroy_assoc_handle ( $assoc_handle );
}
$lifetime = time () + $profile [ 'lifetime' ];
list ( $assoc_handle , $shared_secret ) = new_assoc ( $lifetime );
}
$keys [ 'identity' ] = $profile [ 'idp_url' ];
$keys [ 'assoc_handle' ] = $assoc_handle ;
$keys [ 'return_to' ] = $return_to ;
$fields = array_keys ( $keys );
$tokens = '' ;
foreach ( $fields as $key )
$tokens .= sprintf ( " %s:%s \n " , $key , $keys [ $key ]);
// add sreg keys
foreach ( explode ( ',' , $sreg_required ) as $key ) {
if ( ! isset ( $sreg [ $key ]))
continue ;
$skey = 'sreg.' . $key ;
$tokens .= sprintf ( " %s:%s \n " , $skey , $sreg [ $key ]);
$keys [ $skey ] = $sreg [ $key ];
$fields [] = $skey ;
}
$keys [ 'signed' ] = implode ( ',' , $fields );
$keys [ 'sig' ] = base64_encode ( hmac ( $shared_secret , $tokens ));
}
wrap_keyed_redirect ( $return_to , $keys );
}
/**
* Handle a consumer ' s request to see if the user is already logged in
*/
function checkid_immediate_mode () {
if ( ! isset ( $_REQUEST [ 'openid_mode' ]) || $_REQUEST [ 'openid_mode' ] != 'checkid_immediate' )
error_500 ();
checkid ( false );
}
/**
* Handle a consumer ' s request to see if the user is logged in , but be willing
* to wait for them to perform a login if they ' re not
*/
function checkid_setup_mode () {
if ( ! isset ( $_REQUEST [ 'openid_mode' ]) || $_REQUEST [ 'openid_mode' ] != 'checkid_setup' )
error_500 ();
checkid ( true );
}
/**
* Handle errors
*/
function error_mode () {
isset ( $_REQUEST [ 'openid_error' ])
? wrap_html ( $_REQUEST [ 'openid_error' ])
: error_500 ();
}
/**
* Show a user if they are logged in or not
* @ global array $profile
*/
function id_res_mode () {
global $profile ;
user_session ();
if ( $profile [ 'authorized' ])
wrap_html ( 'You are logged in as ' . $_SESSION [ 'auth_username' ]);
wrap_html ( 'You are not logged in' );
}
/**
* Allow a user to perform a static login
* @ global array $profile
*/
function login_mode () {
global $profile ;
user_session ();
if ( $profile [ 'authorized' ])
id_res_mode ();
$keys = array (
'mode' => 'checkid_setup' ,
'identity' => $profile [ 'idp_url' ],
'return_to' => $profile [ 'idp_url' ]
);
wrap_keyed_redirect ( $profile [ 'idp_url' ], $keys );
}
/**
* Allow a user to perform a static logout
* @ global array $profile
*/
function logout_mode () {
global $profile ;
user_session ();
if ( ! $profile [ 'authorized' ])
wrap_html ( 'You were not logged in' );
$_SESSION = array ();
session_destroy ();
debug ( 'User session destroyed.' );
header ( 'HTTP/1.0 401 Unauthorized' );
wrap_redirect ( $profile [ 'idp_url' ]);
}
/**
* The default information screen
* @ global array $profile
*/
function no_mode () {
2011-06-24 16:02:51 +00:00
global $USERNAME , $profile ;
2011-07-29 19:36:03 +00:00
$tmpl = new OC_Template ( 'user_openid' , 'nomode' , 'guest' );
2011-06-24 20:07:26 +00:00
if ( substr ( $profile [ 'req_url' ], - 1 , 1 ) !== '/' ){ //the identity should always end with a /
$profile [ 'req_url' ] .= '/' ;
}
2011-06-24 16:02:51 +00:00
$tmpl -> addHeader ( 'link' , array ( 'rel' => 'openid.server' , 'href' => $profile [ 'req_url' ]));
$tmpl -> addHeader ( 'link' , array ( 'rel' => 'openid.delegate' , 'href' => $profile [ 'idp_url' ]));
2011-06-24 15:06:02 +00:00
$tmpl -> assign ( 'user' , $USERNAME );
2011-06-23 22:24:45 +00:00
$tmpl -> printPage ();
2011-06-23 15:04:32 +00:00
}
/**
* Testing for setup
* @ global array $profile
*/
function test_mode () {
global $profile , $p , $g ;
if ( $profile [ 'allow_test' ] != true )
error_403 ();
@ ini_set ( 'max_execution_time' , 180 );
$test_expire = time () + 120 ;
$test_ss_enc = 'W7hvmld2yEYdDb0fHfSkKhQX+PM=' ;
$test_ss = base64_decode ( $test_ss_enc );
$test_token = " alpha:bravo \n charlie:delta \n echo:foxtrot " ;
$test_server_private = '11263846781670293092494395517924811173145217135753406847875706165886322533899689335716152496005807017390233667003995430954419468996805220211293016296351031812246187748601293733816011832462964410766956326501185504714561648498549481477143603650090931135412673422192550825523386522507656442905243832471167330268' ;
$test_client_public = base64_decode ( 'AL63zqI5a5p8HdXZF5hFu8p+P9GOb816HcHuvNOhqrgkKdA3fO4XEzmldlb37nv3+xqMBgWj6gxT7vfuFerEZLBvuWyVvR7IOGZmx0BAByoq3fxYd3Fpe2Coxngs015vK37otmH8e83YyyGo5Qua/NAf13yz1PVuJ5Ctk7E+YdVc' );
$res = array ();
// bcmath
$res [ 'bcmath' ] = extension_loaded ( 'bcmath' )
? 'pass' : 'warn - not loaded' ;
// gmp
if ( $profile [ 'allow_gmp' ]) {
$res [ 'gmp' ] = extension_loaded ( 'gmp' )
? 'pass' : 'warn - not loaded' ;
} else {
$res [ 'gmp' ] = 'pass - n/a' ;
}
// sys_get_temp_dir
$res [ 'logfile' ] = is_writable ( $profile [ 'logfile' ])
? 'pass' : " warn - log is not writable " ;
// session & new_assoc
user_session ();
list ( $test_assoc , $test_new_ss ) = new_assoc ( $test_expire );
$res [ 'session' ] = ( $test_assoc != session_id ())
? 'pass' : 'fail' ;
// secret
@ session_unregister ( 'shared_secret' );
list ( $check , $check2 ) = secret ( $test_assoc );
$res [ 'secret' ] = ( $check == $test_new_ss )
? 'pass' : 'fail' ;
// expire
$res [ 'expire' ] = ( $check2 <= $test_expire )
? 'pass' : 'fail' ;
// base64
$res [ 'base64' ] = ( base64_encode ( $test_ss ) == $test_ss_enc )
? 'pass' : 'fail' ;
// hmac
$test_sig = base64_decode ( '/VXgHvZAOdoz/OTa5+XJXzSGhjs=' );
$check = hmac ( $test_ss , $test_token );
$res [ 'hmac' ] = ( $check == $test_sig )
? 'pass' : sprintf ( " fail - '%s' " , base64_encode ( $check ));
if ( $profile [ 'use_bigmath' ]) {
// bigmath powmod
$test_server_public = '102773334773637418574009974502372885384288396853657336911033649141556441102566075470916498748591002884433213640712303846640842555822818660704173387461364443541327856226098159843042567251113889701110175072389560896826887426539315893475252988846151505416694218615764823146765717947374855806613410142231092856731' ;
$check = bmpowmod ( $g , $test_server_private , $p );
$res [ 'bmpowmod-1' ] = ( $check == $test_server_public )
? 'pass' : sprintf ( " fail - '%s' " , $check );
// long
$test_client_long = '133926731803116519408547886573524294471756220428015419404483437186057383311250738749035616354107518232016420809434801736658109316293127101479053449990587221774635063166689561125137927607200322073086097478667514042144489248048756916881344442393090205172004842481037581607299263456852036730858519133859409417564' ;
$res [ 'long' ] = ( long ( $test_client_public ) == $test_client_long )
? 'pass' : 'fail' ;
// bigmath powmod 2
$test_client_share = '19333275433742428703546496981182797556056709274486796259858099992516081822015362253491867310832140733686713353304595602619444380387600756677924791671971324290032515367930532292542300647858206600215875069588627551090223949962823532134061941805446571307168890255137575975911397744471376862555181588554632928402' ;
$check = bmpowmod ( $test_client_long , $test_server_private , $p );
$res [ 'bmpowmod-2' ] = ( $check == $test_client_share )
? 'pass' : sprintf ( " fail - '%s' " , $check );
// bin
$test_client_mac_s1 = base64_decode ( 'G4gQQkYM6QmAzhKbVKSBahFesPL0nL3F2MREVwEtnVRRYI0ifl9zmPklwTcvURt3QTiGBd+9Dn3ESLk5qka6IO5xnILcIoBT8nnGVPiOZvTygfuzKp4tQ2mXuIATJoa7oXRGmBWtlSdFapH5Zt6NJj4B83XF/jzZiRwdYuK4HJI=' );
$check = bin ( $test_client_share );
$res [ 'bin' ] = ( $check == $test_client_mac_s1 )
? 'pass' : sprintf ( " fail - '%s' " , base64_encode ( $check ));
} else {
$res [ 'bigmath' ] = 'fail - big math functions are not available.' ;
}
// sha1_20
$test_client_mac_s1 = base64_decode ( 'G4gQQkYM6QmAzhKbVKSBahFesPL0nL3F2MREVwEtnVRRYI0ifl9zmPklwTcvURt3QTiGBd+9Dn3ESLk5qka6IO5xnILcIoBT8nnGVPiOZvTygfuzKp4tQ2mXuIATJoa7oXRGmBWtlSdFapH5Zt6NJj4B83XF/jzZiRwdYuK4HJI=' );
$test_client_mac_s2 = base64_decode ( '0Mb2t9d/HvAZyuhbARJPYdx3+v4=' );
$check = sha1_20 ( $test_client_mac_s1 );
$res [ 'sha1_20' ] = ( $check == $test_client_mac_s2 )
? 'pass' : sprintf ( " fail - '%s' " , base64_encode ( $check ));
// x_or
$test_client_mac_s3 = base64_decode ( 'i36ZLYAJ1rYEx1VEHObrS8hgAg0=' );
$check = x_or ( $test_client_mac_s2 , $test_ss );
$res [ 'x_or' ] = ( $check == $test_client_mac_s3 )
? 'pass' : sprintf ( " fail - '%s' " , base64_encode ( $check ));
$out = " <table border=1 cellpadding=4> \n " ;
foreach ( $res as $test => $stat ) {
$code = substr ( $stat , 0 , 4 );
$color = ( $code == 'pass' ) ? '#9f9'
: (( $code == 'warn' ) ? '#ff9' : '#f99' );
$out .= sprintf ( " <tr><th>%s</th><td style='background:%s'>%s</td></tr> \n " , $test , $color , $stat );
}
$out .= " </table> " ;
wrap_html ( $out );
}
// Support functions
/**
* Prefix the keys of an array with 'openid.'
* @ param array $array
* @ return array
*/
function append_openid ( $array ) {
$keys = array_keys ( $array );
$vals = array_values ( $array );
$r = array ();
for ( $i = 0 ; $i < sizeof ( $keys ); $i ++ )
$r [ 'openid.' . $keys [ $i ]] = $vals [ $i ];
return $r ;
}
/**
* Create a big math addition function
* @ param string $l
* @ param string $r
* @ return string
* @ url http :// www . icosaedro . it / bigint Inspired by
*/
function bmadd ( $l , $r ) {
if ( function_exists ( 'bcadd' ))
return bcadd ( $l , $r );
global $profile ;
if ( $profile [ 'use_gmp' ])
return gmp_strval ( gmp_add ( $l , $r ));
$l = strval ( $l ); $r = strval ( $r );
$ll = strlen ( $l ); $rl = strlen ( $r );
if ( $ll < $rl ) {
$l = str_repeat ( " 0 " , $rl - $ll ) . $l ;
$o = $rl ;
} elseif ( $ll > $rl ) {
$r = str_repeat ( " 0 " , $ll - $rl ) . $r ;
$o = $ll ;
} else {
$o = $ll ;
}
$v = '' ;
$carry = 0 ;
for ( $i = $o - 1 ; $i >= 0 ; $i -- ) {
$d = ( int ) $l [ $i ] + ( int ) $r [ $i ] + $carry ;
if ( $d <= 9 ) {
$carry = 0 ;
} else {
$carry = 1 ;
$d -= 10 ;
}
$v = ( string ) $d . $v ;
}
if ( $carry > 0 )
$v = " 1 " . $v ;
return $v ;
}
/**
* Create a big math comparison function
* @ param string $l
* @ param string $r
* @ return string
*/
function bmcomp ( $l , $r ) {
if ( function_exists ( 'bccomp' ))
return bccomp ( $l , $r );
global $profile ;
if ( $profile [ 'use_gmp' ])
return gmp_strval ( gmp_cmp ( $l , $r ));
$l = strval ( $l ); $r = strval ( $r );
$ll = strlen ( $l ); $lr = strlen ( $r );
if ( $ll != $lr )
return ( $ll > $lr ) ? 1 : - 1 ;
return strcmp ( $l , $r );
}
/**
* Create a big math division function
* @ param string $l
* @ param string $r
* @ param int $z
* @ return string
* @ url http :// www . icosaedro . it / bigint Inspired by
*/
function bmdiv ( $l , $r , $z = 0 ) {
if ( function_exists ( 'bcdiv' ))
return ( $z == 0 ) ? bcdiv ( $l , $r ) : bcmod ( $l , $r );
global $profile ;
if ( $profile [ 'use_gmp' ])
return gmp_strval (( $z == 0 ) ? gmp_div_q ( $l , $r ) : gmp_mod ( $l , $r ));
$l = strval ( $l ); $r = strval ( $r );
$v = '0' ;
while ( true ) {
if ( bmcomp ( $l , $r ) < 0 )
break ;
$delta = strlen ( $l ) - strlen ( $r );
if ( $delta >= 1 ) {
$zeroes = str_repeat ( " 0 " , $delta );
$r2 = $r . $zeroes ;
if ( strcmp ( $l , $r2 ) >= 0 ) {
$v = bmadd ( $v , " 1 " . $zeroes );
$l = bmsub ( $l , $r2 );
} else {
$zeroes = str_repeat ( " 0 " , $delta - 1 );
$v = bmadd ( $v , " 1 " . $zeroes );
$l = bmsub ( $l , $r . $zeroes );
}
} else {
$l = bmsub ( $l , $r );
$v = bmadd ( $v , " 1 " );
}
}
return ( $z == 0 ) ? $v : $l ;
}
/**
* Create a big math multiplication function
* @ param string $l
* @ param string $r
* @ return string
* @ url http :// www . icosaedro . it / bigint Inspired by
*/
function bmmul ( $l , $r ) {
if ( function_exists ( 'bcmul' ))
return bcmul ( $l , $r );
global $profile ;
if ( $profile [ 'use_gmp' ])
return gmp_strval ( gmp_mul ( $l , $r ));
$l = strval ( $l ); $r = strval ( $r );
$v = '0' ;
$z = '' ;
for ( $i = strlen ( $r ) - 1 ; $i >= 0 ; $i -- ){
$bd = ( int ) $r [ $i ];
$carry = 0 ;
$p = " " ;
for ( $j = strlen ( $l ) - 1 ; $j >= 0 ; $j -- ){
$ad = ( int ) $l [ $j ];
$pd = $ad * $bd + $carry ;
if ( $pd <= 9 ){
$carry = 0 ;
} else {
$carry = ( int ) ( $pd / 10 );
$pd = $pd % 10 ;
}
$p = ( string ) $pd . $p ;
}
if ( $carry > 0 )
$p = ( string ) $carry . $p ;
$p = $p . $z ;
$z .= " 0 " ;
$v = bmadd ( $v , $p );
}
return $v ;
}
/**
* Create a big math modulus function
* @ param string $value
* @ param string $mod
* @ return string
*/
function bmmod ( $value , $mod ) {
if ( function_exists ( 'bcmod' ))
return bcmod ( $value , $mod );
global $profile ;
if ( $profile [ 'use_gmp' ])
return gmp_strval ( gmp_mod ( $value , $mod ));
$r = bmdiv ( $value , $mod , 1 );
return $r ;
}
/**
* Create a big math power function
* @ param string $value
* @ param string $exponent
* @ return string
*/
function bmpow ( $value , $exponent ) {
if ( function_exists ( 'bcpow' ))
return bcpow ( $value , $exponent );
global $profile ;
if ( $profile [ 'use_gmp' ])
return gmp_strval ( gmp_pow ( $value , $exponent ));
$r = '1' ;
while ( $exponent ) {
$r = bmmul ( $r , $value , 100 );
$exponent -- ;
}
return ( string ) rtrim ( $r , '0.' );
}
/**
* Create a big math 'powmod' function
* @ param string $value
* @ param string $exponent
* @ param string $mod
* @ return string
* @ url http :// php . net / manual / en / function . bcpowmod . php #72704 Borrowed from
*/
function bmpowmod ( $value , $exponent , $mod ) {
if ( function_exists ( 'bcpowmod' ))
return bcpowmod ( $value , $exponent , $mod );
global $profile ;
if ( $profile [ 'use_gmp' ])
return gmp_strval ( gmp_powm ( $value , $exponent , $mod ));
$r = '' ;
while ( $exponent != '0' ) {
$t = bmmod ( $exponent , '4096' );
$r = substr ( " 000000000000 " . decbin ( intval ( $t )), - 12 ) . $r ;
$exponent = bmdiv ( $exponent , '4096' );
}
$r = preg_replace ( " !^0+! " , " " , $r );
if ( $r == '' )
$r = '0' ;
$value = bmmod ( $value , $mod );
$erb = strrev ( $r );
$q = '1' ;
$a [ 0 ] = $value ;
for ( $i = 1 ; $i < strlen ( $erb ); $i ++ ) {
$a [ $i ] = bmmod ( bmmul ( $a [ $i - 1 ], $a [ $i - 1 ]), $mod );
}
for ( $i = 0 ; $i < strlen ( $erb ); $i ++ ) {
if ( $erb [ $i ] == " 1 " ) {
$q = bmmod ( bmmul ( $q , $a [ $i ]), $mod );
}
}
return ( $q );
}
/**
* Create a big math subtraction function
* @ param string $l
* @ param string $r
* @ return string
* @ url http :// www . icosaedro . it / bigint Inspired by
*/
function bmsub ( $l , $r ) {
if ( function_exists ( 'bcsub' ))
return bcsub ( $l , $r );
global $profile ;
if ( $profile [ 'use_gmp' ])
return gmp_strval ( gmp_sub ( $l , $r ));
$l = strval ( $l ); $r = strval ( $r );
$ll = strlen ( $l ); $rl = strlen ( $r );
if ( $ll < $rl ) {
$l = str_repeat ( " 0 " , $rl - $ll ) . $l ;
$o = $rl ;
} elseif ( $ll > $rl ) {
$r = str_repeat ( " 0 " , $ll - $rl ) . ( string ) $r ;
$o = $ll ;
} else {
$o = $ll ;
}
if ( strcmp ( $l , $r ) >= 0 ) {
$sign = '' ;
} else {
$x = $l ; $l = $r ; $r = $x ;
$sign = '-' ;
}
$v = '' ;
$carry = 0 ;
for ( $i = $o - 1 ; $i >= 0 ; $i -- ) {
$d = ( $l [ $i ] - $r [ $i ]) - $carry ;
if ( $d < 0 ) {
$carry = 1 ;
$d += 10 ;
} else {
$carry = 0 ;
}
$v = ( string ) $d . $v ;
}
return $sign . ltrim ( $v , '0' );
}
/**
* Get a binary value
* @ param integer $n
* @ return string
* @ url http :// openidenabled . com Borrowed from PHP - OpenID
*/
function bin ( $n ) {
$bytes = array ();
while ( bmcomp ( $n , 0 ) > 0 ) {
array_unshift ( $bytes , bmmod ( $n , 256 ));
$n = bmdiv ( $n , bmpow ( 2 , 8 ));
}
if ( $bytes && ( $bytes [ 0 ] > 127 ))
array_unshift ( $bytes , 0 );
$b = '' ;
foreach ( $bytes as $byte )
$b .= pack ( 'C' , $byte );
return $b ;
}
/**
* Debug logging
* @ param mixed $x
* @ param string $m
*/
function debug ( $x , $m = null ) {
global $profile ;
if ( ! isset ( $profile [ 'debug' ]) || $profile [ 'debug' ] === false )
return true ;
if ( ! is_writable ( dirname ( $profile [ 'logfile' ])) &! is_writable ( $profile [ 'logfile' ]))
error_500 ( 'Cannot write to debug log: ' . $profile [ 'logfile' ]);
if ( is_array ( $x )) {
ob_start ();
print_r ( $x );
$x = $m . ( $m != null ? " \n " : '' ) . ob_get_clean ();
} else {
$x .= " \n " ;
}
}
/**
* Destroy a consumer ' s assoc handle
* @ param string $id
*/
function destroy_assoc_handle ( $id ) {
debug ( " Destroying session: $id " );
$sid = session_id ();
session_write_close ();
session_id ( $id );
2011-09-23 11:52:10 +00:00
if ( OC_Config :: getValue ( " forcessl " , false )) {
ini_set ( " session.cookie_secure " , " on " );
}
2011-06-23 15:04:32 +00:00
session_start ();
session_destroy ();
session_id ( $sid );
session_start ();
}
/**
* Return an error message to the user
* @ param string $message
*/
function error_400 ( $message = 'Bad Request' ) {
header ( " HTTP/1.1 400 Bad Request " );
wrap_html ( $message );
}
/**
* Return an error message to the user
* @ param string $message
*/
function error_403 ( $message = 'Forbidden' ) {
header ( " HTTP/1.1 403 Forbidden " );
wrap_html ( $message );
}
/**
* Return an error message to the user
* @ param string $message
*/
function error_500 ( $message = 'Internal Server Error' ) {
header ( " HTTP/1.1 500 Internal Server Error " );
wrap_html ( $message );
}
/**
* Return an error message to the consumer
* @ param string $message
*/
function error_get ( $url , $message = 'Bad Request' ) {
wrap_keyed_redirect ( $url , array ( 'mode' => 'error' , 'error' => $message ));
}
/**
* Return an error message to the consumer
* @ param string $message
*/
function error_post ( $message = 'Bad Request' ) {
header ( " HTTP/1.1 400 Bad Request " );
echo ( 'error:' . $message );
exit ( 0 );
}
/**
* Do an HMAC
* @ param string $key
* @ param string $data
* @ param string $hash
* @ return string
* @ url http :// php . net / manual / en / function . sha1 . php #39492 Borrowed from
*/
function hmac ( $key , $data , $hash = 'sha1_20' ) {
$blocksize = 64 ;
if ( strlen ( $key ) > $blocksize )
$key = $hash ( $key );
$key = str_pad ( $key , $blocksize , chr ( 0x00 ));
$ipad = str_repeat ( chr ( 0x36 ), $blocksize );
$opad = str_repeat ( chr ( 0x5c ), $blocksize );
$h1 = $hash (( $key ^ $ipad ) . $data );
$hmac = $hash (( $key ^ $opad ) . $h1 );
return $hmac ;
}
if ( ! function_exists ( 'http_build_query' )) {
/**
* Create function if missing
* @ param array $array
* @ return string
*/
function http_build_query ( $array ) {
$r = array ();
foreach ( $array as $key => $val )
$r [] = sprintf ( '%s=%s' , urlencode ( $key ), urlencode ( $val ));
return implode ( '&' , $r );
}}
/**
* Turn a binary back into a long
* @ param string $b
* @ return integer
* @ url http :// openidenabled . com Borrowed from PHP - OpenID
*/
function long ( $b ) {
$bytes = array_merge ( unpack ( 'C*' , $b ));
$n = 0 ;
foreach ( $bytes as $byte ) {
$n = bmmul ( $n , bmpow ( 2 , 8 ));
$n = bmadd ( $n , $byte );
}
return $n ;
}
/**
* Create a new consumer association
* @ param integer $expiration
* @ return array
*/
function new_assoc ( $expiration ) {
if ( isset ( $_SESSION ) && is_array ( $_SESSION )) {
$sid = session_id ();
$dat = session_encode ();
session_write_close ();
}
2011-09-23 11:52:10 +00:00
if ( OC_Config :: getValue ( " forcessl " , false )) {
ini_set ( " session.cookie_secure " , " on " );
}
2011-06-23 15:04:32 +00:00
session_start ();
session_regenerate_id ( 'false' );
$id = session_id ();
$shared_secret = new_secret ();
debug ( 'Started new assoc session: ' . $id );
$_SESSION = array ();
$_SESSION [ 'expiration' ] = $expiration ;
$_SESSION [ 'shared_secret' ] = base64_encode ( $shared_secret );
session_write_close ();
if ( isset ( $sid )) {
session_id ( $sid );
session_start ();
$_SESSION = array ();
session_decode ( $dat );
}
return array ( $id , $shared_secret );
}
/**
* Create a new shared secret
* @ return string
*/
function new_secret () {
$r = '' ;
for ( $i = 0 ; $i < 20 ; $i ++ )
$r .= chr ( mt_rand ( 0 , 255 ));
debug ( " Generated new key: hash = ' " . md5 ( $r ) . " ', length = ' " . strlen ( $r ) . " ' " );
return $r ;
}
/**
* Random number generation
* @ param integer max
* @ return integer
*/
function random ( $max ) {
if ( strlen ( $max ) < 4 )
return mt_rand ( 1 , $max - 1 );
$r = '' ;
for ( $i = 1 ; $i < strlen ( $max ) - 1 ; $i ++ )
$r .= mt_rand ( 0 , 9 );
$r .= mt_rand ( 1 , 9 );
return $r ;
}
/**
* Get the shared secret and expiration time for the specified assoc_handle
* @ param string $handle assoc_handle to look up
* @ return array ( shared_secret , expiration_time )
*/
function secret ( $handle ) {
if ( ! preg_match ( '/^\w+$/' , $handle ))
return array ( false , 0 );
if ( isset ( $_SESSION ) && is_array ( $_SESSION )) {
$sid = session_id ();
$dat = session_encode ();
session_write_close ();
}
session_id ( $handle );
2011-09-23 11:52:10 +00:00
if ( OC_Config :: getValue ( " forcessl " , false )) {
ini_set ( " session.cookie_secure " , " on " );
}
2011-06-23 15:04:32 +00:00
session_start ();
debug ( 'Started session to acquire key: ' . session_id ());
2011-06-24 20:07:26 +00:00
$secret = isset ( $_SESSION [ 'shared_secret' ])
2011-06-23 15:04:32 +00:00
? base64_decode ( $_SESSION [ 'shared_secret' ])
: false ;
2011-06-24 20:07:26 +00:00
$expiration = isset ( $_SESSION [ 'expiration' ])
2011-06-23 15:04:32 +00:00
? $_SESSION [ 'expiration' ]
: null ;
session_write_close ();
if ( isset ( $sid )) {
session_id ( $sid );
session_start ();
$_SESSION = array ();
session_decode ( $dat );
}
debug ( " Found key: hash = ' " . md5 ( $secret ) . " ', length = ' " . strlen ( $secret ) . " ', expiration = ' $expiration ' " );
return array ( $secret , $expiration );
}
/**
* Do an internal self check
* @ global array $profile
* @ global array $sreg
*/
function self_check () {
global $profile , $sreg ;
// if (! isset($profile) || ! is_array($profile))
// error_500('No configuration found, you shouldn\'t access this file directly.');
if ( version_compare ( phpversion (), '4.2.0' , 'lt' ))
error_500 ( 'The required minimum version of PHP is 4.2.0, you are running ' . phpversion ());
$extension_r = array ( 'session' , 'pcre' );
foreach ( $extension_r as $x ) {
if ( ! extension_loaded ( $x ))
@ dl ( $x );
if ( ! extension_loaded ( $x ))
error_500 ( " Required extension ' $x ' is missing. " );
}
// $extension_b = array('suhosin');
// foreach ($extension_b as $x) {
// if (extension_loaded($x) &! $profile["allow_$x"])
// error_500("phpMyID is not compatible with '$x'");
// }
//
// $keys = array('auth_username', 'auth_password');
// foreach ($keys as $key) {
// if (! array_key_exists($key, $profile))
// error_500("'$key' is missing from your profile.");
// }
if ( ! isset ( $sreg ) || ! is_array ( $sreg ))
$sreg = array ();
}
/**
* Do SHA1 20 byte encryption
* @ param string $v
* @ return string
* @ url http :// openidenabled . com Borrowed from PHP - OpenID
*/
function sha1_20 ( $v ) {
if ( version_compare ( phpversion (), '5.0.0' , 'ge' ))
return sha1 ( $v , true );
$hex = sha1 ( $v );
$r = '' ;
for ( $i = 0 ; $i < 40 ; $i += 2 ) {
$hexcode = substr ( $hex , $i , 2 );
$charcode = base_convert ( $hexcode , 16 , 10 );
$r .= chr ( $charcode );
}
return $r ;
}
/**
* Look for the point of differentiation in two strings
* @ param string $a
* @ param string $b
* @ return int
*/
function str_diff_at ( $a , $b ) {
if ( $a == $b )
return - 1 ;
$n = min ( strlen ( $a ), strlen ( $b ));
for ( $i = 0 ; $i < $n ; $i ++ )
if ( $a [ $i ] != $b [ $i ])
return $i ;
return $n ;
}
if ( ! function_exists ( 'sys_get_temp_dir' ) && ini_get ( 'open_basedir' ) == false ) {
/**
* Create function if missing
* @ return string
*/
function sys_get_temp_dir () {
$keys = array ( 'TMP' , 'TMPDIR' , 'TEMP' );
foreach ( $keys as $key ) {
if ( isset ( $_ENV [ $key ]) && is_dir ( $_ENV [ $key ]) && is_writable ( $_ENV [ $key ]))
return realpath ( $_ENV [ $key ]);
}
$tmp = tempnam ( false , null );
if ( file_exists ( $tmp )) {
$dir = realpath ( dirname ( $tmp ));
unlink ( $tmp );
return realpath ( $dir );
}
return realpath ( dirname ( __FILE__ ));
}} elseif ( ! function_exists ( 'sys_get_temp_dir' )) {
function sys_get_temp_dir () {
return realpath ( dirname ( __FILE__ ));
}}
/**
* Determine if a child URL actually decends from the parent , and that the
* parent is a good URL .
* THIS IS EXPERIMENTAL
* @ param string $parent
* @ param string $child
* @ return bool
*/
function url_descends ( $child , $parent ) {
if ( $child == $parent )
return true ;
$keys = array ();
$parts = array ();
$req = array ( 'scheme' , 'host' );
$bad = array ( 'fragment' , 'pass' , 'user' );
foreach ( array ( 'parent' , 'child' ) as $name ) {
$parts [ $name ] = @ parse_url ( $$name );
if ( $parts [ $name ] === false )
return false ;
$keys [ $name ] = array_keys ( $parts [ $name ]);
if ( array_intersect ( $keys [ $name ], $req ) != $req )
return false ;
if ( array_intersect ( $keys [ $name ], $bad ) != array ())
return false ;
if ( ! preg_match ( '/^https?$/i' , strtolower ( $parts [ $name ][ 'scheme' ])))
return false ;
if ( ! array_key_exists ( 'port' , $parts [ $name ]))
$parts [ $name ][ 'port' ] = ( strtolower ( $parts [ $name ][ 'scheme' ]) == 'https' ) ? 443 : 80 ;
if ( ! array_key_exists ( 'path' , $parts [ $name ]))
$parts [ $name ][ 'path' ] = '/' ;
}
// port and scheme must match
if ( $parts [ 'parent' ][ 'scheme' ] != $parts [ 'child' ][ 'scheme' ] ||
$parts [ 'parent' ][ 'port' ] != $parts [ 'child' ][ 'port' ])
return false ;
// compare the hosts by reversing the strings
$cr_host = strtolower ( strrev ( $parts [ 'child' ][ 'host' ]));
$pr_host = strtolower ( strrev ( $parts [ 'parent' ][ 'host' ]));
$break = str_diff_at ( $cr_host , $pr_host );
if ( $break >= 0 && ( $pr_host [ $break ] != '*' || substr_count ( substr ( $pr_host , 0 , $break ), '.' ) < 2 ))
return false ;
// now compare the paths
$break = str_diff_at ( $parts [ 'child' ][ 'path' ], $parts [ 'parent' ][ 'path' ]);
if ( $break >= 0
&& ( $break < strlen ( $parts [ 'parent' ][ 'path' ]) && $parts [ 'parent' ][ 'path' ][ $break ] != '*' )
|| ( $break > strlen ( $parts [ 'child' ][ 'path' ])))
return false ;
return true ;
}
/**
* Create a user session
* @ global array $profile
* @ global array $proto
*/
function user_session () {
global $proto , $profile ;
session_name ( 'phpMyID_Server' );
2011-09-23 11:52:10 +00:00
if ( OC_Config :: getValue ( " forcessl " , false )) {
ini_set ( " session.cookie_secure " , " on " );
}
2011-06-23 15:04:32 +00:00
@ session_start ();
$profile [ 'authorized' ] = ( isset ( $_SESSION [ 'auth_username' ])
&& $_SESSION [ 'auth_username' ] == $profile [ 'auth_username' ])
? true
: false ;
debug ( 'Started user session: ' . session_id () . ' Auth? ' . $profile [ 'authorized' ]);
}
/**
* Return HTML
* @ global string $charset
* @ param string $message
*/
function wrap_html ( $message ) {
global $charset , $profile ;
header ( 'Content-Type: text/html; charset=' . $charset );
$html = ' <! DOCTYPE html PUBLIC " -//W3C//DTD XHTML 1.0 Strict//EN " " http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd " >
< html >
< head >
< title > phpMyID </ title >
< link rel = " openid.server " href = " ' . $profile['req_url'] . ' " />
< link rel = " openid.delegate " href = " ' . $profile['idp_url'] . ' " />
' . implode("\n", $profile[' opt_headers ']) . '
< meta name = " charset " content = " ' . $charset . ' " />
< meta name = " robots " content = " noindex,nofollow " />
</ head >
< body >
< p > ' . $message . ' </ p >
</ body >
</ html >
' ;
echo $html ;
exit ( 0 );
}
/**
* Return a key - value pair in plain text
* @ global string $charset
* @ param array $keys
*/
function wrap_kv ( $keys ) {
global $charset ;
debug ( $keys , 'Wrapped key/vals' );
header ( 'Content-Type: text/plain; charset=' . $charset );
foreach ( $keys as $key => $value )
printf ( " %s:%s \n " , $key , $value );
exit ( 0 );
}
/**
* Redirect , with OpenID keys
* @ param string $url
* @ param array @ keys
*/
function wrap_keyed_redirect ( $url , $keys ) {
$keys = append_openid ( $keys );
debug ( $keys , 'Location keys' );
$q = strpos ( $url , '?' ) ? '&' : '?' ;
wrap_redirect ( $url . $q . http_build_query ( $keys ));
}
/**
* Redirect the browser
* @ global string $charset
* @ param string $url
*/
function wrap_redirect ( $url ) {
header ( 'HTTP/1.1 302 Found' );
header ( 'Location: ' . $url );
debug ( 'Location: ' . $url );
exit ( 0 );
}
/**
* Return an HTML refresh
* @ global string $charset
* @ param string $url
*/
function wrap_refresh ( $url ) {
global $charset ;
header ( 'Content-Type: text/html; charset=' . $charset );
echo ' <! DOCTYPE html PUBLIC " -//W3C//DTD XHTML 1.0 Strict//EN " " http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd " >
< html >
< head >
< title > phpMyID </ title >
< meta http - equiv = " refresh " content = " 0;url=' . $url . ' " >
</ head >
< body >
< p > Redirecting to < a href = " ' . $url . ' " > ' . $url . ' </ a ></ p >
</ body >
</ html >
' ;
debug ( 'Refresh: ' . $url );
exit ( 0 );
}
/**
* Implement binary x_or
* @ param string $a
* @ param string $b
* @ return string
*/
function x_or ( $a , $b ) {
$r = " " ;
for ( $i = 0 ; $i < strlen ( $b ); $i ++ )
$r .= $a [ $i ] ^ $b [ $i ];
debug ( " Xor size: " . strlen ( $r ));
return $r ;
}
/*
* App Initialization
*/
// Determine the charset to use
$GLOBALS [ 'charset' ] = 'iso-8859-1' ;
// Set the internal encoding
if ( function_exists ( 'mb_internal_encoding' ))
mb_internal_encoding ( $charset );
// Avoid problems with non-default arg_separator.output settings
// Credit for this goes to user 'prelog' on the forums
ini_set ( 'arg_separator.output' , '&' );
// Do a check to be sure everything is set up correctly
self_check ();
/**
* Determine the HTTP request port
* @ name $port
* @ global integer $GLOBALS [ 'port' ]
*/
$GLOBALS [ 'port' ] = (( isset ( $_SERVER [ " HTTPS " ]) && $_SERVER [ " HTTPS " ] == 'on' && $_SERVER [ 'SERVER_PORT' ] == 443 )
|| $_SERVER [ 'SERVER_PORT' ] == 80 )
? ''
: ':' . $_SERVER [ 'SERVER_PORT' ];
/**
* Determine the HTTP request protocol
* @ name $proto
* @ global string $GLOBALS [ 'proto' ]
*/
$GLOBALS [ 'proto' ] = ( isset ( $_SERVER [ " HTTPS " ]) && $_SERVER [ " HTTPS " ] == 'on' ) ? 'https' : 'http' ;
// Set the authorization state - DO NOT OVERRIDE
$profile [ 'authorized' ] = false ;
2011-06-24 20:07:26 +00:00
global $IDENTITY ;
global $USERNAME ;
2011-06-23 15:04:32 +00:00
// Set a default IDP URL
if ( ! array_key_exists ( 'idp_url' , $profile ))
2011-06-24 20:07:26 +00:00
$profile [ 'idp_url' ] = $IDENTITY ;
2011-06-23 15:04:32 +00:00
2011-06-24 20:07:26 +00:00
//Determine the requested URL - DO NOT OVERRIDE
2011-06-23 15:04:32 +00:00
$profile [ 'req_url' ] = sprintf ( " %s://%s%s " ,
$proto ,
$_SERVER [ 'HTTP_HOST' ],
// $port,//host already includes the path
$_SERVER [ " REQUEST_URI " ]);
// Set the default allowance for testing
if ( ! array_key_exists ( 'allow_test' , $profile ))
$profile [ 'allow_test' ] = false ;
// Set the default allowance for gmp
if ( ! array_key_exists ( 'allow_gmp' , $profile ))
$profile [ 'allow_gmp' ] = false ;
// Set the default force bigmath - BAD IDEA to override this
if ( ! array_key_exists ( 'force_bigmath' , $profile ))
$profile [ 'force_bigmath' ] = false ;
// Determine if GMP is usable
$profile [ 'use_gmp' ] = ( extension_loaded ( 'gmp' ) && $profile [ 'allow_gmp' ]) ? true : false ;
// Determine if I can perform big math functions
$profile [ 'use_bigmath' ] = ( extension_loaded ( 'bcmath' ) || $profile [ 'use_gmp' ] || $profile [ 'force_bigmath' ]) ? true : false ;
// Set a default authentication domain
if ( ! array_key_exists ( 'auth_domain' , $profile ))
$profile [ 'auth_domain' ] = $profile [ 'req_url' ] . ' ' . $profile [ 'idp_url' ];
// Set a default authentication realm
if ( ! array_key_exists ( 'auth_realm' , $profile ))
2011-06-24 15:06:02 +00:00
$profile [ 'auth_realm' ] = 'ownCloud' ;
2011-06-23 15:04:32 +00:00
// Determine the realm for digest authentication - DO NOT OVERRIDE
$profile [ 'php_realm' ] = $profile [ 'auth_realm' ] . ( ini_get ( 'safe_mode' ) ? '-' . getmyuid () : '' );
// Set a default lifetime - the lesser of GC and cache time
if ( ! array_key_exists ( 'lifetime' , $profile )) {
$sce = session_cache_expire () * 60 ;
$gcm = ini_get ( 'session.gc_maxlifetime' );
$profile [ 'lifetime' ] = $sce < $gcm ? $sce : $gcm ;
}
// Set a default log file
if ( ! array_key_exists ( 'logfile' , $profile ))
$profile [ 'logfile' ] = sys_get_temp_dir () . DIRECTORY_SEPARATOR . $profile [ 'auth_realm' ] . '.debug.log' ;
/*
* Optional Initialization
*/
// Setup optional headers
$profile [ 'opt_headers' ] = array ();
// Determine if I should add microid stuff
if ( array_key_exists ( 'microid' , $profile )) {
$hash = sha1 ( $profile [ 'idp_url' ]);
$values = is_array ( $profile [ 'microid' ]) ? $profile [ 'microid' ] : array ( $profile [ 'microid' ]);
foreach ( $values as $microid ) {
preg_match ( '/^([a-z]+)/i' , $microid , $mtx );
$profile [ 'opt_headers' ][] = sprintf ( '<meta name="microid" content="%s+%s:sha1:%s" />' , $mtx [ 1 ], $proto , sha1 ( sha1 ( $microid ) . $hash ));
}
}
// Determine if I should add pavatar stuff
if ( array_key_exists ( 'pavatar' , $profile ))
$profile [ 'opt_headers' ][] = sprintf ( '<link rel="pavatar" href="%s" />' , $profile [ 'pavatar' ]);
/*
* Do it
*/
// Decide which runmode, based on user request or default
$run_mode = ( isset ( $_REQUEST [ 'openid_mode' ])
&& in_array ( $_REQUEST [ 'openid_mode' ], $known [ 'openid_modes' ]))
? $_REQUEST [ 'openid_mode' ]
: 'no' ;
// Run in the determined runmode
debug ( " Run mode: $run_mode at: " . time ());
debug ( $_REQUEST , 'Request params' );
call_user_func ( $run_mode . '_mode' );
?>