| 1 |
<?php
|
| 2 |
// $Id: openid.module,v 1.28 2007/06/15 20:44:18 walkah Exp $
|
| 3 |
|
| 4 |
/**
|
| 5 |
* @file
|
| 6 |
* Implement OpenID Relying Party support for Drupal
|
| 7 |
*/
|
| 8 |
|
| 9 |
/**
|
| 10 |
* Implementation of hook_menu.
|
| 11 |
*/
|
| 12 |
function openid_menu() {
|
| 13 |
$items['openid/authenticate'] = array(
|
| 14 |
'title' => 'OpenID Login',
|
| 15 |
'page callback' => 'openid_authentication_page',
|
| 16 |
'access callback' => 'user_is_anonymous',
|
| 17 |
'type' => MENU_CALLBACK,
|
| 18 |
);
|
| 19 |
$items['user/%user/openid'] = array(
|
| 20 |
'title' => 'OpenID Identities',
|
| 21 |
'page callback' => 'openid_user_identities',
|
| 22 |
'page arguments' => array(1),
|
| 23 |
'access callback' => 'user_edit_access',
|
| 24 |
'access arguments' => array(1),
|
| 25 |
'type' => MENU_LOCAL_TASK,
|
| 26 |
);
|
| 27 |
$items['user/%user/openid/delete'] = array(
|
| 28 |
'title' => 'Delete OpenID',
|
| 29 |
'page callback' => 'openid_user_delete',
|
| 30 |
'page arguments' => array(1),
|
| 31 |
'type' => MENU_CALLBACK,
|
| 32 |
);
|
| 33 |
return $items;
|
| 34 |
}
|
| 35 |
|
| 36 |
/**
|
| 37 |
* Implementation of hook_help().
|
| 38 |
*/
|
| 39 |
function openid_help($section) {
|
| 40 |
switch ($section) {
|
| 41 |
case 'user/%/openid':
|
| 42 |
return t('You may login to this site using an OpenID. You may add your OpenId URLs below, and also see a list of any OpenIDs which have already been added.');
|
| 43 |
}
|
| 44 |
}
|
| 45 |
|
| 46 |
/**
|
| 47 |
* Implementation of hook_user().
|
| 48 |
*/
|
| 49 |
function openid_user($op, &$edit, &$account, $category = NULL) {
|
| 50 |
if ($op == 'insert' && isset($_SESSION['openid'])) {
|
| 51 |
// The user has registered after trying to login via OpenID.
|
| 52 |
if (variable_get('user_email_verification', TRUE)) {
|
| 53 |
drupal_set_message(t('Once you have verified your email address, you may log in via OpenID.'));
|
| 54 |
}
|
| 55 |
unset($_SESSION['openid']);
|
| 56 |
}
|
| 57 |
}
|
| 58 |
|
| 59 |
/**
|
| 60 |
* Implementation of hook_form_alter : adds OpenID login to the login forms.
|
| 61 |
*/
|
| 62 |
function openid_form_alter(&$form, $form_state, $form_id) {
|
| 63 |
if ($form_id == 'user_login_block' || $form_id == 'user_login') {
|
| 64 |
drupal_add_css(drupal_get_path('module', 'openid') .'/openid.css', 'module');
|
| 65 |
drupal_add_js(drupal_get_path('module', 'openid') .'/openid.js');
|
| 66 |
if (!empty($form_state['post']['openid_url'])) {
|
| 67 |
$form['name']['#required'] = FALSE;
|
| 68 |
$form['pass']['#required'] = FALSE;
|
| 69 |
unset($form['#submit']);
|
| 70 |
$form['#validate'] = array('openid_login_validate');
|
| 71 |
}
|
| 72 |
|
| 73 |
$form['openid_link'] = array('#value' => l(t('Log in using OpenID'), '#', array('attributes' => array('class' => 'openid-link'))));
|
| 74 |
$form['user_link'] = array('#value' => l(t('Cancel OpenID login'), '#', array('attributes' => array('class' => 'user-link'))));
|
| 75 |
|
| 76 |
$form['openid_url'] = array(
|
| 77 |
'#type' => 'textfield',
|
| 78 |
'#title' => t('Log in using OpenID'),
|
| 79 |
'#size' => ($form_id == 'user_login') ? 58 : 13,
|
| 80 |
'#maxlength' => 255,
|
| 81 |
'#weight' => -1,
|
| 82 |
'#description' => l(t('What is OpenID?'), 'http://openid.net/', array('external' => TRUE))
|
| 83 |
);
|
| 84 |
$form['openid.return_to'] = array('#type' => 'hidden', '#value' => url('openid/authenticate', array('absolute' => TRUE, 'query' => drupal_get_destination())));
|
| 85 |
}
|
| 86 |
elseif ($form_id == 'user_register' && isset($_SESSION['openid'])) {
|
| 87 |
// We were unable to auto-register a new user. Prefill the registration
|
| 88 |
// form with the values we have.
|
| 89 |
$form['name']['#default_value'] = $_SESSION['openid']['name'];
|
| 90 |
$form['mail']['#default_value'] = $_SESSION['openid']['mail'];
|
| 91 |
// If user_email_verification is off, hide the password field and just fill
|
| 92 |
// with random password to avoid confusion.
|
| 93 |
if (!variable_get('user_email_verification', TRUE)) {
|
| 94 |
$form['pass']['#type'] = 'hidden';
|
| 95 |
$form['pass']['#value'] = user_password();
|
| 96 |
}
|
| 97 |
$form['auth_openid'] = array('#type' => 'hidden', '#value' => $_SESSION['openid']['auth_openid']);
|
| 98 |
}
|
| 99 |
return $form;
|
| 100 |
}
|
| 101 |
|
| 102 |
/**
|
| 103 |
* Login form _validate hook
|
| 104 |
*/
|
| 105 |
function openid_login_validate($form, &$form_state) {
|
| 106 |
$return_to = $form_state['values']['openid.return_to'];
|
| 107 |
if (empty($return_to)) {
|
| 108 |
$return_to = url('', array('absolute' => TRUE));
|
| 109 |
}
|
| 110 |
|
| 111 |
openid_begin($form_state['values']['openid_url'], $return_to);
|
| 112 |
}
|
| 113 |
|
| 114 |
/**
|
| 115 |
* Callbacks.
|
| 116 |
*/
|
| 117 |
function openid_authentication_page() {
|
| 118 |
$result = openid_complete($_REQUEST);
|
| 119 |
switch ($result['status']) {
|
| 120 |
case 'success':
|
| 121 |
return openid_authentication($result);
|
| 122 |
case 'failed':
|
| 123 |
drupal_set_message(t('OpenID login failed.'));
|
| 124 |
break;
|
| 125 |
case 'cancel':
|
| 126 |
drupal_set_message(t('OpenID login cancelled.'));
|
| 127 |
break;
|
| 128 |
}
|
| 129 |
drupal_goto();
|
| 130 |
}
|
| 131 |
|
| 132 |
function openid_user_identities($account) {
|
| 133 |
drupal_add_css(drupal_get_path('module', 'openid') .'/openid.css', 'module');
|
| 134 |
|
| 135 |
// Check to see if we got a response
|
| 136 |
$result = openid_complete($_REQUEST);
|
| 137 |
if ($result['status'] == 'success') {
|
| 138 |
db_query("INSERT INTO {authmap} (uid, authname, module) VALUES (%d, '%s','openid')", $account->uid, $result['openid.identity']);
|
| 139 |
drupal_set_message(t('Successfully added %identity', array('%identity' => $result['openid.identity'])));
|
| 140 |
}
|
| 141 |
|
| 142 |
$header = array(t('OpenID'), '');
|
| 143 |
$rows = array();
|
| 144 |
|
| 145 |
$result = db_query("SELECT * FROM {authmap} WHERE module='openid' AND uid=%d", $account->uid);
|
| 146 |
while ($identity = db_fetch_object($result)) {
|
| 147 |
$rows[] = array($identity->authname, l(t('Delete'), 'user/'. $account->uid .'/openid/delete/'. $identity->aid));
|
| 148 |
}
|
| 149 |
|
| 150 |
$output = theme('table', $header, $rows);
|
| 151 |
$output .= drupal_get_form('openid_user_add');
|
| 152 |
return $output;
|
| 153 |
}
|
| 154 |
|
| 155 |
function openid_user_add() {
|
| 156 |
$form['openid_url'] = array(
|
| 157 |
'#type' => 'textfield',
|
| 158 |
'#title' => t('Add an OpenID'),
|
| 159 |
);
|
| 160 |
$form['submit'] = array('#type' => 'submit', '#value' => t('Add'));
|
| 161 |
return $form;
|
| 162 |
}
|
| 163 |
|
| 164 |
function openid_user_add_validate($form, &$form_state) {
|
| 165 |
// Check for existing entries.
|
| 166 |
$claimed_id = _openid_normalize($form_state['values']['openid_url']);
|
| 167 |
if (db_result(db_query("SELECT authname FROM {authmap} WHERE authname='%s'", $claimed_id))) {
|
| 168 |
form_set_error('openid_url', t('That OpenID is already in use on this site.'));
|
| 169 |
}
|
| 170 |
else {
|
| 171 |
$return_to = url('user/'. arg(1) .'/openid', array('absolute' => TRUE));
|
| 172 |
openid_begin($form_state['values']['openid_url'], $return_to);
|
| 173 |
}
|
| 174 |
}
|
| 175 |
|
| 176 |
function openid_user_delete($account, $aid = 0) {
|
| 177 |
db_query("DELETE FROM {authmap} WHERE uid=%d AND aid=%d AND module='openid'", $account->uid, $aid);
|
| 178 |
if (db_affected_rows()) {
|
| 179 |
drupal_set_message(t('OpenID deleted.'));
|
| 180 |
}
|
| 181 |
drupal_goto('user/'. $account->uid .'/openid');
|
| 182 |
}
|
| 183 |
|
| 184 |
/**
|
| 185 |
* The initial step of OpenID authentication responsible for the following:
|
| 186 |
* - Perform discovery on the claimed OpenID.
|
| 187 |
* - If possible, create an association with the Provider's endpoint.
|
| 188 |
* - Create the authentication request.
|
| 189 |
* - Perform the appropriate redirect.
|
| 190 |
*
|
| 191 |
* @param $claimed_id The OpenID to authenticate
|
| 192 |
* @param $return_to The endpoint to return to from the OpenID Provider
|
| 193 |
*/
|
| 194 |
function openid_begin($claimed_id, $return_to = '') {
|
| 195 |
include_once drupal_get_path('module', 'openid') .'/openid.inc';
|
| 196 |
|
| 197 |
$claimed_id = _openid_normalize($claimed_id);
|
| 198 |
|
| 199 |
$services = openid_discovery($claimed_id);
|
| 200 |
if (count($services) == 0) {
|
| 201 |
form_set_error('openid_url', t('Sorry, that is not a valid OpenID. Please ensure you have spelled your ID correctly.'));
|
| 202 |
return;
|
| 203 |
}
|
| 204 |
|
| 205 |
$op_endpoint = $services[0]['uri'];
|
| 206 |
// Store the discovered endpoint in the session (so we don't have to rediscover).
|
| 207 |
$_SESSION['openid_op_endpoint'] = $op_endpoint;
|
| 208 |
// Store the claimed_id in the session (for handling delegation).
|
| 209 |
$_SESSION['openid_claimed_id'] = $claimed_id;
|
| 210 |
|
| 211 |
// If bcmath is present, then create an association
|
| 212 |
$assoc_handle = '';
|
| 213 |
if (function_exists('bcadd')) {
|
| 214 |
$assoc_handle = openid_association($op_endpoint);
|
| 215 |
}
|
| 216 |
|
| 217 |
// Now that there is an association created, move on
|
| 218 |
// to request authentication from the IdP
|
| 219 |
$identity = (!empty($services[0]['delegate'])) ? $services[0]['delegate'] : $claimed_id;
|
| 220 |
if (isset($services[0]['types']) && is_array($services[0]['types']) && in_array(OPENID_NS_2_0 .'/server', $services[0]['types'])) {
|
| 221 |
$identity = 'http://openid.net/identifier_select/2.0';
|
| 222 |
}
|
| 223 |
$authn_request = openid_authentication_request($claimed_id, $identity, $return_to, $assoc_handle, $services[0]['version']);
|
| 224 |
|
| 225 |
if ($services[0]['version'] == 2) {
|
| 226 |
openid_redirect($op_endpoint, $authn_request);
|
| 227 |
}
|
| 228 |
else {
|
| 229 |
openid_redirect_http($op_endpoint, $authn_request);
|
| 230 |
}
|
| 231 |
}
|
| 232 |
|
| 233 |
/**
|
| 234 |
* Completes OpenID authentication by validating returned data from the OpenID
|
| 235 |
* Provider.
|
| 236 |
*
|
| 237 |
* @param $response Array of returned from the OpenID provider (typically $_REQUEST).
|
| 238 |
*
|
| 239 |
* @return $response Response values for further processing with
|
| 240 |
* $response['status'] set to one of 'success', 'failed' or 'cancel'.
|
| 241 |
*/
|
| 242 |
function openid_complete($response) {
|
| 243 |
include_once drupal_get_path('module', 'openid') .'/openid.inc';
|
| 244 |
|
| 245 |
// Default to failed response
|
| 246 |
$response['status'] = 'failed';
|
| 247 |
if (isset($_SESSION['openid_op_endpoint']) && isset($_SESSION['openid_claimed_id'])) {
|
| 248 |
_openid_fix_post($response);
|
| 249 |
$op_endpoint = $_SESSION['openid_op_endpoint'];
|
| 250 |
$claimed_id = $_SESSION['openid_claimed_id'];
|
| 251 |
unset($_SESSION['openid_op_endpoint']);
|
| 252 |
unset($_SESSION['openid_claimed_id']);
|
| 253 |
if (isset($response['openid.mode'])) {
|
| 254 |
if ($response['openid.mode'] == 'cancel') {
|
| 255 |
$response['status'] = 'cancel';
|
| 256 |
}
|
| 257 |
else {
|
| 258 |
if (openid_verify_assertion($op_endpoint, $response)) {
|
| 259 |
$response['openid.identity'] = $claimed_id;
|
| 260 |
$response['status'] = 'success';
|
| 261 |
}
|
| 262 |
}
|
| 263 |
}
|
| 264 |
}
|
| 265 |
return $response;
|
| 266 |
}
|
| 267 |
|
| 268 |
/**
|
| 269 |
* Perform discovery on a claimed ID to determine the OpenID provider endpoint.
|
| 270 |
*
|
| 271 |
* @param $claimed_id The OpenID URL to perform discovery on.
|
| 272 |
*
|
| 273 |
* @return Array of services discovered (including OpenID version, endpoint
|
| 274 |
* URI, etc).
|
| 275 |
*/
|
| 276 |
function openid_discovery($claimed_id) {
|
| 277 |
include_once drupal_get_path('module', 'openid') .'/openid.inc';
|
| 278 |
include_once drupal_get_path('module', 'openid') .'/xrds.inc';
|
| 279 |
|
| 280 |
$services = array();
|
| 281 |
|
| 282 |
$xrds_url = $claimed_id;
|
| 283 |
if (_openid_is_xri($claimed_id)) {
|
| 284 |
$xrds_url = 'http://xri.net/'. $claimed_id;
|
| 285 |
}
|
| 286 |
$url = @parse_url($xrds_url);
|
| 287 |
if ($url['scheme'] == 'http' || $url['scheme'] == 'https') {
|
| 288 |
// For regular URLs, try Yadis resolution first, then HTML-based discovery
|
| 289 |
$headers = array('Accept' => 'application/xrds+xml');
|
| 290 |
$result = drupal_http_request($xrds_url, $headers);
|
| 291 |
|
| 292 |
if (!isset($result->error)) {
|
| 293 |
if (isset($result->headers['Content-Type']) && preg_match("/application\/xrds\+xml/", $result->headers['Content-Type'])) {
|
| 294 |
// Parse XML document to find URL
|
| 295 |
$services = xrds_parse($result->data);
|
| 296 |
}
|
| 297 |
else {
|
| 298 |
$xrds_url = NULL;
|
| 299 |
if (isset($result->headers['X-XRDS-Location'])) {
|
| 300 |
$xrds_url = $result->headers['X-XRDS-Location'];
|
| 301 |
}
|
| 302 |
else {
|
| 303 |
// Look for meta http-equiv link in HTML head
|
| 304 |
$xrds_url = _openid_meta_httpequiv('X-XRDS-Location', $result->data);
|
| 305 |
}
|
| 306 |
if (!empty($xrds_url)) {
|
| 307 |
$headers = array('Accept' => 'application/xrds+xml');
|
| 308 |
$xrds_result = drupal_http_request($xrds_url, $headers);
|
| 309 |
if (!isset($xrds_result->error)) {
|
| 310 |
$services = xrds_parse($xrds_result->data);
|
| 311 |
}
|
| 312 |
}
|
| 313 |
}
|
| 314 |
|
| 315 |
// Check for HTML delegation
|
| 316 |
if (count($services) == 0) {
|
| 317 |
// Look for 2.0 links
|
| 318 |
$uri = _openid_link_href('openid2.provider', $result->data);
|
| 319 |
$delegate = _openid_link_href('openid2.local_id', $result->data);
|
| 320 |
$version = 2;
|
| 321 |
|
| 322 |
// 1.0 links
|
| 323 |
if (empty($uri)) {
|
| 324 |
$uri = _openid_link_href('openid.server', $result->data);
|
| 325 |
$delegate = _openid_link_href('openid.delegate', $result->data);
|
| 326 |
$version = 1;
|
| 327 |
}
|
| 328 |
if (!empty($uri)) {
|
| 329 |
$services[] = array('uri' => $uri, 'delegate' => $delegate, 'version' => $version);
|
| 330 |
}
|
| 331 |
}
|
| 332 |
}
|
| 333 |
}
|
| 334 |
return $services;
|
| 335 |
}
|
| 336 |
|
| 337 |
/**
|
| 338 |
* Attempt to create a shared secret with the OpenID Provider.
|
| 339 |
*
|
| 340 |
* @param $op_endpoint URL of the OpenID Provider endpoint.
|
| 341 |
*
|
| 342 |
* @return $assoc_handle The association handle.
|
| 343 |
*/
|
| 344 |
function openid_association($op_endpoint) {
|
| 345 |
include_once drupal_get_path('module', 'openid') .'/openid.inc';
|
| 346 |
|
| 347 |
// Remove Old Associations:
|
| 348 |
db_query("DELETE FROM {openid_association} WHERE created + expires_in < %d", time());
|
| 349 |
|
| 350 |
// Check to see if we have an association for this IdP already
|
| 351 |
$assoc_handle = db_result(db_query("SELECT assoc_handle FROM {openid_association} WHERE idp_endpoint_uri = '%s'", $op_endpoint));
|
| 352 |
if (empty($assoc_handle)) {
|
| 353 |
$mod = OPENID_DH_DEFAULT_MOD;
|
| 354 |
$gen = OPENID_DH_DEFAULT_GEN;
|
| 355 |
$r = _openid_dh_rand($mod);
|
| 356 |
$private = bcadd($r, 1);
|
| 357 |
$public = bcpowmod($gen, $private, $mod);
|
| 358 |
|
| 359 |
// If there is no existing association, then request one
|
| 360 |
$assoc_request = openid_association_request($public);
|
| 361 |
$assoc_message = _openid_encode_message(_openid_create_message($assoc_request));
|
| 362 |
$assoc_headers = array('Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8');
|
| 363 |
$assoc_result = drupal_http_request($op_endpoint, $assoc_headers, 'POST', $assoc_message);
|
| 364 |
if (isset($assoc_result->error)) {
|
| 365 |
return FALSE;
|
| 366 |
}
|
| 367 |
|
| 368 |
$assoc_response = _openid_parse_message($assoc_result->data);
|
| 369 |
if (isset($assoc_response['mode']) && $assoc_response['mode'] == 'error') {
|
| 370 |
return FALSE;
|
| 371 |
}
|
| 372 |
|
| 373 |
if ($assoc_response['session_type'] == 'DH-SHA1') {
|
| 374 |
$spub = _openid_dh_base64_to_long($assoc_response['dh_server_public']);
|
| 375 |
$enc_mac_key = base64_decode($assoc_response['enc_mac_key']);
|
| 376 |
$shared = bcpowmod($spub, $private, $mod);
|
| 377 |
$assoc_response['mac_key'] = base64_encode(_openid_dh_xorsecret($shared, $enc_mac_key));
|
| 378 |
}
|
| 379 |
db_query("INSERT INTO {openid_association} (idp_endpoint_uri, session_type, assoc_handle, assoc_type, expires_in, mac_key, created) VALUES('%s', '%s', '%s', '%s', %d, '%s', %d)",
|
| 380 |
$op_endpoint, $assoc_response['session_type'], $assoc_response['assoc_handle'], $assoc_response['assoc_type'], $assoc_response['expires_in'], $assoc_response['mac_key'], time());
|
| 381 |
|
| 382 |
$assoc_handle = $assoc_response['assoc_handle'];
|
| 383 |
}
|
| 384 |
|
| 385 |
return $assoc_handle;
|
| 386 |
}
|
| 387 |
|
| 388 |
/**
|
| 389 |
* Authenticate a user or attempt registration.
|
| 390 |
*
|
| 391 |
* @param $response Response values from the OpenID Provider.
|
| 392 |
*/
|
| 393 |
function openid_authentication($response) {
|
| 394 |
include_once drupal_get_path('module', 'openid') .'/openid.inc';
|
| 395 |
|
| 396 |
$identity = $response['openid.identity'];
|
| 397 |
|
| 398 |
$account = user_external_load($identity);
|
| 399 |
if (isset($account->uid)) {
|
| 400 |
if (!variable_get('user_email_verification', TRUE) || $account->login) {
|
| 401 |
user_external_login($account);
|
| 402 |
}
|
| 403 |
else {
|
| 404 |
drupal_set_message(t('You must validate your email address for this account before logging in via OpenID'));
|
| 405 |
}
|
| 406 |
}
|
| 407 |
else {
|
| 408 |
// Register new user
|
| 409 |
$form_state['redirect'] = NULL;
|
| 410 |
$form_state['values']['name'] = (empty($response['openid.sreg.nickname'])) ? $identity : $response['openid.sreg.nickname'];
|
| 411 |
$form_state['values']['mail'] = (empty($response['openid.sreg.email'])) ? '' : $response['openid.sreg.email'];
|
| 412 |
$form_state['values']['pass'] = user_password();
|
| 413 |
$form_state['values']['status'] = variable_get('user_register', 1) == 1;
|
| 414 |
$form_state['values']['response'] = $response;
|
| 415 |
$form_state['values']['auth_openid'] = $identity;
|
| 416 |
$form = drupal_retrieve_form('user_register', $form_state);
|
| 417 |
drupal_prepare_form('user_register', $form, $form_state);
|
| 418 |
drupal_validate_form('user_register', $form, $form_state);
|
| 419 |
if (form_get_errors()) {
|
| 420 |
// We were unable to register a valid new user, redirect to standard
|
| 421 |
// user/register and prefill with the values we received.
|
| 422 |
drupal_set_message(t('OpenID registration failed for the reasons listed. You may register now, or if you already have an account you can <a href="@login">log in</a> now and add your OpenID under "My Account"', array('@login' => url('user/login'))), 'error');
|
| 423 |
$_SESSION['openid'] = $form_state['values'];
|
| 424 |
// We'll want to redirect back to the same place.
|
| 425 |
$destination = drupal_get_destination();
|
| 426 |
unset($_REQUEST['destination']);
|
| 427 |
drupal_goto('user/register', $destination);
|
| 428 |
}
|
| 429 |
else {
|
| 430 |
unset($form_state['values']['response']);
|
| 431 |
$account = user_save('', $form_state['values']);
|
| 432 |
user_external_login($account);
|
| 433 |
}
|
| 434 |
drupal_redirect_form($form, $form_state['redirect']);
|
| 435 |
}
|
| 436 |
drupal_goto();
|
| 437 |
}
|
| 438 |
|
| 439 |
function openid_association_request($public) {
|
| 440 |
include_once drupal_get_path('module', 'openid') .'/openid.inc';
|
| 441 |
|
| 442 |
$request = array(
|
| 443 |
'openid.ns' => OPENID_NS_2_0,
|
| 444 |
'openid.mode' => 'associate',
|
| 445 |
'openid.session_type' => 'DH-SHA1',
|
| 446 |
'openid.assoc_type' => 'HMAC-SHA1'
|
| 447 |
);
|
| 448 |
|
| 449 |
if ($request['openid.session_type'] == 'DH-SHA1' || $request['openid.session_type'] == 'DH-SHA256') {
|
| 450 |
$cpub = _openid_dh_long_to_base64($public);
|
| 451 |
$request['openid.dh_consumer_public'] = $cpub;
|
| 452 |
}
|
| 453 |
|
| 454 |
return $request;
|
| 455 |
}
|
| 456 |
|
| 457 |
function openid_authentication_request($claimed_id, $identity, $return_to = '', $assoc_handle = '', $version = 2) {
|
| 458 |
include_once drupal_get_path('module', 'openid') .'/openid.inc';
|
| 459 |
|
| 460 |
$realm = ($return_to) ? $return_to : url('', array('absolute' => TRUE));
|
| 461 |
|
| 462 |
$ns = ($version == 2) ? OPENID_NS_2_0 : OPENID_NS_1_0;
|
| 463 |
$request = array(
|
| 464 |
'openid.ns' => $ns,
|
| 465 |
'openid.mode' => 'checkid_setup',
|
| 466 |
'openid.identity' => $identity,
|
| 467 |
'openid.claimed_id' => $claimed_id,
|
| 468 |
'openid.assoc_handle' => $assoc_handle,
|
| 469 |
'openid.return_to' => $return_to,
|
| 470 |
);
|
| 471 |
|
| 472 |
if ($version == 2) {
|
| 473 |
$request['openid.realm'] = $realm;
|
| 474 |
}
|
| 475 |
else {
|
| 476 |
$request['openid.trust_root'] = $realm;
|
| 477 |
}
|
| 478 |
|
| 479 |
// Simple Registration
|
| 480 |
$request['openid.sreg.required'] = 'nickname,email';
|
| 481 |
$request['openid.ns.sreg'] = "http://openid.net/extensions/sreg/1.1";
|
| 482 |
|
| 483 |
$request = array_merge($request, module_invoke_all('openid', 'request', $request));
|
| 484 |
|
| 485 |
return $request;
|
| 486 |
}
|
| 487 |
|
| 488 |
/**
|
| 489 |
* Attempt to verify the response received from the OpenID Provider.
|
| 490 |
*
|
| 491 |
* @param $op_endpoint The OpenID Provider URL.
|
| 492 |
* @param $response Array of repsonse values from the provider.
|
| 493 |
*
|
| 494 |
* @return boolean
|
| 495 |
*/
|
| 496 |
function openid_verify_assertion($op_endpoint, $response) {
|
| 497 |
include_once drupal_get_path('module', 'openid') .'/openid.inc';
|
| 498 |
|
| 499 |
$valid = FALSE;
|
| 500 |
|
| 501 |
$association = db_fetch_object(db_query("SELECT * FROM {openid_association} WHERE assoc_handle = '%s'", $response['openid.assoc_handle']));
|
| 502 |
if ($association && isset($association->session_type)) {
|
| 503 |
$keys_to_sign = explode(',', $response['openid.signed']);
|
| 504 |
$self_sig = _openid_signature($association, $response, $keys_to_sign);
|
| 505 |
if ($self_sig == $response['openid.sig']) {
|
| 506 |
$valid = TRUE;
|
| 507 |
}
|
| 508 |
else {
|
| 509 |
$valid = FALSE;
|
| 510 |
}
|
| 511 |
}
|
| 512 |
else {
|
| 513 |
$request = $response;
|
| 514 |
$request['openid.mode'] = 'check_authentication';
|
| 515 |
$message = _openid_create_message($request);
|
| 516 |
$headers = array('Content-Type' => 'application/x-www-form-urlencoded; charset=utf-8');
|
| 517 |
$result = drupal_http_request($op_endpoint, $headers, 'POST', _openid_encode_message($message));
|
| 518 |
if (!isset($result->error)) {
|
| 519 |
$response = _openid_parse_message($result->data);
|
| 520 |
if (strtolower(trim($response['is_valid'])) == 'true') {
|
| 521 |
$valid = TRUE;
|
| 522 |
}
|
| 523 |
else {
|
| 524 |
$valid = FALSE;
|
| 525 |
}
|
| 526 |
}
|
| 527 |
}
|
| 528 |
|
| 529 |
return $valid;
|
| 530 |
}
|