📄 consumer.php
字号:
} } return $response; }}class Auth_OpenID_DiffieHellmanConsumerSession { var $session_type = 'DH-SHA1'; function Auth_OpenID_DiffieHellmanConsumerSession($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('openid.dh_consumer_public' => $cpub); if (!$this->dh->usingDefaultValues()) { $args = array_merge($args, array( 'openid.dh_modulus' => $math->longToBase64($this->dh->mod), 'openid.dh_gen' => $math->longToBase64($this->dh->gen))); } return $args; } function extractSecret($response) { if (!array_key_exists('dh_server_public', $response)) { return null; } if (!array_key_exists('enc_mac_key', $response)) { return null; } $math =& Auth_OpenID_getMathLib(); $spub = $math->base64ToLong($response['dh_server_public']); $enc_mac_key = base64_decode($response['enc_mac_key']); return $this->dh->xorSecret($spub, $enc_mac_key); }}class Auth_OpenID_PlainTextConsumerSession { var $session_type = null; function getRequest() { return array(); } function extractSecret($response) { if (!array_key_exists('mac_key', $response)) { return null; } return base64_decode($response['mac_key']); }}/** * This class is the interface to the OpenID consumer logic. * Instances of it maintain no per-request state, so they can be * reused (or even used by multiple threads concurrently) as needed. * * @package OpenID * @access private */class Auth_OpenID_GenericConsumer { /** * This consumer's store object. */ var $store; /** * @access private */ var $_use_assocs; /** * This is the number of characters in the generated nonce for * each transaction. */ var $nonce_len = 8; /** * What characters are allowed in nonces */ var $nonce_chrs = Auth_OpenID_DEFAULT_NONCE_CHRS; /** * This method initializes a new {@link Auth_OpenID_Consumer} * instance to access the library. * * @param Auth_OpenID_OpenIDStore $store This must be an object * that implements the interface in {@link Auth_OpenID_OpenIDStore}. * Several concrete implementations are provided, to cover most common use * cases. For stores backed by MySQL, PostgreSQL, or SQLite, see * the {@link Auth_OpenID_SQLStore} class and its sublcasses. For a * filesystem-backed store, see the {@link Auth_OpenID_FileStore} module. * As a last resort, if it isn't possible for the server to store * state at all, an instance of {@link Auth_OpenID_DumbStore} can be used. * * @param bool $immediate This is an optional boolean value. It * controls whether the library uses immediate mode, as explained * in the module description. The default value is False, which * disables immediate mode. */ function Auth_OpenID_GenericConsumer(&$store) { $this->store =& $store; $this->_use_assocs = !(defined('Auth_OpenID_NO_MATH_SUPPORT') || ($this->store && $this->store->isDumb())); $this->fetcher = Services_Yadis_Yadis::getHTTPFetcher(); } function begin($service_endpoint) { $nonce = $this->_createNonce(); $assoc = $this->_getAssociation($service_endpoint->server_url); $r = new Auth_OpenID_AuthRequest($assoc, $service_endpoint); $r->return_to_args['nonce'] = $nonce; return $r; } function complete($query, $endpoint) { $mode = Auth_OpenID::arrayGet($query, 'openid.mode', '<no mode specified>'); if ($mode == Auth_OpenID_CANCEL) { return new Auth_OpenID_CancelResponse($endpoint); } else if ($mode == 'error') { $error = Auth_OpenID::arrayGet($query, 'openid.error'); return new Auth_OpenID_FailureResponse($endpoint, $error); } else if ($mode == 'id_res') { if ($endpoint->identity_url === null) { return new Auth_OpenID_FailureResponse($identity_url, "No session state found"); } $response = $this->_doIdRes($query, $endpoint); if ($response === null) { return new Auth_OpenID_FailureResponse($endpoint, "HTTP request failed"); } if ($response->status == Auth_OpenID_SUCCESS) { return $this->_checkNonce($response, Auth_OpenID::arrayGet($query, 'nonce')); } else { return $response; } } else { return new Auth_OpenID_FailureResponse($endpoint, sprintf("Invalid openid.mode '%s'", $mode)); } } /** * @access private */ function _doIdRes($query, $endpoint) { $user_setup_url = Auth_OpenID::arrayGet($query, 'openid.user_setup_url'); if ($user_setup_url !== null) { return new Auth_OpenID_SetupNeededResponse($endpoint, $user_setup_url); } $return_to = Auth_OpenID::arrayGet($query, 'openid.return_to', null); $server_id2 = Auth_OpenID::arrayGet($query, 'openid.identity', null); $assoc_handle = Auth_OpenID::arrayGet($query, 'openid.assoc_handle', null); if (($return_to === null) || ($server_id2 === null) || ($assoc_handle === null)) { return new Auth_OpenID_FailureResponse($endpoint, "Missing required field"); } if ($endpoint->getServerID() != $server_id2) { return new Auth_OpenID_FailureResponse($endpoint, "Server ID (delegate) mismatch"); } $signed = Auth_OpenID::arrayGet($query, 'openid.signed'); $assoc = $this->store->getAssociation($endpoint->server_url, $assoc_handle); if ($assoc === null) { // It's not an association we know about. Dumb mode is // our only possible path for recovery. if ($this->_checkAuth($query, $endpoint->server_url)) { return new Auth_OpenID_SuccessResponse($endpoint, $query, $signed); } else { return new Auth_OpenID_FailureResponse($endpoint, "Server denied check_authentication"); } } if ($assoc->getExpiresIn() <= 0) { $msg = sprintf("Association with %s expired", $endpoint->server_url); return new Auth_OpenID_FailureResponse($endpoint, $msg); } // Check the signature $sig = Auth_OpenID::arrayGet($query, 'openid.sig', null); if (($sig === null) || ($signed === null)) { return new Auth_OpenID_FailureResponse($endpoint, "Missing argument signature"); } $signed_list = explode(",", $signed); //Fail if the identity field is present but not signed if (($endpoint->identity_url !== null) && (!in_array('identity', $signed_list))) { $msg = '"openid.identity" not signed'; return new Auth_OpenID_FailureResponse($endpoint, $msg); } $v_sig = $assoc->signDict($signed_list, $query); if ($v_sig != $sig) { return new Auth_OpenID_FailureResponse($endpoint, "Bad signature"); } return Auth_OpenID_SuccessResponse::fromQuery($endpoint, $query, $signed); } /** * @access private */ function _checkAuth($query, $server_url) { $request = $this->_createCheckAuthRequest($query); if ($request === null) { return false; } $response = $this->_makeKVPost($request, $server_url); if ($response == null) { return false; } return $this->_processCheckAuthResponse($response, $server_url); } /** * @access private */ function _createCheckAuthRequest($query) { $signed = Auth_OpenID::arrayGet($query, 'openid.signed', null); if ($signed === null) { return null; } $whitelist = array('assoc_handle', 'sig', 'signed', 'invalidate_handle'); $signed = array_merge(explode(",", $signed), $whitelist); $check_args = array(); foreach ($query as $key => $value) { if (in_array(substr($key, 7), $signed)) { $check_args[$key] = $value; } } $check_args['openid.mode'] = 'check_authentication'; return $check_args; } /** * @access private */ function _processCheckAuthResponse($response, $server_url) { $is_valid = Auth_OpenID::arrayGet($response, 'is_valid', 'false'); $invalidate_handle = Auth_OpenID::arrayGet($response, 'invalidate_handle'); if ($invalidate_handle !== null) { $this->store->removeAssociation($server_url, $invalidate_handle); } if ($is_valid == 'true') { return true; } return false; } /** * @access private */ function _makeKVPost($args, $server_url) { $mode = $args['openid.mode']; $pairs = array(); foreach ($args as $k => $v) { $v = urlencode($v); $pairs[] = "$k=$v"; } $body = implode("&", $pairs); $resp = $this->fetcher->post($server_url, $body); if ($resp === null) { return null; } $response = Auth_OpenID_KVForm::toArray($resp->body); if ($resp->status == 400) { return null; } else if ($resp->status != 200) { return null; } return $response; } /** * @access private */ function _checkNonce($response, $nonce) { $parsed_url = parse_url($response->getReturnTo()); $query_str = @$parsed_url['query']; $query = array(); parse_str($query_str, $query); $found = false; foreach ($query as $k => $v) { if ($k == 'nonce') { if ($v != $nonce) { return new Auth_OpenID_FailureResponse($response, "Nonce mismatch"); } else { $found = true; break; } } } if (!$found) { return new Auth_OpenID_FailureResponse($response, sprintf("Nonce missing from return_to: %s", $response->getReturnTo())); } if (!$this->store->useNonce($nonce)) { return new Auth_OpenID_FailureResponse($response, "Nonce missing from store"); } return $response; } /** * @access private
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -