forked from GNUsocial/gnu-social
		
	
		
			
	
	
		
			1755 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
		
		
			
		
	
	
			1755 lines
		
	
	
		
			56 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| 
								 | 
							
								<?php
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * OpenID server protocol and logic.
							 | 
						||
| 
								 | 
							
								 * 
							 | 
						||
| 
								 | 
							
								 * Overview
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * An OpenID server must perform three tasks:
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 *  1. Examine the incoming request to determine its nature and validity.
							 | 
						||
| 
								 | 
							
								 *  2. Make a decision about how to respond to this request.
							 | 
						||
| 
								 | 
							
								 *  3. Format the response according to the protocol.
							 | 
						||
| 
								 | 
							
								 * 
							 | 
						||
| 
								 | 
							
								 * The first and last of these tasks may performed by the {@link
							 | 
						||
| 
								 | 
							
								 * Auth_OpenID_Server::decodeRequest()} and {@link
							 | 
						||
| 
								 | 
							
								 * Auth_OpenID_Server::encodeResponse} methods.  Who gets to do the
							 | 
						||
| 
								 | 
							
								 * intermediate task -- deciding how to respond to the request -- will
							 | 
						||
| 
								 | 
							
								 * depend on what type of request it is.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * If it's a request to authenticate a user (a 'checkid_setup' or
							 | 
						||
| 
								 | 
							
								 * 'checkid_immediate' request), you need to decide if you will assert
							 | 
						||
| 
								 | 
							
								 * that this user may claim the identity in question.  Exactly how you
							 | 
						||
| 
								 | 
							
								 * do that is a matter of application policy, but it generally
							 | 
						||
| 
								 | 
							
								 * involves making sure the user has an account with your system and
							 | 
						||
| 
								 | 
							
								 * is logged in, checking to see if that identity is hers to claim,
							 | 
						||
| 
								 | 
							
								 * and verifying with the user that she does consent to releasing that
							 | 
						||
| 
								 | 
							
								 * information to the party making the request.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Examine the properties of the {@link Auth_OpenID_CheckIDRequest}
							 | 
						||
| 
								 | 
							
								 * object, and if and when you've come to a decision, form a response
							 | 
						||
| 
								 | 
							
								 * by calling {@link Auth_OpenID_CheckIDRequest::answer()}.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Other types of requests relate to establishing associations between
							 | 
						||
| 
								 | 
							
								 * client and server and verifing the authenticity of previous
							 | 
						||
| 
								 | 
							
								 * communications.  {@link Auth_OpenID_Server} contains all the logic
							 | 
						||
| 
								 | 
							
								 * and data necessary to respond to such requests; just pass it to
							 | 
						||
| 
								 | 
							
								 * {@link Auth_OpenID_Server::handleRequest()}.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * OpenID Extensions
							 | 
						||
| 
								 | 
							
								 * 
							 | 
						||
| 
								 | 
							
								 * Do you want to provide other information for your users in addition
							 | 
						||
| 
								 | 
							
								 * to authentication?  Version 1.2 of the OpenID protocol allows
							 | 
						||
| 
								 | 
							
								 * consumers to add extensions to their requests.  For example, with
							 | 
						||
| 
								 | 
							
								 * sites using the Simple Registration
							 | 
						||
| 
								 | 
							
								 * Extension
							 | 
						||
