12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240 |
- <?php
- require_once "Auth/OpenID.php";
- require_once "Auth/OpenID/Message.php";
- require_once "Auth/OpenID/HMAC.php";
- require_once "Auth/OpenID/Association.php";
- require_once "Auth/OpenID/CryptUtil.php";
- require_once "Auth/OpenID/DiffieHellman.php";
- require_once "Auth/OpenID/KVForm.php";
- require_once "Auth/OpenID/Nonce.php";
- require_once "Auth/OpenID/Discover.php";
- require_once "Auth/OpenID/URINorm.php";
- require_once "Auth/Yadis/Manager.php";
- require_once "Auth/Yadis/XRI.php";
- define('Auth_OpenID_SUCCESS', 'success');
- define('Auth_OpenID_CANCEL', 'cancel');
- define('Auth_OpenID_FAILURE', 'failure');
- define('Auth_OpenID_SETUP_NEEDED', 'setup needed');
- define('Auth_OpenID_PARSE_ERROR', 'parse error');
- class Auth_OpenID_Consumer {
-
- var $discoverMethod = 'Auth_OpenID_discover';
-
- var $session_key_prefix = "_openid_consumer_";
-
- var $_token_suffix = "last_token";
-
- function Auth_OpenID_Consumer($store, $session = null,
- $consumer_cls = null)
- {
- if ($session === null) {
- $session = new Auth_Yadis_PHPSession();
- }
- $this->session = $session;
- if ($consumer_cls !== null) {
- $this->consumer = new $consumer_cls($store);
- } else {
- $this->consumer = new Auth_OpenID_GenericConsumer($store);
- }
- $this->_token_key = $this->session_key_prefix . $this->_token_suffix;
- }
-
- function getDiscoveryObject($session, $openid_url,
- $session_key_prefix)
- {
- return new Auth_Yadis_Discovery($session, $openid_url,
- $session_key_prefix);
- }
-
- function begin($user_url, $anonymous=false)
- {
- $openid_url = $user_url;
- $disco = $this->getDiscoveryObject($this->session,
- $openid_url,
- $this->session_key_prefix);
-
-
-
- $m = $disco->getManager();
- $loader = new Auth_Yadis_ManagerLoader();
- if ($m) {
- if ($m->stale) {
- $disco->destroyManager();
- } else {
- $m->stale = true;
- $disco->session->set($disco->session_key,
- serialize($loader->toSession($m)));
- }
- }
- $endpoint = $disco->getNextService($this->discoverMethod,
- $this->consumer->fetcher);
-
- $m = $disco->getManager();
- if ($m) {
- $m->stale = false;
- $disco->session->set($disco->session_key,
- serialize($loader->toSession($m)));
- }
- if ($endpoint === null) {
- return null;
- } else {
- return $this->beginWithoutDiscovery($endpoint,
- $anonymous);
- }
- }
-
- function beginWithoutDiscovery($endpoint, $anonymous=false)
- {
- $loader = new Auth_OpenID_ServiceEndpointLoader();
- $auth_req = $this->consumer->begin($endpoint);
- $this->session->set($this->_token_key,
- $loader->toSession($auth_req->endpoint));
- if (!$auth_req->setAnonymous($anonymous)) {
- return new Auth_OpenID_FailureResponse(null,
- "OpenID 1 requests MUST include the identifier " .
- "in the request.");
- }
- return $auth_req;
- }
-
- function complete($current_url, $query=null)
- {
- if ($current_url && !is_string($current_url)) {
-
-
- trigger_error("current_url must be a string; see NEWS file " .
- "for upgrading notes.",
- E_USER_ERROR);
- }
- if ($query === null) {
- $query = Auth_OpenID::getQuery();
- }
- $loader = new Auth_OpenID_ServiceEndpointLoader();
- $endpoint_data = $this->session->get($this->_token_key);
- $endpoint =
- $loader->fromSession($endpoint_data);
- $message = Auth_OpenID_Message::fromPostArgs($query);
- $response = $this->consumer->complete($message, $endpoint,
- $current_url);
- $this->session->del($this->_token_key);
- if (in_array($response->status, array(Auth_OpenID_SUCCESS,
- Auth_OpenID_CANCEL))) {
- if ($response->identity_url !== null) {
- $disco = $this->getDiscoveryObject($this->session,
- $response->identity_url,
- $this->session_key_prefix);
- $disco->cleanup(true);
- }
- }
- return $response;
- }
- }
- class Auth_OpenID_DiffieHellmanSHA1ConsumerSession {
- var $session_type = 'DH-SHA1';
- var $hash_func = 'Auth_OpenID_SHA1';
- var $secret_size = 20;
- var $allowed_assoc_types = array('HMAC-SHA1');
- function Auth_OpenID_DiffieHellmanSHA1ConsumerSession($dh = null)
- {
- if ($dh === null) {
- $dh = new Auth_OpenID_DiffieHellman();
- }
- $this->dh = $dh;
- }
- function getRequest()
- {
- $math = Auth_OpenID_getMathLib();
- $cpub = $math->longToBase64($this->dh->public);
- $args = array('dh_consumer_public' => $cpub);
- if (!$this->dh->usingDefaultValues()) {
- $args = array_merge($args, array(
- 'dh_modulus' =>
- $math->longToBase64($this->dh->mod),
- 'dh_gen' =>
- $math->longToBase64($this->dh->gen)));
- }
- return $args;
- }
- function extractSecret($response)
- {
- if (!$response->hasKey(Auth_OpenID_OPENID_NS,
- 'dh_server_public')) {
- return null;
- }
- if (!$response->hasKey(Auth_OpenID_OPENID_NS,
- 'enc_mac_key')) {
- return null;
- }
- $math = Auth_OpenID_getMathLib();
- $spub = $math->base64ToLong($response->getArg(Auth_OpenID_OPENID_NS,
- 'dh_server_public'));
- $enc_mac_key = base64_decode($response->getArg(Auth_OpenID_OPENID_NS,
- 'enc_mac_key'));
- return $this->dh->xorSecret($spub, $enc_mac_key, $this->hash_func);
- }
- }
- class Auth_OpenID_DiffieHellmanSHA256ConsumerSession extends
- Auth_OpenID_DiffieHellmanSHA1ConsumerSession {
- var $session_type = 'DH-SHA256';
- var $hash_func = 'Auth_OpenID_SHA256';
- var $secret_size = 32;
- var $allowed_assoc_types = array('HMAC-SHA256');
- }
- class Auth_OpenID_PlainTextConsumerSession {
- var $session_type = 'no-encryption';
- var $allowed_assoc_types = array('HMAC-SHA1', 'HMAC-SHA256');
- function getRequest()
- {
- return array();
- }
- function extractSecret($response)
- {
- if (!$response->hasKey(Auth_OpenID_OPENID_NS, 'mac_key')) {
- return null;
- }
- return base64_decode($response->getArg(Auth_OpenID_OPENID_NS,
- 'mac_key'));
- }
- }
- function Auth_OpenID_getAvailableSessionTypes()
- {
- $types = array(
- 'no-encryption' => 'Auth_OpenID_PlainTextConsumerSession',
- 'DH-SHA1' => 'Auth_OpenID_DiffieHellmanSHA1ConsumerSession',
- 'DH-SHA256' => 'Auth_OpenID_DiffieHellmanSHA256ConsumerSession');
- return $types;
- }
- class Auth_OpenID_GenericConsumer {
-
- var $discoverMethod = 'Auth_OpenID_discover';
-
- var $store;
-
- var $_use_assocs;
-
- var $openid1_nonce_query_arg_name = 'janrain_nonce';
-
- var $openid1_return_to_identifier_name = 'openid1_claimed_id';
-
- function Auth_OpenID_GenericConsumer($store)
- {
- $this->store = $store;
- $this->negotiator = Auth_OpenID_getDefaultNegotiator();
- $this->_use_assocs = (is_null($this->store) ? false : true);
- if (get_class($this->store) == "Auth_OpenID_DumbStore") {
- $this->_use_assocs = false;
- }
- $this->fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
- $this->session_types = Auth_OpenID_getAvailableSessionTypes();
- }
-
- function begin($service_endpoint)
- {
- $assoc = $this->_getAssociation($service_endpoint);
- $r = new Auth_OpenID_AuthRequest($service_endpoint, $assoc);
- $r->return_to_args[$this->openid1_nonce_query_arg_name] =
- Auth_OpenID_mkNonce();
- if ($r->message->isOpenID1()) {
- $r->return_to_args[$this->openid1_return_to_identifier_name] =
- $r->endpoint->claimed_id;
- }
- return $r;
- }
-
- function complete($message, $endpoint, $return_to)
- {
- $mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode',
- '<no mode set>');
- $mode_methods = array(
- 'cancel' => '_complete_cancel',
- 'error' => '_complete_error',
- 'setup_needed' => '_complete_setup_needed',
- 'id_res' => '_complete_id_res',
- );
- $method = Auth_OpenID::arrayGet($mode_methods, $mode,
- '_completeInvalid');
- return call_user_func_array(array($this, $method),
- array($message, $endpoint, $return_to));
- }
-
- function _completeInvalid($message, $endpoint, $unused)
- {
- $mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode',
- '<No mode set>');
- return new Auth_OpenID_FailureResponse($endpoint,
- sprintf("Invalid openid.mode '%s'", $mode));
- }
-
- function _complete_cancel($message, $endpoint, $unused)
- {
- return new Auth_OpenID_CancelResponse($endpoint);
- }
-
- function _complete_error($message, $endpoint, $unused)
- {
- $error = $message->getArg(Auth_OpenID_OPENID_NS, 'error');
- $contact = $message->getArg(Auth_OpenID_OPENID_NS, 'contact');
- $reference = $message->getArg(Auth_OpenID_OPENID_NS, 'reference');
- return new Auth_OpenID_FailureResponse($endpoint, $error,
- $contact, $reference);
- }
-
- function _complete_setup_needed($message, $endpoint, $unused)
- {
- if (!$message->isOpenID2()) {
- return $this->_completeInvalid($message, $endpoint);
- }
- $user_setup_url = $message->getArg(Auth_OpenID_OPENID2_NS,
- 'user_setup_url');
- return new Auth_OpenID_SetupNeededResponse($endpoint, $user_setup_url);
- }
-
- function _complete_id_res($message, $endpoint, $return_to)
- {
- $user_setup_url = $message->getArg(Auth_OpenID_OPENID1_NS,
- 'user_setup_url');
- if ($this->_checkSetupNeeded($message)) {
- return new Auth_OpenID_SetupNeededResponse(
- $endpoint, $user_setup_url);
- } else {
- return $this->_doIdRes($message, $endpoint, $return_to);
- }
- }
-
- function _checkSetupNeeded($message)
- {
-
-
-
- if ($message->isOpenID1()) {
- $user_setup_url = $message->getArg(Auth_OpenID_OPENID1_NS,
- 'user_setup_url');
- if ($user_setup_url !== null) {
- return true;
- }
- }
- return false;
- }
-
- function _doIdRes($message, $endpoint, $return_to)
- {
-
-
- $result = $this->_idResCheckForFields($message);
- if (Auth_OpenID::isFailure($result)) {
- return $result;
- }
- if (!$this->_checkReturnTo($message, $return_to)) {
- return new Auth_OpenID_FailureResponse(null,
- sprintf("return_to does not match return URL. Expected %s, got %s",
- $return_to,
- $message->getArg(Auth_OpenID_OPENID_NS, 'return_to')));
- }
-
- $result = $this->_verifyDiscoveryResults($message, $endpoint);
- if (Auth_OpenID::isFailure($result)) {
- return $result;
- }
- $endpoint = $result;
- $result = $this->_idResCheckSignature($message,
- $endpoint->server_url);
- if (Auth_OpenID::isFailure($result)) {
- return $result;
- }
- $result = $this->_idResCheckNonce($message, $endpoint);
- if (Auth_OpenID::isFailure($result)) {
- return $result;
- }
- $signed_list_str = $message->getArg(Auth_OpenID_OPENID_NS, 'signed',
- Auth_OpenID_NO_DEFAULT);
- if (Auth_OpenID::isFailure($signed_list_str)) {
- return $signed_list_str;
- }
- $signed_list = explode(',', $signed_list_str);
- $signed_fields = Auth_OpenID::addPrefix($signed_list, "openid.");
- return new Auth_OpenID_SuccessResponse($endpoint, $message,
- $signed_fields);
- }
-
- function _checkReturnTo($message, $return_to)
- {
-
-
-
-
-
- $result = Auth_OpenID_GenericConsumer::_verifyReturnToArgs(
- $message->toPostArgs());
- if (Auth_OpenID::isFailure($result)) {
- return false;
- }
-
-
- $msg_return_to = $message->getArg(Auth_OpenID_OPENID_NS,
- 'return_to');
- if (Auth_OpenID::isFailure($return_to)) {
-
- return false;
- }
- $return_to_parts = parse_url(Auth_OpenID_urinorm($return_to));
- $msg_return_to_parts = parse_url(Auth_OpenID_urinorm($msg_return_to));
-
-
- if ((!array_key_exists('port', $return_to_parts)) &&
- (!array_key_exists('port', $msg_return_to_parts))) {
- $return_to_parts['port'] = null;
- $msg_return_to_parts['port'] = null;
- }
-
-
- if ((!array_key_exists('path', $return_to_parts)) &&
- (!array_key_exists('path', $msg_return_to_parts))) {
- $return_to_parts['path'] = null;
- $msg_return_to_parts['path'] = null;
- }
-
-
- foreach (array('scheme', 'host', 'port', 'path') as $component) {
-
-
- if (!array_key_exists($component, $return_to_parts)) {
- return false;
- }
- if (!array_key_exists($component, $msg_return_to_parts)) {
- return false;
- }
- if (Auth_OpenID::arrayGet($return_to_parts, $component) !==
- Auth_OpenID::arrayGet($msg_return_to_parts, $component)) {
- return false;
- }
- }
- return true;
- }
-
- function _verifyReturnToArgs($query)
- {
-
-
- $message = Auth_OpenID_Message::fromPostArgs($query);
- $return_to = $message->getArg(Auth_OpenID_OPENID_NS, 'return_to');
- if (Auth_OpenID::isFailure($return_to)) {
- return $return_to;
- }
-
- if (!$return_to) {
- return new Auth_OpenID_FailureResponse(null,
- "Response has no return_to");
- }
- $parsed_url = parse_url($return_to);
- $q = array();
- if (array_key_exists('query', $parsed_url)) {
- $rt_query = $parsed_url['query'];
- $q = Auth_OpenID::parse_str($rt_query);
- }
- foreach ($q as $rt_key => $rt_value) {
- if (!array_key_exists($rt_key, $query)) {
- return new Auth_OpenID_FailureResponse(null,
- sprintf("return_to parameter %s absent from query", $rt_key));
- } else {
- $value = $query[$rt_key];
- if ($rt_value != $value) {
- return new Auth_OpenID_FailureResponse(null,
- sprintf("parameter %s value %s does not match " .
- "return_to value %s", $rt_key,
- $value, $rt_value));
- }
- }
- }
-
-
- $bare_args = $message->getArgs(Auth_OpenID_BARE_NS);
- foreach ($bare_args as $key => $value) {
- if (Auth_OpenID::arrayGet($q, $key) != $value) {
- return new Auth_OpenID_FailureResponse(null,
- sprintf("Parameter %s = %s not in return_to URL",
- $key, $value));
- }
- }
- return true;
- }
-
- function _idResCheckSignature($message, $server_url)
- {
- $assoc_handle = $message->getArg(Auth_OpenID_OPENID_NS,
- 'assoc_handle');
- if (Auth_OpenID::isFailure($assoc_handle)) {
- return $assoc_handle;
- }
- $assoc = $this->store->getAssociation($server_url, $assoc_handle);
- if ($assoc) {
- if ($assoc->getExpiresIn() <= 0) {
-
-
-
-
-
-
- return new Auth_OpenID_FailureResponse(null,
- 'Association with ' . $server_url . ' expired');
- }
- if (!$assoc->checkMessageSignature($message)) {
-
-
-
- $this->store->removeAssociation($server_url, $assoc_handle);
- return new Auth_OpenID_FailureResponse(null,
- "Bad signature");
- }
- } else {
-
-
-
-
- if (!$this->_checkAuth($message, $server_url)) {
- return new Auth_OpenID_FailureResponse(null,
- "Server denied check_authentication");
- }
- }
- return null;
- }
-
- function _verifyDiscoveryResults($message, $endpoint=null)
- {
- if ($message->getOpenIDNamespace() == Auth_OpenID_OPENID2_NS) {
- return $this->_verifyDiscoveryResultsOpenID2($message,
- $endpoint);
- } else {
- return $this->_verifyDiscoveryResultsOpenID1($message,
- $endpoint);
- }
- }
-
- function _verifyDiscoveryResultsOpenID1($message, $endpoint)
- {
- $claimed_id = $message->getArg(Auth_OpenID_BARE_NS,
- $this->openid1_return_to_identifier_name);
- if (($endpoint === null) && ($claimed_id === null)) {
- return new Auth_OpenID_FailureResponse($endpoint,
- 'When using OpenID 1, the claimed ID must be supplied, ' .
- 'either by passing it through as a return_to parameter ' .
- 'or by using a session, and supplied to the GenericConsumer ' .
- 'as the argument to complete()');
- } else if (($endpoint !== null) && ($claimed_id === null)) {
- $claimed_id = $endpoint->claimed_id;
- }
- $to_match = new Auth_OpenID_ServiceEndpoint();
- $to_match->type_uris = array(Auth_OpenID_TYPE_1_1);
- $to_match->local_id = $message->getArg(Auth_OpenID_OPENID1_NS,
- 'identity');
-
- $to_match->claimed_id = $claimed_id;
- if ($to_match->local_id === null) {
- return new Auth_OpenID_FailureResponse($endpoint,
- "Missing required field openid.identity");
- }
- $to_match_1_0 = $to_match->copy();
- $to_match_1_0->type_uris = array(Auth_OpenID_TYPE_1_0);
- if ($endpoint !== null) {
- $result = $this->_verifyDiscoverySingle($endpoint, $to_match);
- if (is_a($result, 'Auth_OpenID_TypeURIMismatch')) {
- $result = $this->_verifyDiscoverySingle($endpoint,
- $to_match_1_0);
- }
- if (Auth_OpenID::isFailure($result)) {
-
-
-
-
- } else {
- return $endpoint;
- }
- }
-
- return $this->_discoverAndVerify($to_match->claimed_id,
- array($to_match, $to_match_1_0));
- }
-
- function _verifyDiscoverySingle($endpoint, $to_match)
- {
-
-
- foreach ($to_match->type_uris as $type_uri) {
- if (!$endpoint->usesExtension($type_uri)) {
- return new Auth_OpenID_TypeURIMismatch($endpoint,
- "Required type ".$type_uri." not present");
- }
- }
-
-
-
- list($defragged_claimed_id, $_) =
- Auth_OpenID::urldefrag($to_match->claimed_id);
- if ($defragged_claimed_id != $endpoint->claimed_id) {
- return new Auth_OpenID_FailureResponse($endpoint,
- sprintf('Claimed ID does not match (different subjects!), ' .
- 'Expected %s, got %s', $defragged_claimed_id,
- $endpoint->claimed_id));
- }
- if ($to_match->getLocalID() != $endpoint->getLocalID()) {
- return new Auth_OpenID_FailureResponse($endpoint,
- sprintf('local_id mismatch. Expected %s, got %s',
- $to_match->getLocalID(), $endpoint->getLocalID()));
- }
-
-
-
-
-
- if ($to_match->server_url === null) {
- if ($to_match->preferredNamespace() != Auth_OpenID_OPENID1_NS) {
- return new Auth_OpenID_FailureResponse($endpoint,
- "Preferred namespace mismatch (bug)");
- }
- } else if ($to_match->server_url != $endpoint->server_url) {
- return new Auth_OpenID_FailureResponse($endpoint,
- sprintf('OP Endpoint mismatch. Expected %s, got %s',
- $to_match->server_url, $endpoint->server_url));
- }
- return null;
- }
-
- function _verifyDiscoveryResultsOpenID2($message, $endpoint)
- {
- $to_match = new Auth_OpenID_ServiceEndpoint();
- $to_match->type_uris = array(Auth_OpenID_TYPE_2_0);
- $to_match->claimed_id = $message->getArg(Auth_OpenID_OPENID2_NS,
- 'claimed_id');
- $to_match->local_id = $message->getArg(Auth_OpenID_OPENID2_NS,
- 'identity');
- $to_match->server_url = $message->getArg(Auth_OpenID_OPENID2_NS,
- 'op_endpoint');
- if ($to_match->server_url === null) {
- return new Auth_OpenID_FailureResponse($endpoint,
- "OP Endpoint URL missing");
- }
-
-
- if (($to_match->claimed_id === null) &&
- ($to_match->local_id !== null)) {
- return new Auth_OpenID_FailureResponse($endpoint,
- 'openid.identity is present without openid.claimed_id');
- }
- if (($to_match->claimed_id !== null) &&
- ($to_match->local_id === null)) {
- return new Auth_OpenID_FailureResponse($endpoint,
- 'openid.claimed_id is present without openid.identity');
- }
- if ($to_match->claimed_id === null) {
-
-
-
- return Auth_OpenID_ServiceEndpoint::fromOPEndpointURL(
- $to_match->server_url);
- }
- if (!$endpoint) {
-
-
-
-
-
- return $this->_discoverAndVerify($to_match->claimed_id,
- array($to_match));
- } else {
-
-
-
- $result = $this->_verifyDiscoverySingle($endpoint, $to_match);
- if (Auth_OpenID::isFailure($result)) {
- $endpoint = $this->_discoverAndVerify($to_match->claimed_id,
- array($to_match));
- if (Auth_OpenID::isFailure($endpoint)) {
- return $endpoint;
- }
- }
- }
-
-
- if ($endpoint->claimed_id != $to_match->claimed_id) {
- $endpoint->claimed_id = $to_match->claimed_id;
- }
- return $endpoint;
- }
-
- function _discoverAndVerify($claimed_id, $to_match_endpoints)
- {
-
- list($unused, $services) = call_user_func_array($this->discoverMethod,
- array(
- $claimed_id,
- $this->fetcher,
- ));
- if (!$services) {
- return new Auth_OpenID_FailureResponse(null,
- sprintf("No OpenID information found at %s",
- $claimed_id));
- }
- return $this->_verifyDiscoveryServices($claimed_id, $services,
- $to_match_endpoints);
- }
-
- function _verifyDiscoveryServices($claimed_id,
- $services, $to_match_endpoints)
- {
-
-
- foreach ($services as $endpoint) {
- foreach ($to_match_endpoints as $to_match_endpoint) {
- $result = $this->_verifyDiscoverySingle($endpoint,
- $to_match_endpoint);
- if (!Auth_OpenID::isFailure($result)) {
-
-
- return $endpoint;
- }
- }
- }
- return new Auth_OpenID_FailureResponse(null,
- sprintf('No matching endpoint found after discovering %s: %s',
- $claimed_id, $result->message));
- }
-
- function _idResGetNonceOpenID1($message, $endpoint)
- {
- return $message->getArg(Auth_OpenID_BARE_NS,
- $this->openid1_nonce_query_arg_name);
- }
-
- function _idResCheckNonce($message, $endpoint)
- {
- if ($message->isOpenID1()) {
-
- $nonce = $this->_idResGetNonceOpenID1($message, $endpoint);
- $server_url = '';
- } else {
- $nonce = $message->getArg(Auth_OpenID_OPENID2_NS,
- 'response_nonce');
- $server_url = $endpoint->server_url;
- }
- if ($nonce === null) {
- return new Auth_OpenID_FailureResponse($endpoint,
- "Nonce missing from response");
- }
- $parts = Auth_OpenID_splitNonce($nonce);
- if ($parts === null) {
- return new Auth_OpenID_FailureResponse($endpoint,
- "Malformed nonce in response");
- }
- list($timestamp, $salt) = $parts;
- if (!$this->store->useNonce($server_url, $timestamp, $salt)) {
- return new Auth_OpenID_FailureResponse($endpoint,
- "Nonce already used or out of range");
- }
- return null;
- }
-
- function _idResCheckForFields($message)
- {
- $basic_fields = array('return_to', 'assoc_handle', 'sig', 'signed');
- $basic_sig_fields = array('return_to', 'identity');
- $require_fields = array(
- Auth_OpenID_OPENID2_NS => array_merge($basic_fields,
- array('op_endpoint')),
- Auth_OpenID_OPENID1_NS => array_merge($basic_fields,
- array('identity'))
- );
- $require_sigs = array(
- Auth_OpenID_OPENID2_NS => array_merge($basic_sig_fields,
- array('response_nonce',
- 'claimed_id',
- 'assoc_handle',
- 'op_endpoint')),
- Auth_OpenID_OPENID1_NS => array_merge($basic_sig_fields,
- array('nonce'))
- );
- foreach ($require_fields[$message->getOpenIDNamespace()] as $field) {
- if (!$message->hasKey(Auth_OpenID_OPENID_NS, $field)) {
- return new Auth_OpenID_FailureResponse(null,
- "Missing required field '".$field."'");
- }
- }
- $signed_list_str = $message->getArg(Auth_OpenID_OPENID_NS,
- 'signed',
- Auth_OpenID_NO_DEFAULT);
- if (Auth_OpenID::isFailure($signed_list_str)) {
- return $signed_list_str;
- }
- $signed_list = explode(',', $signed_list_str);
- foreach ($require_sigs[$message->getOpenIDNamespace()] as $field) {
-
- if ($message->hasKey(Auth_OpenID_OPENID_NS, $field) &&
- (!in_array($field, $signed_list))) {
- return new Auth_OpenID_FailureResponse(null,
- "'".$field."' not signed");
- }
- }
- return null;
- }
-
- function _checkAuth($message, $server_url)
- {
- $request = $this->_createCheckAuthRequest($message);
- if ($request === null) {
- return false;
- }
- $resp_message = $this->_makeKVPost($request, $server_url);
- if (($resp_message === null) ||
- (is_a($resp_message, 'Auth_OpenID_ServerErrorContainer'))) {
- return false;
- }
- return $this->_processCheckAuthResponse($resp_message, $server_url);
- }
-
- function _createCheckAuthRequest($message)
- {
- $signed = $message->getArg(Auth_OpenID_OPENID_NS, 'signed');
- if ($signed) {
- foreach (explode(',', $signed) as $k) {
- $value = $message->getAliasedArg($k);
- if ($value === null) {
- return null;
- }
- }
- }
- $ca_message = $message->copy();
- $ca_message->setArg(Auth_OpenID_OPENID_NS, 'mode',
- 'check_authentication');
- return $ca_message;
- }
-
- function _processCheckAuthResponse($response, $server_url)
- {
- $is_valid = $response->getArg(Auth_OpenID_OPENID_NS, 'is_valid',
- 'false');
- $invalidate_handle = $response->getArg(Auth_OpenID_OPENID_NS,
- 'invalidate_handle');
- if ($invalidate_handle !== null) {
- $this->store->removeAssociation($server_url,
- $invalidate_handle);
- }
- if ($is_valid == 'true') {
- return true;
- }
- return false;
- }
-
- static function _httpResponseToMessage($response, $server_url)
- {
-
- $response_message = Auth_OpenID_Message::fromKVForm($response->body);
- if ($response->status == 400) {
- return Auth_OpenID_ServerErrorContainer::fromMessage(
- $response_message);
- } else if ($response->status != 200 and $response->status != 206) {
- return null;
- }
- return $response_message;
- }
-
- function _makeKVPost($message, $server_url)
- {
- $body = $message->toURLEncoded();
- $resp = $this->fetcher->post($server_url, $body);
- if ($resp === null) {
- return null;
- }
- return $this->_httpResponseToMessage($resp, $server_url);
- }
-
- function _getAssociation($endpoint)
- {
- if (!$this->_use_assocs) {
- return null;
- }
- $assoc = $this->store->getAssociation($endpoint->server_url);
- if (($assoc === null) ||
- ($assoc->getExpiresIn() <= 0)) {
- $assoc = $this->_negotiateAssociation($endpoint);
- if ($assoc !== null) {
- $this->store->storeAssociation($endpoint->server_url,
- $assoc);
- }
- }
- return $assoc;
- }
-
- function _extractSupportedAssociationType($server_error, $endpoint,
- $assoc_type)
- {
-
-
- if (($server_error->error_code != 'unsupported-type') ||
- ($server_error->message->isOpenID1())) {
- return null;
- }
-
-
-
-
-
- $assoc_type = $server_error->message->getArg(Auth_OpenID_OPENID_NS,
- 'assoc_type');
- $session_type = $server_error->message->getArg(Auth_OpenID_OPENID_NS,
- 'session_type');
- if (($assoc_type === null) || ($session_type === null)) {
- return null;
- } else if (!$this->negotiator->isAllowed($assoc_type,
- $session_type)) {
- return null;
- } else {
- return array($assoc_type, $session_type);
- }
- }
-
- function _negotiateAssociation($endpoint)
- {
-
- list($assoc_type, $session_type) = $this->negotiator->getAllowedType();
- $assoc = $this->_requestAssociation(
- $endpoint, $assoc_type, $session_type);
- if (Auth_OpenID::isFailure($assoc)) {
- return null;
- }
- if (is_a($assoc, 'Auth_OpenID_ServerErrorContainer')) {
- $why = $assoc;
- $supportedTypes = $this->_extractSupportedAssociationType(
- $why, $endpoint, $assoc_type);
- if ($supportedTypes !== null) {
- list($assoc_type, $session_type) = $supportedTypes;
-
-
-
- $assoc = $this->_requestAssociation(
- $endpoint, $assoc_type, $session_type);
- if (is_a($assoc, 'Auth_OpenID_ServerErrorContainer')) {
-
-
-
-
-
-
- return null;
- } else {
- return $assoc;
- }
- } else {
- return null;
- }
- } else {
- return $assoc;
- }
- }
-
- function _requestAssociation($endpoint, $assoc_type, $session_type)
- {
- list($assoc_session, $args) = $this->_createAssociateRequest(
- $endpoint, $assoc_type, $session_type);
- $response_message = $this->_makeKVPost($args, $endpoint->server_url);
- if ($response_message === null) {
-
- return null;
- } else if (is_a($response_message,
- 'Auth_OpenID_ServerErrorContainer')) {
- return $response_message;
- }
- return $this->_extractAssociation($response_message, $assoc_session);
- }
-
- function _extractAssociation($assoc_response, $assoc_session)
- {
-
-
- $assoc_type = $assoc_response->getArg(
- Auth_OpenID_OPENID_NS, 'assoc_type',
- Auth_OpenID_NO_DEFAULT);
- if (Auth_OpenID::isFailure($assoc_type)) {
- return $assoc_type;
- }
- $assoc_handle = $assoc_response->getArg(
- Auth_OpenID_OPENID_NS, 'assoc_handle',
- Auth_OpenID_NO_DEFAULT);
- if (Auth_OpenID::isFailure($assoc_handle)) {
- return $assoc_handle;
- }
-
-
-
-
- $expires_in_str = $assoc_response->getArg(
- Auth_OpenID_OPENID_NS, 'expires_in',
- Auth_OpenID_NO_DEFAULT);
- if (Auth_OpenID::isFailure($expires_in_str)) {
- return $expires_in_str;
- }
- $expires_in = Auth_OpenID::intval($expires_in_str);
- if ($expires_in === false) {
- $err = sprintf("Could not parse expires_in from association ".
- "response %s", print_r($assoc_response, true));
- return new Auth_OpenID_FailureResponse(null, $err);
- }
-
- if ($assoc_response->isOpenID1()) {
- $session_type = $this->_getOpenID1SessionType($assoc_response);
- } else {
- $session_type = $assoc_response->getArg(
- Auth_OpenID_OPENID2_NS, 'session_type',
- Auth_OpenID_NO_DEFAULT);
- if (Auth_OpenID::isFailure($session_type)) {
- return $session_type;
- }
- }
-
- if ($assoc_session->session_type != $session_type) {
- if ($assoc_response->isOpenID1() &&
- ($session_type == 'no-encryption')) {
-
-
-
-
-
- $assoc_session = new Auth_OpenID_PlainTextConsumerSession();
- } else {
-
-
-
- return null;
- }
- }
-
- if (!in_array($assoc_type, $assoc_session->allowed_assoc_types)) {
- return null;
- }
-
-
-
- $secret = $assoc_session->extractSecret($assoc_response);
- if ($secret === null) {
- return null;
- }
- return Auth_OpenID_Association::fromExpiresIn(
- $expires_in, $assoc_handle, $secret, $assoc_type);
- }
-
- function _createAssociateRequest($endpoint, $assoc_type, $session_type)
- {
- if (array_key_exists($session_type, $this->session_types)) {
- $session_type_class = $this->session_types[$session_type];
- if (is_callable($session_type_class)) {
- $assoc_session = $session_type_class();
- } else {
- $assoc_session = new $session_type_class();
- }
- } else {
- return null;
- }
- $args = array(
- 'mode' => 'associate',
- 'assoc_type' => $assoc_type);
- if (!$endpoint->compatibilityMode()) {
- $args['ns'] = Auth_OpenID_OPENID2_NS;
- }
-
-
- if ((!$endpoint->compatibilityMode()) ||
- ($assoc_session->session_type != 'no-encryption')) {
- $args['session_type'] = $assoc_session->session_type;
- }
- $args = array_merge($args, $assoc_session->getRequest());
- $message = Auth_OpenID_Message::fromOpenIDArgs($args);
- return array($assoc_session, $message);
- }
-
- function _getOpenID1SessionType($assoc_response)
- {
-
-
- $session_type = $assoc_response->getArg(Auth_OpenID_OPENID1_NS,
- 'session_type');
-
-
-
-
- if ($session_type == 'no-encryption') {
-
-
- } else if (($session_type == '') || ($session_type === null)) {
-
-
-
-
- $session_type = 'no-encryption';
- }
- return $session_type;
- }
- }
- class Auth_OpenID_AuthRequest {
-
- function Auth_OpenID_AuthRequest($endpoint, $assoc)
- {
- $this->assoc = $assoc;
- $this->endpoint = $endpoint;
- $this->return_to_args = array();
- $this->message = new Auth_OpenID_Message(
- $endpoint->preferredNamespace());
- $this->_anonymous = false;
- }
-
- function addExtension($extension_request)
- {
- $extension_request->toMessage($this->message);
- }
-
- function addExtensionArg($namespace, $key, $value)
- {
- return $this->message->setArg($namespace, $key, $value);
- }
-
- function setAnonymous($is_anonymous)
- {
- if ($is_anonymous && $this->message->isOpenID1()) {
- return false;
- } else {
- $this->_anonymous = $is_anonymous;
- return true;
- }
- }
-
- function getMessage($realm, $return_to=null, $immediate=false)
- {
- if ($return_to) {
- $return_to = Auth_OpenID::appendArgs($return_to,
- $this->return_to_args);
- } else if ($immediate) {
-
-
-
- return new Auth_OpenID_FailureResponse(null,
- "'return_to' is mandatory when using checkid_immediate");
- } else if ($this->message->isOpenID1()) {
-
-
- return new Auth_OpenID_FailureResponse(null,
- "'return_to' is mandatory for OpenID 1 requests");
- } else if ($this->return_to_args) {
-
-
- return new Auth_OpenID_FailureResponse(null,
- "extra 'return_to' arguments where specified, " .
- "but no return_to was specified");
- }
- if ($immediate) {
- $mode = 'checkid_immediate';
- } else {
- $mode = 'checkid_setup';
- }
- $message = $this->message->copy();
- if ($message->isOpenID1()) {
- $realm_key = 'trust_root';
- } else {
- $realm_key = 'realm';
- }
- $message->updateArgs(Auth_OpenID_OPENID_NS,
- array(
- $realm_key => $realm,
- 'mode' => $mode,
- 'return_to' => $return_to));
- if (!$this->_anonymous) {
- if ($this->endpoint->isOPIdentifier()) {
-
-
-
- $claimed_id = $request_identity =
- Auth_OpenID_IDENTIFIER_SELECT;
- } else {
- $request_identity = $this->endpoint->getLocalID();
- $claimed_id = $this->endpoint->claimed_id;
- }
-
- $message->setArg(Auth_OpenID_OPENID_NS, 'identity',
- $request_identity);
- if ($message->isOpenID2()) {
- $message->setArg(Auth_OpenID_OPENID2_NS, 'claimed_id',
- $claimed_id);
- }
- }
- if ($this->assoc) {
- $message->setArg(Auth_OpenID_OPENID_NS, 'assoc_handle',
- $this->assoc->handle);
- }
- return $message;
- }
- function redirectURL($realm, $return_to = null,
- $immediate = false)
- {
- $message = $this->getMessage($realm, $return_to, $immediate);
- if (Auth_OpenID::isFailure($message)) {
- return $message;
- }
- return $message->toURL($this->endpoint->server_url);
- }
-
- function formMarkup($realm, $return_to=null, $immediate=false,
- $form_tag_attrs=null)
- {
- $message = $this->getMessage($realm, $return_to, $immediate);
- if (Auth_OpenID::isFailure($message)) {
- return $message;
- }
- return $message->toFormMarkup($this->endpoint->server_url,
- $form_tag_attrs);
- }
-
- function htmlMarkup($realm, $return_to=null, $immediate=false,
- $form_tag_attrs=null)
- {
- $form = $this->formMarkup($realm, $return_to, $immediate,
- $form_tag_attrs);
- if (Auth_OpenID::isFailure($form)) {
- return $form;
- }
- return Auth_OpenID::autoSubmitHTML($form);
- }
- function shouldSendRedirect()
- {
- return $this->endpoint->compatibilityMode();
- }
- }
- class Auth_OpenID_ConsumerResponse {
- var $status = null;
- function setEndpoint($endpoint)
- {
- $this->endpoint = $endpoint;
- if ($endpoint === null) {
- $this->identity_url = null;
- } else {
- $this->identity_url = $endpoint->claimed_id;
- }
- }
-
- function getDisplayIdentifier()
- {
- if ($this->endpoint !== null) {
- return $this->endpoint->getDisplayIdentifier();
- }
- return null;
- }
- }
- class Auth_OpenID_SuccessResponse extends Auth_OpenID_ConsumerResponse {
- var $status = Auth_OpenID_SUCCESS;
-
- function Auth_OpenID_SuccessResponse($endpoint, $message, $signed_args=null)
- {
- $this->endpoint = $endpoint;
- $this->identity_url = $endpoint->claimed_id;
- $this->signed_args = $signed_args;
- $this->message = $message;
- if ($this->signed_args === null) {
- $this->signed_args = array();
- }
- }
-
- function extensionResponse($namespace_uri, $require_signed)
- {
- if ($require_signed) {
- return $this->getSignedNS($namespace_uri);
- } else {
- return $this->message->getArgs($namespace_uri);
- }
- }
- function isOpenID1()
- {
- return $this->message->isOpenID1();
- }
- function isSigned($ns_uri, $ns_key)
- {
-
-
- return in_array($this->message->getKey($ns_uri, $ns_key),
- $this->signed_args);
- }
- function getSigned($ns_uri, $ns_key, $default = null)
- {
-
-
- if ($this->isSigned($ns_uri, $ns_key)) {
- return $this->message->getArg($ns_uri, $ns_key, $default);
- } else {
- return $default;
- }
- }
- function getSignedNS($ns_uri)
- {
- $args = array();
- $msg_args = $this->message->getArgs($ns_uri);
- if (Auth_OpenID::isFailure($msg_args)) {
- return null;
- }
- foreach ($msg_args as $key => $value) {
- if (!$this->isSigned($ns_uri, $key)) {
- unset($msg_args[$key]);
- }
- }
- return $msg_args;
- }
-
- function getReturnTo()
- {
- return $this->getSigned(Auth_OpenID_OPENID_NS, 'return_to');
- }
- }
- class Auth_OpenID_FailureResponse extends Auth_OpenID_ConsumerResponse {
- var $status = Auth_OpenID_FAILURE;
- function Auth_OpenID_FailureResponse($endpoint, $message = null,
- $contact = null, $reference = null)
- {
- $this->setEndpoint($endpoint);
- $this->message = $message;
- $this->contact = $contact;
- $this->reference = $reference;
- }
- }
- class Auth_OpenID_TypeURIMismatch extends Auth_OpenID_FailureResponse {
- }
- class Auth_OpenID_ServerErrorContainer {
- function Auth_OpenID_ServerErrorContainer($error_text,
- $error_code,
- $message)
- {
- $this->error_text = $error_text;
- $this->error_code = $error_code;
- $this->message = $message;
- }
-
- static function fromMessage($message)
- {
- $error_text = $message->getArg(
- Auth_OpenID_OPENID_NS, 'error', '<no error message supplied>');
- $error_code = $message->getArg(Auth_OpenID_OPENID_NS, 'error_code');
- return new Auth_OpenID_ServerErrorContainer($error_text,
- $error_code,
- $message);
- }
- }
- class Auth_OpenID_CancelResponse extends Auth_OpenID_ConsumerResponse {
- var $status = Auth_OpenID_CANCEL;
- function Auth_OpenID_CancelResponse($endpoint)
- {
- $this->setEndpoint($endpoint);
- }
- }
- class Auth_OpenID_SetupNeededResponse extends Auth_OpenID_ConsumerResponse {
- var $status = Auth_OpenID_SETUP_NEEDED;
- function Auth_OpenID_SetupNeededResponse($endpoint,
- $setup_url = null)
- {
- $this->setEndpoint($endpoint);
- $this->setup_url = $setup_url;
- }
- }
|