Licence and jqmobile beta 3 upgrade
[busui.git] / lib / openid-php / Auth / OpenID / Server.php
blob:a/lib/openid-php/Auth/OpenID/Server.php -> blob:b/lib/openid-php/Auth/OpenID/Server.php
<?php <?php
   
/** /**
* OpenID server protocol and logic. * OpenID server protocol and logic.
* *
* Overview * Overview
* *
* An OpenID server must perform three tasks: * An OpenID server must perform three tasks:
* *
* 1. Examine the incoming request to determine its nature and validity. * 1. Examine the incoming request to determine its nature and validity.
* 2. Make a decision about how to respond to this request. * 2. Make a decision about how to respond to this request.
* 3. Format the response according to the protocol. * 3. Format the response according to the protocol.
* *
* The first and last of these tasks may performed by the {@link * The first and last of these tasks may performed by the {@link
* Auth_OpenID_Server::decodeRequest()} and {@link * Auth_OpenID_Server::decodeRequest()} and {@link
* Auth_OpenID_Server::encodeResponse} methods. Who gets to do the * Auth_OpenID_Server::encodeResponse} methods. Who gets to do the
* intermediate task -- deciding how to respond to the request -- will * intermediate task -- deciding how to respond to the request -- will
* depend on what type of request it is. * depend on what type of request it is.
* *
* If it's a request to authenticate a user (a 'checkid_setup' or * If it's a request to authenticate a user (a 'checkid_setup' or
* 'checkid_immediate' request), you need to decide if you will assert * 'checkid_immediate' request), you need to decide if you will assert
* that this user may claim the identity in question. Exactly how you * that this user may claim the identity in question. Exactly how you
* do that is a matter of application policy, but it generally * do that is a matter of application policy, but it generally
* involves making sure the user has an account with your system and * 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, * 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 * and verifying with the user that she does consent to releasing that
* information to the party making the request. * information to the party making the request.
* *
* Examine the properties of the {@link Auth_OpenID_CheckIDRequest} * Examine the properties of the {@link Auth_OpenID_CheckIDRequest}
* object, and if and when you've come to a decision, form a response * object, and if and when you've come to a decision, form a response
* by calling {@link Auth_OpenID_CheckIDRequest::answer()}. * by calling {@link Auth_OpenID_CheckIDRequest::answer()}.
* *
* Other types of requests relate to establishing associations between * Other types of requests relate to establishing associations between
* client and server and verifing the authenticity of previous * client and server and verifing the authenticity of previous
* communications. {@link Auth_OpenID_Server} contains all the logic * communications. {@link Auth_OpenID_Server} contains all the logic
* and data necessary to respond to such requests; just pass it to * and data necessary to respond to such requests; just pass it to
* {@link Auth_OpenID_Server::handleRequest()}. * {@link Auth_OpenID_Server::handleRequest()}.
* *
* OpenID Extensions * OpenID Extensions
* *
* Do you want to provide other information for your users in addition * Do you want to provide other information for your users in addition
* to authentication? Version 1.2 of the OpenID protocol allows * to authentication? Version 1.2 of the OpenID protocol allows
* consumers to add extensions to their requests. For example, with * consumers to add extensions to their requests. For example, with
* sites using the Simple Registration * sites using the Simple Registration
* Extension * Extension
* (http://openid.net/specs/openid-simple-registration-extension-1_0.html), * (http://openid.net/specs/openid-simple-registration-extension-1_0.html),
* a user can agree to have their nickname and e-mail address sent to * a user can agree to have their nickname and e-mail address sent to
* a site when they sign up. * a site when they sign up.
* *
* Since extensions do not change the way OpenID authentication works, * Since extensions do not change the way OpenID authentication works,
* code to handle extension requests may be completely separate from * code to handle extension requests may be completely separate from
* the {@link Auth_OpenID_Request} class here. But you'll likely want * the {@link Auth_OpenID_Request} class here. But you'll likely want
* data sent back by your extension to be signed. {@link * data sent back by your extension to be signed. {@link
* Auth_OpenID_ServerResponse} provides methods with which you can add * Auth_OpenID_ServerResponse} provides methods with which you can add
* data to it which can be signed with the other data in the OpenID * data to it which can be signed with the other data in the OpenID
* signature. * signature.
* *
* For example: * For example:
* *
* <pre> // when request is a checkid_* request * <pre> // when request is a checkid_* request
* $response = $request->answer(true); * $response = $request->answer(true);
* // this will a signed 'openid.sreg.timezone' parameter to the response * // this will a signed 'openid.sreg.timezone' parameter to the response
* response.addField('sreg', 'timezone', 'America/Los_Angeles')</pre> * response.addField('sreg', 'timezone', 'America/Los_Angeles')</pre>
* *
* Stores * Stores
* *
* The OpenID server needs to maintain state between requests in order * The OpenID server needs to maintain state between requests in order
* to function. Its mechanism for doing this is called a store. The * to function. Its mechanism for doing this is called a store. The
* store interface is defined in Interface.php. Additionally, several * store interface is defined in Interface.php. Additionally, several
* concrete store implementations are provided, so that most sites * concrete store implementations are provided, so that most sites
* won't need to implement a custom store. For a store backed by flat * 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 * files on disk, see {@link Auth_OpenID_FileStore}. For stores based
* on MySQL, SQLite, or PostgreSQL, see the {@link * on MySQL, SQLite, or PostgreSQL, see the {@link
* Auth_OpenID_SQLStore} subclasses. * Auth_OpenID_SQLStore} subclasses.
* *
* Upgrading * Upgrading
* *
* The keys by which a server looks up associations in its store have * 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 * changed in version 1.2 of this library. If your store has entries
* created from version 1.0 code, you should empty it. * created from version 1.0 code, you should empty it.
* *
* PHP versions 4 and 5 * PHP versions 4 and 5
* *
* LICENSE: See the COPYING file included in this distribution. * LICENSE: See the COPYING file included in this distribution.
* *
* @package OpenID * @package OpenID
* @author JanRain, Inc. <openid@janrain.com> * @author JanRain, Inc. <openid@janrain.com>
* @copyright 2005-2008 Janrain, Inc. * @copyright 2005-2008 Janrain, Inc.
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache * @license http://www.apache.org/licenses/LICENSE-2.0 Apache
*/ */
   
