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")
303 return "No return_to available";
315 $this->return_to = $return_to;
327 $text =
"Malformed trust root")
334 return "Malformed trust root";
359 $this->assoc_handle = $assoc_handle;
360 $this->
signed = $signed;
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);
392 $result->message = $message;
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);
446 return array(
'mac_key' => base64_encode($secret));
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));
567 if (is_a($result,
'Auth_OpenID_ServerError')) {
570 list($dh, $consumer_pubkey) = $result;
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);
742 "server must not be null");
754 $r->namespace = $message->getOpenIDNamespace();
755 $r->message = $message;
757 if (!$r->trustRootValid()) {
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;
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';
881 if (! $message->isOpenID1() &&
882 ($return_to === 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';
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()) {
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;
1317 $this->store = $store;
1333 return $assoc->checkMessageSignature($message);
1342 $signed_response = $response;
1343 $assoc_handle = $response->request->assoc_handle;
1345 if ($assoc_handle) {
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)) {
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);
1390 $this->store->storeAssociation($key, $assoc);
1400 if ($assoc_handle === null) {
1402 "assoc_handle must not be null");
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);
1433 $this->store->removeAssociation($key, $assoc_handle);
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);
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");
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;
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);