| 
								 | 
							
								 * (http://www.openidenabled.com/openid/simple-registration-extension/),
							 | 
						||
| 
								 | 
							
								 * a user can agree to have their nickname and e-mail address sent to
							 | 
						||
| 
								 | 
							
								 * a site when they sign up.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Since extensions do not change the way OpenID authentication works,
							 | 
						||
| 
								 | 
							
								 * code to handle extension requests may be completely separate from
							 | 
						||
| 
								 | 
							
								 * the {@link Auth_OpenID_Request} class here.  But you'll likely want
							 | 
						||
| 
								 | 
							
								 * data sent back by your extension to be signed.  {@link
							 | 
						||
| 
								 | 
							
								 * Auth_OpenID_ServerResponse} provides methods with which you can add
							 | 
						||
| 
								 | 
							
								 * data to it which can be signed with the other data in the OpenID
							 | 
						||
| 
								 | 
							
								 * signature.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * For example:
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * <pre>  // when request is a checkid_* request
							 | 
						||
| 
								 | 
							
								 *  $response = $request->answer(true);
							 | 
						||
| 
								 | 
							
								 *  // this will a signed 'openid.sreg.timezone' parameter to the response
							 | 
						||
| 
								 | 
							
								 *  response.addField('sreg', 'timezone', 'America/Los_Angeles')</pre>
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Stores
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * The OpenID server needs to maintain state between requests in order
							 | 
						||
| 
								 | 
							
								 * to function.  Its mechanism for doing this is called a store.  The
							 | 
						||
| 
								 | 
							
								 * store interface is defined in Interface.php.  Additionally, several
							 | 
						||
| 
								 | 
							
								 * concrete store implementations are provided, so that most sites
							 | 
						||
| 
								 | 
							
								 * won't need to implement a custom store.  For a store backed by flat
							 | 
						||
| 
								 | 
							
								 * files on disk, see {@link Auth_OpenID_FileStore}.  For stores based
							 | 
						||
| 
								 | 
							
								 * on MySQL, SQLite, or PostgreSQL, see the {@link
							 | 
						||
| 
								 | 
							
								 * Auth_OpenID_SQLStore} subclasses.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Upgrading
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * The keys by which a server looks up associations in its store have
							 | 
						||
| 
								 | 
							
								 * changed in version 1.2 of this library.  If your store has entries
							 | 
						||
| 
								 | 
							
								 * created from version 1.0 code, you should empty it.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * PHP versions 4 and 5
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * LICENSE: See the COPYING file included in this distribution.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 * @author JanRain, Inc. <openid@janrain.com>
							 | 
						||
| 
								 | 
							
								 * @copyright 2005-2008 Janrain, Inc.
							 | 
						||
| 
								 | 
							
								 * @license http://www.apache.org/licenses/LICENSE-2.0 Apache
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Required imports
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								require_once "Auth/OpenID.php";
							 | 
						||
| 
								 | 
							
								require_once "Auth/OpenID/Association.php";
							 | 
						||
| 
								 | 
							
								require_once "Auth/OpenID/CryptUtil.php";
							 | 
						||
| 
								 | 
							
								require_once "Auth/OpenID/BigMath.php";
							 | 
						||
| 
								 | 
							
								require_once "Auth/OpenID/DiffieHellman.php";
							 | 
						||
| 
								 | 
							
								require_once "Auth/OpenID/KVForm.php";
							 | 
						||
| 
								 | 
							
								require_once "Auth/OpenID/TrustRoot.php";
							 | 
						||
| 
								 | 
							
								require_once "Auth/OpenID/ServerRequest.php";
							 | 
						||
| 
								 | 
							
								require_once "Auth/OpenID/Message.php";
							 | 
						||
| 
								 | 
							
								require_once "Auth/OpenID/Nonce.php";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								define('AUTH_OPENID_HTTP_OK', 200);
							 | 
						||
| 
								 | 
							
								define('AUTH_OPENID_HTTP_REDIRECT', 302);
							 | 
						||
| 
								 | 
							
								define('AUTH_OPENID_HTTP_ERROR', 400);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @access private
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								global $_Auth_OpenID_Request_Modes;
							 | 
						||
| 
								 | 
							
								$_Auth_OpenID_Request_Modes = array('checkid_setup',
							 | 
						||
| 
								 | 
							
								                                    'checkid_immediate');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @access private
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								define('Auth_OpenID_ENCODE_KVFORM', 'kfvorm');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @access private
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								define('Auth_OpenID_ENCODE_URL', 'URL/redirect');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @access private
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								define('Auth_OpenID_ENCODE_HTML_FORM', 'HTML form');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * @access private
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								function Auth_OpenID_isError($obj, $cls = 'Auth_OpenID_ServerError')
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    return is_a($obj, $cls);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * An error class which gets instantiated and returned whenever an
							 | 
						||
| 
								 | 
							
								 * OpenID protocol error occurs.  Be prepared to use this in place of
							 | 
						||
| 
								 | 
							
								 * an ordinary server response.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_ServerError {
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * @access private
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_ServerError($message = null, $text = null,
							 | 
						||
| 
								 | 
							
								                                     $reference = null, $contact = null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $this->message = $message;
							 | 
						||
| 
								 | 
							
								        $this->text = $text;
							 | 
						||
| 
								 | 
							
								        $this->contact = $contact;
							 | 
						||
| 
								 | 
							
								        $this->reference = $reference;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function getReturnTo()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ($this->message &&
							 | 
						||
| 
								 | 
							
								            $this->message->hasKey(Auth_OpenID_OPENID_NS, 'return_to')) {
							 | 
						||
| 
								 | 
							
								            return $this->message->getArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                          'return_to');
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            return null;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Returns the return_to URL for the request which caused this
							 | 
						||
| 
								 | 
							
								     * error.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function hasReturnTo()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->getReturnTo() !== null;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Encodes this error's response as a URL suitable for
							 | 
						||
| 
								 | 
							
								     * redirection.  If the response has no return_to, another
							 | 
						||
| 
								 | 
							
								     * Auth_OpenID_ServerError is returned.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function encodeToURL()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!$this->message) {
							 | 
						||
| 
								 | 
							
								            return null;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $msg = $this->toMessage();
							 | 
						||
| 
								 | 
							
								        return $msg->toURL($this->getReturnTo());
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Encodes the response to key-value form.  This is a
							 | 
						||
| 
								 | 
							
								     * machine-readable format used to respond to messages which came
							 | 
						||
| 
								 | 
							
								     * directly from the consumer and not through the user-agent.  See
							 | 
						||
| 
								 | 
							
								     * the OpenID specification.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function encodeToKVForm()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return Auth_OpenID_KVForm::fromArray(
							 | 
						||
| 
								 | 
							
								                                      array('mode' => 'error',
							 | 
						||
| 
								 | 
							
								                                            'error' => $this->toString()));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function toFormMarkup($form_tag_attrs=null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $msg = $this->toMessage();
							 | 
						||
| 
								 | 
							
								        return $msg->toFormMarkup($this->getReturnTo(), $form_tag_attrs);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function toHTML($form_tag_attrs=null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return Auth_OpenID::autoSubmitHTML(
							 | 
						||
| 
								 | 
							
								                      $this->toFormMarkup($form_tag_attrs));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function toMessage()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // Generate a Message object for sending to the relying party,
							 | 
						||
| 
								 | 
							
								        // after encoding.
							 | 
						||
| 
								 | 
							
								        $namespace = $this->message->getOpenIDNamespace();
							 | 
						||
| 
								 | 
							
								        $reply = new Auth_OpenID_Message($namespace);
							 | 
						||
| 
								 | 
							
								        $reply->setArg(Auth_OpenID_OPENID_NS, 'mode', 'error');
							 | 
						||
| 
								 | 
							
								        $reply->setArg(Auth_OpenID_OPENID_NS, 'error', $this->toString());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($this->contact !== null) {
							 | 
						||
| 
								 | 
							
								            $reply->setArg(Auth_OpenID_OPENID_NS, 'contact', $this->contact);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($this->reference !== null) {
							 | 
						||
| 
								 | 
							
								            $reply->setArg(Auth_OpenID_OPENID_NS, 'reference',
							 | 
						||
| 
								 | 
							
								                           $this->reference);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $reply;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Returns one of Auth_OpenID_ENCODE_URL,
							 | 
						||
| 
								 | 
							
								     * Auth_OpenID_ENCODE_KVFORM, or null, depending on the type of
							 | 
						||
| 
								 | 
							
								     * encoding expected for this error's payload.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function whichEncoding()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        global $_Auth_OpenID_Request_Modes;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($this->hasReturnTo()) {
							 | 
						||
| 
								 | 
							
								            if ($this->message->isOpenID2() &&
							 | 
						||
| 
								 | 
							
								                (strlen($this->encodeToURL()) >
							 | 
						||
| 
								 | 
							
								                   Auth_OpenID_OPENID1_URL_LIMIT)) {
							 | 
						||
| 
								 | 
							
								                return Auth_OpenID_ENCODE_HTML_FORM;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                return Auth_OpenID_ENCODE_URL;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!$this->message) {
							 | 
						||
| 
								 | 
							
								            return null;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $mode = $this->message->getArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                       'mode');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($mode) {
							 | 
						||
| 
								 | 
							
								            if (!in_array($mode, $_Auth_OpenID_Request_Modes)) {
							 | 
						||
| 
								 | 
							
								                return Auth_OpenID_ENCODE_KVFORM;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return null;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Returns this error message.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function toString()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ($this->text) {
							 | 
						||
| 
								 | 
							
								            return $this->text;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            return get_class($this) . " error";
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Error returned by the server code when a return_to is absent from a
							 | 
						||
| 
								 | 
							
								 * request.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_NoReturnToError extends Auth_OpenID_ServerError {
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_NoReturnToError($message = null,
							 | 
						||
| 
								 | 
							
								                                         $text = "No return_to URL available")
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        parent::Auth_OpenID_ServerError($message, $text);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function toString()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return "No return_to available";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * An error indicating that the return_to URL is malformed.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_MalformedReturnURL extends Auth_OpenID_ServerError {
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_MalformedReturnURL($message, $return_to)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $this->return_to = $return_to;
							 | 
						||
| 
								 | 
							
								        parent::Auth_OpenID_ServerError($message, "malformed return_to URL");
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * This error is returned when the trust_root value is malformed.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_MalformedTrustRoot extends Auth_OpenID_ServerError {
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_MalformedTrustRoot($message = null,
							 | 
						||
| 
								 | 
							
								                                            $text = "Malformed trust root")
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        parent::Auth_OpenID_ServerError($message, $text);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function toString()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return "Malformed trust root";
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * The base class for all server request classes.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_Request {
							 | 
						||
| 
								 | 
							
								    var $mode = null;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * A request to verify the validity of a previous response.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_CheckAuthRequest extends Auth_OpenID_Request {
							 | 
						||
| 
								 | 
							
								    var $mode = "check_authentication";
							 | 
						||
| 
								 | 
							
								    var $invalidate_handle = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_CheckAuthRequest($assoc_handle, $signed,
							 | 
						||
| 
								 | 
							
								                                          $invalidate_handle = null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $this->assoc_handle = $assoc_handle;
							 | 
						||
| 
								 | 
							
								        $this->signed = $signed;
							 | 
						||
| 
								 | 
							
								        if ($invalidate_handle !== null) {
							 | 
						||
| 
								 | 
							
								            $this->invalidate_handle = $invalidate_handle;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $this->namespace = Auth_OpenID_OPENID2_NS;
							 | 
						||
| 
								 | 
							
								        $this->message = null;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function fromMessage($message, $server=null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $required_keys = array('assoc_handle', 'sig', 'signed');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        foreach ($required_keys as $k) {
							 | 
						||
| 
								 | 
							
								            if (!$message->getArg(Auth_OpenID_OPENID_NS, $k)) {
							 | 
						||
| 
								 | 
							
								                return new Auth_OpenID_ServerError($message,
							 | 
						||
| 
								 | 
							
								                    sprintf("%s request missing required parameter %s from \
							 | 
						||
| 
								 | 
							
								                            query", "check_authentication", $k));
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $assoc_handle = $message->getArg(Auth_OpenID_OPENID_NS, 'assoc_handle');
							 | 
						||
| 
								 | 
							
								        $sig = $message->getArg(Auth_OpenID_OPENID_NS, 'sig');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $signed_list = $message->getArg(Auth_OpenID_OPENID_NS, 'signed');
							 | 
						||
| 
								 | 
							
								        $signed_list = explode(",", $signed_list);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $signed = $message;
							 | 
						||
| 
								 | 
							
								        if ($signed->hasKey(Auth_OpenID_OPENID_NS, 'mode')) {
							 | 
						||
| 
								 | 
							
								            $signed->setArg(Auth_OpenID_OPENID_NS, 'mode', 'id_res');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $result = new Auth_OpenID_CheckAuthRequest($assoc_handle, $signed);
							 | 
						||
| 
								 | 
							
								        $result->message = $message;
							 | 
						||
| 
								 | 
							
								        $result->sig = $sig;
							 | 
						||
| 
								 | 
							
								        $result->invalidate_handle = $message->getArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                                      'invalidate_handle');
							 | 
						||
| 
								 | 
							
								        return $result;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function answer(&$signatory)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $is_valid = $signatory->verify($this->assoc_handle, $this->signed);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Now invalidate that assoc_handle so it this checkAuth
							 | 
						||
| 
								 | 
							
								        // message cannot be replayed.
							 | 
						||
| 
								 | 
							
								        $signatory->invalidate($this->assoc_handle, true);
							 | 
						||
| 
								 | 
							
								        $response = new Auth_OpenID_ServerResponse($this);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $response->fields->setArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                  'is_valid',
							 | 
						||
| 
								 | 
							
								                                  ($is_valid ? "true" : "false"));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($this->invalidate_handle) {
							 | 
						||
| 
								 | 
							
								            $assoc = $signatory->getAssociation($this->invalidate_handle,
							 | 
						||
| 
								 | 
							
								                                                false);
							 | 
						||
| 
								 | 
							
								            if (!$assoc) {
							 | 
						||
| 
								 | 
							
								                $response->fields->setArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                          'invalidate_handle',
							 | 
						||
| 
								 | 
							
								                                          $this->invalidate_handle);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return $response;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * A class implementing plaintext server sessions.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_PlainTextServerSession {
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * An object that knows how to handle association requests with no
							 | 
						||
| 
								 | 
							
								     * session type.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    var $session_type = 'no-encryption';
							 | 
						||
| 
								 | 
							
								    var $needs_math = false;
							 | 
						||
| 
								 | 
							
								    var $allowed_assoc_types = array('HMAC-SHA1', 'HMAC-SHA256');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function fromMessage($unused_request)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return new Auth_OpenID_PlainTextServerSession();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function answer($secret)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return array('mac_key' => base64_encode($secret));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * A class implementing DH-SHA1 server sessions.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_DiffieHellmanSHA1ServerSession {
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * An object that knows how to handle association requests with
							 | 
						||
| 
								 | 
							
								     * the Diffie-Hellman session type.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var $session_type = 'DH-SHA1';
							 | 
						||
| 
								 | 
							
								    var $needs_math = true;
							 | 
						||
| 
								 | 
							
								    var $allowed_assoc_types = array('HMAC-SHA1');
							 | 
						||
| 
								 | 
							
								    var $hash_func = 'Auth_OpenID_SHA1';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_DiffieHellmanSHA1ServerSession($dh, $consumer_pubkey)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $this->dh = $dh;
							 | 
						||
| 
								 | 
							
								        $this->consumer_pubkey = $consumer_pubkey;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function getDH($message)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $dh_modulus = $message->getArg(Auth_OpenID_OPENID_NS, 'dh_modulus');
							 | 
						||
| 
								 | 
							
								        $dh_gen = $message->getArg(Auth_OpenID_OPENID_NS, 'dh_gen');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ((($dh_modulus === null) && ($dh_gen !== null)) ||
							 | 
						||
| 
								 | 
							
								            (($dh_gen === null) && ($dh_modulus !== null))) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if ($dh_modulus === null) {
							 | 
						||
| 
								 | 
							
								                $missing = 'modulus';
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                $missing = 'generator';
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError($message,
							 | 
						||
| 
								 | 
							
								                                'If non-default modulus or generator is '.
							 | 
						||
| 
								 | 
							
								                                'supplied, both must be supplied.  Missing '.
							 | 
						||
| 
								 | 
							
								                                $missing);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $lib =& Auth_OpenID_getMathLib();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($dh_modulus || $dh_gen) {
							 | 
						||
| 
								 | 
							
								            $dh_modulus = $lib->base64ToLong($dh_modulus);
							 | 
						||
| 
								 | 
							
								            $dh_gen = $lib->base64ToLong($dh_gen);
							 | 
						||
| 
								 | 
							
								            if ($lib->cmp($dh_modulus, 0) == 0 ||
							 | 
						||
| 
								 | 
							
								                $lib->cmp($dh_gen, 0) == 0) {
							 | 
						||
| 
								 | 
							
								                return new Auth_OpenID_ServerError(
							 | 
						||
| 
								 | 
							
								                  $message, "Failed to parse dh_mod or dh_gen");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            $dh = new Auth_OpenID_DiffieHellman($dh_modulus, $dh_gen);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            $dh = new Auth_OpenID_DiffieHellman();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $consumer_pubkey = $message->getArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                            'dh_consumer_public');
							 | 
						||
| 
								 | 
							
								        if ($consumer_pubkey === null) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError($message,
							 | 
						||
| 
								 | 
							
								                                  'Public key for DH-SHA1 session '.
							 | 
						||
| 
								 | 
							
								                                  'not found in query');
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $consumer_pubkey =
							 | 
						||
| 
								 | 
							
								            $lib->base64ToLong($consumer_pubkey);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($consumer_pubkey === false) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError($message,
							 | 
						||
| 
								 | 
							
								                                       "dh_consumer_public is not base64");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return array($dh, $consumer_pubkey);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function fromMessage($message)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $result = Auth_OpenID_DiffieHellmanSHA1ServerSession::getDH($message);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (is_a($result, 'Auth_OpenID_ServerError')) {
							 | 
						||
| 
								 | 
							
								            return $result;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            list($dh, $consumer_pubkey) = $result;
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_DiffieHellmanSHA1ServerSession($dh,
							 | 
						||
| 
								 | 
							
								                                                    $consumer_pubkey);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function answer($secret)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $lib =& Auth_OpenID_getMathLib();
							 | 
						||
| 
								 | 
							
								        $mac_key = $this->dh->xorSecret($this->consumer_pubkey, $secret,
							 | 
						||
| 
								 | 
							
								                                        $this->hash_func);
							 | 
						||
| 
								 | 
							
								        return array(
							 | 
						||
| 
								 | 
							
								           'dh_server_public' =>
							 | 
						||
| 
								 | 
							
								                $lib->longToBase64($this->dh->public),
							 | 
						||
| 
								 | 
							
								           'enc_mac_key' => base64_encode($mac_key));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * A class implementing DH-SHA256 server sessions.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_DiffieHellmanSHA256ServerSession
							 | 
						||
| 
								 | 
							
								      extends Auth_OpenID_DiffieHellmanSHA1ServerSession {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var $session_type = 'DH-SHA256';
							 | 
						||
| 
								 | 
							
								    var $hash_func = 'Auth_OpenID_SHA256';
							 | 
						||
| 
								 | 
							
								    var $allowed_assoc_types = array('HMAC-SHA256');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function fromMessage($message)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $result = Auth_OpenID_DiffieHellmanSHA1ServerSession::getDH($message);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (is_a($result, 'Auth_OpenID_ServerError')) {
							 | 
						||
| 
								 | 
							
								            return $result;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            list($dh, $consumer_pubkey) = $result;
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_DiffieHellmanSHA256ServerSession($dh,
							 | 
						||
| 
								 | 
							
								                                                      $consumer_pubkey);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * A request to associate with the server.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_AssociateRequest extends Auth_OpenID_Request {
							 | 
						||
| 
								 | 
							
								    var $mode = "associate";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function getSessionClasses()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return array(
							 | 
						||
| 
								 | 
							
								          'no-encryption' => 'Auth_OpenID_PlainTextServerSession',
							 | 
						||
| 
								 | 
							
								          'DH-SHA1' => 'Auth_OpenID_DiffieHellmanSHA1ServerSession',
							 | 
						||
| 
								 | 
							
								          'DH-SHA256' => 'Auth_OpenID_DiffieHellmanSHA256ServerSession');
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_AssociateRequest(&$session, $assoc_type)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $this->session =& $session;
							 | 
						||
| 
								 | 
							
								        $this->namespace = Auth_OpenID_OPENID2_NS;
							 | 
						||
| 
								 | 
							
								        $this->assoc_type = $assoc_type;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function fromMessage($message, $server=null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ($message->isOpenID1()) {
							 | 
						||
| 
								 | 
							
								            $session_type = $message->getArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                             'session_type');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if ($session_type == 'no-encryption') {
							 | 
						||
| 
								 | 
							
								                // oidutil.log('Received OpenID 1 request with a no-encryption '
							 | 
						||
| 
								 | 
							
								                //             'assocaition session type. Continuing anyway.')
							 | 
						||
| 
								 | 
							
								            } else if (!$session_type) {
							 | 
						||
| 
								 | 
							
								                $session_type = 'no-encryption';
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            $session_type = $message->getArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                             'session_type');
							 | 
						||
| 
								 | 
							
								            if ($session_type === null) {
							 | 
						||
| 
								 | 
							
								                return new Auth_OpenID_ServerError($message,
							 | 
						||
| 
								 | 
							
								                  "session_type missing from request");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $session_class = Auth_OpenID::arrayGet(
							 | 
						||
| 
								 | 
							
								           Auth_OpenID_AssociateRequest::getSessionClasses(),
							 | 
						||
| 
								 | 
							
								           $session_type);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($session_class === null) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError($message,
							 | 
						||
| 
								 | 
							
								                                               "Unknown session type " .
							 | 
						||
| 
								 | 
							
								                                               $session_type);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $session = call_user_func(array($session_class, 'fromMessage'),
							 | 
						||
| 
								 | 
							
								                                  $message);
							 | 
						||
| 
								 | 
							
								        if (is_a($session, 'Auth_OpenID_ServerError')) {
							 | 
						||
| 
								 | 
							
								            return $session;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $assoc_type = $message->getArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                       'assoc_type', 'HMAC-SHA1');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!in_array($assoc_type, $session->allowed_assoc_types)) {
							 | 
						||
| 
								 | 
							
								            $fmt = "Session type %s does not support association type %s";
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError($message,
							 | 
						||
| 
								 | 
							
								              sprintf($fmt, $session_type, $assoc_type));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $obj = new Auth_OpenID_AssociateRequest($session, $assoc_type);
							 | 
						||
| 
								 | 
							
								        $obj->message = $message;
							 | 
						||
| 
								 | 
							
								        $obj->namespace = $message->getOpenIDNamespace();
							 | 
						||
| 
								 | 
							
								        return $obj;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function answer($assoc)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $response = new Auth_OpenID_ServerResponse($this);
							 | 
						||
| 
								 | 
							
								        $response->fields->updateArgs(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								           array(
							 | 
						||
| 
								 | 
							
								                 'expires_in' => sprintf('%d', $assoc->getExpiresIn()),
							 | 
						||
| 
								 | 
							
								                 'assoc_type' => $this->assoc_type,
							 | 
						||
| 
								 | 
							
								                 'assoc_handle' => $assoc->handle));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $response->fields->updateArgs(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								           $this->session->answer($assoc->secret));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (! ($this->session->session_type == 'no-encryption' 
							 | 
						||
| 
								 | 
							
								               && $this->message->isOpenID1())) {
							 | 
						||
| 
								 | 
							
								            $response->fields->setArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                      'session_type',
							 | 
						||
| 
								 | 
							
								                                      $this->session->session_type);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $response;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function answerUnsupported($text_message,
							 | 
						||
| 
								 | 
							
								                               $preferred_association_type=null,
							 | 
						||
| 
								 | 
							
								                               $preferred_session_type=null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ($this->message->isOpenID1()) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError($this->message);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $response = new Auth_OpenID_ServerResponse($this);
							 | 
						||
| 
								 | 
							
								        $response->fields->setArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                  'error_code', 'unsupported-type');
							 | 
						||
| 
								 | 
							
								        $response->fields->setArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                  'error', $text_message);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($preferred_association_type) {
							 | 
						||
| 
								 | 
							
								            $response->fields->setArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                      'assoc_type',
							 | 
						||
| 
								 | 
							
								                                      $preferred_association_type);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($preferred_session_type) {
							 | 
						||
| 
								 | 
							
								            $response->fields->setArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                      'session_type',
							 | 
						||
| 
								 | 
							
								                                      $preferred_session_type);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $response;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * A request to confirm the identity of a user.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_CheckIDRequest extends Auth_OpenID_Request {
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Return-to verification callback.  Default is
							 | 
						||
| 
								 | 
							
								     * Auth_OpenID_verifyReturnTo from TrustRoot.php.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    var $verifyReturnTo = 'Auth_OpenID_verifyReturnTo';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * The mode of this request.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    var $mode = "checkid_setup"; // or "checkid_immediate"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Whether this request is for immediate mode.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    var $immediate = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * The trust_root value for this request.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    var $trust_root = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * The OpenID namespace for this request.
							 | 
						||
| 
								 | 
							
								     * deprecated since version 2.0.2
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    var $namespace;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    function make(&$message, $identity, $return_to, $trust_root = null,
							 | 
						||
| 
								 | 
							
								                  $immediate = false, $assoc_handle = null, $server = null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ($server === null) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError($message,
							 | 
						||
| 
								 | 
							
								                                               "server must not be null");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($return_to &&
							 | 
						||
| 
								 | 
							
								            !Auth_OpenID_TrustRoot::_parse($return_to)) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_MalformedReturnURL($message, $return_to);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $r = new Auth_OpenID_CheckIDRequest($identity, $return_to,
							 | 
						||
| 
								 | 
							
								                                            $trust_root, $immediate,
							 | 
						||
| 
								 | 
							
								                                            $assoc_handle, $server);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $r->namespace = $message->getOpenIDNamespace();
							 | 
						||
| 
								 | 
							
								        $r->message =& $message;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!$r->trustRootValid()) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_UntrustedReturnURL($message,
							 | 
						||
| 
								 | 
							
								                                                      $return_to,
							 | 
						||
| 
								 | 
							
								                                                      $trust_root);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            return $r;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_CheckIDRequest($identity, $return_to,
							 | 
						||
| 
								 | 
							
								                                        $trust_root = null, $immediate = false,
							 | 
						||
| 
								 | 
							
								                                        $assoc_handle = null, $server = null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $this->namespace = Auth_OpenID_OPENID2_NS;
							 | 
						||
| 
								 | 
							
								        $this->assoc_handle = $assoc_handle;
							 | 
						||
| 
								 | 
							
								        $this->identity = $identity;
							 | 
						||
| 
								 | 
							
								        $this->claimed_id = $identity;
							 | 
						||
| 
								 | 
							
								        $this->return_to = $return_to;
							 | 
						||
| 
								 | 
							
								        $this->trust_root = $trust_root;
							 | 
						||
| 
								 | 
							
								        $this->server =& $server;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($immediate) {
							 | 
						||
| 
								 | 
							
								            $this->immediate = true;
							 | 
						||
| 
								 | 
							
								            $this->mode = "checkid_immediate";
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            $this->immediate = false;
							 | 
						||
| 
								 | 
							
								            $this->mode = "checkid_setup";
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function equals($other)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return (
							 | 
						||
| 
								 | 
							
								                (is_a($other, 'Auth_OpenID_CheckIDRequest')) &&
							 | 
						||
| 
								 | 
							
								                ($this->namespace == $other->namespace) &&
							 | 
						||
| 
								 | 
							
								                ($this->assoc_handle == $other->assoc_handle) &&
							 | 
						||
| 
								 | 
							
								                ($this->identity == $other->identity) &&
							 | 
						||
| 
								 | 
							
								                ($this->claimed_id == $other->claimed_id) &&
							 | 
						||
| 
								 | 
							
								                ($this->return_to == $other->return_to) &&
							 | 
						||
| 
								 | 
							
								                ($this->trust_root == $other->trust_root));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*
							 | 
						||
| 
								 | 
							
								     * Does the relying party publish the return_to URL for this
							 | 
						||
| 
								 | 
							
								     * response under the realm? It is up to the provider to set a
							 | 
						||
| 
								 | 
							
								     * policy for what kinds of realms should be allowed. This
							 | 
						||
| 
								 | 
							
								     * return_to URL verification reduces vulnerability to data-theft
							 | 
						||
| 
								 | 
							
								     * attacks based on open proxies, corss-site-scripting, or open
							 | 
						||
| 
								 | 
							
								     * redirectors.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * This check should only be performed after making sure that the
							 | 
						||
| 
								 | 
							
								     * return_to URL matches the realm.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return true if the realm publishes a document with the
							 | 
						||
| 
								 | 
							
								     * return_to URL listed, false if not or if discovery fails
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function returnToVerified()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return call_user_func_array($this->verifyReturnTo,
							 | 
						||
| 
								 | 
							
								                                    array($this->trust_root, $this->return_to));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function fromMessage(&$message, $server)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode');
							 | 
						||
| 
								 | 
							
								        $immediate = null;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($mode == "checkid_immediate") {
							 | 
						||
| 
								 | 
							
								            $immediate = true;
							 | 
						||
| 
								 | 
							
								            $mode = "checkid_immediate";
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            $immediate = false;
							 | 
						||
| 
								 | 
							
								            $mode = "checkid_setup";
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $return_to = $message->getArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                      'return_to');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (($message->isOpenID1()) &&
							 | 
						||
| 
								 | 
							
								            (!$return_to)) {
							 | 
						||
| 
								 | 
							
								            $fmt = "Missing required field 'return_to' from checkid request";
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError($message, $fmt);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $identity = $message->getArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                     'identity');
							 | 
						||
| 
								 | 
							
								        $claimed_id = $message->getArg(Auth_OpenID_OPENID_NS, 'claimed_id');
							 | 
						||
| 
								 | 
							
								        if ($message->isOpenID1()) {
							 | 
						||
| 
								 | 
							
								            if ($identity === null) {
							 | 
						||
| 
								 | 
							
								                $s = "OpenID 1 message did not contain openid.identity";
							 | 
						||
| 
								 | 
							
								                return new Auth_OpenID_ServerError($message, $s);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            if ($identity && !$claimed_id) {
							 | 
						||
| 
								 | 
							
								                $s = "OpenID 2.0 message contained openid.identity but not " .
							 | 
						||
| 
								 | 
							
								                  "claimed_id";
							 | 
						||
| 
								 | 
							
								                return new Auth_OpenID_ServerError($message, $s);
							 | 
						||
| 
								 | 
							
								            } else if ($claimed_id && !$identity) {
							 | 
						||
| 
								 | 
							
								                $s = "OpenID 2.0 message contained openid.claimed_id " .
							 | 
						||
| 
								 | 
							
								                  "but not identity";
							 | 
						||
| 
								 | 
							
								                return new Auth_OpenID_ServerError($message, $s);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // There's a case for making self.trust_root be a TrustRoot
							 | 
						||
| 
								 | 
							
								        // here.  But if TrustRoot isn't currently part of the
							 | 
						||
| 
								 | 
							
								        // "public" API, I'm not sure it's worth doing.
							 | 
						||
| 
								 | 
							
								        if ($message->isOpenID1()) {
							 | 
						||
| 
								 | 
							
								            $trust_root_param = 'trust_root';
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            $trust_root_param = 'realm';
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $trust_root = $message->getArg(Auth_OpenID_OPENID_NS, 
							 | 
						||
| 
								 | 
							
								                                       $trust_root_param);
							 | 
						||
| 
								 | 
							
								        if (! $trust_root) {
							 | 
						||
| 
								 | 
							
								            $trust_root = $return_to;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (! $message->isOpenID1() && 
							 | 
						||
| 
								 | 
							
								            ($return_to === null) &&
							 | 
						||
| 
								 | 
							
								            ($trust_root === null)) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError($message,
							 | 
						||
| 
								 | 
							
								              "openid.realm required when openid.return_to absent");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $assoc_handle = $message->getArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                         'assoc_handle');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $obj = Auth_OpenID_CheckIDRequest::make($message,
							 | 
						||
| 
								 | 
							
								                                                $identity,
							 | 
						||
| 
								 | 
							
								                                                $return_to,
							 | 
						||
| 
								 | 
							
								                                                $trust_root,
							 | 
						||
| 
								 | 
							
								                                                $immediate,
							 | 
						||
| 
								 | 
							
								                                                $assoc_handle,
							 | 
						||
| 
								 | 
							
								                                                $server);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (is_a($obj, 'Auth_OpenID_ServerError')) {
							 | 
						||
| 
								 | 
							
								            return $obj;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $obj->claimed_id = $claimed_id;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $obj;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function idSelect()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // Is the identifier to be selected by the IDP?
							 | 
						||
| 
								 | 
							
								        // So IDPs don't have to import the constant
							 | 
						||
| 
								 | 
							
								        return $this->identity == Auth_OpenID_IDENTIFIER_SELECT;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function trustRootValid()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!$this->trust_root) {
							 | 
						||
| 
								 | 
							
								            return true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $tr = Auth_OpenID_TrustRoot::_parse($this->trust_root);
							 | 
						||
| 
								 | 
							
								        if ($tr === false) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_MalformedTrustRoot($this->message,
							 | 
						||
| 
								 | 
							
								                                                      $this->trust_root);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($this->return_to !== null) {
							 | 
						||
| 
								 | 
							
								            return Auth_OpenID_TrustRoot::match($this->trust_root,
							 | 
						||
| 
								 | 
							
								                                                $this->return_to);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            return true;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Respond to this request.  Return either an
							 | 
						||
| 
								 | 
							
								     * {@link Auth_OpenID_ServerResponse} or
							 | 
						||
| 
								 | 
							
								     * {@link Auth_OpenID_ServerError}.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param bool $allow Allow this user to claim this identity, and
							 | 
						||
| 
								 | 
							
								     * allow the consumer to have this information?
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param string $server_url DEPRECATED.  Passing $op_endpoint to
							 | 
						||
| 
								 | 
							
								     * the {@link Auth_OpenID_Server} constructor makes this optional.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * When an OpenID 1.x immediate mode request does not succeed, it
							 | 
						||
| 
								 | 
							
								     * gets back a URL where the request may be carried out in a
							 | 
						||
| 
								 | 
							
								     * not-so-immediate fashion.  Pass my URL in here (the fully
							 | 
						||
| 
								 | 
							
								     * qualified address of this server's endpoint, i.e.
							 | 
						||
| 
								 | 
							
								     * http://example.com/server), and I will use it as a base for the
							 | 
						||
| 
								 | 
							
								     * URL for a new request.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * Optional for requests where {@link $immediate} is false or
							 | 
						||
| 
								 | 
							
								     * $allow is true.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param string $identity The OP-local identifier to answer with.
							 | 
						||
| 
								 | 
							
								     * Only for use when the relying party requested identifier
							 | 
						||
| 
								 | 
							
								     * selection.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param string $claimed_id The claimed identifier to answer
							 | 
						||
| 
								 | 
							
								     * with, for use with identifier selection in the case where the
							 | 
						||
| 
								 | 
							
								     * claimed identifier and the OP-local identifier differ,
							 | 
						||
| 
								 | 
							
								     * i.e. when the claimed_id uses delegation.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * If $identity is provided but this is not, $claimed_id will
							 | 
						||
| 
								 | 
							
								     * default to the value of $identity.  When answering requests
							 | 
						||
| 
								 | 
							
								     * that did not ask for identifier selection, the response
							 | 
						||
| 
								 | 
							
								     * $claimed_id will default to that of the request.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * This parameter is new in OpenID 2.0.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return mixed
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function answer($allow, $server_url = null, $identity = null,
							 | 
						||
| 
								 | 
							
								                    $claimed_id = null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!$this->return_to) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_NoReturnToError();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!$server_url) {
							 | 
						||
| 
								 | 
							
								            if ((!$this->message->isOpenID1()) &&
							 | 
						||
| 
								 | 
							
								                (!$this->server->op_endpoint)) {
							 | 
						||
| 
								 | 
							
								                return new Auth_OpenID_ServerError(null,
							 | 
						||
| 
								 | 
							
								                  "server should be constructed with op_endpoint to " .
							 | 
						||
| 
								 | 
							
								                  "respond to OpenID 2.0 messages.");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            $server_url = $this->server->op_endpoint;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($allow) {
							 | 
						||
| 
								 | 
							
								            $mode = 'id_res';
							 | 
						||
| 
								 | 
							
								        } else if ($this->message->isOpenID1()) {
							 | 
						||
| 
								 | 
							
								            if ($this->immediate) {
							 | 
						||
| 
								 | 
							
								                $mode = 'id_res';
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                $mode = 'cancel';
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            if ($this->immediate) {
							 | 
						||
| 
								 | 
							
								                $mode = 'setup_needed';
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                $mode = 'cancel';
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!$this->trustRootValid()) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_UntrustedReturnURL(null,
							 | 
						||
| 
								 | 
							
								                                                      $this->return_to,
							 | 
						||
| 
								 | 
							
								                                                      $this->trust_root);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $response = new Auth_OpenID_ServerResponse($this);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($claimed_id &&
							 | 
						||
| 
								 | 
							
								            ($this->message->isOpenID1())) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError(null,
							 | 
						||
| 
								 | 
							
								              "claimed_id is new in OpenID 2.0 and not " .
							 | 
						||
| 
								 | 
							
								              "available for ".$this->namespace);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($identity && !$claimed_id) {
							 | 
						||
| 
								 | 
							
								            $claimed_id = $identity;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($allow) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if ($this->identity == Auth_OpenID_IDENTIFIER_SELECT) {
							 | 
						||
| 
								 | 
							
								                if (!$identity) {
							 | 
						||
| 
								 | 
							
								                    return new Auth_OpenID_ServerError(null,
							 | 
						||
| 
								 | 
							
								                      "This request uses IdP-driven identifier selection.  " .
							 | 
						||
| 
								 | 
							
								                      "You must supply an identifier in the response.");
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                $response_identity = $identity;
							 | 
						||
| 
								 | 
							
								                $response_claimed_id = $claimed_id;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            } else if ($this->identity) {
							 | 
						||
| 
								 | 
							
								                if ($identity &&
							 | 
						||
| 
								 | 
							
								                    ($this->identity != $identity)) {
							 | 
						||
| 
								 | 
							
								                    $fmt = "Request was for %s, cannot reply with identity %s";
							 | 
						||
| 
								 | 
							
								                    return new Auth_OpenID_ServerError(null,
							 | 
						||
| 
								 | 
							
								                      sprintf($fmt, $this->identity, $identity));
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                $response_identity = $this->identity;
							 | 
						||
| 
								 | 
							
								                $response_claimed_id = $this->claimed_id;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                if ($identity) {
							 | 
						||
| 
								 | 
							
								                    return new Auth_OpenID_ServerError(null,
							 | 
						||
| 
								 | 
							
								                      "This request specified no identity and " .
							 | 
						||
| 
								 | 
							
								                      "you supplied ".$identity);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                $response_identity = null;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (($this->message->isOpenID1()) &&
							 | 
						||
| 
								 | 
							
								                ($response_identity === null)) {
							 | 
						||
| 
								 | 
							
								                return new Auth_OpenID_ServerError(null,
							 | 
						||
| 
								 | 
							
								                  "Request was an OpenID 1 request, so response must " .
							 | 
						||
| 
								 | 
							
								                  "include an identifier.");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            $response->fields->updateArgs(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                   array('mode' => $mode,
							 | 
						||
| 
								 | 
							
								                         'return_to' => $this->return_to,
							 | 
						||
| 
								 | 
							
								                         'response_nonce' => Auth_OpenID_mkNonce()));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (!$this->message->isOpenID1()) {
							 | 
						||
| 
								 | 
							
								                $response->fields->setArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                          'op_endpoint', $server_url);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if ($response_identity !== null) {
							 | 
						||
| 
								 | 
							
								                $response->fields->setArg(
							 | 
						||
| 
								 | 
							
								                                          Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                          'identity',
							 | 
						||
| 
								 | 
							
								                                          $response_identity);
							 | 
						||
| 
								 | 
							
								                if ($this->message->isOpenID2()) {
							 | 
						||
| 
								 | 
							
								                    $response->fields->setArg(
							 | 
						||
| 
								 | 
							
								                                              Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                              'claimed_id',
							 | 
						||
| 
								 | 
							
								                                              $response_claimed_id);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            $response->fields->setArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                      'mode', $mode);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if ($this->immediate) {
							 | 
						||
| 
								 | 
							
								                if (($this->message->isOpenID1()) &&
							 | 
						||
| 
								 | 
							
								                    (!$server_url)) {
							 | 
						||
| 
								 | 
							
								                    return new Auth_OpenID_ServerError(null,
							 | 
						||
| 
								 | 
							
								                                 'setup_url is required for $allow=false \
							 | 
						||
| 
								 | 
							
								                                  in OpenID 1.x immediate mode.');
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                $setup_request =& new Auth_OpenID_CheckIDRequest(
							 | 
						||
| 
								 | 
							
								                                                $this->identity,
							 | 
						||
| 
								 | 
							
								                                                $this->return_to,
							 | 
						||
| 
								 | 
							
								                                                $this->trust_root,
							 | 
						||
| 
								 | 
							
								                                                false,
							 | 
						||
| 
								 | 
							
								                                                $this->assoc_handle,
							 | 
						||
| 
								 | 
							
								                                                $this->server);
							 | 
						||
| 
								 | 
							
								                $setup_request->message = $this->message;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                $setup_url = $setup_request->encodeToURL($server_url);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if ($setup_url === null) {
							 | 
						||
| 
								 | 
							
								                    return new Auth_OpenID_NoReturnToError();
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                $response->fields->setArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                          'user_setup_url',
							 | 
						||
| 
								 | 
							
								                                          $setup_url);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $response;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function encodeToURL($server_url)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!$this->return_to) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_NoReturnToError();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Imported from the alternate reality where these classes are
							 | 
						||
| 
								 | 
							
								        // used in both the client and server code, so Requests are
							 | 
						||
| 
								 | 
							
								        // Encodable too.  That's right, code imported from alternate
							 | 
						||
| 
								 | 
							
								        // realities all for the love of you, id_res/user_setup_url.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $q = array('mode' => $this->mode,
							 | 
						||
| 
								 | 
							
								                   'identity' => $this->identity,
							 | 
						||
| 
								 | 
							
								                   'claimed_id' => $this->claimed_id,
							 | 
						||
| 
								 | 
							
								                   'return_to' => $this->return_to);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($this->trust_root) {
							 | 
						||
| 
								 | 
							
								            if ($this->message->isOpenID1()) {
							 | 
						||
| 
								 | 
							
								                $q['trust_root'] = $this->trust_root;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                $q['realm'] = $this->trust_root;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($this->assoc_handle) {
							 | 
						||
| 
								 | 
							
								            $q['assoc_handle'] = $this->assoc_handle;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $response = new Auth_OpenID_Message(
							 | 
						||
| 
								 | 
							
								            $this->message->getOpenIDNamespace());
							 | 
						||
| 
								 | 
							
								        $response->updateArgs(Auth_OpenID_OPENID_NS, $q);
							 | 
						||
| 
								 | 
							
								        return $response->toURL($server_url);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function getCancelURL()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!$this->return_to) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_NoReturnToError();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($this->immediate) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError(null,
							 | 
						||
| 
								 | 
							
								                                               "Cancel is not an appropriate \
							 | 
						||
| 
								 | 
							
								                                               response to immediate mode \
							 | 
						||
| 
								 | 
							
								                                               requests.");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $response = new Auth_OpenID_Message(
							 | 
						||
| 
								 | 
							
								            $this->message->getOpenIDNamespace());
							 | 
						||
| 
								 | 
							
								        $response->setArg(Auth_OpenID_OPENID_NS, 'mode', 'cancel');
							 | 
						||
| 
								 | 
							
								        return $response->toURL($this->return_to);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * This class encapsulates the response to an OpenID server request.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_ServerResponse {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_ServerResponse(&$request)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $this->request =& $request;
							 | 
						||
| 
								 | 
							
								        $this->fields = new Auth_OpenID_Message($this->request->namespace);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function whichEncoding()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								      global $_Auth_OpenID_Request_Modes;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (in_array($this->request->mode, $_Auth_OpenID_Request_Modes)) {
							 | 
						||
| 
								 | 
							
								            if ($this->fields->isOpenID2() &&
							 | 
						||
| 
								 | 
							
								                (strlen($this->encodeToURL()) >
							 | 
						||
| 
								 | 
							
								                   Auth_OpenID_OPENID1_URL_LIMIT)) {
							 | 
						||
| 
								 | 
							
								                return Auth_OpenID_ENCODE_HTML_FORM;
							 | 
						||
| 
								 | 
							
								            } else {
							 | 
						||
| 
								 | 
							
								                return Auth_OpenID_ENCODE_URL;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            return Auth_OpenID_ENCODE_KVFORM;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*
							 | 
						||
| 
								 | 
							
								     * Returns the form markup for this response.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return str
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function toFormMarkup($form_tag_attrs=null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->fields->toFormMarkup($this->request->return_to,
							 | 
						||
| 
								 | 
							
								                                           $form_tag_attrs);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*
							 | 
						||
| 
								 | 
							
								     * Returns an HTML document containing the form markup for this
							 | 
						||
| 
								 | 
							
								     * response that autosubmits with javascript.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function toHTML()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return Auth_OpenID::autoSubmitHTML($this->toFormMarkup());
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /*
							 | 
						||
| 
								 | 
							
								     * Returns True if this response's encoding is ENCODE_HTML_FORM.
							 | 
						||
| 
								 | 
							
								     * Convenience method for server authors.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return bool
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function renderAsForm()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->whichEncoding() == Auth_OpenID_ENCODE_HTML_FORM;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function encodeToURL()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->fields->toURL($this->request->return_to);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function addExtension($extension_response)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $extension_response->toMessage($this->fields);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function needsSigning()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->fields->getArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                                     'mode') == 'id_res';
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function encodeToKVForm()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->fields->toKVForm();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * A web-capable response object which you can use to generate a
							 | 
						||
| 
								 | 
							
								 * user-agent response.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_WebResponse {
							 | 
						||
| 
								 | 
							
								    var $code = AUTH_OPENID_HTTP_OK;
							 | 
						||
| 
								 | 
							
								    var $body = "";
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_WebResponse($code = null, $headers = null,
							 | 
						||
| 
								 | 
							
								                                     $body = null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ($code) {
							 | 
						||
| 
								 | 
							
								            $this->code = $code;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($headers !== null) {
							 | 
						||
| 
								 | 
							
								            $this->headers = $headers;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            $this->headers = array();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($body !== null) {
							 | 
						||
| 
								 | 
							
								            $this->body = $body;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Responsible for the signature of query data and the verification of
							 | 
						||
| 
								 | 
							
								 * OpenID signature values.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_Signatory {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // = 14 * 24 * 60 * 60; # 14 days, in seconds
							 | 
						||
| 
								 | 
							
								    var $SECRET_LIFETIME = 1209600;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // keys have a bogus server URL in them because the filestore
							 | 
						||
| 
								 | 
							
								    // really does expect that key to be a URL.  This seems a little
							 | 
						||
| 
								 | 
							
								    // silly for the server store, since I expect there to be only one
							 | 
						||
| 
								 | 
							
								    // server URL.
							 | 
						||
| 
								 | 
							
								    var $normal_key = 'http://localhost/|normal';
							 | 
						||
| 
								 | 
							
								    var $dumb_key = 'http://localhost/|dumb';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Create a new signatory using a given store.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_Signatory(&$store)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // assert store is not None
							 | 
						||
| 
								 | 
							
								        $this->store =& $store;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Verify, using a given association handle, a signature with
							 | 
						||
| 
								 | 
							
								     * signed key-value pairs from an HTTP request.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function verify($assoc_handle, $message)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $assoc = $this->getAssociation($assoc_handle, true);
							 | 
						||
| 
								 | 
							
								        if (!$assoc) {
							 | 
						||
| 
								 | 
							
								            // oidutil.log("failed to get assoc with handle %r to verify sig %r"
							 | 
						||
| 
								 | 
							
								            //             % (assoc_handle, sig))
							 | 
						||
| 
								 | 
							
								            return false;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $assoc->checkMessageSignature($message);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Given a response, sign the fields in the response's 'signed'
							 | 
						||
| 
								 | 
							
								     * list, and insert the signature into the response.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function sign($response)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $signed_response = $response;
							 | 
						||
| 
								 | 
							
								        $assoc_handle = $response->request->assoc_handle;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($assoc_handle) {
							 | 
						||
| 
								 | 
							
								            // normal mode
							 | 
						||
| 
								 | 
							
								            $assoc = $this->getAssociation($assoc_handle, false, false);
							 | 
						||
| 
								 | 
							
								            if (!$assoc || ($assoc->getExpiresIn() <= 0)) {
							 | 
						||
| 
								 | 
							
								                // fall back to dumb mode
							 | 
						||
| 
								 | 
							
								                $signed_response->fields->setArg(Auth_OpenID_OPENID_NS,
							 | 
						||
| 
								 | 
							
								                             'invalidate_handle', $assoc_handle);
							 | 
						||
| 
								 | 
							
								                $assoc_type = ($assoc ? $assoc->assoc_type : 'HMAC-SHA1');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                if ($assoc && ($assoc->getExpiresIn() <= 0)) {
							 | 
						||
| 
								 | 
							
								                    $this->invalidate($assoc_handle, false);
							 | 
						||
| 
								 | 
							
								                }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                $assoc = $this->createAssociation(true, $assoc_type);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            // dumb mode.
							 | 
						||
| 
								 | 
							
								            $assoc = $this->createAssociation(true);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $signed_response->fields = $assoc->signMessage(
							 | 
						||
| 
								 | 
							
								                                      $signed_response->fields);
							 | 
						||
| 
								 | 
							
								        return $signed_response;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Make a new association.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function createAssociation($dumb = true, $assoc_type = 'HMAC-SHA1')
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $secret = Auth_OpenID_CryptUtil::getBytes(
							 | 
						||
| 
								 | 
							
								                    Auth_OpenID_getSecretSize($assoc_type));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $uniq = base64_encode(Auth_OpenID_CryptUtil::getBytes(4));
							 | 
						||
| 
								 | 
							
								        $handle = sprintf('{%s}{%x}{%s}', $assoc_type, intval(time()), $uniq);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $assoc = Auth_OpenID_Association::fromExpiresIn(
							 | 
						||
| 
								 | 
							
								                      $this->SECRET_LIFETIME, $handle, $secret, $assoc_type);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($dumb) {
							 | 
						||
| 
								 | 
							
								            $key = $this->dumb_key;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            $key = $this->normal_key;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $this->store->storeAssociation($key, $assoc);
							 | 
						||
| 
								 | 
							
								        return $assoc;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Given an association handle, get the association from the
							 | 
						||
| 
								 | 
							
								     * store, or return a ServerError or null if something goes wrong.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function getAssociation($assoc_handle, $dumb, $check_expiration=true)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ($assoc_handle === null) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError(null,
							 | 
						||
| 
								 | 
							
								                                     "assoc_handle must not be null");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($dumb) {
							 | 
						||
| 
								 | 
							
								            $key = $this->dumb_key;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            $key = $this->normal_key;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $assoc = $this->store->getAssociation($key, $assoc_handle);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (($assoc !== null) && ($assoc->getExpiresIn() <= 0)) {
							 | 
						||
| 
								 | 
							
								            if ($check_expiration) {
							 | 
						||
| 
								 | 
							
								                $this->store->removeAssociation($key, $assoc_handle);
							 | 
						||
| 
								 | 
							
								                $assoc = null;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $assoc;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Invalidate a given association handle.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function invalidate($assoc_handle, $dumb)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ($dumb) {
							 | 
						||
| 
								 | 
							
								            $key = $this->dumb_key;
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            $key = $this->normal_key;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        $this->store->removeAssociation($key, $assoc_handle);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Encode an {@link Auth_OpenID_ServerResponse} to an
							 | 
						||
| 
								 | 
							
								 * {@link Auth_OpenID_WebResponse}.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_Encoder {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    var $responseFactory = 'Auth_OpenID_WebResponse';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Encode an {@link Auth_OpenID_ServerResponse} and return an
							 | 
						||
| 
								 | 
							
								     * {@link Auth_OpenID_WebResponse}.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function encode(&$response)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $cls = $this->responseFactory;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $encode_as = $response->whichEncoding();
							 | 
						||
| 
								 | 
							
								        if ($encode_as == Auth_OpenID_ENCODE_KVFORM) {
							 | 
						||
| 
								 | 
							
								            $wr = new $cls(null, null, $response->encodeToKVForm());
							 | 
						||
| 
								 | 
							
								            if (is_a($response, 'Auth_OpenID_ServerError')) {
							 | 
						||
| 
								 | 
							
								                $wr->code = AUTH_OPENID_HTTP_ERROR;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								        } else if ($encode_as == Auth_OpenID_ENCODE_URL) {
							 | 
						||
| 
								 | 
							
								            $location = $response->encodeToURL();
							 | 
						||
| 
								 | 
							
								            $wr = new $cls(AUTH_OPENID_HTTP_REDIRECT,
							 | 
						||
| 
								 | 
							
								                           array('location' => $location));
							 | 
						||
| 
								 | 
							
								        } else if ($encode_as == Auth_OpenID_ENCODE_HTML_FORM) {
							 | 
						||
| 
								 | 
							
								          $wr = new $cls(AUTH_OPENID_HTTP_OK, array(),
							 | 
						||
| 
								 | 
							
								                         $response->toFormMarkup());
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_EncodingError($response);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return $wr;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * An encoder which also takes care of signing fields when required.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_SigningEncoder extends Auth_OpenID_Encoder {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_SigningEncoder(&$signatory)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $this->signatory =& $signatory;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Sign an {@link Auth_OpenID_ServerResponse} and return an
							 | 
						||
| 
								 | 
							
								     * {@link Auth_OpenID_WebResponse}.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function encode(&$response)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // the isinstance is a bit of a kludge... it means there isn't
							 | 
						||
| 
								 | 
							
								        // really an adapter to make the interfaces quite match.
							 | 
						||
| 
								 | 
							
								        if (!is_a($response, 'Auth_OpenID_ServerError') &&
							 | 
						||
| 
								 | 
							
								            $response->needsSigning()) {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if (!$this->signatory) {
							 | 
						||
| 
								 | 
							
								                return new Auth_OpenID_ServerError(null,
							 | 
						||
| 
								 | 
							
								                                       "Must have a store to sign request");
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if ($response->fields->hasKey(Auth_OpenID_OPENID_NS, 'sig')) {
							 | 
						||
| 
								 | 
							
								                return new Auth_OpenID_AlreadySigned($response);
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            $response = $this->signatory->sign($response);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return parent::encode($response);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * Decode an incoming query into an Auth_OpenID_Request.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_Decoder {
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_Decoder(&$server)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $this->server =& $server;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $this->handlers = array(
							 | 
						||
| 
								 | 
							
								            'checkid_setup' => 'Auth_OpenID_CheckIDRequest',
							 | 
						||
| 
								 | 
							
								            'checkid_immediate' => 'Auth_OpenID_CheckIDRequest',
							 | 
						||
| 
								 | 
							
								            'check_authentication' => 'Auth_OpenID_CheckAuthRequest',
							 | 
						||
| 
								 | 
							
								            'associate' => 'Auth_OpenID_AssociateRequest'
							 | 
						||
| 
								 | 
							
								            );
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Given an HTTP query in an array (key-value pairs), decode it
							 | 
						||
| 
								 | 
							
								     * into an Auth_OpenID_Request object.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function decode($query)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (!$query) {
							 | 
						||
| 
								 | 
							
								            return null;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $message = Auth_OpenID_Message::fromPostArgs($query);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if ($message === null) {
							 | 
						||
| 
								 | 
							
								            /*
							 | 
						||
| 
								 | 
							
								             * It's useful to have a Message attached to a
							 | 
						||
| 
								 | 
							
								             * ProtocolError, so we override the bad ns value to build
							 | 
						||
| 
								 | 
							
								             * a Message out of it.  Kinda kludgy, since it's made of
							 | 
						||
| 
								 | 
							
								             * lies, but the parts that aren't lies are more useful
							 | 
						||
| 
								 | 
							
								             * than a 'None'.
							 | 
						||
| 
								 | 
							
								             */
							 | 
						||
| 
								 | 
							
								            $old_ns = $query['openid.ns'];
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            $query['openid.ns'] = Auth_OpenID_OPENID2_NS;
							 | 
						||
| 
								 | 
							
								            $message = Auth_OpenID_Message::fromPostArgs($query);
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError(
							 | 
						||
| 
								 | 
							
								                  $message,
							 | 
						||
| 
								 | 
							
								                  sprintf("Invalid OpenID namespace URI: %s", $old_ns));
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode');
							 | 
						||
| 
								 | 
							
								        if (!$mode) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError($message,
							 | 
						||
| 
								 | 
							
								                                               "No mode value in message");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (Auth_OpenID::isFailure($mode)) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError($message,
							 | 
						||
| 
								 | 
							
								                                               $mode->message);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        $handlerCls = Auth_OpenID::arrayGet($this->handlers, $mode,
							 | 
						||
| 
								 | 
							
								                                            $this->defaultDecoder($message));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (!is_a($handlerCls, 'Auth_OpenID_ServerError')) {
							 | 
						||
| 
								 | 
							
								            return call_user_func_array(array($handlerCls, 'fromMessage'),
							 | 
						||
| 
								 | 
							
								                                        array($message, $this->server));
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            return $handlerCls;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function defaultDecoder($message)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if (Auth_OpenID::isFailure($mode)) {
							 | 
						||
| 
								 | 
							
								            return new Auth_OpenID_ServerError($message,
							 | 
						||
| 
								 | 
							
								                                               $mode->message);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return new Auth_OpenID_ServerError($message,
							 | 
						||
| 
								 | 
							
								                       sprintf("Unrecognized OpenID mode %s", $mode));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * An error that indicates an encoding problem occurred.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_EncodingError {
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_EncodingError(&$response)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $this->response =& $response;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * An error that indicates that a response was already signed.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_AlreadySigned extends Auth_OpenID_EncodingError {
							 | 
						||
| 
								 | 
							
								    // This response is already signed.
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * An error that indicates that the given return_to is not under the
							 | 
						||
| 
								 | 
							
								 * given trust_root.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_UntrustedReturnURL extends Auth_OpenID_ServerError {
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_UntrustedReturnURL($message, $return_to,
							 | 
						||
| 
								 | 
							
								                                            $trust_root)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        parent::Auth_OpenID_ServerError($message, "Untrusted return_to URL");
							 | 
						||
| 
								 | 
							
								        $this->return_to = $return_to;
							 | 
						||
| 
								 | 
							
								        $this->trust_root = $trust_root;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    function toString()
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return sprintf("return_to %s not under trust_root %s",
							 | 
						||
| 
								 | 
							
								                       $this->return_to, $this->trust_root);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								 * I handle requests for an OpenID server.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Some types of requests (those which are not checkid requests) may
							 | 
						||
| 
								 | 
							
								 * be handed to my {@link handleRequest} method, and I will take care
							 | 
						||
| 
								 | 
							
								 * of it and return a response.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * For your convenience, I also provide an interface to {@link
							 | 
						||
| 
								 | 
							
								 * Auth_OpenID_Decoder::decode()} and {@link
							 | 
						||
| 
								 | 
							
								 * Auth_OpenID_SigningEncoder::encode()} through my methods {@link
							 | 
						||
| 
								 | 
							
								 * decodeRequest} and {@link encodeResponse}.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * All my state is encapsulated in an {@link Auth_OpenID_OpenIDStore}.
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * Example:
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * <pre> $oserver = new Auth_OpenID_Server(Auth_OpenID_FileStore($data_path),
							 | 
						||
| 
								 | 
							
								 *                                   "http://example.com/op");
							 | 
						||
| 
								 | 
							
								 * $request = $oserver->decodeRequest();
							 | 
						||
| 
								 | 
							
								 * if (in_array($request->mode, array('checkid_immediate',
							 | 
						||
| 
								 | 
							
								 *                                    'checkid_setup'))) {
							 | 
						||
| 
								 | 
							
								 *     if ($app->isAuthorized($request->identity, $request->trust_root)) {
							 | 
						||
| 
								 | 
							
								 *         $response = $request->answer(true);
							 | 
						||
| 
								 | 
							
								 *     } else if ($request->immediate) {
							 | 
						||
| 
								 | 
							
								 *         $response = $request->answer(false);
							 | 
						||
| 
								 | 
							
								 *     } else {
							 | 
						||
| 
								 | 
							
								 *         $app->showDecidePage($request);
							 | 
						||
| 
								 | 
							
								 *         return;
							 | 
						||
| 
								 | 
							
								 *     }
							 | 
						||
| 
								 | 
							
								 * } else {
							 | 
						||
| 
								 | 
							
								 *     $response = $oserver->handleRequest($request);
							 | 
						||
| 
								 | 
							
								 * }
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * $webresponse = $oserver->encode($response);</pre>
							 | 
						||
| 
								 | 
							
								 *
							 | 
						||
| 
								 | 
							
								 * @package OpenID
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								class Auth_OpenID_Server {
							 | 
						||
| 
								 | 
							
								    function Auth_OpenID_Server(&$store, $op_endpoint=null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $this->store =& $store;
							 | 
						||
| 
								 | 
							
								        $this->signatory =& new Auth_OpenID_Signatory($this->store);
							 | 
						||
| 
								 | 
							
								        $this->encoder =& new Auth_OpenID_SigningEncoder($this->signatory);
							 | 
						||
| 
								 | 
							
								        $this->decoder =& new Auth_OpenID_Decoder($this);
							 | 
						||
| 
								 | 
							
								        $this->op_endpoint = $op_endpoint;
							 | 
						||
| 
								 | 
							
								        $this->negotiator =& Auth_OpenID_getDefaultNegotiator();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Handle a request.  Given an {@link Auth_OpenID_Request} object,
							 | 
						||
| 
								 | 
							
								     * call the appropriate {@link Auth_OpenID_Server} method to
							 | 
						||
| 
								 | 
							
								     * process the request and generate a response.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @param Auth_OpenID_Request $request An {@link Auth_OpenID_Request}
							 | 
						||
| 
								 | 
							
								     * returned by {@link Auth_OpenID_Server::decodeRequest()}.
							 | 
						||
| 
								 | 
							
								     *
							 | 
						||
| 
								 | 
							
								     * @return Auth_OpenID_ServerResponse $response A response object
							 | 
						||
| 
								 | 
							
								     * capable of generating a user-agent reply.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function handleRequest($request)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if (method_exists($this, "openid_" . $request->mode)) {
							 | 
						||
| 
								 | 
							
								            $handler = array($this, "openid_" . $request->mode);
							 | 
						||
| 
								 | 
							
								            return call_user_func($handler, $request);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        return null;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * The callback for 'check_authentication' messages.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function openid_check_authentication(&$request)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $request->answer($this->signatory);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * The callback for 'associate' messages.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function openid_associate(&$request)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        $assoc_type = $request->assoc_type;
							 | 
						||
| 
								 | 
							
								        $session_type = $request->session->session_type;
							 | 
						||
| 
								 | 
							
								        if ($this->negotiator->isAllowed($assoc_type, $session_type)) {
							 | 
						||
| 
								 | 
							
								            $assoc = $this->signatory->createAssociation(false,
							 | 
						||
| 
								 | 
							
								                                                         $assoc_type);
							 | 
						||
| 
								 | 
							
								            return $request->answer($assoc);
							 | 
						||
| 
								 | 
							
								        } else {
							 | 
						||
| 
								 | 
							
								            $message = sprintf('Association type %s is not supported with '.
							 | 
						||
| 
								 | 
							
								                               'session type %s', $assoc_type, $session_type);
							 | 
						||
| 
								 | 
							
								            list($preferred_assoc_type, $preferred_session_type) =
							 | 
						||
| 
								 | 
							
								                $this->negotiator->getAllowedType();
							 | 
						||
| 
								 | 
							
								            return $request->answerUnsupported($message,
							 | 
						||
| 
								 | 
							
								                                               $preferred_assoc_type,
							 | 
						||
| 
								 | 
							
								                                               $preferred_session_type);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Encodes as response in the appropriate format suitable for
							 | 
						||
| 
								 | 
							
								     * sending to the user agent.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function encodeResponse(&$response)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        return $this->encoder->encode($response);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    /**
							 | 
						||
| 
								 | 
							
								     * Decodes a query args array into the appropriate
							 | 
						||
| 
								 | 
							
								     * {@link Auth_OpenID_Request} object.
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								    function decodeRequest($query=null)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        if ($query === null) {
							 | 
						||
| 
								 | 
							
								            $query = Auth_OpenID::getQuery();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return $this->decoder->decode($query);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								?>
							 |