/** /**
* Required imports * Required imports
*/ */
require_once "Auth/OpenID.php"; require_once "Auth/OpenID.php";
require_once "Auth/OpenID/Association.php"; require_once "Auth/OpenID/Association.php";
require_once "Auth/OpenID/CryptUtil.php"; require_once "Auth/OpenID/CryptUtil.php";
require_once "Auth/OpenID/BigMath.php"; require_once "Auth/OpenID/BigMath.php";
require_once "Auth/OpenID/DiffieHellman.php"; require_once "Auth/OpenID/DiffieHellman.php";
require_once "Auth/OpenID/KVForm.php"; require_once "Auth/OpenID/KVForm.php";
require_once "Auth/OpenID/TrustRoot.php"; require_once "Auth/OpenID/TrustRoot.php";
require_once "Auth/OpenID/ServerRequest.php"; require_once "Auth/OpenID/ServerRequest.php";
require_once "Auth/OpenID/Message.php"; require_once "Auth/OpenID/Message.php";
require_once "Auth/OpenID/Nonce.php"; require_once "Auth/OpenID/Nonce.php";
   
define('AUTH_OPENID_HTTP_OK', 200); define('AUTH_OPENID_HTTP_OK', 200);
define('AUTH_OPENID_HTTP_REDIRECT', 302); define('AUTH_OPENID_HTTP_REDIRECT', 302);
define('AUTH_OPENID_HTTP_ERROR', 400); define('AUTH_OPENID_HTTP_ERROR', 400);
   
