We are no longer offering accounts on this server. Consider https://gitlab.freedesktop.org/ as a place to host projects.

Commit 49b75591 authored by mattl's avatar mattl

Updating Janrain OpenID auth library

Source: https://github.com/openid/php-openid
parent f01c478a
......@@ -374,42 +374,7 @@ class Auth_OpenID_Association {
}
$calculated_sig = $this->getMessageSignature($message);
return $this->constantTimeCompare($calculated_sig, $sig);
}
/**
* String comparison function which will complete in a constant time
* for strings of any given matching length, to help prevent an attacker
* from distinguishing how much of a signature token they have guessed
* correctly.
*
* For this usage, it's assumed that the length of the string is known,
* so we may safely short-circuit on mismatched lengths which will be known
* to be invalid by the attacker.
*
* http://lists.openid.net/pipermail/openid-security/2010-July/001156.html
* http://rdist.root.org/2010/01/07/timing-independent-array-comparison/
*/
private function constantTimeCompare($a, $b)
{
$len = strlen($a);
if (strlen($b) !== $len) {
// Short-circuit on length mismatch; attackers will already know
// the correct target length so this is safe.
return false;
}
if ($len == 0) {
// 0-length valid input shouldn't really happen. :)
return true;
}
$result = 0;
for ($i = 0; $i < strlen($a); $i++) {
// We use scary bitwise operations to avoid logical short-circuits
// in lower-level code.
$result |= ord($a{$i}) ^ ord($b{$i});
}
return ($result == 0);
return Auth_OpenID_CryptUtil::constEq($calculated_sig, $sig);
}
}
......
......@@ -365,7 +365,6 @@ function Auth_OpenID_detectMathLibrary($exts)
{
$loaded = false;
$hasDl = function_exists('dl');
foreach ($exts as $extension) {
if (extension_loaded($extension['extension'])) {
return $extension;
......
......@@ -957,6 +957,10 @@ class Auth_OpenID_GenericConsumer {
}
if (!$assoc->checkMessageSignature($message)) {
// If we get a "bad signature" here, it means that the association
// is unrecoverabley corrupted in some way. Any futher attempts
// to login with this association is likely to fail. Drop it.
$this->store->removeAssociation($server_url, $assoc_handle);
return new Auth_OpenID_FailureResponse(null,
"Bad signature");
}
......@@ -1179,9 +1183,11 @@ class Auth_OpenID_GenericConsumer {
function _discoverAndVerify($claimed_id, $to_match_endpoints)
{
// oidutil.log('Performing discovery on %s' % (claimed_id,))
list($unused, $services) = call_user_func($this->discoverMethod,
$claimed_id,
&$this->fetcher);
list($unused, $services) = call_user_func_array($this->discoverMethod,
array(
$claimed_id,
&$this->fetcher,
));
if (!$services) {
return new Auth_OpenID_FailureResponse(null,
......
......@@ -104,5 +104,19 @@ class Auth_OpenID_CryptUtil {
return $str;
}
static function constEq($s1, $s2)
{
if (strlen($s1) != strlen($s2)) {
return false;
}
$result = true;
$length = strlen($s1);
for ($i = 0; $i < $length; $i++) {
$result &= ($s1[$i] == $s2[$i]);
}
return $result;
}
}
......@@ -39,7 +39,7 @@ class Auth_OpenID_Extension {
*
* Returns the message with the extension arguments added.
*/
function toMessage($message)
function toMessage($message, $request = null)
{
$implicit = $message->isOpenID1();
$added = $message->namespaces->addAlias($this->ns_uri,
......@@ -53,8 +53,13 @@ class Auth_OpenID_Extension {
}
}
$message->updateArgs($this->ns_uri,
$this->getExtensionArgs());
if ($request !== null) {
$message->updateArgs($this->ns_uri,
$this->getExtensionArgs($request));
} else {
$message->updateArgs($this->ns_uri,
$this->getExtensionArgs());
}
return $message;
}
}
......
......@@ -300,13 +300,22 @@ class Auth_OpenID_FileStore extends Auth_OpenID_OpenIDStore {
return null;
}
if (file_exists($filename) !== true) {
return null;
}
$assoc_file = @fopen($filename, 'rb');
if ($assoc_file === false) {
return null;
}
$assoc_s = fread($assoc_file, filesize($filename));
$filesize = filesize($filename);
if ($filesize === false || $filesize <= 0) {
return null;
}
$assoc_s = fread($assoc_file, $filesize);
fclose($assoc_file);
if (!$assoc_s) {
......
......@@ -60,6 +60,13 @@ function Auth_OpenID_HMACSHA1($key, $text)
$key = Auth_OpenID_SHA1($key, true);
}
if (function_exists('hash_hmac') &&
function_exists('hash_algos') &&
(in_array('sha1', hash_algos()))) {
return hash_hmac('sha1', $text, $key, true);
}
// Home-made solution
$key = str_pad($key, Auth_OpenID_SHA1_BLOCKSIZE, chr(0x00));
$ipad = str_repeat(chr(0x36), Auth_OpenID_SHA1_BLOCKSIZE);
$opad = str_repeat(chr(0x5c), Auth_OpenID_SHA1_BLOCKSIZE);
......
This diff is collapsed.
......@@ -675,7 +675,7 @@ class Auth_OpenID_Message {
if ($form_tag_attrs) {
foreach ($form_tag_attrs as $name => $attr) {
$form .= sprintf(" %s=\"%s\"", $name, $attr);
$form .= sprintf(" %s=\"%s\"", $name, htmlspecialchars($attr));
}
}
......@@ -684,11 +684,11 @@ class Auth_OpenID_Message {
foreach ($this->toPostArgs() as $name => $value) {
$form .= sprintf(
"<input type=\"hidden\" name=\"%s\" value=\"%s\" />\n",
$name, $value);
htmlspecialchars($name), htmlspecialchars($value));
}
$form .= sprintf("<input type=\"submit\" value=\"%s\" />\n",
$submit_text);
htmlspecialchars($submit_text));
$form .= "</form>\n";
......
......@@ -32,7 +32,7 @@ class Auth_OpenID_MySQLStore extends Auth_OpenID_SQLStore {
$this->sql['assoc_table'] =
"CREATE TABLE %s (\n".
" server_url BLOB NOT NULL,\n".
" server_url VARCHAR(2047) NOT NULL,\n".
" handle VARCHAR(255) NOT NULL,\n".
" secret BLOB NOT NULL,\n".
" issued INTEGER NOT NULL,\n".
......
......@@ -219,7 +219,11 @@ class Auth_OpenID_Parse {
function match($regexp, $text, &$match)
{
if (!is_callable('mb_ereg_search_init')) {
return preg_match($regexp, $text, $match);
if (!preg_match($regexp, $text, $match)) {
return false;
}
$match = $match[0];
return true;
}
$regexp = substr($regexp, 1, strlen($regexp) - 2 - strlen($this->_re_flags));
......@@ -227,7 +231,7 @@ class Auth_OpenID_Parse {
if (!mb_ereg_search($regexp)) {
return false;
}
list($match) = mb_ereg_search_getregs();
$match = mb_ereg_search_getregs();
return true;
}
......@@ -269,7 +273,7 @@ class Auth_OpenID_Parse {
// Try to find the <HEAD> tag.
$head_re = $this->headFind();
$head_match = '';
$head_match = array();
if (!$this->match($head_re, $stripped, $head_match)) {
ini_set( 'pcre.backtrack_limit', $old_btlimit );
return array();
......@@ -278,7 +282,7 @@ class Auth_OpenID_Parse {
$link_data = array();
$link_matches = array();
if (!preg_match_all($this->_link_find, $head_match,
if (!preg_match_all($this->_link_find, $head_match[0],
$link_matches)) {
ini_set( 'pcre.backtrack_limit', $old_btlimit );
return array();
......
<?php
/**
* Supplies Redis server store backend for OpenID servers and consumers.
* Uses Predis library {@see https://github.com/nrk/predis}.
* Requires PHP >= 5.3.
*
* LICENSE: See the COPYING file included in this distribution.
*
* @package OpenID
* @author Ville Mattila <ville@eventio.fi>
* @copyright 2008 JanRain Inc., 2013 Eventio Oy / Ville Mattila
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache
* Contributed by Eventio Oy <http://www.eventio.fi/>
*/
/**
* Import the interface for creating a new store class.
*/
require_once 'Auth/OpenID/Interface.php';
/**
* Supplies Redis server store backend for OpenID servers and consumers.
* Uses Predis library {@see https://github.com/nrk/predis}.
* Requires PHP >= 5.3.
*
* @package OpenID
*/
class Auth_OpenID_PredisStore extends Auth_OpenID_OpenIDStore {
/**
* @var \Predis\Client
*/
protected $redis;
/**
* Prefix for Redis keys
* @var string
*/
protected $prefix;
/**
* Initializes a new {@link Auth_OpenID_PredisStore} instance.
*
* @param \Predis\Client $redis Predis client object
* @param string $prefix Prefix for all keys stored to the Redis
*/
function Auth_OpenID_PredisStore(\Predis\Client $redis, $prefix = '')
{
$this->prefix = $prefix;
$this->redis = $redis;
}
/**
* Store association until its expiration time in Redis server.
* Overwrites any existing association with same server_url and
* handle. Handles list of associations for every server.
*/
function storeAssociation($server_url, $association)
{
// create Redis keys for association itself
// and list of associations for this server
$associationKey = $this->associationKey($server_url,
$association->handle);
$serverKey = $this->associationServerKey($server_url);
// save association to server's associations' keys list
$this->redis->lpush(
$serverKey,
$associationKey
);
// Will touch the association list expiration, to avoid filling up
$newExpiration = ($association->issued + $association->lifetime);
$expirationKey = $serverKey.'_expires_at';
$expiration = $this->redis->get($expirationKey);
if (!$expiration || $newExpiration > $expiration) {
$this->redis->set($expirationKey, $newExpiration);
$this->redis->expireat($serverKey, $newExpiration);
$this->redis->expireat($expirationKey, $newExpiration);
}
// save association itself, will automatically expire
$this->redis->setex(
$associationKey,
$newExpiration - time(),
serialize($association)
);
}
/**
* Read association from Redis. If no handle given
* and multiple associations found, returns latest issued
*/
function getAssociation($server_url, $handle = null)
{
// simple case: handle given
if ($handle !== null) {
return $this->getAssociationFromServer(
$this->associationKey($server_url, $handle)
);
}
// no handle given, receiving the latest issued
$serverKey = $this->associationServerKey($server_url);
$lastKey = $this->redis->lpop($serverKey);
if (!$lastKey) { return null; }
// get association, return null if failed
return $this->getAssociationFromServer($lastKey);
}
/**
* Function to actually receive and unserialize the association
* from the server.
*/
private function getAssociationFromServer($associationKey)
{
$association = $this->redis->get($associationKey);
return $association ? unserialize($association) : null;
}
/**
* Immediately delete association from Redis.
*/
function removeAssociation($server_url, $handle)
{
// create Redis keys
$serverKey = $this->associationServerKey($server_url);
$associationKey = $this->associationKey($server_url,
$handle);
// Removing the association from the server's association list
$removed = $this->redis->lrem($serverKey, 0, $associationKey);
if ($removed < 1) {
return false;
}
// Delete the association itself
return $this->redis->del($associationKey);
}
/**
* Create nonce for server and salt, expiring after
* $Auth_OpenID_SKEW seconds.
*/
function useNonce($server_url, $timestamp, $salt)
{
global $Auth_OpenID_SKEW;
// save one request to memcache when nonce obviously expired
if (abs($timestamp - time()) > $Auth_OpenID_SKEW) {
return false;
}
// SETNX will set the value only of the key doesn't exist yet.
$nonceKey = $this->nonceKey($server_url, $salt);
$added = $this->predis->setnx($nonceKey);
if ($added) {
// Will set expiration
$this->predis->expire($nonceKey, $Auth_OpenID_SKEW);
return true;
} else {
return false;
}
}
/**
* Build up nonce key
*/
private function nonceKey($server_url, $salt)
{
return $this->prefix .
'openid_nonce_' .
sha1($server_url) . '_' . sha1($salt);
}
/**
* Key is prefixed with $prefix and 'openid_association_' string
*/
function associationKey($server_url, $handle = null)
{
return $this->prefix .
'openid_association_' .
sha1($server_url) . '_' . sha1($handle);
}
/**
* Key is prefixed with $prefix and 'openid_association_server_' string
*/
function associationServerKey($server_url)
{
return $this->prefix .
'openid_association_server_' .
sha1($server_url);
}
/**
* Report that this storage doesn't support cleanup
*/
function supportsCleanup()
{
return false;
}
}
......@@ -166,7 +166,7 @@ class Auth_OpenID_SQLStore extends Auth_OpenID_OpenIDStore {
*/
function isError($value)
{
return PEAR::isError($value);
return @PEAR::isError($value);
}
/**
......
......@@ -817,11 +817,11 @@ class Auth_OpenID_CheckIDRequest extends Auth_OpenID_Request {
*/
function returnToVerified()
{
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
return call_user_func_array($this->verifyReturnTo,
array($this->trust_root, $this->return_to, $fetcher));
}
static function fromMessage($message, $server)
{
$mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode');
......@@ -1704,7 +1704,7 @@ class Auth_OpenID_Server {
{
if (method_exists($this, "openid_" . $request->mode)) {
$handler = array($this, "openid_" . $request->mode);
return call_user_func($handler, &$request);
return call_user_func_array($handler, array($request));
}
return null;
}
......
......@@ -37,7 +37,7 @@ class Auth_Yadis_PHPSession {
*/
function get($name, $default=null)
{
if (array_key_exists($name, $_SESSION)) {
if (isset($_SESSION) && array_key_exists($name, $_SESSION)) {
return $_SESSION[$name];
} else {
return $default;
......@@ -411,9 +411,11 @@ class Auth_Yadis_Discovery {
if (!$manager || (!$manager->services)) {
$this->destroyManager();
list($yadis_url, $services) = call_user_func($discover_cb,
$this->url,
&$fetcher);
list($yadis_url, $services) = call_user_func_array($discover_cb,
array(
$this->url,
&$fetcher,
));
$manager = $this->createManager($services, $yadis_url);
}
......
......@@ -129,8 +129,20 @@ class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
curl_setopt($c, CURLOPT_URL, $url);
if (defined('Auth_OpenID_VERIFY_HOST')) {
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
// set SSL verification options only if Auth_OpenID_VERIFY_HOST
// is explicitly set, otherwise use system default.
if (Auth_OpenID_VERIFY_HOST) {
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
if (defined('Auth_OpenID_CAINFO')) {
curl_setopt($c, CURLOPT_CAINFO, Auth_OpenID_CAINFO);
}
} else {
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
}
}
if (defined('Auth_OpenID_HTTP_PROXY')) {
curl_setopt($c, CURLOPT_PROXY, Auth_OpenID_HTTP_PROXY);
}
curl_exec($c);
......@@ -153,6 +165,7 @@ class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
curl_close($c);
if (defined('Auth_OpenID_VERIFY_HOST') &&
Auth_OpenID_VERIFY_HOST == true &&
$this->isHTTPS($url)) {
Auth_OpenID::log('OpenID: Verified SSL host %s using '.
'curl/get', $url);
......@@ -166,10 +179,6 @@ class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
}
}
Auth_OpenID::log(
"Successfully fetched '%s': GET response code %s",
$url, $code);
return new Auth_Yadis_HTTPResponse($url, $code,
$new_headers, $body);
}
......@@ -194,6 +203,10 @@ class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
curl_setopt($c, CURLOPT_NOSIGNAL, true);
}
if (defined('Auth_OpenID_HTTP_PROXY')) {
curl_setopt($c, CURLOPT_PROXY, Auth_OpenID_HTTP_PROXY);
}
curl_setopt($c, CURLOPT_POST, true);
curl_setopt($c, CURLOPT_POSTFIELDS, $body);
curl_setopt($c, CURLOPT_TIMEOUT, $this->timeout);
......@@ -202,8 +215,17 @@ class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
array($this, "_writeData"));
if (defined('Auth_OpenID_VERIFY_HOST')) {
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
// set SSL verification options only if Auth_OpenID_VERIFY_HOST
// is explicitly set, otherwise use system default.
if (Auth_OpenID_VERIFY_HOST) {
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
if (defined('Auth_OpenID_CAINFO')) {
curl_setopt($c, CURLOPT_CAINFO, Auth_OpenID_CAINFO);
}
} else {
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
}
}
curl_exec($c);
......@@ -217,7 +239,9 @@ class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
return null;
}
if (defined('Auth_OpenID_VERIFY_HOST') && $this->isHTTPS($url)) {
if (defined('Auth_OpenID_VERIFY_HOST') &&
Auth_OpenID_VERIFY_HOST == true &&
$this->isHTTPS($url)) {
Auth_OpenID::log('OpenID: Verified SSL host %s using '.
'curl/post', $url);
}
......@@ -235,9 +259,6 @@ class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
}
Auth_OpenID::log("Successfully fetched '%s': POST response code %s",
$url, $code);
return new Auth_Yadis_HTTPResponse($url, $code,
$new_headers, $body);
}
......
......@@ -234,7 +234,19 @@ class Auth_Yadis_dom extends Auth_Yadis_XMLParser {
return false;
}
if (!@$this->doc->loadXML($xml_string)) {
// libxml_disable_entity_loader (PHP 5 >= 5.2.11)
if (function_exists('libxml_disable_entity_loader') && function_exists('libxml_use_internal_errors')) {
// disable external entities and libxml errors
$loader = libxml_disable_entity_loader(true);
$errors = libxml_use_internal_errors(true);
$parse_result = @$this->doc->loadXML($xml_string);
libxml_disable_entity_loader($loader);
libxml_use_internal_errors($errors);
} else {
$parse_result = @$this->doc->loadXML($xml_string);
}
if (!$parse_result) {
return false;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment