95 require_once
"Auth/OpenID.php";
96 require_once
"Auth/OpenID/Association.php";
97 require_once
"Auth/OpenID/CryptUtil.php";
98 require_once
"Auth/OpenID/BigMath.php";
99 require_once
"Auth/OpenID/DiffieHellman.php";
100 require_once
"Auth/OpenID/KVForm.php";
101 require_once
"Auth/OpenID/TrustRoot.php";
102 require_once
"Auth/OpenID/ServerRequest.php";
103 require_once
"Auth/OpenID/Message.php";
104 require_once
"Auth/OpenID/Nonce.php";
106 define(
'AUTH_OPENID_HTTP_OK', 200);
107 define(
'AUTH_OPENID_HTTP_REDIRECT', 302);
108 define(
'AUTH_OPENID_HTTP_ERROR', 400);
115 'checkid_immediate');
120 define(
'Auth_OpenID_ENCODE_KVFORM',
'kfvorm');
125 define(
'Auth_OpenID_ENCODE_URL',
'URL/redirect');
130 define(
'Auth_OpenID_ENCODE_HTML_FORM',
'HTML form');
137 return is_a($obj, $cls);
152 $reference = null, $contact = null)
154 $this->message = $message;
156 $this->contact = $contact;
157 $this->reference = $reference;
162 if ($this->message &&
187 if (!$this->message) {
204 array(
'mode' =>
'error',
211 return $msg->toFormMarkup($this->
getReturnTo(), $form_tag_attrs);
224 $namespace = $this->message->getOpenIDNamespace();
229 if ($this->contact !== null) {
233 if ($this->reference !== null) {
251 if ($this->message->isOpenID2() &&
260 if (!$this->message) {
268 if (!in_array($mode, $_Auth_OpenID_Request_Modes)) {
283 return get_class($this) .
" error";
296 $text =
"No return_to URL available")
298 parent::Auth_OpenID_ServerError($message, $text);
303 return "No return_to available";
315 $this->return_to = $return_to;
316 parent::Auth_OpenID_ServerError($message,
"malformed return_to URL");
327 $text =
"Malformed trust root")
329 parent::Auth_OpenID_ServerError($message, $text);
334 return "Malformed trust root";
353 var $mode =
"check_authentication";
354 var $invalidate_handle = null;
357 $invalidate_handle = null)
359 $this->assoc_handle = $assoc_handle;
360 $this->
signed = $signed;
361 if ($invalidate_handle !== null) {
362 $this->invalidate_handle = $invalidate_handle;
365 $this->message = null;
370 $required_keys = array(
'assoc_handle',
'sig',
'signed');
372 foreach ($required_keys as $k) {
375 sprintf(
"%s request missing required parameter %s from \ 376 query",
"check_authentication", $k));
384 $signed_list = explode(
",", $signed_list);
395 'invalidate_handle');
401 $is_valid = $signatory->verify($this->assoc_handle, $this->
signed);
405 $signatory->invalidate($this->assoc_handle,
true);
410 ($is_valid ?
"true" :
"false"));
412 if ($this->invalidate_handle) {
413 $assoc = $signatory->getAssociation($this->invalidate_handle,
418 $this->invalidate_handle);
435 var $session_type =
'no-encryption';
436 var $needs_math =
false;
437 var $allowed_assoc_types = array(
'HMAC-SHA1',
'HMAC-SHA256');
446 return array(
'mac_key' => base64_encode($secret));
461 var $session_type =
'DH-SHA1';
462 var $needs_math =
true;
463 var $allowed_assoc_types = array(
'HMAC-SHA1');
464 var $hash_func =
'Auth_OpenID_SHA1';
469 $this->consumer_pubkey = $consumer_pubkey;
477 if ((($dh_modulus === null) && ($dh_gen !== null)) ||
478 (($dh_gen === null) && ($dh_modulus !== null))) {
480 if ($dh_modulus === null) {
481 $missing =
'modulus';
483 $missing =
'generator';
487 'If non-default modulus or generator is '.
488 'supplied, both must be supplied. Missing '.
494 if ($dh_modulus || $dh_gen) {
495 $dh_modulus = $lib->base64ToLong($dh_modulus);
496 $dh_gen = $lib->base64ToLong($dh_gen);
497 if ($lib->cmp($dh_modulus, 0) == 0 ||
498 $lib->cmp($dh_gen, 0) == 0) {
500 $message,
"Failed to parse dh_mod or dh_gen");
508 'dh_consumer_public');
509 if ($consumer_pubkey === null) {
511 'Public key for DH-SHA1 session '.
512 'not found in query');
516 $lib->base64ToLong($consumer_pubkey);
518 if ($consumer_pubkey ===
false) {
520 "dh_consumer_public is not base64");
523 return array($dh, $consumer_pubkey);
530 if (is_a(
$result,
'Auth_OpenID_ServerError')) {
533 list($dh, $consumer_pubkey) =
$result;
542 $mac_key = $this->dh->xorSecret($this->consumer_pubkey, $secret,
545 'dh_server_public' =>
546 $lib->longToBase64($this->dh->public),
547 'enc_mac_key' => base64_encode($mac_key));
559 var $session_type =
'DH-SHA256';
560 var $hash_func =
'Auth_OpenID_SHA256';
561 var $allowed_assoc_types = array(
'HMAC-SHA256');
567 if (is_a(
$result,
'Auth_OpenID_ServerError')) {
570 list($dh, $consumer_pubkey) =
$result;
583 var $mode =
"associate";
588 'no-encryption' =>
'Auth_OpenID_PlainTextServerSession',
589 'DH-SHA1' =>
'Auth_OpenID_DiffieHellmanSHA1ServerSession',
590 'DH-SHA256' =>
'Auth_OpenID_DiffieHellmanSHA256ServerSession');
595 $this->session = $session;
597 $this->assoc_type = $assoc_type;
602 if ($message->isOpenID1()) {
606 if ($session_type ==
'no-encryption') {
609 }
else if (!$session_type) {
610 $session_type =
'no-encryption';
615 if ($session_type === null) {
617 "session_type missing from request");
625 if ($session_class === null) {
627 "Unknown session type " .
631 $session = call_user_func(array($session_class,
'fromMessage'),
633 if (is_a($session,
'Auth_OpenID_ServerError')) {
638 'assoc_type',
'HMAC-SHA1');
640 if (!in_array($assoc_type, $session->allowed_assoc_types)) {
641 $fmt =
"Session type %s does not support association type %s";
643 sprintf($fmt, $session_type, $assoc_type));
647 $obj->message = $message;
648 $obj->namespace = $message->getOpenIDNamespace();
657 'expires_in' => sprintf(
'%d', $assoc->getExpiresIn()),
658 'assoc_type' => $this->assoc_type,
659 'assoc_handle' => $assoc->handle));
662 $this->session->answer($assoc->secret));
664 if (! ($this->session->session_type ==
'no-encryption' 665 && $this->message->isOpenID1())) {
668 $this->session->session_type);
675 $preferred_association_type=null,
676 $preferred_session_type=null)
678 if ($this->message->isOpenID1()) {
684 'error_code',
'unsupported-type');
686 'error', $text_message);
688 if ($preferred_association_type) {
691 $preferred_association_type);
694 if ($preferred_session_type) {
697 $preferred_session_type);
714 var $verifyReturnTo =
'Auth_OpenID_verifyReturnTo';
719 var $mode =
"checkid_setup";
724 var $immediate =
false;
729 var $trust_root = null;
737 static function make($message, $identity, $return_to, $trust_root = null,
738 $immediate =
false, $assoc_handle = null,
$server = null)
742 "server must not be null");
751 $trust_root, $immediate,
754 $r->namespace = $message->getOpenIDNamespace();
755 $r->message = $message;
757 if (!
$r->trustRootValid()) {
767 $trust_root = null, $immediate =
false,
768 $assoc_handle = null,
$server = null,
772 $this->assoc_handle = $assoc_handle;
773 $this->identity = $identity;
774 if ($claimed_id === null) {
775 $this->claimed_id = $identity;
777 $this->claimed_id = $claimed_id;
779 $this->return_to = $return_to;
780 $this->trust_root = $trust_root;
784 $this->immediate =
true;
785 $this->mode =
"checkid_immediate";
787 $this->immediate =
false;
788 $this->mode =
"checkid_setup";
795 (is_a($other,
'Auth_OpenID_CheckIDRequest')) &&
796 ($this->
namespace == $other->namespace) &&
797 ($this->assoc_handle == $other->assoc_handle) &&
798 ($this->identity == $other->identity) &&
799 ($this->claimed_id == $other->claimed_id) &&
800 ($this->return_to == $other->return_to) &&
801 ($this->trust_root == $other->trust_root));
821 return call_user_func_array($this->verifyReturnTo,
822 array($this->trust_root, $this->return_to, $fetcher));
830 if ($mode ==
"checkid_immediate") {
832 $mode =
"checkid_immediate";
835 $mode =
"checkid_setup";
841 if (($message->isOpenID1()) &&
843 $fmt =
"Missing required field 'return_to' from checkid request";
850 if ($message->isOpenID1()) {
851 if ($identity === null) {
852 $s =
"OpenID 1 message did not contain openid.identity";
856 if ($identity && !$claimed_id) {
857 $s =
"OpenID 2.0 message contained openid.identity but not " .
860 }
else if ($claimed_id && !$identity) {
861 $s =
"OpenID 2.0 message contained openid.claimed_id " .
870 if ($message->isOpenID1()) {
871 $trust_root_param =
'trust_root';
873 $trust_root_param =
'realm';
878 $trust_root = $return_to;
881 if (! $message->isOpenID1() &&
882 ($return_to === null) &&
883 ($trust_root === null)) {
885 "openid.realm required when openid.return_to absent");
899 if (is_a($obj,
'Auth_OpenID_ServerError')) {
903 $obj->claimed_id = $claimed_id;
917 if (!$this->trust_root) {
927 if ($this->return_to !== null) {
974 function answer($allow, $server_url = null, $identity = null,
977 if (!$this->return_to) {
982 if ((!$this->message->isOpenID1()) &&
983 (!$this->server->op_endpoint)) {
985 "server should be constructed with op_endpoint to " .
986 "respond to OpenID 2.0 messages.");
989 $server_url = $this->server->op_endpoint;
994 }
else if ($this->message->isOpenID1()) {
995 if ($this->immediate) {
1001 if ($this->immediate) {
1002 $mode =
'setup_needed';
1008 if (!$this->trustRootValid()) {
1017 ($this->message->isOpenID1())) {
1019 "claimed_id is new in OpenID 2.0 and not " .
1020 "available for ".$this->
namespace);
1023 if ($identity && !$claimed_id) {
1024 $claimed_id = $identity;
1032 "This request uses IdP-driven identifier selection. " .
1033 "You must supply an identifier in the response.");
1036 $response_identity = $identity;
1037 $response_claimed_id = $claimed_id;
1039 }
else if ($this->identity) {
1041 ($this->identity != $identity)) {
1042 $fmt =
"Request was for %s, cannot reply with identity %s";
1044 sprintf($fmt, $this->identity, $identity));
1047 $response_identity = $this->identity;
1048 $response_claimed_id = $this->claimed_id;
1052 "This request specified no identity and " .
1053 "you supplied ".$identity);
1056 $response_identity = null;
1059 if (($this->message->isOpenID1()) &&
1060 ($response_identity === null)) {
1062 "Request was an OpenID 1 request, so response must " .
1063 "include an identifier.");
1067 array(
'mode' => $mode,
1068 'return_to' => $this->return_to,
1071 if (!$this->message->isOpenID1()) {
1073 'op_endpoint', $server_url);
1076 if ($response_identity !== null) {
1077 $response->fields->setArg(
1080 $response_identity);
1081 if ($this->message->isOpenID2()) {
1082 $response->fields->setArg(
1085 $response_claimed_id);
1093 if ($this->immediate) {
1094 if (($this->message->isOpenID1()) &&
1097 'setup_url is required for $allow=false \ 1098 in OpenID 1.x immediate mode.');
1106 $this->assoc_handle,
1109 $setup_request->message = $this->message;
1111 $setup_url = $setup_request->encodeToURL($server_url);
1113 if ($setup_url === null) {
1128 if (!$this->return_to) {
1137 $q = array(
'mode' => $this->mode,
1138 'identity' => $this->identity,
1139 'claimed_id' => $this->claimed_id,
1140 'return_to' => $this->return_to);
1142 if ($this->trust_root) {
1143 if ($this->message->isOpenID1()) {
1144 $q[
'trust_root'] = $this->trust_root;
1146 $q[
'realm'] = $this->trust_root;
1150 if ($this->assoc_handle) {
1151 $q[
'assoc_handle'] = $this->assoc_handle;
1155 $this->message->getOpenIDNamespace());
1157 return $response->toURL($server_url);
1162 if (!$this->return_to) {
1166 if ($this->immediate) {
1168 "Cancel is not an appropriate \ 1169 response to immediate mode \ 1174 $this->message->getOpenIDNamespace());
1176 return $response->toURL($this->return_to);
1189 $this->request = $request;
1197 if (in_array($this->request->mode, $_Auth_OpenID_Request_Modes)) {
1198 if ($this->
fields->isOpenID2() &&
1217 return $this->
fields->toFormMarkup($this->request->return_to,
1244 return $this->
fields->toURL($this->request->return_to);
1249 $extension_response->toMessage($this->
fields);
1255 'mode') ==
'id_res';
1260 return $this->
fields->toKVForm();
1278 $this->code = $code;
1281 if ($headers !== null) {
1282 $this->headers = $headers;
1284 $this->headers = array();
1287 if ($body !== null) {
1288 $this->body = $body;
1302 var $SECRET_LIFETIME = 1209600;
1308 var $normal_key =
'http://localhost/|normal';
1309 var $dumb_key =
'http://localhost/|dumb';
1317 $this->store = $store;
1326 $assoc = $this->getAssociation($assoc_handle,
true);
1333 return $assoc->checkMessageSignature($message);
1342 $signed_response = $response;
1343 $assoc_handle = $response->request->assoc_handle;
1345 if ($assoc_handle) {
1347 $assoc = $this->getAssociation($assoc_handle,
false,
false);
1348 if (!$assoc || ($assoc->getExpiresIn() <= 0)) {
1351 'invalidate_handle', $assoc_handle);
1352 $assoc_type = ($assoc ? $assoc->assoc_type :
'HMAC-SHA1');
1354 if ($assoc && ($assoc->getExpiresIn() <= 0)) {
1355 $this->invalidate($assoc_handle,
false);
1358 $assoc = $this->createAssociation(
true, $assoc_type);
1362 $assoc = $this->createAssociation(
true);
1365 $signed_response->fields = $assoc->signMessage(
1366 $signed_response->fields);
1367 return $signed_response;
1379 $handle = sprintf(
'{%s}{%x}{%s}', $assoc_type, intval(time()), $uniq);
1382 $this->SECRET_LIFETIME, $handle, $secret, $assoc_type);
1385 $key = $this->dumb_key;
1387 $key = $this->normal_key;
1390 $this->store->storeAssociation($key, $assoc);
1400 if ($assoc_handle === null) {
1402 "assoc_handle must not be null");
1406 $key = $this->dumb_key;
1408 $key = $this->normal_key;
1411 $assoc = $this->store->getAssociation($key, $assoc_handle);
1413 if (($assoc !== null) && ($assoc->getExpiresIn() <= 0)) {
1414 if ($check_expiration) {
1415 $this->store->removeAssociation($key, $assoc_handle);
1429 $key = $this->dumb_key;
1431 $key = $this->normal_key;
1433 $this->store->removeAssociation($key, $assoc_handle);
1445 var $responseFactory =
'Auth_OpenID_WebResponse';
1453 $cls = $this->responseFactory;
1455 $encode_as = $response->whichEncoding();
1457 $wr =
new $cls(null, null, $response->encodeToKVForm());
1458 if (is_a($response,
'Auth_OpenID_ServerError')) {
1467 $response->toHTML());
1472 if(isset($response->code)) {
1473 $wr->code = $response->code;
1488 $this->signatory = $signatory;
1499 if (!is_a($response,
'Auth_OpenID_ServerError') &&
1500 $response->needsSigning()) {
1502 if (!$this->signatory) {
1504 "Must have a store to sign request");
1510 $response = $this->signatory->sign($response);
1513 return parent::encode($response);
1528 $this->handlers = array(
1529 'checkid_setup' =>
'Auth_OpenID_CheckIDRequest',
1530 'checkid_immediate' =>
'Auth_OpenID_CheckIDRequest',
1531 'check_authentication' =>
'Auth_OpenID_CheckAuthRequest',
1532 'associate' =>
'Auth_OpenID_AssociateRequest' 1548 if ($message === null) {
1556 $old_ns =
$query[
'openid.ns'];
1562 sprintf(
"Invalid OpenID namespace URI: %s", $old_ns));
1568 "No mode value in message");
1577 $this->defaultDecoder($message));
1579 if (!is_a($handlerCls,
'Auth_OpenID_ServerError')) {
1580 return call_user_func_array(array($handlerCls,
'fromMessage'),
1581 array($message, $this->server));
1597 sprintf(
"Unrecognized OpenID mode %s", $mode));
1609 $this->response = $response;
1632 parent::Auth_OpenID_ServerError($message,
"Untrusted return_to URL");
1633 $this->return_to = $return_to;
1634 $this->trust_root = $trust_root;
1639 return sprintf(
"return_to %s not under trust_root %s",
1640 $this->return_to, $this->trust_root);
1684 $this->store = $store;
1688 $this->op_endpoint = $op_endpoint;
1705 if (method_exists($this,
"openid_" . $request->mode)) {
1706 $handler = array($this,
"openid_" . $request->mode);
1707 return call_user_func($handler, &$request);
1717 return $request->answer($this->signatory);
1725 $assoc_type = $request->assoc_type;
1726 $session_type = $request->session->session_type;
1727 if ($this->negotiator->isAllowed($assoc_type, $session_type)) {
1728 $assoc = $this->signatory->createAssociation(
false,
1730 return $request->answer($assoc);
1732 $message = sprintf(
'Association type %s is not supported with '.
1733 'session type %s', $assoc_type, $session_type);
1734 list($preferred_assoc_type, $preferred_session_type) =
1735 $this->negotiator->getAllowedType();
1736 return $request->answerUnsupported($message,
1737 $preferred_assoc_type,
1738 $preferred_session_type);
1748 return $this->encoder->encode($response);
1761 return $this->decoder->decode(
$query);
if($err=$client->getError()) $namespace
static fromMessage($message)
Auth_OpenID_getDefaultNegotiator()
decode($query)
Given an HTTP query in an array (key-value pairs), decode it into an Auth_OpenID_Request object...
Auth_OpenID_ServerResponse($request)
const Auth_OpenID_OPENID_NS
static getHTTPFetcher($timeout=20)
Returns an HTTP fetcher object.
invalidate($assoc_handle, $dumb)
Invalidate a given association handle.
Auth_OpenID_isError($obj, $cls='Auth_OpenID_ServerError')
private
Auth_OpenID_AssociateRequest($session, $assoc_type)
sign($response)
Given a response, sign the fields in the response's 'signed' list, and insert the signature into the ...
global $_Auth_OpenID_Request_Modes
private
const AUTH_OPENID_HTTP_ERROR
const Auth_OpenID_ENCODE_KVFORM
private
Auth_OpenID_Server($store, $op_endpoint=null)
static make($message, $identity, $return_to, $trust_root=null, $immediate=false, $assoc_handle=null, $server=null)
static fromExpiresIn($expires_in, $handle, $secret, $assoc_type)
This is an alternate constructor (factory method) used by the OpenID consumer library to create assoc...
static _parse($trust_root)
Parse a URL into its trust_root parts.
encodeToURL()
Encodes this error's response as a URL suitable for redirection.
setArg($namespace, $key, $value)
addExtension($extension_response)
static fromMessage($message, $server=null)
const Auth_OpenID_OPENID2_NS
openid_check_authentication($request)
The callback for 'check_authentication' messages.
$namespace
The OpenID namespace for this request.
static autoSubmitHTML($form, $title="OpenId transaction in progress")
Auth_OpenID_getSecretSize($assoc_type)
encode($response)
Encode an Auth_OpenID_ServerResponse and return an Auth_OpenID_WebResponse.
Auth_OpenID_WebResponse($code=null, $headers=null, $body=null)
static fromMessage($message, $server=null)
static fromPostArgs($args)
Auth_OpenID_UntrustedReturnURL($message, $return_to, $trust_root)
toFormMarkup($form_tag_attrs=null)
Auth_OpenID_SigningEncoder($signatory)
encodeToKVForm()
Encodes the response to key-value form.
Auth_OpenID_CheckIDRequest($identity, $return_to, $trust_root=null, $immediate=false, $assoc_handle=null, $server=null, $claimed_id=null)
handleRequest($request)
Handle a request.
createAssociation($dumb=true, $assoc_type='HMAC-SHA1')
Make a new association.
Auth_OpenID_DiffieHellmanSHA1ServerSession($dh, $consumer_pubkey)
static fromMessage($unused_request)
getAssociation($assoc_handle, $dumb, $check_expiration=true)
Given an association handle, get the association from the store, or return a ServerError or null if s...
const Auth_OpenID_ENCODE_HTML_FORM
private
toFormMarkup($form_tag_attrs=null)
encodeResponse($response)
Encodes as response in the appropriate format suitable for sending to the user agent.
Auth_OpenID_Decoder($server)
const Auth_OpenID_ENCODE_URL
private
answerUnsupported($text_message, $preferred_association_type=null, $preferred_session_type=null)
hasReturnTo()
Returns the return_to URL for the request which caused this error.
static match($trust_root, $url)
Does this URL match the given trust root?
openid_associate($request)
The callback for 'associate' messages.
const AUTH_OPENID_HTTP_REDIRECT
verify($assoc_handle, $message)
Verify, using a given association handle, a signature with signed key-value pairs from an HTTP reques...
toHTML($form_tag_attrs=null)
static fromMessage($message, $server)
decodeRequest($query=null)
Decodes a query args array into the appropriate Auth_OpenID_Request object.
Auth_OpenID_CheckAuthRequest($assoc_handle, $signed, $invalidate_handle=null)
answer($allow, $server_url=null, $identity=null, $claimed_id=null)
Respond to this request.
static arrayGet($arr, $key, $fallback=null)
Convenience function for getting array values.
static fromMessage($message)
Auth_OpenID_NoReturnToError($message=null, $text="No return_to URL available")
Auth_OpenID_mkNonce($when=null)
Auth_OpenID_Signatory($store)
Create a new signatory using a given store.
toString()
Returns this error message.
static getQuery($query_str=null)
Gets the query data from the server environment based on the request method used. ...
static isFailure($thing)
Return true if $thing is an Auth_OpenID_FailureResponse object; false if not.
whichEncoding()
Returns one of Auth_OpenID_ENCODE_URL, Auth_OpenID_ENCODE_KVFORM, or null, depending on the type of e...
static getBytes($num_bytes)
Get the specified number of random bytes.
static getSessionClasses()
const AUTH_OPENID_HTTP_OK
Required imports.
encode($response)
Sign an Auth_OpenID_ServerResponse and return an Auth_OpenID_WebResponse.
const Auth_OpenID_OPENID1_URL_LIMIT
updateArgs($namespace, $updates)
const Auth_OpenID_IDENTIFIER_SELECT
Import tools needed to deal with messages.
Auth_OpenID_EncodingError($response)
Auth_OpenID_ServerError($message=null, $text=null, $reference=null, $contact=null)
private