/** /**
* @access private * @access private
*/ */
global $_Auth_OpenID_Request_Modes; global $_Auth_OpenID_Request_Modes;
$_Auth_OpenID_Request_Modes = array('checkid_setup', $_Auth_OpenID_Request_Modes = array('checkid_setup',
'checkid_immediate'); 'checkid_immediate');
   
/** /**
* @access private * @access private
*/ */
define('Auth_OpenID_ENCODE_KVFORM', 'kfvorm'); define('Auth_OpenID_ENCODE_KVFORM', 'kfvorm');
   
/** /**
* @access private * @access private
*/ */
define('Auth_OpenID_ENCODE_URL', 'URL/redirect'); define('Auth_OpenID_ENCODE_URL', 'URL/redirect');
   
/** /**
* @access private * @access private
*/ */
define('Auth_OpenID_ENCODE_HTML_FORM', 'HTML form'); define('Auth_OpenID_ENCODE_HTML_FORM', 'HTML form');
   
/** /**
* @access private * @access private
*/ */
function Auth_OpenID_isError($obj, $cls = 'Auth_OpenID_ServerError') function Auth_OpenID_isError($obj, $cls = 'Auth_OpenID_ServerError')
{ {
return is_a($obj, $cls); return is_a($obj, $cls);
} }
   
