| 42 | aurelien | 1 | <?php
 | 
        
           |  |  | 2 |   | 
        
           |  |  | 3 | /**
 | 
        
           |  |  | 4 |  * This module documents the main interface with the OpenID consumer
 | 
        
           |  |  | 5 |  * library.  The only part of the library which has to be used and
 | 
        
           |  |  | 6 |  * isn't documented in full here is the store required to create an
 | 
        
           |  |  | 7 |  * Auth_OpenID_Consumer instance.  More on the abstract store type and
 | 
        
           |  |  | 8 |  * concrete implementations of it that are provided in the
 | 
        
           |  |  | 9 |  * documentation for the Auth_OpenID_Consumer constructor.
 | 
        
           |  |  | 10 |  *
 | 
        
           |  |  | 11 |  * OVERVIEW
 | 
        
           |  |  | 12 |  *
 | 
        
           |  |  | 13 |  * The OpenID identity verification process most commonly uses the
 | 
        
           |  |  | 14 |  * following steps, as visible to the user of this library:
 | 
        
           |  |  | 15 |  *
 | 
        
           |  |  | 16 |  *   1. The user enters their OpenID into a field on the consumer's
 | 
        
           |  |  | 17 |  *      site, and hits a login button.
 | 
        
           |  |  | 18 |  *   2. The consumer site discovers the user's OpenID server using the
 | 
        
           |  |  | 19 |  *      YADIS protocol.
 | 
        
           |  |  | 20 |  *   3. The consumer site sends the browser a redirect to the identity
 | 
        
           |  |  | 21 |  *      server.  This is the authentication request as described in
 | 
        
           |  |  | 22 |  *      the OpenID specification.
 | 
        
           |  |  | 23 |  *   4. The identity server's site sends the browser a redirect back
 | 
        
           |  |  | 24 |  *      to the consumer site.  This redirect contains the server's
 | 
        
           |  |  | 25 |  *      response to the authentication request.
 | 
        
           |  |  | 26 |  *
 | 
        
           |  |  | 27 |  * The most important part of the flow to note is the consumer's site
 | 
        
           |  |  | 28 |  * must handle two separate HTTP requests in order to perform the full
 | 
        
           |  |  | 29 |  * identity check.
 | 
        
           |  |  | 30 |  *
 | 
        
           |  |  | 31 |  * LIBRARY DESIGN
 | 
        
           |  |  | 32 |  *
 | 
        
           |  |  | 33 |  * This consumer library is designed with that flow in mind.  The goal
 | 
        
           |  |  | 34 |  * is to make it as easy as possible to perform the above steps
 | 
        
           |  |  | 35 |  * securely.
 | 
        
           |  |  | 36 |  *
 | 
        
           |  |  | 37 |  * At a high level, there are two important parts in the consumer
 | 
        
           |  |  | 38 |  * library.  The first important part is this module, which contains
 | 
        
           |  |  | 39 |  * the interface to actually use this library.  The second is the
 | 
        
           |  |  | 40 |  * Auth_OpenID_Interface class, which describes the interface to use
 | 
        
           |  |  | 41 |  * if you need to create a custom method for storing the state this
 | 
        
           |  |  | 42 |  * library needs to maintain between requests.
 | 
        
           |  |  | 43 |  *
 | 
        
           |  |  | 44 |  * In general, the second part is less important for users of the
 | 
        
           |  |  | 45 |  * library to know about, as several implementations are provided
 | 
        
           |  |  | 46 |  * which cover a wide variety of situations in which consumers may use
 | 
        
           |  |  | 47 |  * the library.
 | 
        
           |  |  | 48 |  *
 | 
        
           |  |  | 49 |  * This module contains a class, Auth_OpenID_Consumer, with methods
 | 
        
           |  |  | 50 |  * corresponding to the actions necessary in each of steps 2, 3, and 4
 | 
        
           |  |  | 51 |  * described in the overview.  Use of this library should be as easy
 | 
        
           |  |  | 52 |  * as creating an Auth_OpenID_Consumer instance and calling the
 | 
        
           |  |  | 53 |  * methods appropriate for the action the site wants to take.
 | 
        
           |  |  | 54 |  *
 | 
        
           |  |  | 55 |  * STORES AND DUMB MODE
 | 
        
           |  |  | 56 |  *
 | 
        
           |  |  | 57 |  * OpenID is a protocol that works best when the consumer site is able
 | 
        
           |  |  | 58 |  * to store some state.  This is the normal mode of operation for the
 | 
        
           |  |  | 59 |  * protocol, and is sometimes referred to as smart mode.  There is
 | 
        
           |  |  | 60 |  * also a fallback mode, known as dumb mode, which is available when
 | 
        
           |  |  | 61 |  * the consumer site is not able to store state.  This mode should be
 | 
        
           |  |  | 62 |  * avoided when possible, as it leaves the implementation more
 | 
        
           |  |  | 63 |  * vulnerable to replay attacks.
 | 
        
           |  |  | 64 |  *
 | 
        
           |  |  | 65 |  * The mode the library works in for normal operation is determined by
 | 
        
           |  |  | 66 |  * the store that it is given.  The store is an abstraction that
 | 
        
           |  |  | 67 |  * handles the data that the consumer needs to manage between http
 | 
        
           |  |  | 68 |  * requests in order to operate efficiently and securely.
 | 
        
           |  |  | 69 |  *
 | 
        
           |  |  | 70 |  * Several store implementation are provided, and the interface is
 | 
        
           |  |  | 71 |  * fully documented so that custom stores can be used as well.  See
 | 
        
           |  |  | 72 |  * the documentation for the Auth_OpenID_Consumer class for more
 | 
        
           |  |  | 73 |  * information on the interface for stores.  The implementations that
 | 
        
           |  |  | 74 |  * are provided allow the consumer site to store the necessary data in
 | 
        
           |  |  | 75 |  * several different ways, including several SQL databases and normal
 | 
        
           |  |  | 76 |  * files on disk.
 | 
        
           |  |  | 77 |  *
 | 
        
           |  |  | 78 |  * There is an additional concrete store provided that puts the system
 | 
        
           |  |  | 79 |  * in dumb mode.  This is not recommended, as it removes the library's
 | 
        
           |  |  | 80 |  * ability to stop replay attacks reliably.  It still uses time-based
 | 
        
           |  |  | 81 |  * checking to make replay attacks only possible within a small
 | 
        
           |  |  | 82 |  * window, but they remain possible within that window.  This store
 | 
        
           |  |  | 83 |  * should only be used if the consumer site has no way to retain data
 | 
        
           |  |  | 84 |  * between requests at all.
 | 
        
           |  |  | 85 |  *
 | 
        
           |  |  | 86 |  * IMMEDIATE MODE
 | 
        
           |  |  | 87 |  *
 | 
        
           |  |  | 88 |  * In the flow described above, the user may need to confirm to the
 | 
        
           |  |  | 89 |  * lidentity server that it's ok to authorize his or her identity.
 | 
        
           |  |  | 90 |  * The server may draw pages asking for information from the user
 | 
        
           |  |  | 91 |  * before it redirects the browser back to the consumer's site.  This
 | 
        
           |  |  | 92 |  * is generally transparent to the consumer site, so it is typically
 | 
        
           |  |  | 93 |  * ignored as an implementation detail.
 | 
        
           |  |  | 94 |  *
 | 
        
           |  |  | 95 |  * There can be times, however, where the consumer site wants to get a
 | 
        
           |  |  | 96 |  * response immediately.  When this is the case, the consumer can put
 | 
        
           |  |  | 97 |  * the library in immediate mode.  In immediate mode, there is an
 | 
        
           |  |  | 98 |  * extra response possible from the server, which is essentially the
 | 
        
           |  |  | 99 |  * server reporting that it doesn't have enough information to answer
 | 
        
           |  |  | 100 |  * the question yet.  In addition to saying that, the identity server
 | 
        
           |  |  | 101 |  * provides a URL to which the user can be sent to provide the needed
 | 
        
           |  |  | 102 |  * information and let the server finish handling the original
 | 
        
           |  |  | 103 |  * request.
 | 
        
           |  |  | 104 |  *
 | 
        
           |  |  | 105 |  * USING THIS LIBRARY
 | 
        
           |  |  | 106 |  *
 | 
        
           |  |  | 107 |  * Integrating this library into an application is usually a
 | 
        
           |  |  | 108 |  * relatively straightforward process.  The process should basically
 | 
        
           |  |  | 109 |  * follow this plan:
 | 
        
           |  |  | 110 |  *
 | 
        
           |  |  | 111 |  * Add an OpenID login field somewhere on your site.  When an OpenID
 | 
        
           |  |  | 112 |  * is entered in that field and the form is submitted, it should make
 | 
        
           |  |  | 113 |  * a request to the your site which includes that OpenID URL.
 | 
        
           |  |  | 114 |  *
 | 
        
           |  |  | 115 |  * First, the application should instantiate the Auth_OpenID_Consumer
 | 
        
           |  |  | 116 |  * class using the store of choice (Auth_OpenID_FileStore or one of
 | 
        
           |  |  | 117 |  * the SQL-based stores).  If the application has any sort of session
 | 
        
           |  |  | 118 |  * framework that provides per-client state management, a dict-like
 | 
        
           |  |  | 119 |  * object to access the session should be passed as the optional
 | 
        
           |  |  | 120 |  * second parameter.  (The default behavior is to use PHP's standard
 | 
        
           |  |  | 121 |  * session machinery.)
 | 
        
           |  |  | 122 |  *
 | 
        
           |  |  | 123 |  * Next, the application should call the Auth_OpenID_Consumer object's
 | 
        
           |  |  | 124 |  * 'begin' method.  This method takes the OpenID URL.  The 'begin'
 | 
        
           |  |  | 125 |  * method returns an Auth_OpenID_AuthRequest object.
 | 
        
           |  |  | 126 |  *
 | 
        
           |  |  | 127 |  * Next, the application should call the 'redirectURL' method of the
 | 
        
           |  |  | 128 |  * Auth_OpenID_AuthRequest object.  The 'return_to' URL parameter is
 | 
        
           |  |  | 129 |  * the URL that the OpenID server will send the user back to after
 | 
        
           |  |  | 130 |  * attempting to verify his or her identity.  The 'trust_root' is the
 | 
        
           |  |  | 131 |  * URL (or URL pattern) that identifies your web site to the user when
 | 
        
           |  |  | 132 |  * he or she is authorizing it.  Send a redirect to the resulting URL
 | 
        
           |  |  | 133 |  * to the user's browser.
 | 
        
           |  |  | 134 |  *
 | 
        
           |  |  | 135 |  * That's the first half of the authentication process.  The second
 | 
        
           |  |  | 136 |  * half of the process is done after the user's ID server sends the
 | 
        
           |  |  | 137 |  * user's browser a redirect back to your site to complete their
 | 
        
           |  |  | 138 |  * login.
 | 
        
           |  |  | 139 |  *
 | 
        
           |  |  | 140 |  * When that happens, the user will contact your site at the URL given
 | 
        
           |  |  | 141 |  * as the 'return_to' URL to the Auth_OpenID_AuthRequest::redirectURL
 | 
        
           |  |  | 142 |  * call made above.  The request will have several query parameters
 | 
        
           |  |  | 143 |  * added to the URL by the identity server as the information
 | 
        
           |  |  | 144 |  * necessary to finish the request.
 | 
        
           |  |  | 145 |  *
 | 
        
           |  |  | 146 |  * Lastly, instantiate an Auth_OpenID_Consumer instance as above and
 | 
        
           |  |  | 147 |  * call its 'complete' method, passing in all the received query
 | 
        
           |  |  | 148 |  * arguments.
 | 
        
           |  |  | 149 |  *
 | 
        
           |  |  | 150 |  * There are multiple possible return types possible from that
 | 
        
           |  |  | 151 |  * method. These indicate the whether or not the login was successful,
 | 
        
           |  |  | 152 |  * and include any additional information appropriate for their type.
 | 
        
           |  |  | 153 |  *
 | 
        
           |  |  | 154 |  * PHP versions 4 and 5
 | 
        
           |  |  | 155 |  *
 | 
        
           |  |  | 156 |  * LICENSE: See the COPYING file included in this distribution.
 | 
        
           |  |  | 157 |  *
 | 
        
           |  |  | 158 |  * @package OpenID
 | 
        
           |  |  | 159 |  * @author JanRain, Inc. <openid@janrain.com>
 | 
        
           |  |  | 160 |  * @copyright 2005 Janrain, Inc.
 | 
        
           |  |  | 161 |  * @license http://www.gnu.org/copyleft/lesser.html LGPL
 | 
        
           |  |  | 162 |  */
 | 
        
           |  |  | 163 |   | 
        
           |  |  | 164 | /**
 | 
        
           |  |  | 165 |  * Require utility classes and functions for the consumer.
 | 
        
           |  |  | 166 |  */
 | 
        
           |  |  | 167 | require_once "Auth/OpenID.php";
 | 
        
           |  |  | 168 | require_once "Auth/OpenID/HMACSHA1.php";
 | 
        
           |  |  | 169 | require_once "Auth/OpenID/Association.php";
 | 
        
           |  |  | 170 | require_once "Auth/OpenID/CryptUtil.php";
 | 
        
           |  |  | 171 | require_once "Auth/OpenID/DiffieHellman.php";
 | 
        
           |  |  | 172 | require_once "Auth/OpenID/KVForm.php";
 | 
        
           |  |  | 173 | require_once "Auth/OpenID/Discover.php";
 | 
        
           |  |  | 174 | require_once "Services/Yadis/Manager.php";
 | 
        
           |  |  | 175 | require_once "Services/Yadis/XRI.php";
 | 
        
           |  |  | 176 |   | 
        
           |  |  | 177 | /**
 | 
        
           |  |  | 178 |  * This is the status code returned when the complete method returns
 | 
        
           |  |  | 179 |  * successfully.
 | 
        
           |  |  | 180 |  */
 | 
        
           |  |  | 181 | define('Auth_OpenID_SUCCESS', 'success');
 | 
        
           |  |  | 182 |   | 
        
           |  |  | 183 | /**
 | 
        
           |  |  | 184 |  * Status to indicate cancellation of OpenID authentication.
 | 
        
           |  |  | 185 |  */
 | 
        
           |  |  | 186 | define('Auth_OpenID_CANCEL', 'cancel');
 | 
        
           |  |  | 187 |   | 
        
           |  |  | 188 | /**
 | 
        
           |  |  | 189 |  * This is the status code completeAuth returns when the value it
 | 
        
           |  |  | 190 |  * received indicated an invalid login.
 | 
        
           |  |  | 191 |  */
 | 
        
           |  |  | 192 | define('Auth_OpenID_FAILURE', 'failure');
 | 
        
           |  |  | 193 |   | 
        
           |  |  | 194 | /**
 | 
        
           |  |  | 195 |  * This is the status code completeAuth returns when the
 | 
        
           |  |  | 196 |  * {@link Auth_OpenID_Consumer} instance is in immediate mode, and the
 | 
        
           |  |  | 197 |  * identity server sends back a URL to send the user to to complete his
 | 
        
           |  |  | 198 |  * or her login.
 | 
        
           |  |  | 199 |  */
 | 
        
           |  |  | 200 | define('Auth_OpenID_SETUP_NEEDED', 'setup needed');
 | 
        
           |  |  | 201 |   | 
        
           |  |  | 202 | /**
 | 
        
           |  |  | 203 |  * This is the status code beginAuth returns when the page fetched
 | 
        
           |  |  | 204 |  * from the entered OpenID URL doesn't contain the necessary link tags
 | 
        
           |  |  | 205 |  * to function as an identity page.
 | 
        
           |  |  | 206 |  */
 | 
        
           |  |  | 207 | define('Auth_OpenID_PARSE_ERROR', 'parse error');
 | 
        
           |  |  | 208 |   | 
        
           |  |  | 209 | /**
 | 
        
           |  |  | 210 |  * This is the characters that the nonces are made from.
 | 
        
           |  |  | 211 |  */
 | 
        
           |  |  | 212 | define('Auth_OpenID_DEFAULT_NONCE_CHRS',"abcdefghijklmnopqrstuvwxyz" .
 | 
        
           |  |  | 213 |        "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
 | 
        
           |  |  | 214 |   | 
        
           |  |  | 215 | /**
 | 
        
           |  |  | 216 |  * An OpenID consumer implementation that performs discovery and does
 | 
        
           |  |  | 217 |  * session management.  See the Consumer.php file documentation for
 | 
        
           |  |  | 218 |  * more information.
 | 
        
           |  |  | 219 |  *
 | 
        
           |  |  | 220 |  * @package OpenID
 | 
        
           |  |  | 221 |  */
 | 
        
           |  |  | 222 | class Auth_OpenID_Consumer {
 | 
        
           |  |  | 223 |   | 
        
           |  |  | 224 |     /**
 | 
        
           |  |  | 225 |      * @access private
 | 
        
           |  |  | 226 |      */
 | 
        
           |  |  | 227 |     var $session_key_prefix = "_openid_consumer_";
 | 
        
           |  |  | 228 |   | 
        
           |  |  | 229 |     /**
 | 
        
           |  |  | 230 |      * @access private
 | 
        
           |  |  | 231 |      */
 | 
        
           |  |  | 232 |     var $_token_suffix = "last_token";
 | 
        
           |  |  | 233 |   | 
        
           |  |  | 234 |     /**
 | 
        
           |  |  | 235 |      * Initialize a Consumer instance.
 | 
        
           |  |  | 236 |      *
 | 
        
           |  |  | 237 |      * You should create a new instance of the Consumer object with
 | 
        
           |  |  | 238 |      * every HTTP request that handles OpenID transactions.
 | 
        
           |  |  | 239 |      *
 | 
        
           |  |  | 240 |      * @param Auth_OpenID_OpenIDStore $store This must be an object
 | 
        
           |  |  | 241 |      * that implements the interface in {@link
 | 
        
           |  |  | 242 |      * Auth_OpenID_OpenIDStore}.  Several concrete implementations are
 | 
        
           |  |  | 243 |      * provided, to cover most common use cases.  For stores backed by
 | 
        
           |  |  | 244 |      * MySQL, PostgreSQL, or SQLite, see the {@link
 | 
        
           |  |  | 245 |      * Auth_OpenID_SQLStore} class and its sublcasses.  For a
 | 
        
           |  |  | 246 |      * filesystem-backed store, see the {@link Auth_OpenID_FileStore}
 | 
        
           |  |  | 247 |      * module.  As a last resort, if it isn't possible for the server
 | 
        
           |  |  | 248 |      * to store state at all, an instance of {@link
 | 
        
           |  |  | 249 |      * Auth_OpenID_DumbStore} can be used.
 | 
        
           |  |  | 250 |      *
 | 
        
           |  |  | 251 |      * @param mixed session An object which implements the interface
 | 
        
           |  |  | 252 |      * of the Services_Yadis_Session class.  Particularly, this object
 | 
        
           |  |  | 253 |      * is expected to have these methods: get($key), set($key,
 | 
        
           |  |  | 254 |      * $value), and del($key).  This defaults to a session object
 | 
        
           |  |  | 255 |      * which wraps PHP's native session machinery.  You should only
 | 
        
           |  |  | 256 |      * need to pass something here if you have your own sessioning
 | 
        
           |  |  | 257 |      * implementation.
 | 
        
           |  |  | 258 |      */
 | 
        
           |  |  | 259 |     function Auth_OpenID_Consumer(&$store, $session = null)
 | 
        
           |  |  | 260 |     {
 | 
        
           |  |  | 261 |         if ($session === null) {
 | 
        
           |  |  | 262 |             $session = new Services_Yadis_PHPSession();
 | 
        
           |  |  | 263 |         }
 | 
        
           |  |  | 264 |   | 
        
           |  |  | 265 |         $this->session =& $session;
 | 
        
           |  |  | 266 |         $this->consumer =& new Auth_OpenID_GenericConsumer($store);
 | 
        
           |  |  | 267 |         $this->_token_key = $this->session_key_prefix . $this->_token_suffix;
 | 
        
           |  |  | 268 |     }
 | 
        
           |  |  | 269 |   | 
        
           |  |  | 270 |     /**
 | 
        
           |  |  | 271 |      * Start the OpenID authentication process. See steps 1-2 in the
 | 
        
           |  |  | 272 |      * overview at the top of this file.
 | 
        
           |  |  | 273 |      *
 | 
        
           |  |  | 274 |      * @param User_url: Identity URL given by the user. This method
 | 
        
           |  |  | 275 |      * performs a textual transformation of the URL to try and make
 | 
        
           |  |  | 276 |      * sure it is normalized. For example, a user_url of example.com
 | 
        
           |  |  | 277 |      * will be normalized to http://example.com/ normalizing and
 | 
        
           |  |  | 278 |      * resolving any redirects the server might issue.
 | 
        
           |  |  | 279 |      *
 | 
        
           |  |  | 280 |      * @return Auth_OpenID_AuthRequest $auth_request An object
 | 
        
           |  |  | 281 |      * containing the discovered information will be returned, with a
 | 
        
           |  |  | 282 |      * method for building a redirect URL to the server, as described
 | 
        
           |  |  | 283 |      * in step 3 of the overview. This object may also be used to add
 | 
        
           |  |  | 284 |      * extension arguments to the request, using its 'addExtensionArg'
 | 
        
           |  |  | 285 |      * method.
 | 
        
           |  |  | 286 |      */
 | 
        
           |  |  | 287 |     function begin($user_url)
 | 
        
           |  |  | 288 |     {
 | 
        
           |  |  | 289 |         $discoverMethod = '_Auth_OpenID_discoverServiceList';
 | 
        
           |  |  | 290 |         $openid_url = $user_url;
 | 
        
           |  |  | 291 |   | 
        
           |  |  | 292 |         if (Services_Yadis_identifierScheme($user_url) == 'XRI') {
 | 
        
           |  |  | 293 |             $discoverMethod = '_Auth_OpenID_discoverXRIServiceList';
 | 
        
           |  |  | 294 |         } else {
 | 
        
           |  |  | 295 |             $openid_url = Auth_OpenID::normalizeUrl($user_url);
 | 
        
           |  |  | 296 |         }
 | 
        
           |  |  | 297 |   | 
        
           |  |  | 298 |         $disco =& new Services_Yadis_Discovery($this->session,
 | 
        
           |  |  | 299 |                                                $openid_url,
 | 
        
           |  |  | 300 |                                                $this->session_key_prefix);
 | 
        
           |  |  | 301 |   | 
        
           |  |  | 302 |         // Set the 'stale' attribute of the manager.  If discovery
 | 
        
           |  |  | 303 |         // fails in a fatal way, the stale flag will cause the manager
 | 
        
           |  |  | 304 |         // to be cleaned up next time discovery is attempted.
 | 
        
           |  |  | 305 |   | 
        
           |  |  | 306 |         $m = $disco->getManager();
 | 
        
           |  |  | 307 |         $loader = new Services_Yadis_ManagerLoader();
 | 
        
           |  |  | 308 |   | 
        
           |  |  | 309 |         if ($m) {
 | 
        
           |  |  | 310 |             if ($m->stale) {
 | 
        
           |  |  | 311 |                 $disco->destroyManager();
 | 
        
           |  |  | 312 |             } else {
 | 
        
           |  |  | 313 |                 $m->stale = true;
 | 
        
           |  |  | 314 |                 $disco->session->set($disco->session_key,
 | 
        
           |  |  | 315 |                                      serialize($loader->toSession($m)));
 | 
        
           |  |  | 316 |             }
 | 
        
           |  |  | 317 |         }
 | 
        
           |  |  | 318 |   | 
        
           |  |  | 319 |         $endpoint = $disco->getNextService($discoverMethod,
 | 
        
           |  |  | 320 |                                            $this->consumer->fetcher);
 | 
        
           |  |  | 321 |   | 
        
           |  |  | 322 |         // Reset the 'stale' attribute of the manager.
 | 
        
           |  |  | 323 |         $m =& $disco->getManager();
 | 
        
           |  |  | 324 |         if ($m) {
 | 
        
           |  |  | 325 |             $m->stale = false;
 | 
        
           |  |  | 326 |             $disco->session->set($disco->session_key,
 | 
        
           |  |  | 327 |                                  serialize($loader->toSession($m)));
 | 
        
           |  |  | 328 |         }
 | 
        
           |  |  | 329 |   | 
        
           |  |  | 330 |         if ($endpoint === null) {
 | 
        
           |  |  | 331 |             return null;
 | 
        
           |  |  | 332 |         } else {
 | 
        
           |  |  | 333 |             return $this->beginWithoutDiscovery($endpoint);
 | 
        
           |  |  | 334 |         }
 | 
        
           |  |  | 335 |     }
 | 
        
           |  |  | 336 |   | 
        
           |  |  | 337 |     /**
 | 
        
           |  |  | 338 |      * Start OpenID verification without doing OpenID server
 | 
        
           |  |  | 339 |      * discovery. This method is used internally by Consumer.begin
 | 
        
           |  |  | 340 |      * after discovery is performed, and exists to provide an
 | 
        
           |  |  | 341 |      * interface for library users needing to perform their own
 | 
        
           |  |  | 342 |      * discovery.
 | 
        
           |  |  | 343 |      *
 | 
        
           |  |  | 344 |      * @param Auth_OpenID_ServiceEndpoint $endpoint an OpenID service
 | 
        
           |  |  | 345 |      * endpoint descriptor.
 | 
        
           |  |  | 346 |      *
 | 
        
           |  |  | 347 |      * @return Auth_OpenID_AuthRequest $auth_request An OpenID
 | 
        
           |  |  | 348 |      * authentication request object.
 | 
        
           |  |  | 349 |      */
 | 
        
           |  |  | 350 |     function &beginWithoutDiscovery($endpoint)
 | 
        
           |  |  | 351 |     {
 | 
        
           |  |  | 352 |         $loader = new Auth_OpenID_ServiceEndpointLoader();
 | 
        
           |  |  | 353 |         $auth_req = $this->consumer->begin($endpoint);
 | 
        
           |  |  | 354 |         $this->session->set($this->_token_key,
 | 
        
           |  |  | 355 |               $loader->toSession($auth_req->endpoint));
 | 
        
           |  |  | 356 |         return $auth_req;
 | 
        
           |  |  | 357 |     }
 | 
        
           |  |  | 358 |   | 
        
           |  |  | 359 |     /**
 | 
        
           |  |  | 360 |      * Called to interpret the server's response to an OpenID
 | 
        
           |  |  | 361 |      * request. It is called in step 4 of the flow described in the
 | 
        
           |  |  | 362 |      * consumer overview.
 | 
        
           |  |  | 363 |      *
 | 
        
           |  |  | 364 |      * @param array $query An array of the query parameters (key =>
 | 
        
           |  |  | 365 |      * value pairs) for this HTTP request.
 | 
        
           |  |  | 366 |      *
 | 
        
           |  |  | 367 |      * @return Auth_OpenID_ConsumerResponse $response A instance of an
 | 
        
           |  |  | 368 |      * Auth_OpenID_ConsumerResponse subclass. The type of response is
 | 
        
           |  |  | 369 |      * indicated by the status attribute, which will be one of
 | 
        
           |  |  | 370 |      * SUCCESS, CANCEL, FAILURE, or SETUP_NEEDED.
 | 
        
           |  |  | 371 |      */
 | 
        
           |  |  | 372 |     function complete($query)
 | 
        
           |  |  | 373 |     {
 | 
        
           |  |  | 374 |         $query = Auth_OpenID::fixArgs($query);
 | 
        
           |  |  | 375 |   | 
        
           |  |  | 376 |         $loader = new Auth_OpenID_ServiceEndpointLoader();
 | 
        
           |  |  | 377 |         $endpoint_data = $this->session->get($this->_token_key);
 | 
        
           |  |  | 378 |         $endpoint =
 | 
        
           |  |  | 379 |             $loader->fromSession($endpoint_data);
 | 
        
           |  |  | 380 |   | 
        
           |  |  | 381 |         if ($endpoint === null) {
 | 
        
           |  |  | 382 |             $response = new Auth_OpenID_FailureResponse(null,
 | 
        
           |  |  | 383 |                                                    'No session state found');
 | 
        
           |  |  | 384 |         } else {
 | 
        
           |  |  | 385 |             $response = $this->consumer->complete($query, $endpoint);
 | 
        
           |  |  | 386 |             $this->session->del($this->_token_key);
 | 
        
           |  |  | 387 |         }
 | 
        
           |  |  | 388 |   | 
        
           |  |  | 389 |         if (in_array($response->status, array(Auth_OpenID_SUCCESS,
 | 
        
           |  |  | 390 |                                               Auth_OpenID_CANCEL))) {
 | 
        
           |  |  | 391 |             if ($response->identity_url !== null) {
 | 
        
           |  |  | 392 |                 $disco = new Services_Yadis_Discovery($this->session,
 | 
        
           |  |  | 393 |                                                   $response->identity_url,
 | 
        
           |  |  | 394 |                                                   $this->session_key_prefix);
 | 
        
           |  |  | 395 |                 $disco->cleanup();
 | 
        
           |  |  | 396 |             }
 | 
        
           |  |  | 397 |         }
 | 
        
           |  |  | 398 |   | 
        
           |  |  | 399 |         return $response;
 | 
        
           |  |  | 400 |     }
 | 
        
           |  |  | 401 | }
 | 
        
           |  |  | 402 |   | 
        
           |  |  | 403 | class Auth_OpenID_DiffieHellmanConsumerSession {
 | 
        
           |  |  | 404 |     var $session_type = 'DH-SHA1';
 | 
        
           |  |  | 405 |   | 
        
           |  |  | 406 |     function Auth_OpenID_DiffieHellmanConsumerSession($dh = null)
 | 
        
           |  |  | 407 |     {
 | 
        
           |  |  | 408 |         if ($dh === null) {
 | 
        
           |  |  | 409 |             $dh = new Auth_OpenID_DiffieHellman();
 | 
        
           |  |  | 410 |         }
 | 
        
           |  |  | 411 |   | 
        
           |  |  | 412 |         $this->dh = $dh;
 | 
        
           |  |  | 413 |     }
 | 
        
           |  |  | 414 |   | 
        
           |  |  | 415 |     function getRequest()
 | 
        
           |  |  | 416 |     {
 | 
        
           |  |  | 417 |         $math =& Auth_OpenID_getMathLib();
 | 
        
           |  |  | 418 |   | 
        
           |  |  | 419 |         $cpub = $math->longToBase64($this->dh->public);
 | 
        
           |  |  | 420 |   | 
        
           |  |  | 421 |         $args = array('openid.dh_consumer_public' => $cpub);
 | 
        
           |  |  | 422 |   | 
        
           |  |  | 423 |         if (!$this->dh->usingDefaultValues()) {
 | 
        
           |  |  | 424 |             $args = array_merge($args, array(
 | 
        
           |  |  | 425 |                 'openid.dh_modulus' =>
 | 
        
           |  |  | 426 |                      $math->longToBase64($this->dh->mod),
 | 
        
           |  |  | 427 |                 'openid.dh_gen' =>
 | 
        
           |  |  | 428 |                 $math->longToBase64($this->dh->gen)));
 | 
        
           |  |  | 429 |         }
 | 
        
           |  |  | 430 |   | 
        
           |  |  | 431 |         return $args;
 | 
        
           |  |  | 432 |     }
 | 
        
           |  |  | 433 |   | 
        
           |  |  | 434 |     function extractSecret($response)
 | 
        
           |  |  | 435 |     {
 | 
        
           |  |  | 436 |         if (!array_key_exists('dh_server_public', $response)) {
 | 
        
           |  |  | 437 |             return null;
 | 
        
           |  |  | 438 |         }
 | 
        
           |  |  | 439 |   | 
        
           |  |  | 440 |         if (!array_key_exists('enc_mac_key', $response)) {
 | 
        
           |  |  | 441 |             return null;
 | 
        
           |  |  | 442 |         }
 | 
        
           |  |  | 443 |   | 
        
           |  |  | 444 |         $math =& Auth_OpenID_getMathLib();
 | 
        
           |  |  | 445 |         $spub = $math->base64ToLong($response['dh_server_public']);
 | 
        
           |  |  | 446 |         $enc_mac_key = base64_decode($response['enc_mac_key']);
 | 
        
           |  |  | 447 |   | 
        
           |  |  | 448 |         return $this->dh->xorSecret($spub, $enc_mac_key);
 | 
        
           |  |  | 449 |     }
 | 
        
           |  |  | 450 | }
 | 
        
           |  |  | 451 |   | 
        
           |  |  | 452 | class Auth_OpenID_PlainTextConsumerSession {
 | 
        
           |  |  | 453 |     var $session_type = null;
 | 
        
           |  |  | 454 |   | 
        
           |  |  | 455 |     function getRequest()
 | 
        
           |  |  | 456 |     {
 | 
        
           |  |  | 457 |         return array();
 | 
        
           |  |  | 458 |     }
 | 
        
           |  |  | 459 |   | 
        
           |  |  | 460 |     function extractSecret($response)
 | 
        
           |  |  | 461 |     {
 | 
        
           |  |  | 462 |         if (!array_key_exists('mac_key', $response)) {
 | 
        
           |  |  | 463 |             return null;
 | 
        
           |  |  | 464 |         }
 | 
        
           |  |  | 465 |   | 
        
           |  |  | 466 |         return base64_decode($response['mac_key']);
 | 
        
           |  |  | 467 |     }
 | 
        
           |  |  | 468 | }
 | 
        
           |  |  | 469 |   | 
        
           |  |  | 470 | /**
 | 
        
           |  |  | 471 |  * This class is the interface to the OpenID consumer logic.
 | 
        
           |  |  | 472 |  * Instances of it maintain no per-request state, so they can be
 | 
        
           |  |  | 473 |  * reused (or even used by multiple threads concurrently) as needed.
 | 
        
           |  |  | 474 |  *
 | 
        
           |  |  | 475 |  * @package OpenID
 | 
        
           |  |  | 476 |  * @access private
 | 
        
           |  |  | 477 |  */
 | 
        
           |  |  | 478 | class Auth_OpenID_GenericConsumer {
 | 
        
           |  |  | 479 |     /**
 | 
        
           |  |  | 480 |      * This consumer's store object.
 | 
        
           |  |  | 481 |      */
 | 
        
           |  |  | 482 |     var $store;
 | 
        
           |  |  | 483 |   | 
        
           |  |  | 484 |     /**
 | 
        
           |  |  | 485 |      * @access private
 | 
        
           |  |  | 486 |      */
 | 
        
           |  |  | 487 |     var $_use_assocs;
 | 
        
           |  |  | 488 |   | 
        
           |  |  | 489 |     /**
 | 
        
           |  |  | 490 |      * This is the number of characters in the generated nonce for
 | 
        
           |  |  | 491 |      * each transaction.
 | 
        
           |  |  | 492 |      */
 | 
        
           |  |  | 493 |     var $nonce_len = 8;
 | 
        
           |  |  | 494 |   | 
        
           |  |  | 495 |     /**
 | 
        
           |  |  | 496 |      * What characters are allowed in nonces
 | 
        
           |  |  | 497 |      */
 | 
        
           |  |  | 498 |     var $nonce_chrs = Auth_OpenID_DEFAULT_NONCE_CHRS;
 | 
        
           |  |  | 499 |   | 
        
           |  |  | 500 |     /**
 | 
        
           |  |  | 501 |      * This method initializes a new {@link Auth_OpenID_Consumer}
 | 
        
           |  |  | 502 |      * instance to access the library.
 | 
        
           |  |  | 503 |      *
 | 
        
           |  |  | 504 |      * @param Auth_OpenID_OpenIDStore $store This must be an object
 | 
        
           |  |  | 505 |      * that implements the interface in {@link Auth_OpenID_OpenIDStore}.
 | 
        
           |  |  | 506 |      * Several concrete implementations are provided, to cover most common use
 | 
        
           |  |  | 507 |      * cases.  For stores backed by MySQL, PostgreSQL, or SQLite, see
 | 
        
           |  |  | 508 |      * the {@link Auth_OpenID_SQLStore} class and its sublcasses.  For a
 | 
        
           |  |  | 509 |      * filesystem-backed store, see the {@link Auth_OpenID_FileStore} module.
 | 
        
           |  |  | 510 |      * As a last resort, if it isn't possible for the server to store
 | 
        
           |  |  | 511 |      * state at all, an instance of {@link Auth_OpenID_DumbStore} can be used.
 | 
        
           |  |  | 512 |      *
 | 
        
           |  |  | 513 |      * @param bool $immediate This is an optional boolean value.  It
 | 
        
           |  |  | 514 |      * controls whether the library uses immediate mode, as explained
 | 
        
           |  |  | 515 |      * in the module description.  The default value is False, which
 | 
        
           |  |  | 516 |      * disables immediate mode.
 | 
        
           |  |  | 517 |      */
 | 
        
           |  |  | 518 |     function Auth_OpenID_GenericConsumer(&$store)
 | 
        
           |  |  | 519 |     {
 | 
        
           |  |  | 520 |         $this->store =& $store;
 | 
        
           |  |  | 521 |         $this->_use_assocs =
 | 
        
           |  |  | 522 |             !(defined('Auth_OpenID_NO_MATH_SUPPORT') ||
 | 
        
           |  |  | 523 |               ($this->store && $this->store->isDumb()));
 | 
        
           |  |  | 524 |   | 
        
           |  |  | 525 |         $this->fetcher = Services_Yadis_Yadis::getHTTPFetcher();
 | 
        
           |  |  | 526 |     }
 | 
        
           |  |  | 527 |   | 
        
           |  |  | 528 |     function begin($service_endpoint)
 | 
        
           |  |  | 529 |     {
 | 
        
           |  |  | 530 |         $nonce = $this->_createNonce();
 | 
        
           |  |  | 531 |         $assoc = $this->_getAssociation($service_endpoint->server_url);
 | 
        
           |  |  | 532 |         $r = new Auth_OpenID_AuthRequest($assoc, $service_endpoint);
 | 
        
           |  |  | 533 |         $r->return_to_args['nonce'] = $nonce;
 | 
        
           |  |  | 534 |         return $r;
 | 
        
           |  |  | 535 |     }
 | 
        
           |  |  | 536 |   | 
        
           |  |  | 537 |     function complete($query, $endpoint)
 | 
        
           |  |  | 538 |     {
 | 
        
           |  |  | 539 |         $mode = Auth_OpenID::arrayGet($query, 'openid.mode',
 | 
        
           |  |  | 540 |                                       '<no mode specified>');
 | 
        
           |  |  | 541 |   | 
        
           |  |  | 542 |         if ($mode == Auth_OpenID_CANCEL) {
 | 
        
           |  |  | 543 |             return new Auth_OpenID_CancelResponse($endpoint);
 | 
        
           |  |  | 544 |         } else if ($mode == 'error') {
 | 
        
           |  |  | 545 |             $error = Auth_OpenID::arrayGet($query, 'openid.error');
 | 
        
           |  |  | 546 |             return new Auth_OpenID_FailureResponse($endpoint, $error);
 | 
        
           |  |  | 547 |         } else if ($mode == 'id_res') {
 | 
        
           |  |  | 548 |             if ($endpoint->identity_url === null) {
 | 
        
           |  |  | 549 |                 return new Auth_OpenID_FailureResponse($identity_url,
 | 
        
           |  |  | 550 |                                                "No session state found");
 | 
        
           |  |  | 551 |             }
 | 
        
           |  |  | 552 |   | 
        
           |  |  | 553 |             $response = $this->_doIdRes($query, $endpoint);
 | 
        
           |  |  | 554 |   | 
        
           |  |  | 555 |             if ($response === null) {
 | 
        
           |  |  | 556 |                 return new Auth_OpenID_FailureResponse($endpoint,
 | 
        
           |  |  | 557 |                                                        "HTTP request failed");
 | 
        
           |  |  | 558 |             }
 | 
        
           |  |  | 559 |             if ($response->status == Auth_OpenID_SUCCESS) {
 | 
        
           |  |  | 560 |                 return $this->_checkNonce($response,
 | 
        
           |  |  | 561 |                                           Auth_OpenID::arrayGet($query,
 | 
        
           |  |  | 562 |                                                                 'nonce'));
 | 
        
           |  |  | 563 |             } else {
 | 
        
           |  |  | 564 |                 return $response;
 | 
        
           |  |  | 565 |             }
 | 
        
           |  |  | 566 |         } else {
 | 
        
           |  |  | 567 |             return new Auth_OpenID_FailureResponse($endpoint,
 | 
        
           |  |  | 568 |                                            sprintf("Invalid openid.mode '%s'",
 | 
        
           |  |  | 569 |                                                    $mode));
 | 
        
           |  |  | 570 |         }
 | 
        
           |  |  | 571 |     }
 | 
        
           |  |  | 572 |   | 
        
           |  |  | 573 |     /**
 | 
        
           |  |  | 574 |      * @access private
 | 
        
           |  |  | 575 |      */
 | 
        
           |  |  | 576 |     function _doIdRes($query, $endpoint)
 | 
        
           |  |  | 577 |     {
 | 
        
           |  |  | 578 |         $user_setup_url = Auth_OpenID::arrayGet($query,
 | 
        
           |  |  | 579 |                                                 'openid.user_setup_url');
 | 
        
           |  |  | 580 |   | 
        
           |  |  | 581 |         if ($user_setup_url !== null) {
 | 
        
           |  |  | 582 |             return new Auth_OpenID_SetupNeededResponse($endpoint,
 | 
        
           |  |  | 583 |                                                        $user_setup_url);
 | 
        
           |  |  | 584 |         }
 | 
        
           |  |  | 585 |   | 
        
           |  |  | 586 |         $return_to = Auth_OpenID::arrayGet($query, 'openid.return_to', null);
 | 
        
           |  |  | 587 |         $server_id2 = Auth_OpenID::arrayGet($query, 'openid.identity', null);
 | 
        
           |  |  | 588 |         $assoc_handle = Auth_OpenID::arrayGet($query,
 | 
        
           |  |  | 589 |                                              'openid.assoc_handle', null);
 | 
        
           |  |  | 590 |   | 
        
           |  |  | 591 |         if (($return_to === null) ||
 | 
        
           |  |  | 592 |             ($server_id2 === null) ||
 | 
        
           |  |  | 593 |             ($assoc_handle === null)) {
 | 
        
           |  |  | 594 |             return new Auth_OpenID_FailureResponse($endpoint,
 | 
        
           |  |  | 595 |                                                    "Missing required field");
 | 
        
           |  |  | 596 |         }
 | 
        
           |  |  | 597 |   | 
        
           |  |  | 598 |         if ($endpoint->getServerID() != $server_id2) {
 | 
        
           |  |  | 599 |             return new Auth_OpenID_FailureResponse($endpoint,
 | 
        
           |  |  | 600 |                                              "Server ID (delegate) mismatch");
 | 
        
           |  |  | 601 |         }
 | 
        
           |  |  | 602 |   | 
        
           |  |  | 603 |         $signed = Auth_OpenID::arrayGet($query, 'openid.signed');
 | 
        
           |  |  | 604 |   | 
        
           |  |  | 605 |         $assoc = $this->store->getAssociation($endpoint->server_url,
 | 
        
           |  |  | 606 |                                               $assoc_handle);
 | 
        
           |  |  | 607 |   | 
        
           |  |  | 608 |         if ($assoc === null) {
 | 
        
           |  |  | 609 |             // It's not an association we know about.  Dumb mode is
 | 
        
           |  |  | 610 |             // our only possible path for recovery.
 | 
        
           |  |  | 611 |             if ($this->_checkAuth($query, $endpoint->server_url)) {
 | 
        
           |  |  | 612 |                 return new Auth_OpenID_SuccessResponse($endpoint, $query,
 | 
        
           |  |  | 613 |                                                        $signed);
 | 
        
           |  |  | 614 |             } else {
 | 
        
           |  |  | 615 |                 return new Auth_OpenID_FailureResponse($endpoint,
 | 
        
           |  |  | 616 |                                        "Server denied check_authentication");
 | 
        
           |  |  | 617 |             }
 | 
        
           |  |  | 618 |         }
 | 
        
           |  |  | 619 |   | 
        
           |  |  | 620 |         if ($assoc->getExpiresIn() <= 0) {
 | 
        
           |  |  | 621 |             $msg = sprintf("Association with %s expired",
 | 
        
           |  |  | 622 |                            $endpoint->server_url);
 | 
        
           |  |  | 623 |             return new Auth_OpenID_FailureResponse($endpoint, $msg);
 | 
        
           |  |  | 624 |         }
 | 
        
           |  |  | 625 |   | 
        
           |  |  | 626 |         // Check the signature
 | 
        
           |  |  | 627 |         $sig = Auth_OpenID::arrayGet($query, 'openid.sig', null);
 | 
        
           |  |  | 628 |         if (($sig === null) ||
 | 
        
           |  |  | 629 |             ($signed === null)) {
 | 
        
           |  |  | 630 |             return new Auth_OpenID_FailureResponse($endpoint,
 | 
        
           |  |  | 631 |                                                "Missing argument signature");
 | 
        
           |  |  | 632 |         }
 | 
        
           |  |  | 633 |   | 
        
           |  |  | 634 |         $signed_list = explode(",", $signed);
 | 
        
           |  |  | 635 |   | 
        
           |  |  | 636 |         //Fail if the identity field is present but not signed
 | 
        
           |  |  | 637 |         if (($endpoint->identity_url !== null) &&
 | 
        
           |  |  | 638 |             (!in_array('identity', $signed_list))) {
 | 
        
           |  |  | 639 |             $msg = '"openid.identity" not signed';
 | 
        
           |  |  | 640 |             return new Auth_OpenID_FailureResponse($endpoint, $msg);
 | 
        
           |  |  | 641 |         }
 | 
        
           |  |  | 642 |   | 
        
           |  |  | 643 |         $v_sig = $assoc->signDict($signed_list, $query);
 | 
        
           |  |  | 644 |   | 
        
           |  |  | 645 |         if ($v_sig != $sig) {
 | 
        
           |  |  | 646 |             return new Auth_OpenID_FailureResponse($endpoint,
 | 
        
           |  |  | 647 |                                                    "Bad signature");
 | 
        
           |  |  | 648 |         }
 | 
        
           |  |  | 649 |   | 
        
           |  |  | 650 |         return Auth_OpenID_SuccessResponse::fromQuery($endpoint,
 | 
        
           |  |  | 651 |                                                       $query, $signed);
 | 
        
           |  |  | 652 |     }
 | 
        
           |  |  | 653 |   | 
        
           |  |  | 654 |     /**
 | 
        
           |  |  | 655 |      * @access private
 | 
        
           |  |  | 656 |      */
 | 
        
           |  |  | 657 |     function _checkAuth($query, $server_url)
 | 
        
           |  |  | 658 |     {
 | 
        
           |  |  | 659 |         $request = $this->_createCheckAuthRequest($query);
 | 
        
           |  |  | 660 |         if ($request === null) {
 | 
        
           |  |  | 661 |             return false;
 | 
        
           |  |  | 662 |         }
 | 
        
           |  |  | 663 |   | 
        
           |  |  | 664 |         $response = $this->_makeKVPost($request, $server_url);
 | 
        
           |  |  | 665 |         if ($response == null) {
 | 
        
           |  |  | 666 |             return false;
 | 
        
           |  |  | 667 |         }
 | 
        
           |  |  | 668 |   | 
        
           |  |  | 669 |         return $this->_processCheckAuthResponse($response, $server_url);
 | 
        
           |  |  | 670 |     }
 | 
        
           |  |  | 671 |   | 
        
           |  |  | 672 |     /**
 | 
        
           |  |  | 673 |      * @access private
 | 
        
           |  |  | 674 |      */
 | 
        
           |  |  | 675 |     function _createCheckAuthRequest($query)
 | 
        
           |  |  | 676 |     {
 | 
        
           |  |  | 677 |         $signed = Auth_OpenID::arrayGet($query, 'openid.signed', null);
 | 
        
           |  |  | 678 |         if ($signed === null) {
 | 
        
           |  |  | 679 |             return null;
 | 
        
           |  |  | 680 |         }
 | 
        
           |  |  | 681 |   | 
        
           |  |  | 682 |         $whitelist = array('assoc_handle', 'sig',
 | 
        
           |  |  | 683 |                            'signed', 'invalidate_handle');
 | 
        
           |  |  | 684 |   | 
        
           |  |  | 685 |         $signed = array_merge(explode(",", $signed), $whitelist);
 | 
        
           |  |  | 686 |   | 
        
           |  |  | 687 |         $check_args = array();
 | 
        
           |  |  | 688 |   | 
        
           |  |  | 689 |         foreach ($query as $key => $value) {
 | 
        
           |  |  | 690 |             if (in_array(substr($key, 7), $signed)) {
 | 
        
           |  |  | 691 |                 $check_args[$key] = $value;
 | 
        
           |  |  | 692 |             }
 | 
        
           |  |  | 693 |         }
 | 
        
           |  |  | 694 |   | 
        
           |  |  | 695 |         $check_args['openid.mode'] = 'check_authentication';
 | 
        
           |  |  | 696 |         return $check_args;
 | 
        
           |  |  | 697 |     }
 | 
        
           |  |  | 698 |   | 
        
           |  |  | 699 |     /**
 | 
        
           |  |  | 700 |      * @access private
 | 
        
           |  |  | 701 |      */
 | 
        
           |  |  | 702 |     function _processCheckAuthResponse($response, $server_url)
 | 
        
           |  |  | 703 |     {
 | 
        
           |  |  | 704 |         $is_valid = Auth_OpenID::arrayGet($response, 'is_valid', 'false');
 | 
        
           |  |  | 705 |   | 
        
           |  |  | 706 |         $invalidate_handle = Auth_OpenID::arrayGet($response,
 | 
        
           |  |  | 707 |                                                    'invalidate_handle');
 | 
        
           |  |  | 708 |   | 
        
           |  |  | 709 |         if ($invalidate_handle !== null) {
 | 
        
           |  |  | 710 |             $this->store->removeAssociation($server_url,
 | 
        
           |  |  | 711 |                                             $invalidate_handle);
 | 
        
           |  |  | 712 |         }
 | 
        
           |  |  | 713 |   | 
        
           |  |  | 714 |         if ($is_valid == 'true') {
 | 
        
           |  |  | 715 |             return true;
 | 
        
           |  |  | 716 |         }
 | 
        
           |  |  | 717 |   | 
        
           |  |  | 718 |         return false;
 | 
        
           |  |  | 719 |     }
 | 
        
           |  |  | 720 |   | 
        
           |  |  | 721 |     /**
 | 
        
           |  |  | 722 |      * @access private
 | 
        
           |  |  | 723 |      */
 | 
        
           |  |  | 724 |     function _makeKVPost($args, $server_url)
 | 
        
           |  |  | 725 |     {
 | 
        
           |  |  | 726 |         $mode = $args['openid.mode'];
 | 
        
           |  |  | 727 |   | 
        
           |  |  | 728 |         $pairs = array();
 | 
        
           |  |  | 729 |         foreach ($args as $k => $v) {
 | 
        
           |  |  | 730 |             $v = urlencode($v);
 | 
        
           |  |  | 731 |             $pairs[] = "$k=$v";
 | 
        
           |  |  | 732 |         }
 | 
        
           |  |  | 733 |   | 
        
           |  |  | 734 |         $body = implode("&", $pairs);
 | 
        
           |  |  | 735 |   | 
        
           |  |  | 736 |         $resp = $this->fetcher->post($server_url, $body);
 | 
        
           |  |  | 737 |   | 
        
           |  |  | 738 |         if ($resp === null) {
 | 
        
           |  |  | 739 |             return null;
 | 
        
           |  |  | 740 |         }
 | 
        
           |  |  | 741 |   | 
        
           |  |  | 742 |         $response = Auth_OpenID_KVForm::toArray($resp->body);
 | 
        
           |  |  | 743 |   | 
        
           |  |  | 744 |         if ($resp->status == 400) {
 | 
        
           |  |  | 745 |             return null;
 | 
        
           |  |  | 746 |         } else if ($resp->status != 200) {
 | 
        
           |  |  | 747 |             return null;
 | 
        
           |  |  | 748 |         }
 | 
        
           |  |  | 749 |   | 
        
           |  |  | 750 |         return $response;
 | 
        
           |  |  | 751 |     }
 | 
        
           |  |  | 752 |   | 
        
           |  |  | 753 |     /**
 | 
        
           |  |  | 754 |      * @access private
 | 
        
           |  |  | 755 |      */
 | 
        
           |  |  | 756 |     function _checkNonce($response, $nonce)
 | 
        
           |  |  | 757 |     {
 | 
        
           |  |  | 758 |         $parsed_url = parse_url($response->getReturnTo());
 | 
        
           |  |  | 759 |         $query_str = @$parsed_url['query'];
 | 
        
           |  |  | 760 |         $query = array();
 | 
        
           |  |  | 761 |         parse_str($query_str, $query);
 | 
        
           |  |  | 762 |   | 
        
           |  |  | 763 |         $found = false;
 | 
        
           |  |  | 764 |   | 
        
           |  |  | 765 |         foreach ($query as $k => $v) {
 | 
        
           |  |  | 766 |             if ($k == 'nonce') {
 | 
        
           |  |  | 767 |                 if ($v != $nonce) {
 | 
        
           |  |  | 768 |                     return new Auth_OpenID_FailureResponse($response,
 | 
        
           |  |  | 769 |                                                            "Nonce mismatch");
 | 
        
           |  |  | 770 |                 } else {
 | 
        
           |  |  | 771 |                     $found = true;
 | 
        
           |  |  | 772 |                     break;
 | 
        
           |  |  | 773 |                 }
 | 
        
           |  |  | 774 |             }
 | 
        
           |  |  | 775 |         }
 | 
        
           |  |  | 776 |   | 
        
           |  |  | 777 |         if (!$found) {
 | 
        
           |  |  | 778 |             return new Auth_OpenID_FailureResponse($response,
 | 
        
           |  |  | 779 |                                  sprintf("Nonce missing from return_to: %s",
 | 
        
           |  |  | 780 |                                          $response->getReturnTo()));
 | 
        
           |  |  | 781 |         }
 | 
        
           |  |  | 782 |   | 
        
           |  |  | 783 |         if (!$this->store->useNonce($nonce)) {
 | 
        
           |  |  | 784 |             return new Auth_OpenID_FailureResponse($response,
 | 
        
           |  |  | 785 |                                                    "Nonce missing from store");
 | 
        
           |  |  | 786 |         }
 | 
        
           |  |  | 787 |   | 
        
           |  |  | 788 |         return $response;
 | 
        
           |  |  | 789 |     }
 | 
        
           |  |  | 790 |   | 
        
           |  |  | 791 |     /**
 | 
        
           |  |  | 792 |      * @access private
 | 
        
           |  |  | 793 |      */
 | 
        
           |  |  | 794 |     function _createNonce()
 | 
        
           |  |  | 795 |     {
 | 
        
           |  |  | 796 |         $nonce = Auth_OpenID_CryptUtil::randomString($this->nonce_len,
 | 
        
           |  |  | 797 |                                                      $this->nonce_chrs);
 | 
        
           |  |  | 798 |         $this->store->storeNonce($nonce);
 | 
        
           |  |  | 799 |         return $nonce;
 | 
        
           |  |  | 800 |     }
 | 
        
           |  |  | 801 |   | 
        
           |  |  | 802 |     /**
 | 
        
           |  |  | 803 |      * @access protected
 | 
        
           |  |  | 804 |      */
 | 
        
           |  |  | 805 |     function _createDiffieHellman()
 | 
        
           |  |  | 806 |     {
 | 
        
           |  |  | 807 |         return new Auth_OpenID_DiffieHellman();
 | 
        
           |  |  | 808 |     }
 | 
        
           |  |  | 809 |   | 
        
           |  |  | 810 |     /**
 | 
        
           |  |  | 811 |      * @access private
 | 
        
           |  |  | 812 |      */
 | 
        
           |  |  | 813 |     function _getAssociation($server_url)
 | 
        
           |  |  | 814 |     {
 | 
        
           |  |  | 815 |         if (!$this->_use_assocs) {
 | 
        
           |  |  | 816 |             return null;
 | 
        
           |  |  | 817 |         }
 | 
        
           |  |  | 818 |   | 
        
           |  |  | 819 |         $assoc = $this->store->getAssociation($server_url);
 | 
        
           |  |  | 820 |   | 
        
           |  |  | 821 |         if (($assoc === null) ||
 | 
        
           |  |  | 822 |             ($assoc->getExpiresIn() <= 0)) {
 | 
        
           |  |  | 823 |   | 
        
           |  |  | 824 |             $parts = $this->_createAssociateRequest($server_url);
 | 
        
           |  |  | 825 |   | 
        
           |  |  | 826 |             if ($parts === null) {
 | 
        
           |  |  | 827 |                 return null;
 | 
        
           |  |  | 828 |             }
 | 
        
           |  |  | 829 |   | 
        
           |  |  | 830 |             list($assoc_session, $args) = $parts;
 | 
        
           |  |  | 831 |   | 
        
           |  |  | 832 |             $response = $this->_makeKVPost($args, $server_url);
 | 
        
           |  |  | 833 |   | 
        
           |  |  | 834 |             if ($response === null) {
 | 
        
           |  |  | 835 |                 $assoc = null;
 | 
        
           |  |  | 836 |             } else {
 | 
        
           |  |  | 837 |                 $assoc = $this->_parseAssociation($response, $assoc_session,
 | 
        
           |  |  | 838 |                                                   $server_url);
 | 
        
           |  |  | 839 |             }
 | 
        
           |  |  | 840 |         }
 | 
        
           |  |  | 841 |   | 
        
           |  |  | 842 |         return $assoc;
 | 
        
           |  |  | 843 |     }
 | 
        
           |  |  | 844 |   | 
        
           |  |  | 845 |     function _createAssociateRequest($server_url)
 | 
        
           |  |  | 846 |     {
 | 
        
           |  |  | 847 |         $parts = parse_url($server_url);
 | 
        
           |  |  | 848 |   | 
        
           |  |  | 849 |         if ($parts === false) {
 | 
        
           |  |  | 850 |             return null;
 | 
        
           |  |  | 851 |         }
 | 
        
           |  |  | 852 |   | 
        
           |  |  | 853 |         if (array_key_exists('scheme', $parts)) {
 | 
        
           |  |  | 854 |             $proto = $parts['scheme'];
 | 
        
           |  |  | 855 |         } else {
 | 
        
           |  |  | 856 |             $proto = 'http';
 | 
        
           |  |  | 857 |         }
 | 
        
           |  |  | 858 |   | 
        
           |  |  | 859 |         if ($proto == 'https') {
 | 
        
           |  |  | 860 |             $assoc_session = new Auth_OpenID_PlainTextConsumerSession();
 | 
        
           |  |  | 861 |         } else {
 | 
        
           |  |  | 862 |             $assoc_session = new Auth_OpenID_DiffieHellmanConsumerSession();
 | 
        
           |  |  | 863 |         }
 | 
        
           |  |  | 864 |   | 
        
           |  |  | 865 |         $args = array(
 | 
        
           |  |  | 866 |             'openid.mode' => 'associate',
 | 
        
           |  |  | 867 |             'openid.assoc_type' => 'HMAC-SHA1');
 | 
        
           |  |  | 868 |   | 
        
           |  |  | 869 |         if ($assoc_session->session_type !== null) {
 | 
        
           |  |  | 870 |             $args['openid.session_type'] = $assoc_session->session_type;
 | 
        
           |  |  | 871 |         }
 | 
        
           |  |  | 872 |   | 
        
           |  |  | 873 |         $args = array_merge($args, $assoc_session->getRequest());
 | 
        
           |  |  | 874 |         return array($assoc_session, $args);
 | 
        
           |  |  | 875 |     }
 | 
        
           |  |  | 876 |   | 
        
           |  |  | 877 |     /**
 | 
        
           |  |  | 878 |      * @access private
 | 
        
           |  |  | 879 |      */
 | 
        
           |  |  | 880 |     function _parseAssociation($results, $assoc_session, $server_url)
 | 
        
           |  |  | 881 |     {
 | 
        
           |  |  | 882 |         $required_keys = array('assoc_type', 'assoc_handle',
 | 
        
           |  |  | 883 |                                'expires_in');
 | 
        
           |  |  | 884 |   | 
        
           |  |  | 885 |         foreach ($required_keys as $key) {
 | 
        
           |  |  | 886 |             if (!array_key_exists($key, $results)) {
 | 
        
           |  |  | 887 |                 return null;
 | 
        
           |  |  | 888 |             }
 | 
        
           |  |  | 889 |         }
 | 
        
           |  |  | 890 |   | 
        
           |  |  | 891 |         $assoc_type = $results['assoc_type'];
 | 
        
           |  |  | 892 |         $assoc_handle = $results['assoc_handle'];
 | 
        
           |  |  | 893 |         $expires_in_str = $results['expires_in'];
 | 
        
           |  |  | 894 |   | 
        
           |  |  | 895 |         if ($assoc_type != 'HMAC-SHA1') {
 | 
        
           |  |  | 896 |             return null;
 | 
        
           |  |  | 897 |         }
 | 
        
           |  |  | 898 |   | 
        
           |  |  | 899 |         $expires_in = intval($expires_in_str);
 | 
        
           |  |  | 900 |   | 
        
           |  |  | 901 |         if ($expires_in <= 0) {
 | 
        
           |  |  | 902 |             return null;
 | 
        
           |  |  | 903 |         }
 | 
        
           |  |  | 904 |   | 
        
           |  |  | 905 |         $session_type = Auth_OpenID::arrayGet($results, 'session_type');
 | 
        
           |  |  | 906 |         if ($session_type != $assoc_session->session_type) {
 | 
        
           |  |  | 907 |             if ($session_type === null) {
 | 
        
           |  |  | 908 |                 $assoc_session = new Auth_OpenID_PlainTextConsumerSession();
 | 
        
           |  |  | 909 |             } else {
 | 
        
           |  |  | 910 |                 return null;
 | 
        
           |  |  | 911 |             }
 | 
        
           |  |  | 912 |         }
 | 
        
           |  |  | 913 |   | 
        
           |  |  | 914 |         $secret = $assoc_session->extractSecret($results);
 | 
        
           |  |  | 915 |   | 
        
           |  |  | 916 |         if (!$secret) {
 | 
        
           |  |  | 917 |             return null;
 | 
        
           |  |  | 918 |         }
 | 
        
           |  |  | 919 |   | 
        
           |  |  | 920 |         $assoc = Auth_OpenID_Association::fromExpiresIn(
 | 
        
           |  |  | 921 |                          $expires_in, $assoc_handle, $secret, $assoc_type);
 | 
        
           |  |  | 922 |         $this->store->storeAssociation($server_url, $assoc);
 | 
        
           |  |  | 923 |   | 
        
           |  |  | 924 |         return $assoc;
 | 
        
           |  |  | 925 |     }
 | 
        
           |  |  | 926 | }
 | 
        
           |  |  | 927 |   | 
        
           |  |  | 928 | /**
 | 
        
           |  |  | 929 |  * This class represents an authentication request from a consumer to
 | 
        
           |  |  | 930 |  * an OpenID server.
 | 
        
           |  |  | 931 |  *
 | 
        
           |  |  | 932 |  * @package OpenID
 | 
        
           |  |  | 933 |  */
 | 
        
           |  |  | 934 | class Auth_OpenID_AuthRequest {
 | 
        
           |  |  | 935 |   | 
        
           |  |  | 936 |     /**
 | 
        
           |  |  | 937 |      * Initialize an authentication request with the specified token,
 | 
        
           |  |  | 938 |      * association, and endpoint.
 | 
        
           |  |  | 939 |      *
 | 
        
           |  |  | 940 |      * Users of this library should not create instances of this
 | 
        
           |  |  | 941 |      * class.  Instances of this class are created by the library when
 | 
        
           |  |  | 942 |      * needed.
 | 
        
           |  |  | 943 |      */
 | 
        
           |  |  | 944 |     function Auth_OpenID_AuthRequest($assoc, $endpoint)
 | 
        
           |  |  | 945 |     {
 | 
        
           |  |  | 946 |         $this->assoc = $assoc;
 | 
        
           |  |  | 947 |         $this->endpoint = $endpoint;
 | 
        
           |  |  | 948 |         $this->extra_args = array();
 | 
        
           |  |  | 949 |         $this->return_to_args = array();
 | 
        
           |  |  | 950 |     }
 | 
        
           |  |  | 951 |   | 
        
           |  |  | 952 |     /**
 | 
        
           |  |  | 953 |      * Add an extension argument to this OpenID authentication
 | 
        
           |  |  | 954 |      * request.
 | 
        
           |  |  | 955 |      *
 | 
        
           |  |  | 956 |      * Use caution when adding arguments, because they will be
 | 
        
           |  |  | 957 |      * URL-escaped and appended to the redirect URL, which can easily
 | 
        
           |  |  | 958 |      * get quite long.
 | 
        
           |  |  | 959 |      *
 | 
        
           |  |  | 960 |      * @param string $namespace The namespace for the extension. For
 | 
        
           |  |  | 961 |      * example, the simple registration extension uses the namespace
 | 
        
           |  |  | 962 |      * 'sreg'.
 | 
        
           |  |  | 963 |      *
 | 
        
           |  |  | 964 |      * @param string $key The key within the extension namespace. For
 | 
        
           |  |  | 965 |      * example, the nickname field in the simple registration
 | 
        
           |  |  | 966 |      * extension's key is 'nickname'.
 | 
        
           |  |  | 967 |      *
 | 
        
           |  |  | 968 |      * @param string $value The value to provide to the server for
 | 
        
           |  |  | 969 |      * this argument.
 | 
        
           |  |  | 970 |      */
 | 
        
           |  |  | 971 |     function addExtensionArg($namespace, $key, $value)
 | 
        
           |  |  | 972 |     {
 | 
        
           |  |  | 973 |         $arg_name = implode('.', array('openid', $namespace, $key));
 | 
        
           |  |  | 974 |         $this->extra_args[$arg_name] = $value;
 | 
        
           |  |  | 975 |     }
 | 
        
           |  |  | 976 |   | 
        
           |  |  | 977 |     /**
 | 
        
           |  |  | 978 |      * Compute the appropriate redirection URL for this request based
 | 
        
           |  |  | 979 |      * on a specified trust root and return-to.
 | 
        
           |  |  | 980 |      *
 | 
        
           |  |  | 981 |      * @param string $trust_root The trust root URI for your
 | 
        
           |  |  | 982 |      * application.
 | 
        
           |  |  | 983 |      *
 | 
        
           |  |  | 984 |      * @param string$ $return_to The return-to URL to be used when the
 | 
        
           |  |  | 985 |      * OpenID server redirects the user back to your site.
 | 
        
           |  |  | 986 |      *
 | 
        
           |  |  | 987 |      * @return string $redirect_url The resulting redirect URL that
 | 
        
           |  |  | 988 |      * you should send to the user agent.
 | 
        
           |  |  | 989 |      */
 | 
        
           |  |  | 990 |     function redirectURL($trust_root, $return_to, $immediate=false)
 | 
        
           |  |  | 991 |     {
 | 
        
           |  |  | 992 |         if ($immediate) {
 | 
        
           |  |  | 993 |             $mode = 'checkid_immediate';
 | 
        
           |  |  | 994 |         } else {
 | 
        
           |  |  | 995 |             $mode = 'checkid_setup';
 | 
        
           |  |  | 996 |         }
 | 
        
           |  |  | 997 |   | 
        
           |  |  | 998 |         $return_to = Auth_OpenID::appendArgs($return_to, $this->return_to_args);
 | 
        
           |  |  | 999 |   | 
        
           |  |  | 1000 |         $redir_args = array(
 | 
        
           |  |  | 1001 |             'openid.mode' => $mode,
 | 
        
           |  |  | 1002 |             'openid.identity' => $this->endpoint->getServerID(),
 | 
        
           |  |  | 1003 |             'openid.return_to' => $return_to,
 | 
        
           |  |  | 1004 |             'openid.trust_root' => $trust_root);
 | 
        
           |  |  | 1005 |   | 
        
           |  |  | 1006 |         if ($this->assoc) {
 | 
        
           |  |  | 1007 |             $redir_args['openid.assoc_handle'] = $this->assoc->handle;
 | 
        
           |  |  | 1008 |         }
 | 
        
           |  |  | 1009 |   | 
        
           |  |  | 1010 |         $redir_args = array_merge($redir_args, $this->extra_args);
 | 
        
           |  |  | 1011 |   | 
        
           |  |  | 1012 |         return Auth_OpenID::appendArgs($this->endpoint->server_url,
 | 
        
           |  |  | 1013 |                                        $redir_args);
 | 
        
           |  |  | 1014 |     }
 | 
        
           |  |  | 1015 | }
 | 
        
           |  |  | 1016 |   | 
        
           |  |  | 1017 | /**
 | 
        
           |  |  | 1018 |  * The base class for responses from the Auth_OpenID_Consumer.
 | 
        
           |  |  | 1019 |  *
 | 
        
           |  |  | 1020 |  * @package OpenID
 | 
        
           |  |  | 1021 |  */
 | 
        
           |  |  | 1022 | class Auth_OpenID_ConsumerResponse {
 | 
        
           |  |  | 1023 |     var $status = null;
 | 
        
           |  |  | 1024 | }
 | 
        
           |  |  | 1025 |   | 
        
           |  |  | 1026 | /**
 | 
        
           |  |  | 1027 |  * A response with a status of Auth_OpenID_SUCCESS. Indicates that
 | 
        
           |  |  | 1028 |  * this request is a successful acknowledgement from the OpenID server
 | 
        
           |  |  | 1029 |  * that the supplied URL is, indeed controlled by the requesting
 | 
        
           |  |  | 1030 |  * agent.  This has three relevant attributes:
 | 
        
           |  |  | 1031 |  *
 | 
        
           |  |  | 1032 |  * identity_url - The identity URL that has been authenticated
 | 
        
           |  |  | 1033 |  *
 | 
        
           |  |  | 1034 |  * signed_args - The arguments in the server's response that were
 | 
        
           |  |  | 1035 |  * signed and verified.
 | 
        
           |  |  | 1036 |  *
 | 
        
           |  |  | 1037 |  * status - Auth_OpenID_SUCCESS.
 | 
        
           |  |  | 1038 |  *
 | 
        
           |  |  | 1039 |  * @package OpenID
 | 
        
           |  |  | 1040 |  */
 | 
        
           |  |  | 1041 | class Auth_OpenID_SuccessResponse extends Auth_OpenID_ConsumerResponse {
 | 
        
           |  |  | 1042 |     var $status = Auth_OpenID_SUCCESS;
 | 
        
           |  |  | 1043 |   | 
        
           |  |  | 1044 |     /**
 | 
        
           |  |  | 1045 |      * @access private
 | 
        
           |  |  | 1046 |      */
 | 
        
           |  |  | 1047 |     function Auth_OpenID_SuccessResponse($endpoint, $signed_args)
 | 
        
           |  |  | 1048 |     {
 | 
        
           |  |  | 1049 |         $this->endpoint = $endpoint;
 | 
        
           |  |  | 1050 |         $this->identity_url = $endpoint->identity_url;
 | 
        
           |  |  | 1051 |         $this->signed_args = $signed_args;
 | 
        
           |  |  | 1052 |     }
 | 
        
           |  |  | 1053 |   | 
        
           |  |  | 1054 |     /**
 | 
        
           |  |  | 1055 |      * @access private
 | 
        
           |  |  | 1056 |      */
 | 
        
           |  |  | 1057 |     function fromQuery($endpoint, $query, $signed)
 | 
        
           |  |  | 1058 |     {
 | 
        
           |  |  | 1059 |         $signed_args = array();
 | 
        
           |  |  | 1060 |         foreach (explode(",", $signed) as $field_name) {
 | 
        
           |  |  | 1061 |             $field_name = 'openid.' . $field_name;
 | 
        
           |  |  | 1062 |             $signed_args[$field_name] = Auth_OpenID::arrayGet($query,
 | 
        
           |  |  | 1063 |                                                               $field_name, '');
 | 
        
           |  |  | 1064 |         }
 | 
        
           |  |  | 1065 |         return new Auth_OpenID_SuccessResponse($endpoint, $signed_args);
 | 
        
           |  |  | 1066 |     }
 | 
        
           |  |  | 1067 |   | 
        
           |  |  | 1068 |     /**
 | 
        
           |  |  | 1069 |      * Extract signed extension data from the server's response.
 | 
        
           |  |  | 1070 |      *
 | 
        
           |  |  | 1071 |      * @param string $prefix The extension namespace from which to
 | 
        
           |  |  | 1072 |      * extract the extension data.
 | 
        
           |  |  | 1073 |      */
 | 
        
           |  |  | 1074 |     function extensionResponse($prefix)
 | 
        
           |  |  | 1075 |     {
 | 
        
           |  |  | 1076 |         $response = array();
 | 
        
           |  |  | 1077 |         $prefix = sprintf('openid.%s.', $prefix);
 | 
        
           |  |  | 1078 |         $prefix_len = strlen($prefix);
 | 
        
           |  |  | 1079 |         foreach ($this->signed_args as $k => $v) {
 | 
        
           |  |  | 1080 |             if (strpos($k, $prefix) === 0) {
 | 
        
           |  |  | 1081 |                 $response_key = substr($k, $prefix_len);
 | 
        
           |  |  | 1082 |                 $response[$response_key] = $v;
 | 
        
           |  |  | 1083 |             }
 | 
        
           |  |  | 1084 |         }
 | 
        
           |  |  | 1085 |   | 
        
           |  |  | 1086 |         return $response;
 | 
        
           |  |  | 1087 |     }
 | 
        
           |  |  | 1088 |   | 
        
           |  |  | 1089 |     /**
 | 
        
           |  |  | 1090 |      * Get the openid.return_to argument from this response.
 | 
        
           |  |  | 1091 |      *
 | 
        
           |  |  | 1092 |      * This is useful for verifying that this request was initiated by
 | 
        
           |  |  | 1093 |      * this consumer.
 | 
        
           |  |  | 1094 |      *
 | 
        
           |  |  | 1095 |      * @return string $return_to The return_to URL supplied to the
 | 
        
           |  |  | 1096 |      * server on the initial request, or null if the response did not
 | 
        
           |  |  | 1097 |      * contain an 'openid.return_to' argument.
 | 
        
           |  |  | 1098 |     */
 | 
        
           |  |  | 1099 |     function getReturnTo()
 | 
        
           |  |  | 1100 |     {
 | 
        
           |  |  | 1101 |         return Auth_OpenID::arrayGet($this->signed_args, 'openid.return_to');
 | 
        
           |  |  | 1102 |     }
 | 
        
           |  |  | 1103 | }
 | 
        
           |  |  | 1104 |   | 
        
           |  |  | 1105 | /**
 | 
        
           |  |  | 1106 |  * A response with a status of Auth_OpenID_FAILURE. Indicates that the
 | 
        
           |  |  | 1107 |  * OpenID protocol has failed. This could be locally or remotely
 | 
        
           |  |  | 1108 |  * triggered.  This has three relevant attributes:
 | 
        
           |  |  | 1109 |  *
 | 
        
           |  |  | 1110 |  * identity_url - The identity URL for which authentication was
 | 
        
           |  |  | 1111 |  * attempted, if it can be determined.  Otherwise, null.
 | 
        
           |  |  | 1112 |  *
 | 
        
           |  |  | 1113 |  * message - A message indicating why the request failed, if one is
 | 
        
           |  |  | 1114 |  * supplied.  Otherwise, null.
 | 
        
           |  |  | 1115 |  *
 | 
        
           |  |  | 1116 |  * status - Auth_OpenID_FAILURE.
 | 
        
           |  |  | 1117 |  *
 | 
        
           |  |  | 1118 |  * @package OpenID
 | 
        
           |  |  | 1119 |  */
 | 
        
           |  |  | 1120 | class Auth_OpenID_FailureResponse extends Auth_OpenID_ConsumerResponse {
 | 
        
           |  |  | 1121 |     var $status = Auth_OpenID_FAILURE;
 | 
        
           |  |  | 1122 |   | 
        
           |  |  | 1123 |     function Auth_OpenID_FailureResponse($endpoint, $message = null)
 | 
        
           |  |  | 1124 |     {
 | 
        
           |  |  | 1125 |         $this->endpoint = $endpoint;
 | 
        
           |  |  | 1126 |         if ($endpoint !== null) {
 | 
        
           |  |  | 1127 |             $this->identity_url = $endpoint->identity_url;
 | 
        
           |  |  | 1128 |         } else {
 | 
        
           |  |  | 1129 |             $this->identity_url = null;
 | 
        
           |  |  | 1130 |         }
 | 
        
           |  |  | 1131 |         $this->message = $message;
 | 
        
           |  |  | 1132 |     }
 | 
        
           |  |  | 1133 | }
 | 
        
           |  |  | 1134 |   | 
        
           |  |  | 1135 | /**
 | 
        
           |  |  | 1136 |  * A response with a status of Auth_OpenID_CANCEL. Indicates that the
 | 
        
           |  |  | 1137 |  * user cancelled the OpenID authentication request.  This has two
 | 
        
           |  |  | 1138 |  * relevant attributes:
 | 
        
           |  |  | 1139 |  *
 | 
        
           |  |  | 1140 |  * identity_url - The identity URL for which authentication was
 | 
        
           |  |  | 1141 |  * attempted, if it can be determined.  Otherwise, null.
 | 
        
           |  |  | 1142 |  *
 | 
        
           |  |  | 1143 |  * status - Auth_OpenID_SUCCESS.
 | 
        
           |  |  | 1144 |  *
 | 
        
           |  |  | 1145 |  * @package OpenID
 | 
        
           |  |  | 1146 |  */
 | 
        
           |  |  | 1147 | class Auth_OpenID_CancelResponse extends Auth_OpenID_ConsumerResponse {
 | 
        
           |  |  | 1148 |     var $status = Auth_OpenID_CANCEL;
 | 
        
           |  |  | 1149 |   | 
        
           |  |  | 1150 |     function Auth_OpenID_CancelResponse($endpoint)
 | 
        
           |  |  | 1151 |     {
 | 
        
           |  |  | 1152 |         $this->endpoint = $endpoint;
 | 
        
           |  |  | 1153 |         $this->identity_url = $endpoint->identity_url;
 | 
        
           |  |  | 1154 |     }
 | 
        
           |  |  | 1155 | }
 | 
        
           |  |  | 1156 |   | 
        
           |  |  | 1157 | /**
 | 
        
           |  |  | 1158 |  * A response with a status of Auth_OpenID_SETUP_NEEDED. Indicates
 | 
        
           |  |  | 1159 |  * that the request was in immediate mode, and the server is unable to
 | 
        
           |  |  | 1160 |  * authenticate the user without further interaction.
 | 
        
           |  |  | 1161 |  *
 | 
        
           |  |  | 1162 |  * identity_url - The identity URL for which authentication was
 | 
        
           |  |  | 1163 |  * attempted.
 | 
        
           |  |  | 1164 |  *
 | 
        
           |  |  | 1165 |  * setup_url - A URL that can be used to send the user to the server
 | 
        
           |  |  | 1166 |  * to set up for authentication. The user should be redirected in to
 | 
        
           |  |  | 1167 |  * the setup_url, either in the current window or in a new browser
 | 
        
           |  |  | 1168 |  * window.
 | 
        
           |  |  | 1169 |  *
 | 
        
           |  |  | 1170 |  * status - Auth_OpenID_SETUP_NEEDED.
 | 
        
           |  |  | 1171 |  *
 | 
        
           |  |  | 1172 |  * @package OpenID
 | 
        
           |  |  | 1173 |  */
 | 
        
           |  |  | 1174 | class Auth_OpenID_SetupNeededResponse extends Auth_OpenID_ConsumerResponse {
 | 
        
           |  |  | 1175 |     var $status = Auth_OpenID_SETUP_NEEDED;
 | 
        
           |  |  | 1176 |   | 
        
           |  |  | 1177 |     function Auth_OpenID_SetupNeededResponse($endpoint,
 | 
        
           |  |  | 1178 |                                              $setup_url = null)
 | 
        
           |  |  | 1179 |     {
 | 
        
           |  |  | 1180 |         $this->endpoint = $endpoint;
 | 
        
           |  |  | 1181 |         $this->identity_url = $endpoint->identity_url;
 | 
        
           |  |  | 1182 |         $this->setup_url = $setup_url;
 | 
        
           |  |  | 1183 |     }
 | 
        
           |  |  | 1184 | }
 | 
        
           |  |  | 1185 |   | 
        
           |  |  | 1186 | ?>
 |