Returns true on success and false of failure.
Normalization is performed according to the following rules:
1. If the user's input starts with one of the "xri://", "xri://$ip*",
or "xri://$dns*" prefixes, they MUST be stripped off, so that XRIs
are used in the canonical form, and URI-authority XRIs are further
considered URL identifiers.
2. If the first character of the resulting string is an XRI Global
Context Symbol ("=", "@", "+", "$", "!"), then the input SHOULD be
treated as an XRI.
3. Otherwise, the input SHOULD be treated as an http URL; if it does
not include a "http" or "https" scheme, the Identifier MUST be
prefixed with the string "http://".
4. URL identifiers MUST then be further normalized by both following
redirects when retrieving their content and finally applying the
rules in Section 6 of [RFC3986] to the final destination URL.
/** * Performs login of user with given $id, $password and $username * Returns true in case of success and false otherwise * * @param string $id user identity URL * @param string $password user password * @param string $username Tine 2.0 login name * @return bool */ public function login($id, $password, $username = null) { if (!Zend_OpenId::normalize($id)) { return false; } if (!$this->_storage->checkUser($id, $password, $username)) { return false; } $this->_user->setLoggedInUser($id); return true; }
/** * Normalizes OpenID identifier that can be URL or XRI name. * Returns true on success and false of failure. * * Normalization is performed according to the following rules: * 1. If the user's input starts with one of the "xri://", "xri://$ip*", * or "xri://$dns*" prefixes, they MUST be stripped off, so that XRIs * are used in the canonical form, and URI-authority XRIs are further * considered URL identifiers. * 2. If the first character of the resulting string is an XRI Global * Context Symbol ("=", "@", "+", "$", "!"), then the input SHOULD be * treated as an XRI. * 3. Otherwise, the input SHOULD be treated as an http URL; if it does * not include a "http" or "https" scheme, the Identifier MUST be * prefixed with the string "http://". * 4. URL identifiers MUST then be further normalized by both following * redirects when retrieving their content and finally applying the * rules in Section 6 of [RFC3986] to the final destination URL. * @param string &$id identifier to be normalized * @return bool */ public static function normalize(&$id) { $validator = new Zend_Validate_EmailAddress(); if ($validator->isValid($id)) { if (false !== strpos($id, 'gmail')) { $id = 'https://www.google.com/accounts/o8/id'; return true; } $email = explode('@', $id); $id = 'https://www.google.com/accounts/o8/site-xrds?ns=2&hd=' . $email[1]; return true; } else { return Zend_OpenId::normalize($id); } }
/** * Performs check of OpenID identity. * * This is the first step of OpenID authentication process. * On success the function does not return (it does HTTP redirection to * server and exits). On failure it returns false. * * @param bool $immediate enables or disables interaction with user * @param string $id OpenID identity * @param string $returnTo HTTP URL to redirect response from server to * @param string $root HTTP URL to identify consumer on server * @param mixed $extensions extension object or array of extensions objects * @param Zend_Controller_Response_Abstract $response an optional response * object to perform HTTP or HTML form redirection * @return bool */ protected function _checkId($immediate, $id, $returnTo = null, $root = null, $extensions = null, Zend_Controller_Response_Abstract $response = null) { $this->_setError(''); if (!Zend_OpenId::normalize($id)) { $this->_setError("Normalisation failed"); return false; } $claimedId = $id; if (!$this->_discovery($id, $server, $version)) { $this->_setError("Discovery failed: " . $this->getError()); return false; } if (!$this->_associate($server, $version)) { $this->_setError("Association failed: " . $this->getError()); return false; } if (!$this->_getAssociation($server, $handle, $macFunc, $secret, $expires)) { /* Use dumb mode */ unset($handle); unset($macFunc); unset($secret); unset($expires); } $params = array(); if ($version >= 2.0) { $params['openid.ns'] = Zend_OpenId::NS_2_0; } $params['openid.mode'] = $immediate ? 'checkid_immediate' : 'checkid_setup'; $params['openid.identity'] = $id; $params['openid.claimed_id'] = $claimedId; if ($version <= 2.0) { if ($this->_session !== null) { $this->_session->identity = $id; $this->_session->claimed_id = $claimedId; } else { if (defined('SID')) { $_SESSION["zend_openid"] = array("identity" => $id, "claimed_id" => $claimedId); } else { require_once "Zend/Session/Namespace.php"; $this->_session = new Zend_Session_Namespace("zend_openid"); $this->_session->identity = $id; $this->_session->claimed_id = $claimedId; } } } if (isset($handle)) { $params['openid.assoc_handle'] = $handle; } $params['openid.return_to'] = Zend_OpenId::absoluteUrl($returnTo); if (empty($root)) { $root = Zend_OpenId::selfUrl(); if ($root[strlen($root) - 1] != '/') { $root = dirname($root); } } if ($version >= 2.0) { $params['openid.realm'] = $root; } else { $params['openid.trust_root'] = $root; } if (!Zend_OpenId_Extension::forAll($extensions, 'prepareRequest', $params)) { $this->_setError("Extension::prepareRequest failure"); return false; } Zend_OpenId::redirect($server, $params, $response); return true; }
/** * testing testNormalize * */ public function testNormalize() { $url = ''; $this->assertTrue( Zend_OpenId::normalize($url) ); $this->assertSame( '', $url ); $url = ' localhost '; $this->assertTrue( Zend_OpenId::normalize($url) ); $this->assertSame( 'http://localhost/', $url ); $url = 'xri://$ip*127.0.0.1'; $this->assertTrue( Zend_OpenId::normalize($url) ); $this->assertSame( 'http://127.0.0.1/', $url ); $url = 'xri://$dns*localhost'; $this->assertTrue( Zend_OpenId::normalize($url) ); $this->assertSame( 'http://localhost/', $url ); $url = 'xri://localhost'; $this->assertTrue( Zend_OpenId::normalize($url) ); $this->assertSame( 'http://localhost/', $url ); $url = '=name'; $this->assertTrue( Zend_OpenId::normalize($url) ); $this->assertSame( '=name', $url ); $url = '@name'; $this->assertTrue( Zend_OpenId::normalize($url) ); $this->assertSame( '@name', $url ); $url = '+name'; $this->assertTrue( Zend_OpenId::normalize($url) ); $this->assertSame( '+name', $url ); $url = '$name'; $this->assertTrue( Zend_OpenId::normalize($url) ); $this->assertSame( '$name', $url ); $url = '!name'; $this->assertTrue( Zend_OpenId::normalize($url) ); $this->assertSame( '!name', $url ); $url = 'localhost'; $this->assertTrue( Zend_OpenId::normalize($url) ); $this->assertSame( 'http://localhost/', $url ); $url = 'http://localhost'; $this->assertTrue( Zend_OpenId::normalize($url) ); $this->assertSame( 'http://localhost/', $url ); $url = 'https://localhost'; $this->assertTrue( Zend_OpenId::normalize($url) ); $this->assertSame( 'https://localhost/', $url ); }
/** * Performs check of OpenID identity. * * This is the first step of OpenID authentication process. * On success the function does not return (it does HTTP redirection to * server and exits). On failure it returns false. * * @param bool $immediate enables or disables interaction with user * @param string $id OpenID identity * @param string $returnTo HTTP URL to redirect response from server to * @param string $root HTTP URL to identify consumer on server * @param mixed $extensions extension object or array of extensions objects * @param Zend_Controller_Response_Abstract $response an optional response * object to perform HTTP or HTML form redirection * @return bool */ protected function _checkId($immediate, $id, $returnTo = null, $root = null, $extensions = null, Zend_Controller_Response_Abstract $response = null) { if (!Zend_OpenId::normalize($id)) { return false; } $claimedId = $id; if (!$this->_discovery($id, $server, $version)) { return false; } if (!$this->_associate($server, $version)) { return false; } if (!$this->_getAssociation($server, $handle, $macFunc, $secret, $expires)) { /* Use dumb mode */ unset($handle); unset($macFunc); unset($secret); unset($expires); } $params = array(); if ($version >= 2.0) { $params['openid.ns'] = Zend_OpenId::NS_2_0; } $params['openid.mode'] = $immediate ? 'checkid_immediate' : 'checkid_setup'; $params['openid.identity'] = $id; $params['openid.claimed_id'] = $claimedId; if (isset($handle)) { $params['openid.assoc_handle'] = $handle; } $params['openid.return_to'] = Zend_OpenId::absoluteUrl($returnTo); if (empty($root)) { $root = dirname(Zend_OpenId::selfUrl()); } if ($version >= 2.0) { $params['openid.realm'] = $root; } else { $params['openid.trust_root'] = $root; } if (!Zend_OpenId_Extension::forAll($extensions, 'prepareRequest', $params)) { return false; } Zend_OpenId::redirect($server, $params, $response); return true; }
/** * In CID we chose from the beginning not to use SET NAMES, and instead leave the charset encodings configurations * to remain in the database server side (my.cnf). * * CID's strings are UTF8. If character_set_client is not UTF8 but latin1 for example (unfortunatly that's the common case), non-latin1 * characters will appear garbled when manually browsing the db, but they should show OK in CID's web pages. * * When authenticating below, we use MySQL's MD5 function. From my tests, it looks like the argument of this function * gets automatically converted to the charset of that field. Sorta like if we had implicitly MD5(CONVERT(arg using charset)). * When the tables are build during setup, the charset of string fields are set accordingly to the my.cnf directives * character-set-server and collation-server. * If those directives don't match character_set_client, the conversion inside MD5 will in fact transform the string, and we'll * get the MD5 of a different string than what we had intended (well, only if the string contains non-latin1 characters). * For this reason we have to override that conversion, converting to the charset specified in character_set_client, as shown below. * * @return Zend_Auth_Result */ public function authenticate($identity, $password, $isOpenId = false, Zend_View $view = null, $bypassMarkSuccessfullLogin = false) { $config = Zend_Registry::get('config'); $useYubikey = false; if ($isOpenId) { if (!Zend_OpenId::normalize($identity)) { return false; } if (!($this->_user = $this->getUserWithOpenId($identity))) { return false; } $cn = $this->_user->username; } else { $cn = $identity; $this->_user = $this->getUserWithUsername($identity, false, $view); } if ($this->_user && $config->yubikey->enabled && ($this->_user->auth_type == Users_Model_User::AUTH_YUBIKEY || $config->yubikey->force)) { $parts = Yubico_Auth::parsePasswordOTP($password); if (!$parts || $this->_user->yubikey_publicid != $parts['prefix']) { return false; } $useYubikey = true; } $config = Zend_Registry::get('config'); $ldapConfig = $config->ldap; if ($useYubikey) { if (!@$config->yubikey->api_id || !@$config->yubikey->api_key) { throw new Zend_Exception('Admin must set the yubikey configuration options before attempting to log in using this method'); } $authAdapter = new Monkeys_Auth_Adapter_Yubikey(array('api_id' => $config->yubikey->api_id, 'api_key' => $config->yubikey->api_key), $identity, $password); } else { if ($ldapConfig->enabled) { $ldapOptions = $ldapConfig->toArray(); $ldapOptions['accountCanonicalForm'] = Zend_Ldap::ACCTNAME_FORM_USERNAME; unset($ldapOptions['enabled']); unset($ldapOptions['admin']); unset($ldapOptions['fields']); unset($ldapOptions['keepRecordsSynced']); unset($ldapOptions['canChangePassword']); unset($ldapOptions['passwordHashing']); // we'll try to bind directly as the user to be authenticated, so we're unsetting // the LDAP admin credentials unset($ldapOptions['username']); unset($ldapOptions['password']); $username = "******"; $authAdapter = new Zend_Auth_Adapter_Ldap(array('server1' => $ldapOptions), $username, $password); } else { $db = $this->getAdapter(); $result = $db->query("SHOW VARIABLES LIKE 'character_set_client'")->fetch(); $clientCharset = $result['Value']; if ($isOpenId) { $authAdapter = new Zend_Auth_Adapter_DbTable($db, 'users', 'openid', 'password', 'MD5(CONCAT(CONVERT(openid using ' . $clientCharset . '), CONVERT(? using ' . $clientCharset . ')))'); } else { $authAdapter = new Zend_Auth_Adapter_DbTable($db, 'users', 'username', 'password', 'MD5(CONCAT(CONVERT(openid using ' . $clientCharset . '), CONVERT(? using ' . $clientCharset . ')))'); } $authAdapter->setIdentity($identity); $authAdapter->setCredential($password); } } $auth = Zend_Auth::getInstance(); $result = $auth->authenticate($authAdapter); if ($result->isValid()) { if (!$isOpenId) { try { $this->_user = $this->getUserWithUsername($identity, true, $view); } catch (Exception $e) { // avoid leaving in the session an empty user object Zend_Auth::getInstance()->clearIdentity(); Zend_Session::forgetMe(); throw $e; } } if (!$bypassMarkSuccessfullLogin) { $this->_user->markSuccessfullLogin(); } $this->_user->save(); $auth->getStorage()->write($this->_user); Zend_Registry::set('user', $this->_user); return true; } // this is ugly, logging should be done in the controller, not here $logger = Zend_Registry::get('logger'); $logger->log("Invalid authentication: " . implode(' - ', $result->getMessages()), Zend_Log::DEBUG); if (is_a($authAdapter, 'Monkeys_Auth_Adapter_Yubikey')) { $authOptions = $authAdapter->getOptions(); if ($yubi = @$authOptions['yubiClient']) { $logger->log("Yubi request was: " . $yubi->getlastQuery(), Zend_Log::DEBUG); } } return false; }
/** * Performs check of OpenID identity. * * This is the first step of OpenID authentication process. * On success the function does not return (it does HTTP redirection to * server and exits). On failure it returns false. * * @param bool $immediate enables or disables interaction with user * @param string $id OpenID identity * @param string $returnTo HTTP URL to redirect response from server to * @param string $root HTTP URL to identify consumer on server * @param mixed $extensions extension object or array of extensions objects * @param Zend_Controller_Response_Abstract $response an optional response * object to perform HTTP or HTML form redirection * @return bool */ protected function _checkId($immediate, $id, $returnTo = null, $root = null, $extensions = null, Zend_Controller_Response_Abstract $response = null) { $this->_setError(''); if (!Zend_OpenId::normalize($id)) { $this->_setError("Normalisation failed"); return false; } $claimedId = $id; if (!$this->_discovery($id, $server, $version)) { $this->_setError("Discovery failed: " . $this->getError()); return false; } if (!$this->_associate($server, $version)) { $this->_setError("Association failed: " . $this->getError()); return false; } if (!$this->_getAssociation($server, $handle, $macFunc, $secret, $expires)) { /* Use dumb mode */ unset($handle); unset($macFunc); unset($secret); unset($expires); } $params = array(); if ($version >= 2.0) { $params['openid.ns'] = Zend_OpenId::NS_2_0; } $params['openid.mode'] = $immediate ? 'checkid_immediate' : 'checkid_setup'; $params['openid.identity'] = $id; $params['openid.claimed_id'] = $claimedId; if ($version <= 2.0) { if ($this->_session !== null) { $this->_session->identity = $id; $this->_session->claimed_id = $claimedId; if ($server == 'https://www.google.com/accounts/o8/ud') { $params['openid.identity'] = 'http://specs.openid.net/auth/2.0/identifier_select'; $params['openid.claimed_id'] = 'http://specs.openid.net/auth/2.0/identifier_select'; $params['openid.ns.ax'] = 'http://openid.net/srv/ax/1.0'; $params['openid.ax.mode'] = 'fetch_request'; $params['openid.ax.type.email'] = 'http://axschema.org/contact/email'; $params['openid.ax.type.country'] = 'http://axschema.org/contact/country/home'; $params['openid.ax.type.firstname'] = 'http://axschema.org/namePerson/first'; $params['openid.ax.type.lastname'] = 'http://axschema.org/namePerson/last'; $params['openid.ax.type.language'] = 'http://axschema.org/pref/language'; $params['openid.ax.required'] = 'country,firstname,email,language,lastname'; } } else { if (defined('SID')) { $_SESSION["zend_openid"] = array("identity" => $id, "claimed_id" => $claimedId); } else { require_once "Zend/Session/Namespace.php"; $this->_session = new Zend_Session_Namespace("zend_openid"); $this->_session->identity = $id; $this->_session->claimed_id = $claimedId; } } } if (isset($handle)) { $params['openid.assoc_handle'] = $handle; } $params['openid.return_to'] = Zend_OpenId::absoluteUrl($returnTo); if (empty($root)) { $root = Zend_OpenId::selfUrl(); if ($root[strlen($root) - 1] != '/') { $root = dirname($root); } } if ($version >= 2.0) { $params['openid.realm'] = $root; } else { $params['openid.trust_root'] = $root; } if (!Zend_OpenId_Extension::forAll($extensions, 'prepareRequest', $params)) { $this->_setError("Extension::prepareRequest failure"); return false; } Zend_OpenId::redirect($server, $params, $response); return true; }
/** * The constructor is called in three different ways and defines which step of * the OpenID auth process will be done: * * 1. $id, $verifyUrl and $redirectUrl are given - Login at provider * 2. $get is given - Verify the response * 3. $sReg is additionally given - Do not check the local store... We want to * register a new user. * * @param string $id * @param string $verifyUrl * @param string $redirectUrl * @param array $get * @param Zend_OpenId_Extension_Sreg */ public function __construct($id = null, $verifyUrl = null, $redirectUrl = null, $get = null, $sReg = null) { if (null !== $id) { // pass by reference Zend_OpenId::normalize($id); } $this->_id = $id; $this->_verifyUrl = $verifyUrl; $this->_redirectUrl = $redirectUrl; $this->_get = $get; $this->_sReg = $sReg; $app = Erfurt_App::getInstance(); $config = $app->getConfig(); $this->_acModelUri = $config->ac->modelUri; // load URIs from config $this->_uris = array('user_class' => $config->ac->user->class, 'user_username' => $config->ac->user->name, 'user_password' => $config->ac->user->pass, 'user_mail' => $config->ac->user->mail, 'user_superadmin' => $config->ac->user->superAdmin, 'user_anonymous' => $config->ac->user->anonymousUser, 'action_deny' => $config->ac->action->deny, 'action_login' => $config->ac->action->login); }