forked from GNUsocial/gnu-social
Updating Janrain OpenID auth library
Source: https://github.com/openid/php-openid
This commit is contained in:
parent
f01c478aab
commit
49b755912f
@ -374,42 +374,7 @@ class Auth_OpenID_Association {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$calculated_sig = $this->getMessageSignature($message);
|
$calculated_sig = $this->getMessageSignature($message);
|
||||||
|
return Auth_OpenID_CryptUtil::constEq($calculated_sig, $sig);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,7 +365,6 @@ function Auth_OpenID_detectMathLibrary($exts)
|
|||||||
{
|
{
|
||||||
$loaded = false;
|
$loaded = false;
|
||||||
|
|
||||||
$hasDl = function_exists('dl');
|
|
||||||
foreach ($exts as $extension) {
|
foreach ($exts as $extension) {
|
||||||
if (extension_loaded($extension['extension'])) {
|
if (extension_loaded($extension['extension'])) {
|
||||||
return $extension;
|
return $extension;
|
||||||
|
@ -957,6 +957,10 @@ class Auth_OpenID_GenericConsumer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!$assoc->checkMessageSignature($message)) {
|
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,
|
return new Auth_OpenID_FailureResponse(null,
|
||||||
"Bad signature");
|
"Bad signature");
|
||||||
}
|
}
|
||||||
@ -1179,9 +1183,11 @@ class Auth_OpenID_GenericConsumer {
|
|||||||
function _discoverAndVerify($claimed_id, $to_match_endpoints)
|
function _discoverAndVerify($claimed_id, $to_match_endpoints)
|
||||||
{
|
{
|
||||||
// oidutil.log('Performing discovery on %s' % (claimed_id,))
|
// oidutil.log('Performing discovery on %s' % (claimed_id,))
|
||||||
list($unused, $services) = call_user_func($this->discoverMethod,
|
list($unused, $services) = call_user_func_array($this->discoverMethod,
|
||||||
$claimed_id,
|
array(
|
||||||
&$this->fetcher);
|
$claimed_id,
|
||||||
|
&$this->fetcher,
|
||||||
|
));
|
||||||
|
|
||||||
if (!$services) {
|
if (!$services) {
|
||||||
return new Auth_OpenID_FailureResponse(null,
|
return new Auth_OpenID_FailureResponse(null,
|
||||||
|
@ -104,5 +104,19 @@ class Auth_OpenID_CryptUtil {
|
|||||||
|
|
||||||
return $str;
|
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.
|
* Returns the message with the extension arguments added.
|
||||||
*/
|
*/
|
||||||
function toMessage($message)
|
function toMessage($message, $request = null)
|
||||||
{
|
{
|
||||||
$implicit = $message->isOpenID1();
|
$implicit = $message->isOpenID1();
|
||||||
$added = $message->namespaces->addAlias($this->ns_uri,
|
$added = $message->namespaces->addAlias($this->ns_uri,
|
||||||
@ -53,8 +53,13 @@ class Auth_OpenID_Extension {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$message->updateArgs($this->ns_uri,
|
if ($request !== null) {
|
||||||
$this->getExtensionArgs());
|
$message->updateArgs($this->ns_uri,
|
||||||
|
$this->getExtensionArgs($request));
|
||||||
|
} else {
|
||||||
|
$message->updateArgs($this->ns_uri,
|
||||||
|
$this->getExtensionArgs());
|
||||||
|
}
|
||||||
return $message;
|
return $message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -300,13 +300,22 @@ class Auth_OpenID_FileStore extends Auth_OpenID_OpenIDStore {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (file_exists($filename) !== true) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
$assoc_file = @fopen($filename, 'rb');
|
$assoc_file = @fopen($filename, 'rb');
|
||||||
|
|
||||||
if ($assoc_file === false) {
|
if ($assoc_file === false) {
|
||||||
return null;
|
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);
|
fclose($assoc_file);
|
||||||
|
|
||||||
if (!$assoc_s) {
|
if (!$assoc_s) {
|
||||||
|
@ -60,6 +60,13 @@ function Auth_OpenID_HMACSHA1($key, $text)
|
|||||||
$key = Auth_OpenID_SHA1($key, true);
|
$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));
|
$key = str_pad($key, Auth_OpenID_SHA1_BLOCKSIZE, chr(0x00));
|
||||||
$ipad = str_repeat(chr(0x36), Auth_OpenID_SHA1_BLOCKSIZE);
|
$ipad = str_repeat(chr(0x36), Auth_OpenID_SHA1_BLOCKSIZE);
|
||||||
$opad = str_repeat(chr(0x5c), Auth_OpenID_SHA1_BLOCKSIZE);
|
$opad = str_repeat(chr(0x5c), Auth_OpenID_SHA1_BLOCKSIZE);
|
||||||
|
413
extlib/Auth/OpenID/MDB2Store.php
Normal file
413
extlib/Auth/OpenID/MDB2Store.php
Normal file
@ -0,0 +1,413 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SQL-backed OpenID stores for use with PEAR::MDB2.
|
||||||
|
*
|
||||||
|
* PHP versions 4 and 5
|
||||||
|
*
|
||||||
|
* LICENSE: See the COPYING file included in this distribution.
|
||||||
|
*
|
||||||
|
* @package OpenID
|
||||||
|
* @author JanRain, Inc. <openid@janrain.com>
|
||||||
|
* @copyright 2005 Janrain, Inc.
|
||||||
|
* @license http://www.gnu.org/copyleft/lesser.html LGPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
require_once 'MDB2.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
require_once 'Auth/OpenID/Interface.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
require_once 'Auth/OpenID.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @access private
|
||||||
|
*/
|
||||||
|
require_once 'Auth/OpenID/Nonce.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This store uses a PEAR::MDB2 connection to store persistence
|
||||||
|
* information.
|
||||||
|
*
|
||||||
|
* The table names used are determined by the class variables
|
||||||
|
* associations_table_name and nonces_table_name. To change the name
|
||||||
|
* of the tables used, pass new table names into the constructor.
|
||||||
|
*
|
||||||
|
* To create the tables with the proper schema, see the createTables
|
||||||
|
* method.
|
||||||
|
*
|
||||||
|
* @package OpenID
|
||||||
|
*/
|
||||||
|
class Auth_OpenID_MDB2Store extends Auth_OpenID_OpenIDStore {
|
||||||
|
/**
|
||||||
|
* This creates a new MDB2Store instance. It requires an
|
||||||
|
* established database connection be given to it, and it allows
|
||||||
|
* overriding the default table names.
|
||||||
|
*
|
||||||
|
* @param connection $connection This must be an established
|
||||||
|
* connection to a database of the correct type for the SQLStore
|
||||||
|
* subclass you're using. This must be a PEAR::MDB2 connection
|
||||||
|
* handle.
|
||||||
|
*
|
||||||
|
* @param associations_table: This is an optional parameter to
|
||||||
|
* specify the name of the table used for storing associations.
|
||||||
|
* The default value is 'oid_associations'.
|
||||||
|
*
|
||||||
|
* @param nonces_table: This is an optional parameter to specify
|
||||||
|
* the name of the table used for storing nonces. The default
|
||||||
|
* value is 'oid_nonces'.
|
||||||
|
*/
|
||||||
|
function Auth_OpenID_MDB2Store($connection,
|
||||||
|
$associations_table = null,
|
||||||
|
$nonces_table = null)
|
||||||
|
{
|
||||||
|
$this->associations_table_name = "oid_associations";
|
||||||
|
$this->nonces_table_name = "oid_nonces";
|
||||||
|
|
||||||
|
// Check the connection object type to be sure it's a PEAR
|
||||||
|
// database connection.
|
||||||
|
if (!is_object($connection) ||
|
||||||
|
!is_subclass_of($connection, 'mdb2_driver_common')) {
|
||||||
|
trigger_error("Auth_OpenID_MDB2Store expected PEAR connection " .
|
||||||
|
"object (got ".get_class($connection).")",
|
||||||
|
E_USER_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->connection = $connection;
|
||||||
|
|
||||||
|
// Be sure to set the fetch mode so the results are keyed on
|
||||||
|
// column name instead of column index.
|
||||||
|
$this->connection->setFetchMode(MDB2_FETCHMODE_ASSOC);
|
||||||
|
|
||||||
|
if (@PEAR::isError($this->connection->loadModule('Extended'))) {
|
||||||
|
trigger_error("Unable to load MDB2_Extended module", E_USER_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($associations_table) {
|
||||||
|
$this->associations_table_name = $associations_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($nonces_table) {
|
||||||
|
$this->nonces_table_name = $nonces_table;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->max_nonce_age = 6 * 60 * 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
function tableExists($table_name)
|
||||||
|
{
|
||||||
|
return !@PEAR::isError($this->connection->query(
|
||||||
|
sprintf("SELECT * FROM %s LIMIT 0",
|
||||||
|
$table_name)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function createTables()
|
||||||
|
{
|
||||||
|
$n = $this->create_nonce_table();
|
||||||
|
$a = $this->create_assoc_table();
|
||||||
|
|
||||||
|
if (!$n || !$a) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_nonce_table()
|
||||||
|
{
|
||||||
|
if (!$this->tableExists($this->nonces_table_name)) {
|
||||||
|
switch ($this->connection->phptype) {
|
||||||
|
case "mysql":
|
||||||
|
case "mysqli":
|
||||||
|
// Custom SQL for MySQL to use InnoDB and variable-
|
||||||
|
// length keys
|
||||||
|
$r = $this->connection->exec(
|
||||||
|
sprintf("CREATE TABLE %s (\n".
|
||||||
|
" server_url VARCHAR(2047) NOT NULL DEFAULT '',\n".
|
||||||
|
" timestamp INTEGER NOT NULL,\n".
|
||||||
|
" salt CHAR(40) NOT NULL,\n".
|
||||||
|
" UNIQUE (server_url(255), timestamp, salt)\n".
|
||||||
|
") TYPE=InnoDB",
|
||||||
|
$this->nonces_table_name));
|
||||||
|
if (@PEAR::isError($r)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (@PEAR::isError(
|
||||||
|
$this->connection->loadModule('Manager'))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$fields = array(
|
||||||
|
"server_url" => array(
|
||||||
|
"type" => "text",
|
||||||
|
"length" => 2047,
|
||||||
|
"notnull" => true
|
||||||
|
),
|
||||||
|
"timestamp" => array(
|
||||||
|
"type" => "integer",
|
||||||
|
"notnull" => true
|
||||||
|
),
|
||||||
|
"salt" => array(
|
||||||
|
"type" => "text",
|
||||||
|
"length" => 40,
|
||||||
|
"fixed" => true,
|
||||||
|
"notnull" => true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$constraint = array(
|
||||||
|
"unique" => 1,
|
||||||
|
"fields" => array(
|
||||||
|
"server_url" => true,
|
||||||
|
"timestamp" => true,
|
||||||
|
"salt" => true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$r = $this->connection->createTable($this->nonces_table_name,
|
||||||
|
$fields);
|
||||||
|
if (@PEAR::isError($r)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = $this->connection->createConstraint(
|
||||||
|
$this->nonces_table_name,
|
||||||
|
$this->nonces_table_name . "_constraint",
|
||||||
|
$constraint);
|
||||||
|
if (@PEAR::isError($r)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_assoc_table()
|
||||||
|
{
|
||||||
|
if (!$this->tableExists($this->associations_table_name)) {
|
||||||
|
switch ($this->connection->phptype) {
|
||||||
|
case "mysql":
|
||||||
|
case "mysqli":
|
||||||
|
// Custom SQL for MySQL to use InnoDB and variable-
|
||||||
|
// length keys
|
||||||
|
$r = $this->connection->exec(
|
||||||
|
sprintf("CREATE TABLE %s(\n".
|
||||||
|
" server_url VARCHAR(2047) NOT NULL DEFAULT '',\n".
|
||||||
|
" handle VARCHAR(255) NOT NULL,\n".
|
||||||
|
" secret BLOB NOT NULL,\n".
|
||||||
|
" issued INTEGER NOT NULL,\n".
|
||||||
|
" lifetime INTEGER NOT NULL,\n".
|
||||||
|
" assoc_type VARCHAR(64) NOT NULL,\n".
|
||||||
|
" PRIMARY KEY (server_url(255), handle)\n".
|
||||||
|
") TYPE=InnoDB",
|
||||||
|
$this->associations_table_name));
|
||||||
|
if (@PEAR::isError($r)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (@PEAR::isError(
|
||||||
|
$this->connection->loadModule('Manager'))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$fields = array(
|
||||||
|
"server_url" => array(
|
||||||
|
"type" => "text",
|
||||||
|
"length" => 2047,
|
||||||
|
"notnull" => true
|
||||||
|
),
|
||||||
|
"handle" => array(
|
||||||
|
"type" => "text",
|
||||||
|
"length" => 255,
|
||||||
|
"notnull" => true
|
||||||
|
),
|
||||||
|
"secret" => array(
|
||||||
|
"type" => "blob",
|
||||||
|
"length" => "255",
|
||||||
|
"notnull" => true
|
||||||
|
),
|
||||||
|
"issued" => array(
|
||||||
|
"type" => "integer",
|
||||||
|
"notnull" => true
|
||||||
|
),
|
||||||
|
"lifetime" => array(
|
||||||
|
"type" => "integer",
|
||||||
|
"notnull" => true
|
||||||
|
),
|
||||||
|
"assoc_type" => array(
|
||||||
|
"type" => "text",
|
||||||
|
"length" => 64,
|
||||||
|
"notnull" => true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
$options = array(
|
||||||
|
"primary" => array(
|
||||||
|
"server_url" => true,
|
||||||
|
"handle" => true
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$r = $this->connection->createTable(
|
||||||
|
$this->associations_table_name,
|
||||||
|
$fields,
|
||||||
|
$options);
|
||||||
|
if (@PEAR::isError($r)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function storeAssociation($server_url, $association)
|
||||||
|
{
|
||||||
|
$fields = array(
|
||||||
|
"server_url" => array(
|
||||||
|
"value" => $server_url,
|
||||||
|
"key" => true
|
||||||
|
),
|
||||||
|
"handle" => array(
|
||||||
|
"value" => $association->handle,
|
||||||
|
"key" => true
|
||||||
|
),
|
||||||
|
"secret" => array(
|
||||||
|
"value" => $association->secret,
|
||||||
|
"type" => "blob"
|
||||||
|
),
|
||||||
|
"issued" => array(
|
||||||
|
"value" => $association->issued
|
||||||
|
),
|
||||||
|
"lifetime" => array(
|
||||||
|
"value" => $association->lifetime
|
||||||
|
),
|
||||||
|
"assoc_type" => array(
|
||||||
|
"value" => $association->assoc_type
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return !@PEAR::isError($this->connection->replace(
|
||||||
|
$this->associations_table_name,
|
||||||
|
$fields));
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanupNonces()
|
||||||
|
{
|
||||||
|
global $Auth_OpenID_SKEW;
|
||||||
|
$v = time() - $Auth_OpenID_SKEW;
|
||||||
|
|
||||||
|
return $this->connection->exec(
|
||||||
|
sprintf("DELETE FROM %s WHERE timestamp < %d",
|
||||||
|
$this->nonces_table_name, $v));
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanupAssociations()
|
||||||
|
{
|
||||||
|
return $this->connection->exec(
|
||||||
|
sprintf("DELETE FROM %s WHERE issued + lifetime < %d",
|
||||||
|
$this->associations_table_name, time()));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAssociation($server_url, $handle = null)
|
||||||
|
{
|
||||||
|
$sql = "";
|
||||||
|
$params = null;
|
||||||
|
$types = array(
|
||||||
|
"text",
|
||||||
|
"blob",
|
||||||
|
"integer",
|
||||||
|
"integer",
|
||||||
|
"text"
|
||||||
|
);
|
||||||
|
if ($handle !== null) {
|
||||||
|
$sql = sprintf("SELECT handle, secret, issued, lifetime, assoc_type " .
|
||||||
|
"FROM %s WHERE server_url = ? AND handle = ?",
|
||||||
|
$this->associations_table_name);
|
||||||
|
$params = array($server_url, $handle);
|
||||||
|
} else {
|
||||||
|
$sql = sprintf("SELECT handle, secret, issued, lifetime, assoc_type " .
|
||||||
|
"FROM %s WHERE server_url = ? ORDER BY issued DESC",
|
||||||
|
$this->associations_table_name);
|
||||||
|
$params = array($server_url);
|
||||||
|
}
|
||||||
|
|
||||||
|
$assoc = $this->connection->getRow($sql, $types, $params);
|
||||||
|
|
||||||
|
if (!$assoc || @PEAR::isError($assoc)) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
$association = new Auth_OpenID_Association($assoc['handle'],
|
||||||
|
stream_get_contents(
|
||||||
|
$assoc['secret']),
|
||||||
|
$assoc['issued'],
|
||||||
|
$assoc['lifetime'],
|
||||||
|
$assoc['assoc_type']);
|
||||||
|
fclose($assoc['secret']);
|
||||||
|
return $association;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeAssociation($server_url, $handle)
|
||||||
|
{
|
||||||
|
$r = $this->connection->execParam(
|
||||||
|
sprintf("DELETE FROM %s WHERE server_url = ? AND handle = ?",
|
||||||
|
$this->associations_table_name),
|
||||||
|
array($server_url, $handle));
|
||||||
|
|
||||||
|
if (@PEAR::isError($r) || $r == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function useNonce($server_url, $timestamp, $salt)
|
||||||
|
{
|
||||||
|
global $Auth_OpenID_SKEW;
|
||||||
|
|
||||||
|
if (abs($timestamp - time()) > $Auth_OpenID_SKEW ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fields = array(
|
||||||
|
"timestamp" => $timestamp,
|
||||||
|
"salt" => $salt
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!empty($server_url)) {
|
||||||
|
$fields["server_url"] = $server_url;
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = $this->connection->autoExecute(
|
||||||
|
$this->nonces_table_name,
|
||||||
|
$fields,
|
||||||
|
MDB2_AUTOQUERY_INSERT);
|
||||||
|
|
||||||
|
if (@PEAR::isError($r)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the store by removing all records from the store's
|
||||||
|
* tables.
|
||||||
|
*/
|
||||||
|
function reset()
|
||||||
|
{
|
||||||
|
$this->connection->query(sprintf("DELETE FROM %s",
|
||||||
|
$this->associations_table_name));
|
||||||
|
|
||||||
|
$this->connection->query(sprintf("DELETE FROM %s",
|
||||||
|
$this->nonces_table_name));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
@ -675,7 +675,7 @@ class Auth_OpenID_Message {
|
|||||||
|
|
||||||
if ($form_tag_attrs) {
|
if ($form_tag_attrs) {
|
||||||
foreach ($form_tag_attrs as $name => $attr) {
|
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) {
|
foreach ($this->toPostArgs() as $name => $value) {
|
||||||
$form .= sprintf(
|
$form .= sprintf(
|
||||||
"<input type=\"hidden\" name=\"%s\" value=\"%s\" />\n",
|
"<input type=\"hidden\" name=\"%s\" value=\"%s\" />\n",
|
||||||
$name, $value);
|
htmlspecialchars($name), htmlspecialchars($value));
|
||||||
}
|
}
|
||||||
|
|
||||||
$form .= sprintf("<input type=\"submit\" value=\"%s\" />\n",
|
$form .= sprintf("<input type=\"submit\" value=\"%s\" />\n",
|
||||||
$submit_text);
|
htmlspecialchars($submit_text));
|
||||||
|
|
||||||
$form .= "</form>\n";
|
$form .= "</form>\n";
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class Auth_OpenID_MySQLStore extends Auth_OpenID_SQLStore {
|
|||||||
|
|
||||||
$this->sql['assoc_table'] =
|
$this->sql['assoc_table'] =
|
||||||
"CREATE TABLE %s (\n".
|
"CREATE TABLE %s (\n".
|
||||||
" server_url BLOB NOT NULL,\n".
|
" server_url VARCHAR(2047) NOT NULL,\n".
|
||||||
" handle VARCHAR(255) NOT NULL,\n".
|
" handle VARCHAR(255) NOT NULL,\n".
|
||||||
" secret BLOB NOT NULL,\n".
|
" secret BLOB NOT NULL,\n".
|
||||||
" issued INTEGER NOT NULL,\n".
|
" issued INTEGER NOT NULL,\n".
|
||||||
|
@ -219,7 +219,11 @@ class Auth_OpenID_Parse {
|
|||||||
function match($regexp, $text, &$match)
|
function match($regexp, $text, &$match)
|
||||||
{
|
{
|
||||||
if (!is_callable('mb_ereg_search_init')) {
|
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));
|
$regexp = substr($regexp, 1, strlen($regexp) - 2 - strlen($this->_re_flags));
|
||||||
@ -227,7 +231,7 @@ class Auth_OpenID_Parse {
|
|||||||
if (!mb_ereg_search($regexp)) {
|
if (!mb_ereg_search($regexp)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
list($match) = mb_ereg_search_getregs();
|
$match = mb_ereg_search_getregs();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,7 +273,7 @@ class Auth_OpenID_Parse {
|
|||||||
|
|
||||||
// Try to find the <HEAD> tag.
|
// Try to find the <HEAD> tag.
|
||||||
$head_re = $this->headFind();
|
$head_re = $this->headFind();
|
||||||
$head_match = '';
|
$head_match = array();
|
||||||
if (!$this->match($head_re, $stripped, $head_match)) {
|
if (!$this->match($head_re, $stripped, $head_match)) {
|
||||||
ini_set( 'pcre.backtrack_limit', $old_btlimit );
|
ini_set( 'pcre.backtrack_limit', $old_btlimit );
|
||||||
return array();
|
return array();
|
||||||
@ -278,7 +282,7 @@ class Auth_OpenID_Parse {
|
|||||||
$link_data = array();
|
$link_data = array();
|
||||||
$link_matches = 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)) {
|
$link_matches)) {
|
||||||
ini_set( 'pcre.backtrack_limit', $old_btlimit );
|
ini_set( 'pcre.backtrack_limit', $old_btlimit );
|
||||||
return array();
|
return array();
|
||||||
|
208
extlib/Auth/OpenID/PredisStore.php
Normal file
208
extlib/Auth/OpenID/PredisStore.php
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
<?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)
|
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()
|
function returnToVerified()
|
||||||
{
|
{
|
||||||
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
|
$fetcher = Auth_Yadis_Yadis::getHTTPFetcher();
|
||||||
return call_user_func_array($this->verifyReturnTo,
|
return call_user_func_array($this->verifyReturnTo,
|
||||||
array($this->trust_root, $this->return_to, $fetcher));
|
array($this->trust_root, $this->return_to, $fetcher));
|
||||||
}
|
}
|
||||||
|
|
||||||
static function fromMessage($message, $server)
|
static function fromMessage($message, $server)
|
||||||
{
|
{
|
||||||
$mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode');
|
$mode = $message->getArg(Auth_OpenID_OPENID_NS, 'mode');
|
||||||
@ -1704,7 +1704,7 @@ class Auth_OpenID_Server {
|
|||||||
{
|
{
|
||||||
if (method_exists($this, "openid_" . $request->mode)) {
|
if (method_exists($this, "openid_" . $request->mode)) {
|
||||||
$handler = array($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;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ class Auth_Yadis_PHPSession {
|
|||||||
*/
|
*/
|
||||||
function get($name, $default=null)
|
function get($name, $default=null)
|
||||||
{
|
{
|
||||||
if (array_key_exists($name, $_SESSION)) {
|
if (isset($_SESSION) && array_key_exists($name, $_SESSION)) {
|
||||||
return $_SESSION[$name];
|
return $_SESSION[$name];
|
||||||
} else {
|
} else {
|
||||||
return $default;
|
return $default;
|
||||||
@ -411,9 +411,11 @@ class Auth_Yadis_Discovery {
|
|||||||
if (!$manager || (!$manager->services)) {
|
if (!$manager || (!$manager->services)) {
|
||||||
$this->destroyManager();
|
$this->destroyManager();
|
||||||
|
|
||||||
list($yadis_url, $services) = call_user_func($discover_cb,
|
list($yadis_url, $services) = call_user_func_array($discover_cb,
|
||||||
$this->url,
|
array(
|
||||||
&$fetcher);
|
$this->url,
|
||||||
|
&$fetcher,
|
||||||
|
));
|
||||||
|
|
||||||
$manager = $this->createManager($services, $yadis_url);
|
$manager = $this->createManager($services, $yadis_url);
|
||||||
}
|
}
|
||||||
|
@ -129,8 +129,20 @@ class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
|
|||||||
curl_setopt($c, CURLOPT_URL, $url);
|
curl_setopt($c, CURLOPT_URL, $url);
|
||||||
|
|
||||||
if (defined('Auth_OpenID_VERIFY_HOST')) {
|
if (defined('Auth_OpenID_VERIFY_HOST')) {
|
||||||
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true);
|
// set SSL verification options only if Auth_OpenID_VERIFY_HOST
|
||||||
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
|
// 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);
|
curl_exec($c);
|
||||||
|
|
||||||
@ -153,6 +165,7 @@ class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
|
|||||||
curl_close($c);
|
curl_close($c);
|
||||||
|
|
||||||
if (defined('Auth_OpenID_VERIFY_HOST') &&
|
if (defined('Auth_OpenID_VERIFY_HOST') &&
|
||||||
|
Auth_OpenID_VERIFY_HOST == true &&
|
||||||
$this->isHTTPS($url)) {
|
$this->isHTTPS($url)) {
|
||||||
Auth_OpenID::log('OpenID: Verified SSL host %s using '.
|
Auth_OpenID::log('OpenID: Verified SSL host %s using '.
|
||||||
'curl/get', $url);
|
'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,
|
return new Auth_Yadis_HTTPResponse($url, $code,
|
||||||
$new_headers, $body);
|
$new_headers, $body);
|
||||||
}
|
}
|
||||||
@ -194,6 +203,10 @@ class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
|
|||||||
curl_setopt($c, CURLOPT_NOSIGNAL, true);
|
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_POST, true);
|
||||||
curl_setopt($c, CURLOPT_POSTFIELDS, $body);
|
curl_setopt($c, CURLOPT_POSTFIELDS, $body);
|
||||||
curl_setopt($c, CURLOPT_TIMEOUT, $this->timeout);
|
curl_setopt($c, CURLOPT_TIMEOUT, $this->timeout);
|
||||||
@ -202,8 +215,17 @@ class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
|
|||||||
array($this, "_writeData"));
|
array($this, "_writeData"));
|
||||||
|
|
||||||
if (defined('Auth_OpenID_VERIFY_HOST')) {
|
if (defined('Auth_OpenID_VERIFY_HOST')) {
|
||||||
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, true);
|
// set SSL verification options only if Auth_OpenID_VERIFY_HOST
|
||||||
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
|
// 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);
|
curl_exec($c);
|
||||||
@ -217,7 +239,9 @@ class Auth_Yadis_ParanoidHTTPFetcher extends Auth_Yadis_HTTPFetcher {
|
|||||||
return null;
|
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 '.
|
Auth_OpenID::log('OpenID: Verified SSL host %s using '.
|
||||||
'curl/post', $url);
|
'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,
|
return new Auth_Yadis_HTTPResponse($url, $code,
|
||||||
$new_headers, $body);
|
$new_headers, $body);
|
||||||
}
|
}
|
||||||
|
@ -234,7 +234,19 @@ class Auth_Yadis_dom extends Auth_Yadis_XMLParser {
|
|||||||
return false;
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user