/** /**
* An error class which gets instantiated and returned whenever an * An error class which gets instantiated and returned whenever an
* OpenID protocol error occurs. Be prepared to use this in place of * OpenID protocol error occurs. Be prepared to use this in place of
* an ordinary server response. * an ordinary server response.
* *
* @package OpenID * @package OpenID
*/ */
class Auth_OpenID_ServerError { class Auth_OpenID_ServerError {
/** /**
* @access private * @access private
*/ */
function Auth_OpenID_ServerError($message = null, $text = null, function Auth_OpenID_ServerError($message = null, $text = null,
$reference = null, $contact = null) $reference = null, $contact = null)
{ {
$this->message = $message; $this->message = $message;
$this->text = $text; $this->text = $text;
$this->contact = $contact; $this->contact = $contact;
$this->reference = $reference; $this->reference = $reference;
} }
   
function getReturnTo() function getReturnTo()
{ {
if ($this->message && if ($this->message &&
$this->message->hasKey(Auth_OpenID_OPENID_NS, 'return_to')) { $this->message->hasKey(Auth_OpenID_OPENID_NS, 'return_to')) {
return $this->message->getArg(Auth_OpenID_OPENID_NS, return $this->message->getArg(Auth_OpenID_OPENID_NS,
'return_to'); 'return_to');
} else { } else {
return null; return null;
} }
} }
   
/** /**
* Returns the return_to URL for the request which caused this * Returns the return_to URL for the request which caused this
* error. * error.
*/ */
function hasReturnTo() function hasReturnTo()
{ {
return $this->getReturnTo() !== null; return $this->getReturnTo() !== null;
} }
   
/** /**
* Encodes this error's response as a URL suitable for * Encodes this error's response as a URL suitable for
* redirection. If the response has no return_to, another * redirection. If the response has no return_to, another
* Auth_OpenID_ServerError is returned. * Auth_OpenID_ServerError is returned.
*/ */
function encodeToURL() function encodeToURL()
{ {
if (!$this->message) { if (!$this->message) {
return null; return null;
} }
   
$msg = $this->toMessage(); $msg = $this->toMessage();
return $msg->toURL($this->getReturnTo()); return $msg->toURL($this->getReturnTo());
} }
   
/** /**
* Encodes the response to key-value form. This is a * Encodes the response to key-value form. This is a
* machine-readable format used to respond to messages which came * machine-readable format used to respond to messages which came
* directly from the consumer and not through the user-agent. See * directly from the consumer and not through the user-agent. See
* the OpenID specification. * the OpenID specification.
*/ */
function encodeToKVForm() function encodeToKVForm()
{ {
return Auth_OpenID_KVForm::fromArray( return Auth_OpenID_KVForm::fromArray(
array('mode' => 'error', array('mode' => 'error',
'error' => $this->toString())); 'error' => $this->toString()));
} }
   
function toFormMarkup($form_tag_attrs=null) function toFormMarkup($form_tag_attrs=null)
{ {
$msg = $this->toMessage(); $msg = $this->toMessage();
return $msg->toFormMarkup($this->getReturnTo(), $form_tag_attrs); return $msg->toFormMarkup($this->getReturnTo(), $form_tag_attrs);
} }
   
function toHTML($form_tag_attrs=null) function toHTML($form_tag_attrs=null)
{ {
return Auth_OpenID::autoSubmitHTML( return Auth_OpenID::autoSubmitHTML(
$this->toFormMarkup($form_tag_attrs)); $this->toFormMarkup($form_tag_attrs));
} }
   
function toMessage() function toMessage()
{ {
// Generate a Message object for sending to the relying party, // Generate a Message object for sending to the relying party,
// after encoding. // after encoding.
$namespace = $this->message->getOpenIDNamespace(); $namespace = $this->message->getOpenIDNamespace();
$reply = new Auth_OpenID_Message($namespace); $reply = new Auth_OpenID_Message($namespace);
$reply->setArg(Auth_OpenID_OPENID_NS, 'mode', 'error'); $reply->setArg(Auth_OpenID_OPENID_NS, 'mode', 'error');
$reply->setArg(Auth_OpenID_OPENID_NS, 'error', $this->toString()); $reply->setArg(Auth_OpenID_OPENID_NS, 'error', $this->toString());
   
if ($this->contact !== null) { if ($this->contact !== null) {
$reply->setArg(Auth_OpenID_OPENID_NS, 'contact', $this->contact); $reply->setArg(Auth_OpenID_OPENID_NS, 'contact', $this->contact);
} }
   
if ($this->reference !== null) { if ($this->reference !== null) {
$reply->setArg(Auth_OpenID_OPENID_NS, 'reference', $reply->setArg(Auth_OpenID_OPENID_NS, 'reference',
$this->reference); $this->reference);
} }
   
return $reply; return $reply;
} }
   
/** /**
* Returns one of Auth_OpenID_ENCODE_URL, * Returns one of Auth_OpenID_ENCODE_URL,
* Auth_OpenID_ENCODE_KVFORM, or null, depending on the type of * Auth_OpenID_ENCODE_KVFORM, or null, depending on the type of
* encoding expected for this error's payload. * encoding expected for this error's payload.
*/ */
function whichEncoding() function whichEncoding()
{ {
global $_Auth_OpenID_Request_Modes; global $_Auth_OpenID_Request_Modes;
   
if ($this->hasReturnTo()) { if ($this->hasReturnTo()) {
if ($this->message->isOpenID2() && if ($this->message->isOpenID2() &&
(strlen($this->encodeToURL()) > (strlen($this->encodeToURL()) >
Auth_OpenID_OPENID1_URL_LIMIT)) { Auth_OpenID_OPENID1_URL_LIMIT)) {
return Auth_OpenID_ENCODE_HTML_FORM; return Auth_OpenID_ENCODE_HTML_FORM;
} else { } else {
return Auth_OpenID_ENCODE_URL; return Auth_OpenID_ENCODE_URL;
} }
} }
   
if (!$this->message) { if (!$this->message) {
return null; return null;
} }
   
$mode = $this->message->getArg(Auth_OpenID_OPENID_NS, $mode = $this->message->getArg(Auth_OpenID_OPENID_NS,
'mode'); 'mode');
   
if ($mode) { if ($mode) {
if (!in_array($mode, $_Auth_OpenID_Request_Modes)) { if (!in_array($mode, $_Auth_OpenID_Request_Modes)) {
return Auth_OpenID_ENCODE_KVFORM; return Auth_OpenID_ENCODE_KVFORM;
} }
} }
return null; return null;
} }
   
/** /**
* Returns this error message. * Returns this error message.
*/ */
function toString() function toString()
{ {
if ($this->text) { if ($this->text) {
return $this->text; return $this->text;
} else { } else {
return get_class($this) . " error"; return get_class($this) . " error";
} }
} }
} }
   
