role_names as $key => $name) { $role = $wp_roles->get_role($key); if ($role->has_cap('use_openid_provider')) { $provider_enabled = true; break; } } if (!$provider_enabled) return $xrds; $user = openid_server_requested_user(); if (!$user && get_option('openid_blog_owner')) { $url_parts = parse_url(get_option('home')); $path = array_key_exists('path', $url_parts) ? $url_parts['path'] : ''; $path = trailingslashit($path); $script = preg_replace('/index.php$/', '', $_SERVER['SCRIPT_NAME']); $script = trailingslashit($script); if ($path != $script && !is_admin()) { return $xrds; } if (!defined('OPENID_DISALLOW_OWNER') || !OPENID_DISALLOW_OWNER) { $user = get_user_by('login', get_option('openid_blog_owner')); } } if ($user) { // if user doesn't have capability, bail $user_object = new WP_User($user->ID); if (!$user_object->has_cap('use_openid_provider')) return $xrds; if (get_user_meta($user->ID, 'openid_delegate', true)) { $services = get_user_meta($user->ID, 'openid_delegate_services', true); } else { $services = array(); $tmp_types = apply_filters('openid_server_xrds_types', array('http://specs.openid.net/auth/2.0/signon')); $types = array(); foreach ($tmp_types as $t) { $types[] = array('content' => $t); } $services[] = array( 'Type' => $types, 'URI' => openid_server_url(), 'LocalID' => get_author_posts_url($user->ID), ); $tmp_types = apply_filters('openid_server_xrds_types', array('http://openid.net/signon/1.1')); $types = array(); foreach ($tmp_types as $t) { $types[] = array('content' => $t); } $services[] = array( 'Type' => $types, 'URI' => openid_server_url(), 'openid:Delegate' => get_author_posts_url($user->ID), ); } } else { $services = array( array( 'Type' => array(array('content' => 'http://specs.openid.net/auth/2.0/server')), 'URI' => openid_server_url(), 'LocalID' => 'http://specs.openid.net/auth/2.0/identifier_select', ) ); } if (!empty($services)) { foreach ($services as $index => $service) { $name = 'OpenID Provider Service (' . $index . ')'; $xrds = xrds_add_service($xrds, 'main', $name, $service, $index); } } return $xrds; } /** * Add WebFinger entries for OpenID Server. Entries added will be highly * dependant on the requested URL and plugin configuration. * * @param array $webfinger The WebFinger data array * @param string $resource The requested WebFinger resource * @param WP_User $user The WordPress user * @return array The updated WebFinger data array */ function openid_provider_webfinger( $webfinger, $resource, $user ) { // check if OpenID provider is enabled for user if ( ! $user->has_cap( 'use_openid_provider' ) ) { return $webfinger; } // use delegation URL if set if ( get_user_meta( $user->ID, 'openid_delegate', true ) ) { $webfinger['links'][] = array( 'href' => get_user_meta( $user->ID, 'openid_delegate', true ), 'rel' => 'http://specs.openid.net/auth/2.0/provider', ); } else { // check if WebFinger user is "blog-owner" if ( get_option( 'openid_blog_owner' ) && $user->user_login == get_option( 'openid_blog_owner' ) ) { $webfinger['links'][] = array( 'href' => site_url( '/' ), 'rel' => 'http://specs.openid.net/auth/2.0/provider', ); } else { // otherwise use author-url $webfinger['links'][] = array( 'href' => get_author_posts_url( $user->ID ), 'rel' => 'http://specs.openid.net/auth/2.0/provider', ); } } return $webfinger; } /** * Parse the request URL to determine which author is associated with it. * * @return bool|object false on failure, User DB row object */ function openid_server_requested_user() { global $wp_rewrite; if (array_key_exists('author', $_REQUEST) && $_REQUEST['author']) { if (is_numeric($_REQUEST['author'])) { return get_user_by('id', $_REQUEST['author']); } else { return get_user_by('login', $_REQUEST['author']); } } else { $regex = preg_replace('/%author%/', '(.+)', $wp_rewrite->get_author_permastruct()); preg_match('|'.$regex.'|', $_SERVER['REQUEST_URI'], $matches); if ($matches) { $username = sanitize_user($matches[1], true); return get_user_by('login', $username); } } } /** * Process an OpenID Server request. * * @uses apply_filters() Calls 'openid_server_auth_response' before sending the authentication response. */ function openid_server_request() { $server = openid_server(); // get OpenID request, either from session or HTTP request $request = $server->decodeRequest(); if (!$request || Auth_OpenID_isError($request)) { @session_start(); if (isset($_SESSION['openid_server_request']) && $_SESSION['openid_server_request']) { $request = $_SESSION['openid_server_request']; unset($_SESSION['openid_server_request']); } } if (!$request || Auth_OpenID_isError($request)) { $html = '

This is an OpenID Server.

'; if (Auth_OpenID_isError($request)) { $html .= '

Request Error: ' . $request->toString() . '

'; } else { $html .= '

Nothing to see here… move along.

'; } wp_die($html); } // process request if (in_array($request->mode, array('checkid_immediate', 'checkid_setup'))) { $response = openid_server_auth_request($request); $response = apply_filters('openid_server_auth_response', $response); } else { $response = $server->handleRequest($request); } openid_server_process_response($response); } /** * Process an OpenID Server authentication request. * * @uses do_action() Calls the 'openid_server_pre_auth' hook action before checking if the user is logged in. * @uses do_action() Calls the 'openid_server_post_auth' hook action after ensuring that the user is logged in. */ function openid_server_auth_request($request) { do_action('openid_server_pre_auth', $request); // user must be logged in if (!is_user_logged_in()) { if ($request->mode == 'checkid_immediate') { return $request->answer(false); } else { @session_start(); $_SESSION['openid_server_request'] = $request; auth_redirect(); } } do_action('openid_server_post_auth', $request); // get some user data $user = wp_get_current_user(); $author_url = get_author_posts_url($user->ID); $id_select = $request->idSelect(); // bail if user does not have access to OpenID provider if (!$user->has_cap('use_openid_provider')) return $request->answer(false); // if using id select but user is delegating, display error to user (unless checkid_immediate) if ($id_select && get_user_meta($user->ID, 'openid_delegate', true)) { if ($request->mode != 'checkid_immediate') { if ($_REQUEST['action'] == 'cancel') { check_admin_referer('openid-server_cancel'); return $request->answer(false); } else { @session_start(); $_SESSION['openid_server_request'] = $request; ob_start(); echo '

'.__('OpenID Login Error', 'openid').'

'; echo '

'; printf(__('Because you have delegated your OpenID, you cannot login with the URL %s. Instead, you must use your full OpenID when logging in.', 'openid'), trailingslashit(get_option('home'))); echo'

'; echo '

' . sprintf(__('Your full OpenID is: %s', 'openid'), ''.$author_url.'') . '

'; echo '

' . wp_nonce_field('openid-server_cancel', '_wpnonce', true, false) .'
'; $html = ob_get_contents(); ob_end_clean(); wp_die($html, 'OpenID Login Error'); } } } // if user trusts site, we're done $trusted_sites = get_user_meta($user->ID, 'openid_trusted_sites', true); $site_hash = md5($request->trust_root); if (is_array($trusted_sites) && array_key_exists($site_hash, $trusted_sites)) { $trusted_sites[$site_hash]['last_login'] = time(); update_user_meta($user->ID, 'openid_trusted_sites', $trusted_sites); if ($id_select) { return $request->answer(true, null, $author_url); } else { return $request->answer(true); } } // that's all we can do without interacting with the user... bail if using immediate if ($request->mode == 'checkid_immediate') { return $request->answer(false); } // finally, prompt the user to trust this site if (openid_server_user_trust($request)) { if ($id_select) { return $request->answer(true, null, $author_url); } else { return $request->answer(true); } } else { return $request->answer(false); } } /** * Check that the current user's author URL matches the claimed URL. * * @param string $claimed claimed url * @return bool whether the current user matches the claimed URL */ function openid_server_check_user_login($claimed) { $user = wp_get_current_user(); if (!$user) return false; $identifier = get_author_posts_url($user->ID); return ($claimed == $identifier); } /** * Process OpenID server response * * @param object $response response object */ function openid_server_process_response($response) { $server = openid_server(); $web_response = $server->encodeResponse($response); if ($web_response->code != AUTH_OPENID_HTTP_OK) { header(sprintf('HTTP/1.1 %d', $web_response->code), true, $web_response->code); } foreach ($web_response->headers as $k => $v) { header("$k: $v"); } print $web_response->body; exit; } /** * Get Auth_OpenID_Server singleton. * * @return object Auth_OpenID_Server singleton instance */ function openid_server() { static $server; if (!$server || !is_a($server, 'Auth_OpenID_Server')) { $server = new Auth_OpenID_Server(openid_getStore(), openid_server_url()); } return $server; } /** * Add OpenID HTML link tags when appropriate. */ function openid_provider_link_tags() { if (is_front_page()) { if (!defined('OPENID_DISALLOW_OWNER') || !OPENID_DISALLOW_OWNER) { $user = get_user_by('login', get_option('openid_blog_owner')); } } else if (is_author()) { global $wp_query; $user = $wp_query->get_queried_object(); } if ( isset($user) && $user) { // if user doesn't have capability, bail $user_object = new WP_User($user->ID); if (!$user_object->has_cap('use_openid_provider')) return; if (get_user_meta($user->ID, 'openid_delegate', true)) { $services = get_user_meta($user->ID, 'openid_delegate_services', true); $openid_1 = false; $openid_2 = false; foreach($services as $service) { if (!$openid_1 && $service['openid:Delegate']) { echo ' '; $openid_1 = true; } if (!$openid_2 && $service['LocalID']) { echo ' '; $openid_2 = true; } } } else { $server = openid_server_url(); $identifier = get_author_posts_url($user->ID); echo ' '; } } } function openid_server_add_trust_site($user_id, $site_url, $site_name = null, $release_attributes) { } function openid_server_remove_trust_site() { } /** * Determine if the current user trusts the the relying party of the OpenID authentication request. * * @uses do_action() Calls the 'openid_server_trust_form' hook action when displaying the trust form. * @uses do_action() Calls the 'openid_server_trust_submit' hook action when processing the submitted trust form. * @uses apply_filters() Calls 'openid_server_store_trusted_site' before storing trusted site data. */ function openid_server_user_trust($request) { $user = wp_get_current_user(); if (isset($_REQUEST['openid_trust']) && $_REQUEST['openid_trust']) { $trust = null; if ($_REQUEST['openid_trust'] == 'cancel') { $trust = false; } else { check_admin_referer('openid-server_trust'); $trust = true; } do_action('openid_server_trust_submit', $trust, $request); if ($trust) { // store trusted site (unless hidden constant is set) if (!defined('OPENID_NO_AUTO_TRUST') || !OPENID_NO_AUTO_TRUST) { $site = array( 'url' => $request->trust_root, 'last_login' => time()); $site = apply_filters('openid_server_store_trusted_site', $site); $trusted_sites = get_user_meta($user->ID, 'openid_trusted_sites', true); $site_hash = md5($request->trust_root); $trusted_sites[$site_hash] = $site; update_user_meta($user->ID, 'openid_trusted_sites', $trusted_sites); } } return $trust; } else { // prompt the user to make a trust decision @session_start(); $_SESSION['openid_server_request'] = $request; ob_start(); echo '

'.__('Verify Your Identity', 'openid').'

' . sprintf(__('%s has asked to verify your identity.', 'openid'), ''.$request->trust_root.'') . '

' . __('Click Continue to verify your identity and login without creating a new password.', 'openid') . '

'; do_action('openid_server_trust_form'); echo '

'.__('Cancel and go back', 'openid').'

' . sprintf(__('Manage or remove access on the Trusted Sites page.', 'openid'), admin_url((current_user_can('edit_users') ? 'users.php' : 'profile.php') . '?page=openid_trusted_sites')) . '

' . sprintf(__('Edit your profile to change the information that gets shared with Trusted Sites.', 'openid'), admin_url('profile.php')) . '

'; wp_nonce_field('openid-server_trust', '_wpnonce', true); echo '
'; $html = ob_get_contents(); ob_end_clean(); openid_page($html, __('Verify Your Identity', 'openid')); } } /** * Discover and cache OpenID services for a user's delegate OpenID. * * @param int $userid user ID * @url string URL to discover. If not provided, user's current delegate will be used * @return bool true if successful */ function openid_server_get_delegation_info($userid, $url = null) { if (empty($url)) $url = get_user_meta($userid, 'openid_delegate', true); if (empty($url)) return false; $fetcher = Auth_Yadis_Yadis::getHTTPFetcher(); $discoveryResult = Auth_Yadis_Yadis::discover($url, $fetcher); $endpoints = Auth_OpenID_ServiceEndpoint::fromDiscoveryResult($discoveryResult); $services = array(); if (!empty($endpoints)) { foreach ($endpoints as $endpoint) { $service = array( 'Type' => array(), 'URI' => $endpoint->server_url, ); foreach ($endpoint->type_uris as $type) { $service['Type'][] = array('content' => $type); if ($type == Auth_OpenID_TYPE_2_0_IDP) { $service['LocalID'] = Auth_OpenID_IDENTIFIER_SELECT; } else if ($type == Auth_OpenID_TYPE_2_0) { $service['LocalID'] = $endpoint->local_id; } else if (in_array($type, array(Auth_OpenID_TYPE_1_0, Auth_OpenID_TYPE_1_1, Auth_OpenID_TYPE_1_2))) { $service['openid:Delegate'] = $endpoint->local_id; } } $services[] = $service; } } if (empty($services)) { // resort to checking for HTML links $response = $fetcher->get($url); if ( ! $response ) { return false; } $html_content = $response->body; $p = new Auth_OpenID_Parse(); $link_attrs = $p->parseLinkAttrs($html_content); // check HTML for OpenID2 $server_url = $p->findFirstHref($link_attrs, 'openid2.provider'); if ($server_url !== null) { $openid_url = $p->findFirstHref($link_attrs, 'openid2.local_id'); if ($openid_url == null) $openid_url = $url; $services[] = array( 'Type' => array(array('content' => Auth_OpenID_Type_1_1)), 'URI' => $server_url, 'LocalID' => $openid_url, ); } // check HTML for OpenID1 $server_url = $p->findFirstHref($link_attrs, 'openid.server'); if ($server_url !== null) { $openid_url = $p->findFirstHref($link_attrs, 'openid.delegate'); if ($openid_url == null) $openid_url = $url; $services[] = array( 'Type' => array(array('content' => Auth_OpenID_Type_2_0)), 'URI' => $server_url, 'openid:Delegate' => $openid_url, ); } } if (empty($services)) return false; return array( 'url' => $url, 'services' => $services ); }