/** /**
* Error returned by the server code when a return_to is absent from a * Error returned by the server code when a return_to is absent from a
* request. * request.
* *
* @package OpenID * @package OpenID
*/ */
class Auth_OpenID_NoReturnToError extends Auth_OpenID_ServerError { class Auth_OpenID_NoReturnToError extends Auth_OpenID_ServerError {
function Auth_OpenID_NoReturnToError($message = null, function Auth_OpenID_NoReturnToError($message = null,
$text = "No return_to URL available") $text = "No return_to URL available")
{ {
parent::Auth_OpenID_ServerError($message, $text); parent::Auth_OpenID_ServerError($message, $text);
} }
   
function toString() function toString()
{ {
return "No return_to available"; return "No return_to available";
} }
} }
   
/** /**
* An error indicating that the return_to URL is malformed. * An error indicating that the return_to URL is malformed.
* *
* @package OpenID * @package OpenID
*/ */
class Auth_OpenID_MalformedReturnURL extends Auth_OpenID_ServerError { class Auth_OpenID_MalformedReturnURL extends Auth_OpenID_ServerError {
function Auth_OpenID_MalformedReturnURL($message, $return_to) function Auth_OpenID_MalformedReturnURL($message, $return_to)
{ {
$this->return_to = $return_to; $this->return_to = $return_to;
parent::Auth_OpenID_ServerError($message, "malformed return_to URL"); parent::Auth_OpenID_ServerError($message, "malformed return_to URL");
} }
} }
   
/** /**
* This error is returned when the trust_root value is malformed. * This error is returned when the trust_root value is malformed.
* *
* @package OpenID * @package OpenID
*/ */
class Auth_OpenID_MalformedTrustRoot extends Auth_OpenID_ServerError { class Auth_OpenID_MalformedTrustRoot extends Auth_OpenID_ServerError {
function Auth_OpenID_MalformedTrustRoot($message = null, function Auth_OpenID_MalformedTrustRoot($message = null,
$text = "Malformed trust root") $text = "Malformed trust root")
{ {
parent::Auth_OpenID_ServerError($message, $text); parent::Auth_OpenID_ServerError($message, $text);
} }
   
function toString() function toString()
{ {
return "Malformed trust root"; return "Malformed trust root";
} }
} }
   
/** /**
* The base class for all server request classes. * The base class for all server request classes.
* *
* @package OpenID * @package OpenID
*/ */
class Auth_OpenID_Request { class Auth_OpenID_Request {
var $mode = null; var $mode = null;
} }
   
/** /**
* A request to verify the validity of a previous response. * A request to verify the validity of a previous response.
* *
* @package OpenID * @package OpenID
*/ */
class Auth_OpenID_CheckAuthRequest extends Auth_OpenID_Request { class Auth_OpenID_CheckAuthRequest extends Auth_OpenID_Request {
var $mode = "check_authentication"; var $mode = "check_authentication";
var $invalidate_handle = null; var $invalidate_handle = null;
   
function Auth_OpenID_CheckAuthRequest($assoc_handle, $signed, function Auth_OpenID_CheckAuthRequest($assoc_handle, $signed,
$invalidate_handle = null) $invalidate_handle = null)
{ {
$this->assoc_handle = $assoc_handle; $this->assoc_handle = $assoc_handle;
$this->signed = $signed; $this->signed = $signed;
if ($invalidate_handle !== null) { if ($invalidate_handle !== null) {
$this->invalidate_handle = $invalidate_handle; $this->invalidate_handle = $invalidate_handle;
} }
$this->namespace = Auth_OpenID_OPENID2_NS; $this->namespace = Auth_OpenID_OPENID2_NS;
$this->message = null; $this->message = null;
} }
   
static function fromMessage($message, $server=null) static function fromMessage($message, $server=null)
{ {
$required_keys = array('assoc_handle', 'sig', 'signed'); $required_keys = array('assoc_handle', 'sig', 'signed');
   
foreach ($required_keys as $k) { foreach ($required_keys as $k) {