mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-02-01 01:29:58 +09:00
17515512: JanRain php-openid library included, normalization fix
git-svn-id: http://xe-core.googlecode.com/svn/sandbox@5137 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
parent
f541dd59b9
commit
658c0e6dbc
219 changed files with 41415 additions and 10 deletions
412
modules/member/php-openid-1.2.3/Auth/OpenID.php
Normal file
412
modules/member/php-openid-1.2.3/Auth/OpenID.php
Normal file
|
|
@ -0,0 +1,412 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This is the PHP OpenID library by JanRain, Inc.
|
||||
*
|
||||
* This module contains core utility functionality used by the
|
||||
* library. See Consumer.php and Server.php for the consumer and
|
||||
* server implementations.
|
||||
*
|
||||
* 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 the fetcher code.
|
||||
*/
|
||||
require_once "Services/Yadis/PlainHTTPFetcher.php";
|
||||
require_once "Services/Yadis/ParanoidHTTPFetcher.php";
|
||||
require_once "Auth/OpenID/BigMath.php";
|
||||
|
||||
/**
|
||||
* Status code returned by the server when the only option is to show
|
||||
* an error page, since we do not have enough information to redirect
|
||||
* back to the consumer. The associated value is an error message that
|
||||
* should be displayed on an HTML error page.
|
||||
*
|
||||
* @see Auth_OpenID_Server
|
||||
*/
|
||||
define('Auth_OpenID_LOCAL_ERROR', 'local_error');
|
||||
|
||||
/**
|
||||
* Status code returned when there is an error to return in key-value
|
||||
* form to the consumer. The caller should return a 400 Bad Request
|
||||
* response with content-type text/plain and the value as the body.
|
||||
*
|
||||
* @see Auth_OpenID_Server
|
||||
*/
|
||||
define('Auth_OpenID_REMOTE_ERROR', 'remote_error');
|
||||
|
||||
/**
|
||||
* Status code returned when there is a key-value form OK response to
|
||||
* the consumer. The value associated with this code is the
|
||||
* response. The caller should return a 200 OK response with
|
||||
* content-type text/plain and the value as the body.
|
||||
*
|
||||
* @see Auth_OpenID_Server
|
||||
*/
|
||||
define('Auth_OpenID_REMOTE_OK', 'remote_ok');
|
||||
|
||||
/**
|
||||
* Status code returned when there is a redirect back to the
|
||||
* consumer. The value is the URL to redirect back to. The caller
|
||||
* should return a 302 Found redirect with a Location: header
|
||||
* containing the URL.
|
||||
*
|
||||
* @see Auth_OpenID_Server
|
||||
*/
|
||||
define('Auth_OpenID_REDIRECT', 'redirect');
|
||||
|
||||
/**
|
||||
* Status code returned when the caller needs to authenticate the
|
||||
* user. The associated value is a {@link Auth_OpenID_ServerRequest}
|
||||
* object that can be used to complete the authentication. If the user
|
||||
* has taken some authentication action, use the retry() method of the
|
||||
* {@link Auth_OpenID_ServerRequest} object to complete the request.
|
||||
*
|
||||
* @see Auth_OpenID_Server
|
||||
*/
|
||||
define('Auth_OpenID_DO_AUTH', 'do_auth');
|
||||
|
||||
/**
|
||||
* Status code returned when there were no OpenID arguments
|
||||
* passed. This code indicates that the caller should return a 200 OK
|
||||
* response and display an HTML page that says that this is an OpenID
|
||||
* server endpoint.
|
||||
*
|
||||
* @see Auth_OpenID_Server
|
||||
*/
|
||||
define('Auth_OpenID_DO_ABOUT', 'do_about');
|
||||
|
||||
/**
|
||||
* Defines for regexes and format checking.
|
||||
*/
|
||||
define('Auth_OpenID_letters',
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
|
||||
|
||||
define('Auth_OpenID_digits',
|
||||
"0123456789");
|
||||
|
||||
define('Auth_OpenID_punct',
|
||||
"!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~");
|
||||
|
||||
if (Auth_OpenID_getMathLib() === null) {
|
||||
define('Auth_OpenID_NO_MATH_SUPPORT', true);
|
||||
}
|
||||
|
||||
/**
|
||||
* The OpenID utility function class.
|
||||
*
|
||||
* @package OpenID
|
||||
* @access private
|
||||
*/
|
||||
class Auth_OpenID {
|
||||
|
||||
/**
|
||||
* These namespaces are automatically fixed in query arguments by
|
||||
* Auth_OpenID::fixArgs.
|
||||
*/
|
||||
function getOpenIDNamespaces()
|
||||
{
|
||||
return array('openid',
|
||||
'sreg');
|
||||
}
|
||||
|
||||
/**
|
||||
* Rename query arguments back to 'openid.' from 'openid_'
|
||||
*
|
||||
* @access private
|
||||
* @param array $args An associative array of URL query arguments
|
||||
*/
|
||||
function fixArgs($args)
|
||||
{
|
||||
foreach (array_keys($args) as $key) {
|
||||
$fixed = $key;
|
||||
if (preg_match('/^openid/', $key)) {
|
||||
foreach (Auth_OpenID::getOpenIDNamespaces() as $ns) {
|
||||
if (preg_match('/'.$ns.'_/', $key)) {
|
||||
$fixed = preg_replace('/'.$ns.'_/', $ns.'.', $fixed);
|
||||
}
|
||||
}
|
||||
|
||||
if ($fixed != $key) {
|
||||
$val = $args[$key];
|
||||
unset($args[$key]);
|
||||
$args[$fixed] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create dir_name as a directory if it does not exist. If it
|
||||
* exists, make sure that it is, in fact, a directory. Returns
|
||||
* true if the operation succeeded; false if not.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function ensureDir($dir_name)
|
||||
{
|
||||
if (is_dir($dir_name) || @mkdir($dir_name)) {
|
||||
return true;
|
||||
} else {
|
||||
if (Auth_OpenID::ensureDir(dirname($dir_name))) {
|
||||
return is_dir($dir_name) || @mkdir($dir_name);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience function for getting array values.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function arrayGet($arr, $key, $fallback = null)
|
||||
{
|
||||
if (is_array($arr)) {
|
||||
if (array_key_exists($key, $arr)) {
|
||||
return $arr[$key];
|
||||
} else {
|
||||
return $fallback;
|
||||
}
|
||||
} else {
|
||||
trigger_error("Auth_OpenID::arrayGet expected " .
|
||||
"array as first parameter", E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the PHP 5 'http_build_query' functionality.
|
||||
*
|
||||
* @access private
|
||||
* @param array $data Either an array key/value pairs or an array
|
||||
* of arrays, each of which holding two values: a key and a value,
|
||||
* sequentially.
|
||||
* @return string $result The result of url-encoding the key/value
|
||||
* pairs from $data into a URL query string
|
||||
* (e.g. "username=bob&id=56").
|
||||
*/
|
||||
function httpBuildQuery($data)
|
||||
{
|
||||
$pairs = array();
|
||||
foreach ($data as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
$pairs[] = urlencode($value[0])."=".urlencode($value[1]);
|
||||
} else {
|
||||
$pairs[] = urlencode($key)."=".urlencode($value);
|
||||
}
|
||||
}
|
||||
return implode("&", $pairs);
|
||||
}
|
||||
|
||||
/**
|
||||
* "Appends" query arguments onto a URL. The URL may or may not
|
||||
* already have arguments (following a question mark).
|
||||
*
|
||||
* @param string $url A URL, which may or may not already have
|
||||
* arguments.
|
||||
* @param array $args Either an array key/value pairs or an array of
|
||||
* arrays, each of which holding two values: a key and a value,
|
||||
* sequentially. If $args is an ordinary key/value array, the
|
||||
* parameters will be added to the URL in sorted alphabetical order;
|
||||
* if $args is an array of arrays, their order will be preserved.
|
||||
* @return string $url The original URL with the new parameters added.
|
||||
*
|
||||
*/
|
||||
function appendArgs($url, $args)
|
||||
{
|
||||
if (count($args) == 0) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
// Non-empty array; if it is an array of arrays, use
|
||||
// multisort; otherwise use sort.
|
||||
if (array_key_exists(0, $args) &&
|
||||
is_array($args[0])) {
|
||||
// Do nothing here.
|
||||
} else {
|
||||
$keys = array_keys($args);
|
||||
sort($keys);
|
||||
$new_args = array();
|
||||
foreach ($keys as $key) {
|
||||
$new_args[] = array($key, $args[$key]);
|
||||
}
|
||||
$args = $new_args;
|
||||
}
|
||||
|
||||
$sep = '?';
|
||||
if (strpos($url, '?') !== false) {
|
||||
$sep = '&';
|
||||
}
|
||||
|
||||
return $url . $sep . Auth_OpenID::httpBuildQuery($args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn a string into an ASCII string.
|
||||
*
|
||||
* Replace non-ascii characters with a %-encoded, UTF-8
|
||||
* encoding. This function will fail if the input is a string and
|
||||
* there are non-7-bit-safe characters. It is assumed that the
|
||||
* caller will have already translated the input into a Unicode
|
||||
* character sequence, according to the encoding of the HTTP POST
|
||||
* or GET.
|
||||
*
|
||||
* Do not escape anything that is already 7-bit safe, so we do the
|
||||
* minimal transform on the identity URL
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function quoteMinimal($s)
|
||||
{
|
||||
$res = array();
|
||||
for ($i = 0; $i < strlen($s); $i++) {
|
||||
$c = $s[$i];
|
||||
if ($c >= "\x80") {
|
||||
for ($j = 0; $j < count(utf8_encode($c)); $j++) {
|
||||
array_push($res, sprintf("%02X", ord($c[$j])));
|
||||
}
|
||||
} else {
|
||||
array_push($res, $c);
|
||||
}
|
||||
}
|
||||
|
||||
return implode('', $res);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements python's urlunparse, which is not available in PHP.
|
||||
* Given the specified components of a URL, this function rebuilds
|
||||
* and returns the URL.
|
||||
*
|
||||
* @access private
|
||||
* @param string $scheme The scheme (e.g. 'http'). Defaults to 'http'.
|
||||
* @param string $host The host. Required.
|
||||
* @param string $port The port.
|
||||
* @param string $path The path.
|
||||
* @param string $query The query.
|
||||
* @param string $fragment The fragment.
|
||||
* @return string $url The URL resulting from assembling the
|
||||
* specified components.
|
||||
*/
|
||||
function urlunparse($scheme, $host, $port = null, $path = '/',
|
||||
$query = '', $fragment = '')
|
||||
{
|
||||
|
||||
if (!$scheme) {
|
||||
$scheme = 'http';
|
||||
}
|
||||
|
||||
if (!$host) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$path) {
|
||||
$path = '/';
|
||||
}
|
||||
|
||||
$result = $scheme . "://" . $host;
|
||||
|
||||
if ($port) {
|
||||
$result .= ":" . $port;
|
||||
}
|
||||
|
||||
$result .= $path;
|
||||
|
||||
if ($query) {
|
||||
$result .= "?" . $query;
|
||||
}
|
||||
|
||||
if ($fragment) {
|
||||
$result .= "#" . $fragment;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a URL, this "normalizes" it by adding a trailing slash
|
||||
* and / or a leading http:// scheme where necessary. Returns
|
||||
* null if the original URL is malformed and cannot be normalized.
|
||||
*
|
||||
* @access private
|
||||
* @param string $url The URL to be normalized.
|
||||
* @return mixed $new_url The URL after normalization, or null if
|
||||
* $url was malformed.
|
||||
*/
|
||||
function normalizeUrl($url)
|
||||
{
|
||||
if ($url === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
assert(is_string($url));
|
||||
|
||||
$old_url = $url;
|
||||
$url = trim($url);
|
||||
|
||||
if (strpos($url, "://") === false) {
|
||||
$url = "http://" . $url;
|
||||
}
|
||||
|
||||
$parsed = @parse_url($url);
|
||||
|
||||
if ($parsed === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$defaults = array(
|
||||
'scheme' => '',
|
||||
'host' => '',
|
||||
'path' => '',
|
||||
'query' => '',
|
||||
'fragment' => '',
|
||||
'port' => ''
|
||||
);
|
||||
|
||||
$parsed = array_merge($defaults, $parsed);
|
||||
|
||||
if (($parsed['scheme'] == '') ||
|
||||
($parsed['host'] == '')) {
|
||||
if ($parsed['path'] == '' &&
|
||||
$parsed['query'] == '' &&
|
||||
$parsed['fragment'] == '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
$url = 'http://' + $url;
|
||||
$parsed = parse_url($url);
|
||||
|
||||
$parsed = array_merge($defaults, $parsed);
|
||||
}
|
||||
|
||||
$tail = array_map(array('Auth_OpenID', 'quoteMinimal'),
|
||||
array($parsed['path'],
|
||||
$parsed['query'],
|
||||
$parsed['fragment']));
|
||||
if ($tail[0] == '') {
|
||||
$tail[0] = '/';
|
||||
}
|
||||
|
||||
$url = Auth_OpenID::urlunparse($parsed['scheme'], $parsed['host'],
|
||||
$parsed['port'], $tail[0], $tail[1],
|
||||
$tail[2]);
|
||||
|
||||
assert(is_string($url));
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
308
modules/member/php-openid-1.2.3/Auth/OpenID/Association.php
Normal file
308
modules/member/php-openid-1.2.3/Auth/OpenID/Association.php
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This module contains code for dealing with associations between
|
||||
* consumers and servers.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
require_once 'Auth/OpenID/CryptUtil.php';
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
require_once 'Auth/OpenID/KVForm.php';
|
||||
|
||||
/**
|
||||
* This class represents an association between a server and a
|
||||
* consumer. In general, users of this library will never see
|
||||
* instances of this object. The only exception is if you implement a
|
||||
* custom {@link Auth_OpenID_OpenIDStore}.
|
||||
*
|
||||
* If you do implement such a store, it will need to store the values
|
||||
* of the handle, secret, issued, lifetime, and assoc_type instance
|
||||
* variables.
|
||||
*
|
||||
* @package OpenID
|
||||
*/
|
||||
class Auth_OpenID_Association {
|
||||
|
||||
/**
|
||||
* This is a HMAC-SHA1 specific value.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $SIG_LENGTH = 20;
|
||||
|
||||
/**
|
||||
* The ordering and name of keys as stored by serialize.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
var $assoc_keys = array(
|
||||
'version',
|
||||
'handle',
|
||||
'secret',
|
||||
'issued',
|
||||
'lifetime',
|
||||
'assoc_type'
|
||||
);
|
||||
|
||||
/**
|
||||
* This is an alternate constructor (factory method) used by the
|
||||
* OpenID consumer library to create associations. OpenID store
|
||||
* implementations shouldn't use this constructor.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param integer $expires_in This is the amount of time this
|
||||
* association is good for, measured in seconds since the
|
||||
* association was issued.
|
||||
*
|
||||
* @param string $handle This is the handle the server gave this
|
||||
* association.
|
||||
*
|
||||
* @param string secret This is the shared secret the server
|
||||
* generated for this association.
|
||||
*
|
||||
* @param assoc_type This is the type of association this
|
||||
* instance represents. The only valid value of this field at
|
||||
* this time is 'HMAC-SHA1', but new types may be defined in the
|
||||
* future.
|
||||
*
|
||||
* @return association An {@link Auth_OpenID_Association}
|
||||
* instance.
|
||||
*/
|
||||
function fromExpiresIn($expires_in, $handle, $secret, $assoc_type)
|
||||
{
|
||||
$issued = time();
|
||||
$lifetime = $expires_in;
|
||||
return new Auth_OpenID_Association($handle, $secret,
|
||||
$issued, $lifetime, $assoc_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the standard constructor for creating an association.
|
||||
* The library should create all of the necessary associations, so
|
||||
* this constructor is not part of the external API.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param string $handle This is the handle the server gave this
|
||||
* association.
|
||||
*
|
||||
* @param string $secret This is the shared secret the server
|
||||
* generated for this association.
|
||||
*
|
||||
* @param integer $issued This is the time this association was
|
||||
* issued, in seconds since 00:00 GMT, January 1, 1970. (ie, a
|
||||
* unix timestamp)
|
||||
*
|
||||
* @param integer $lifetime This is the amount of time this
|
||||
* association is good for, measured in seconds since the
|
||||
* association was issued.
|
||||
*
|
||||
* @param string $assoc_type This is the type of association this
|
||||
* instance represents. The only valid value of this field at
|
||||
* this time is 'HMAC-SHA1', but new types may be defined in the
|
||||
* future.
|
||||
*/
|
||||
function Auth_OpenID_Association(
|
||||
$handle, $secret, $issued, $lifetime, $assoc_type)
|
||||
{
|
||||
if ($assoc_type != 'HMAC-SHA1') {
|
||||
$fmt = 'HMAC-SHA1 is the only supported association type (got %s)';
|
||||
trigger_error(sprintf($fmt, $assoc_type), E_USER_ERROR);
|
||||
}
|
||||
|
||||
$this->handle = $handle;
|
||||
$this->secret = $secret;
|
||||
$this->issued = $issued;
|
||||
$this->lifetime = $lifetime;
|
||||
$this->assoc_type = $assoc_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* This returns the number of seconds this association is still
|
||||
* valid for, or 0 if the association is no longer valid.
|
||||
*
|
||||
* @return integer $seconds The number of seconds this association
|
||||
* is still valid for, or 0 if the association is no longer valid.
|
||||
*/
|
||||
function getExpiresIn($now = null)
|
||||
{
|
||||
if ($now == null) {
|
||||
$now = time();
|
||||
}
|
||||
|
||||
return max(0, $this->issued + $this->lifetime - $now);
|
||||
}
|
||||
|
||||
/**
|
||||
* This checks to see if two {@link Auth_OpenID_Association}
|
||||
* instances represent the same association.
|
||||
*
|
||||
* @return bool $result true if the two instances represent the
|
||||
* same association, false otherwise.
|
||||
*/
|
||||
function equal($other)
|
||||
{
|
||||
return ((gettype($this) == gettype($other))
|
||||
&& ($this->handle == $other->handle)
|
||||
&& ($this->secret == $other->secret)
|
||||
&& ($this->issued == $other->issued)
|
||||
&& ($this->lifetime == $other->lifetime)
|
||||
&& ($this->assoc_type == $other->assoc_type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an association to KV form.
|
||||
*
|
||||
* @return string $result String in KV form suitable for
|
||||
* deserialization by deserialize.
|
||||
*/
|
||||
function serialize()
|
||||
{
|
||||
$data = array(
|
||||
'version' => '2',
|
||||
'handle' => $this->handle,
|
||||
'secret' => base64_encode($this->secret),
|
||||
'issued' => strval(intval($this->issued)),
|
||||
'lifetime' => strval(intval($this->lifetime)),
|
||||
'assoc_type' => $this->assoc_type
|
||||
);
|
||||
|
||||
assert(array_keys($data) == $this->assoc_keys);
|
||||
|
||||
return Auth_OpenID_KVForm::fromArray($data, $strict = true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse an association as stored by serialize(). This is the
|
||||
* inverse of serialize.
|
||||
*
|
||||
* @param string $assoc_s Association as serialized by serialize()
|
||||
* @return Auth_OpenID_Association $result instance of this class
|
||||
*/
|
||||
function deserialize($class_name, $assoc_s)
|
||||
{
|
||||
$pairs = Auth_OpenID_KVForm::toArray($assoc_s, $strict = true);
|
||||
$keys = array();
|
||||
$values = array();
|
||||
foreach ($pairs as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
list($key, $value) = $value;
|
||||
}
|
||||
$keys[] = $key;
|
||||
$values[] = $value;
|
||||
}
|
||||
|
||||
$class_vars = get_class_vars($class_name);
|
||||
$class_assoc_keys = $class_vars['assoc_keys'];
|
||||
|
||||
sort($keys);
|
||||
sort($class_assoc_keys);
|
||||
|
||||
if ($keys != $class_assoc_keys) {
|
||||
trigger_error('Unexpected key values: ' . strval($keys),
|
||||
E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
|
||||
$version = $pairs['version'];
|
||||
$handle = $pairs['handle'];
|
||||
$secret = $pairs['secret'];
|
||||
$issued = $pairs['issued'];
|
||||
$lifetime = $pairs['lifetime'];
|
||||
$assoc_type = $pairs['assoc_type'];
|
||||
|
||||
if ($version != '2') {
|
||||
trigger_error('Unknown version: ' . $version, E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
|
||||
$issued = intval($issued);
|
||||
$lifetime = intval($lifetime);
|
||||
$secret = base64_decode($secret);
|
||||
|
||||
return new $class_name(
|
||||
$handle, $secret, $issued, $lifetime, $assoc_type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a signature for a sequence of (key, value) pairs
|
||||
*
|
||||
* @access private
|
||||
* @param array $pairs The pairs to sign, in order. This is an
|
||||
* array of two-tuples.
|
||||
* @return string $signature The binary signature of this sequence
|
||||
* of pairs
|
||||
*/
|
||||
function sign($pairs)
|
||||
{
|
||||
$kv = Auth_OpenID_KVForm::fromArray($pairs);
|
||||
return Auth_OpenID_HMACSHA1($this->secret, $kv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a signature for some fields in a dictionary
|
||||
*
|
||||
* @access private
|
||||
* @param array $fields The fields to sign, in order; this is an
|
||||
* array of strings.
|
||||
* @param array $data Dictionary of values to sign (an array of
|
||||
* string => string pairs).
|
||||
* @return string $signature The signature, base64 encoded
|
||||
*/
|
||||
function signDict($fields, $data, $prefix = 'openid.')
|
||||
{
|
||||
$pairs = array();
|
||||
foreach ($fields as $field) {
|
||||
$pairs[] = array($field, $data[$prefix . $field]);
|
||||
}
|
||||
|
||||
return base64_encode($this->sign($pairs));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a signature to an array of fields
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function addSignature($fields, &$data, $prefix = 'openid.')
|
||||
{
|
||||
$sig = $this->signDict($fields, $data, $prefix);
|
||||
$signed = implode(",", $fields);
|
||||
$data[$prefix . 'sig'] = $sig;
|
||||
$data[$prefix . 'signed'] = $signed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm that the signature of these fields matches the
|
||||
* signature contained in the data
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function checkSignature($data, $prefix = 'openid.')
|
||||
{
|
||||
$signed = $data[$prefix . 'signed'];
|
||||
$fields = explode(",", $signed);
|
||||
$expected_sig = $this->signDict($fields, $data, $prefix);
|
||||
$request_sig = $data[$prefix . 'sig'];
|
||||
|
||||
return ($request_sig == $expected_sig);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
444
modules/member/php-openid-1.2.3/Auth/OpenID/BigMath.php
Normal file
444
modules/member/php-openid-1.2.3/Auth/OpenID/BigMath.php
Normal file
|
|
@ -0,0 +1,444 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* BigMath: A math library wrapper that abstracts out the underlying
|
||||
* long integer library.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: See the COPYING file included in this distribution.
|
||||
*
|
||||
* @access private
|
||||
* @package OpenID
|
||||
* @author JanRain, Inc. <openid@janrain.com>
|
||||
* @copyright 2005 Janrain, Inc.
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL
|
||||
*/
|
||||
|
||||
/**
|
||||
* Needed for random number generation
|
||||
*/
|
||||
require_once 'Auth/OpenID/CryptUtil.php';
|
||||
|
||||
/**
|
||||
* The superclass of all big-integer math implementations
|
||||
* @access private
|
||||
* @package OpenID
|
||||
*/
|
||||
class Auth_OpenID_MathLibrary {
|
||||
/**
|
||||
* Given a long integer, returns the number converted to a binary
|
||||
* string. This function accepts long integer values of arbitrary
|
||||
* magnitude and uses the local large-number math library when
|
||||
* available.
|
||||
*
|
||||
* @param integer $long The long number (can be a normal PHP
|
||||
* integer or a number created by one of the available long number
|
||||
* libraries)
|
||||
* @return string $binary The binary version of $long
|
||||
*/
|
||||
function longToBinary($long)
|
||||
{
|
||||
$cmp = $this->cmp($long, 0);
|
||||
if ($cmp < 0) {
|
||||
$msg = __FUNCTION__ . " takes only positive integers.";
|
||||
trigger_error($msg, E_USER_ERROR);
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($cmp == 0) {
|
||||
return "\x00";
|
||||
}
|
||||
|
||||
$bytes = array();
|
||||
|
||||
while ($this->cmp($long, 0) > 0) {
|
||||
array_unshift($bytes, $this->mod($long, 256));
|
||||
$long = $this->div($long, pow(2, 8));
|
||||
}
|
||||
|
||||
if ($bytes && ($bytes[0] > 127)) {
|
||||
array_unshift($bytes, 0);
|
||||
}
|
||||
|
||||
$string = '';
|
||||
foreach ($bytes as $byte) {
|
||||
$string .= pack('C', $byte);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a binary string, returns the binary string converted to a
|
||||
* long number.
|
||||
*
|
||||
* @param string $binary The binary version of a long number,
|
||||
* probably as a result of calling longToBinary
|
||||
* @return integer $long The long number equivalent of the binary
|
||||
* string $str
|
||||
*/
|
||||
function binaryToLong($str)
|
||||
{
|
||||
if ($str === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Use array_merge to return a zero-indexed array instead of a
|
||||
// one-indexed array.
|
||||
$bytes = array_merge(unpack('C*', $str));
|
||||
|
||||
$n = $this->init(0);
|
||||
|
||||
if ($bytes && ($bytes[0] > 127)) {
|
||||
trigger_error("bytesToNum works only for positive integers.",
|
||||
E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach ($bytes as $byte) {
|
||||
$n = $this->mul($n, pow(2, 8));
|
||||
$n = $this->add($n, $byte);
|
||||
}
|
||||
|
||||
return $n;
|
||||
}
|
||||
|
||||
function base64ToLong($str)
|
||||
{
|
||||
$b64 = base64_decode($str);
|
||||
|
||||
if ($b64 === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->binaryToLong($b64);
|
||||
}
|
||||
|
||||
function longToBase64($str)
|
||||
{
|
||||
return base64_encode($this->longToBinary($str));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random number in the specified range. This function
|
||||
* accepts $start, $stop, and $step values of arbitrary magnitude
|
||||
* and will utilize the local large-number math library when
|
||||
* available.
|
||||
*
|
||||
* @param integer $start The start of the range, or the minimum
|
||||
* random number to return
|
||||
* @param integer $stop The end of the range, or the maximum
|
||||
* random number to return
|
||||
* @param integer $step The step size, such that $result - ($step
|
||||
* * N) = $start for some N
|
||||
* @return integer $result The resulting randomly-generated number
|
||||
*/
|
||||
function rand($stop)
|
||||
{
|
||||
static $duplicate_cache = array();
|
||||
|
||||
// Used as the key for the duplicate cache
|
||||
$rbytes = $this->longToBinary($stop);
|
||||
|
||||
if (array_key_exists($rbytes, $duplicate_cache)) {
|
||||
list($duplicate, $nbytes) = $duplicate_cache[$rbytes];
|
||||
} else {
|
||||
if ($rbytes[0] == "\x00") {
|
||||
$nbytes = strlen($rbytes) - 1;
|
||||
} else {
|
||||
$nbytes = strlen($rbytes);
|
||||
}
|
||||
|
||||
$mxrand = $this->pow(256, $nbytes);
|
||||
|
||||
// If we get a number less than this, then it is in the
|
||||
// duplicated range.
|
||||
$duplicate = $this->mod($mxrand, $stop);
|
||||
|
||||
if (count($duplicate_cache) > 10) {
|
||||
$duplicate_cache = array();
|
||||
}
|
||||
|
||||
$duplicate_cache[$rbytes] = array($duplicate, $nbytes);
|
||||
}
|
||||
|
||||
do {
|
||||
$bytes = "\x00" . Auth_OpenID_CryptUtil::getBytes($nbytes);
|
||||
$n = $this->binaryToLong($bytes);
|
||||
// Keep looping if this value is in the low duplicated range
|
||||
} while ($this->cmp($n, $duplicate) < 0);
|
||||
|
||||
return $this->mod($n, $stop);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes BCmath math library functionality.
|
||||
*
|
||||
* {@link Auth_OpenID_BcMathWrapper} wraps the functionality provided
|
||||
* by the BCMath extension.
|
||||
*
|
||||
* @access private
|
||||
* @package OpenID
|
||||
*/
|
||||
class Auth_OpenID_BcMathWrapper extends Auth_OpenID_MathLibrary{
|
||||
var $type = 'bcmath';
|
||||
|
||||
function add($x, $y)
|
||||
{
|
||||
return bcadd($x, $y);
|
||||
}
|
||||
|
||||
function sub($x, $y)
|
||||
{
|
||||
return bcsub($x, $y);
|
||||
}
|
||||
|
||||
function pow($base, $exponent)
|
||||
{
|
||||
return bcpow($base, $exponent);
|
||||
}
|
||||
|
||||
function cmp($x, $y)
|
||||
{
|
||||
return bccomp($x, $y);
|
||||
}
|
||||
|
||||
function init($number, $base = 10)
|
||||
{
|
||||
return $number;
|
||||
}
|
||||
|
||||
function mod($base, $modulus)
|
||||
{
|
||||
return bcmod($base, $modulus);
|
||||
}
|
||||
|
||||
function mul($x, $y)
|
||||
{
|
||||
return bcmul($x, $y);
|
||||
}
|
||||
|
||||
function div($x, $y)
|
||||
{
|
||||
return bcdiv($x, $y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as bcpowmod when bcpowmod is missing
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _powmod($base, $exponent, $modulus)
|
||||
{
|
||||
$square = $this->mod($base, $modulus);
|
||||
$result = 1;
|
||||
while($this->cmp($exponent, 0) > 0) {
|
||||
if ($this->mod($exponent, 2)) {
|
||||
$result = $this->mod($this->mul($result, $square), $modulus);
|
||||
}
|
||||
$square = $this->mod($this->mul($square, $square), $modulus);
|
||||
$exponent = $this->div($exponent, 2);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function powmod($base, $exponent, $modulus)
|
||||
{
|
||||
if (function_exists('bcpowmod')) {
|
||||
return bcpowmod($base, $exponent, $modulus);
|
||||
} else {
|
||||
return $this->_powmod($base, $exponent, $modulus);
|
||||
}
|
||||
}
|
||||
|
||||
function toString($num)
|
||||
{
|
||||
return $num;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Exposes GMP math library functionality.
|
||||
*
|
||||
* {@link Auth_OpenID_GmpMathWrapper} wraps the functionality provided
|
||||
* by the GMP extension.
|
||||
*
|
||||
* @access private
|
||||
* @package OpenID
|
||||
*/
|
||||
class Auth_OpenID_GmpMathWrapper extends Auth_OpenID_MathLibrary{
|
||||
var $type = 'gmp';
|
||||
|
||||
function add($x, $y)
|
||||
{
|
||||
return gmp_add($x, $y);
|
||||
}
|
||||
|
||||
function sub($x, $y)
|
||||
{
|
||||
return gmp_sub($x, $y);
|
||||
}
|
||||
|
||||
function pow($base, $exponent)
|
||||
{
|
||||
return gmp_pow($base, $exponent);
|
||||
}
|
||||
|
||||
function cmp($x, $y)
|
||||
{
|
||||
return gmp_cmp($x, $y);
|
||||
}
|
||||
|
||||
function init($number, $base = 10)
|
||||
{
|
||||
return gmp_init($number, $base);
|
||||
}
|
||||
|
||||
function mod($base, $modulus)
|
||||
{
|
||||
return gmp_mod($base, $modulus);
|
||||
}
|
||||
|
||||
function mul($x, $y)
|
||||
{
|
||||
return gmp_mul($x, $y);
|
||||
}
|
||||
|
||||
function div($x, $y)
|
||||
{
|
||||
return gmp_div_q($x, $y);
|
||||
}
|
||||
|
||||
function powmod($base, $exponent, $modulus)
|
||||
{
|
||||
return gmp_powm($base, $exponent, $modulus);
|
||||
}
|
||||
|
||||
function toString($num)
|
||||
{
|
||||
return gmp_strval($num);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Define the supported extensions. An extension array has keys
|
||||
* 'modules', 'extension', and 'class'. 'modules' is an array of PHP
|
||||
* module names which the loading code will attempt to load. These
|
||||
* values will be suffixed with a library file extension (e.g. ".so").
|
||||
* 'extension' is the name of a PHP extension which will be tested
|
||||
* before 'modules' are loaded. 'class' is the string name of a
|
||||
* {@link Auth_OpenID_MathWrapper} subclass which should be
|
||||
* instantiated if a given extension is present.
|
||||
*
|
||||
* You can define new math library implementations and add them to
|
||||
* this array.
|
||||
*/
|
||||
global $_Auth_OpenID_math_extensions;
|
||||
$_Auth_OpenID_math_extensions = array(
|
||||
array('modules' => array('gmp', 'php_gmp'),
|
||||
'extension' => 'gmp',
|
||||
'class' => 'Auth_OpenID_GmpMathWrapper'),
|
||||
array('modules' => array('bcmath', 'php_bcmath'),
|
||||
'extension' => 'bcmath',
|
||||
'class' => 'Auth_OpenID_BcMathWrapper')
|
||||
);
|
||||
|
||||
/**
|
||||
* Detect which (if any) math library is available
|
||||
*/
|
||||
function Auth_OpenID_detectMathLibrary($exts)
|
||||
{
|
||||
$loaded = false;
|
||||
|
||||
foreach ($exts as $extension) {
|
||||
// See if the extension specified is already loaded.
|
||||
if ($extension['extension'] &&
|
||||
extension_loaded($extension['extension'])) {
|
||||
$loaded = true;
|
||||
}
|
||||
|
||||
// Try to load dynamic modules.
|
||||
if (!$loaded) {
|
||||
foreach ($extension['modules'] as $module) {
|
||||
if (@dl($module . "." . PHP_SHLIB_SUFFIX)) {
|
||||
$loaded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If the load succeeded, supply an instance of
|
||||
// Auth_OpenID_MathWrapper which wraps the specified
|
||||
// module's functionality.
|
||||
if ($loaded) {
|
||||
return $extension;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link Auth_OpenID_getMathLib} checks for the presence of long
|
||||
* number extension modules and returns an instance of
|
||||
* {@link Auth_OpenID_MathWrapper} which exposes the module's
|
||||
* functionality.
|
||||
*
|
||||
* Checks for the existence of an extension module described by the
|
||||
* local {@link Auth_OpenID_math_extensions} array and returns an
|
||||
* instance of a wrapper for that extension module. If no extension
|
||||
* module is found, an instance of {@link Auth_OpenID_MathWrapper} is
|
||||
* returned, which wraps the native PHP integer implementation. The
|
||||
* proper calling convention for this method is $lib =&
|
||||
* Auth_OpenID_getMathLib().
|
||||
*
|
||||
* This function checks for the existence of specific long number
|
||||
* implementations in the following order: GMP followed by BCmath.
|
||||
*
|
||||
* @return Auth_OpenID_MathWrapper $instance An instance of
|
||||
* {@link Auth_OpenID_MathWrapper} or one of its subclasses
|
||||
*
|
||||
* @package OpenID
|
||||
*/
|
||||
function &Auth_OpenID_getMathLib()
|
||||
{
|
||||
// The instance of Auth_OpenID_MathWrapper that we choose to
|
||||
// supply will be stored here, so that subseqent calls to this
|
||||
// method will return a reference to the same object.
|
||||
static $lib = null;
|
||||
|
||||
if (isset($lib)) {
|
||||
return $lib;
|
||||
}
|
||||
|
||||
if (defined('Auth_OpenID_NO_MATH_SUPPORT')) {
|
||||
$null = null;
|
||||
return $null;
|
||||
}
|
||||
|
||||
// If this method has not been called before, look at
|
||||
// $Auth_OpenID_math_extensions and try to find an extension that
|
||||
// works.
|
||||
global $_Auth_OpenID_math_extensions;
|
||||
$ext = Auth_OpenID_detectMathLibrary($_Auth_OpenID_math_extensions);
|
||||
if ($ext === false) {
|
||||
$tried = array();
|
||||
foreach ($_Auth_OpenID_math_extensions as $extinfo) {
|
||||
$tried[] = $extinfo['extension'];
|
||||
}
|
||||
$triedstr = implode(", ", $tried);
|
||||
|
||||
define('Auth_OpenID_NO_MATH_SUPPORT', true);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Instantiate a new wrapper
|
||||
$class = $ext['class'];
|
||||
$lib = new $class();
|
||||
|
||||
return $lib;
|
||||
}
|
||||
|
||||
?>
|
||||
1186
modules/member/php-openid-1.2.3/Auth/OpenID/Consumer.php
Normal file
1186
modules/member/php-openid-1.2.3/Auth/OpenID/Consumer.php
Normal file
File diff suppressed because it is too large
Load diff
109
modules/member/php-openid-1.2.3/Auth/OpenID/CryptUtil.php
Normal file
109
modules/member/php-openid-1.2.3/Auth/OpenID/CryptUtil.php
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* CryptUtil: A suite of wrapper utility functions for the OpenID
|
||||
* library.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: See the COPYING file included in this distribution.
|
||||
*
|
||||
* @access private
|
||||
* @package OpenID
|
||||
* @author JanRain, Inc. <openid@janrain.com>
|
||||
* @copyright 2005 Janrain, Inc.
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL
|
||||
*/
|
||||
|
||||
if (!defined('Auth_OpenID_RAND_SOURCE')) {
|
||||
/**
|
||||
* The filename for a source of random bytes. Define this yourself
|
||||
* if you have a different source of randomness.
|
||||
*/
|
||||
define('Auth_OpenID_RAND_SOURCE', '/dev/urandom');
|
||||
}
|
||||
|
||||
class Auth_OpenID_CryptUtil {
|
||||
/**
|
||||
* Get the specified number of random bytes.
|
||||
*
|
||||
* Attempts to use a cryptographically secure (not predictable)
|
||||
* source of randomness if available. If there is no high-entropy
|
||||
* randomness source available, it will fail. As a last resort,
|
||||
* for non-critical systems, define
|
||||
* <code>Auth_OpenID_RAND_SOURCE</code> as <code>null</code>, and
|
||||
* the code will fall back on a pseudo-random number generator.
|
||||
*
|
||||
* @param int $num_bytes The length of the return value
|
||||
* @return string $bytes random bytes
|
||||
*/
|
||||
function getBytes($num_bytes)
|
||||
{
|
||||
static $f = null;
|
||||
$bytes = '';
|
||||
if ($f === null) {
|
||||
if (Auth_OpenID_RAND_SOURCE === null) {
|
||||
$f = false;
|
||||
} else {
|
||||
$f = @fopen(Auth_OpenID_RAND_SOURCE, "r");
|
||||
if ($f === false) {
|
||||
$msg = 'Define Auth_OpenID_RAND_SOURCE as null to ' .
|
||||
' continue with an insecure random number generator.';
|
||||
trigger_error($msg, E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($f === false) {
|
||||
// pseudorandom used
|
||||
$bytes = '';
|
||||
for ($i = 0; $i < $num_bytes; $i += 4) {
|
||||
$bytes .= pack('L', mt_rand());
|
||||
}
|
||||
$bytes = substr($bytes, 0, $num_bytes);
|
||||
} else {
|
||||
$bytes = fread($f, $num_bytes);
|
||||
}
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produce a string of length random bytes, chosen from chrs. If
|
||||
* $chrs is null, the resulting string may contain any characters.
|
||||
*
|
||||
* @param integer $length The length of the resulting
|
||||
* randomly-generated string
|
||||
* @param string $chrs A string of characters from which to choose
|
||||
* to build the new string
|
||||
* @return string $result A string of randomly-chosen characters
|
||||
* from $chrs
|
||||
*/
|
||||
function randomString($length, $population = null)
|
||||
{
|
||||
if ($population === null) {
|
||||
return Auth_OpenID_CryptUtil::getBytes($length);
|
||||
}
|
||||
|
||||
$popsize = strlen($population);
|
||||
|
||||
if ($popsize > 256) {
|
||||
$msg = 'More than 256 characters supplied to ' . __FUNCTION__;
|
||||
trigger_error($msg, E_USER_ERROR);
|
||||
}
|
||||
|
||||
$duplicate = 256 % $popsize;
|
||||
|
||||
$str = "";
|
||||
for ($i = 0; $i < $length; $i++) {
|
||||
do {
|
||||
$n = ord(Auth_OpenID_CryptUtil::getBytes(1));
|
||||
} while ($n < $duplicate);
|
||||
|
||||
$n %= $popsize;
|
||||
$str .= $population[$n];
|
||||
}
|
||||
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* The Auth_OpenID_DatabaseConnection class, which is used to emulate
|
||||
* a PEAR database connection.
|
||||
*
|
||||
* @package OpenID
|
||||
* @author JanRain, Inc. <openid@janrain.com>
|
||||
* @copyright 2005 Janrain, Inc.
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL
|
||||
*/
|
||||
|
||||
/**
|
||||
* An empty base class intended to emulate PEAR connection
|
||||
* functionality in applications that supply their own database
|
||||
* abstraction mechanisms. See {@link Auth_OpenID_SQLStore} for more
|
||||
* information. You should subclass this class if you need to create
|
||||
* an SQL store that needs to access its database using an
|
||||
* application's database abstraction layer instead of a PEAR database
|
||||
* connection. Any subclass of Auth_OpenID_DatabaseConnection MUST
|
||||
* adhere to the interface specified here.
|
||||
*
|
||||
* @package OpenID
|
||||
*/
|
||||
class Auth_OpenID_DatabaseConnection {
|
||||
/**
|
||||
* Sets auto-commit mode on this database connection.
|
||||
*
|
||||
* @param bool $mode True if auto-commit is to be used; false if
|
||||
* not.
|
||||
*/
|
||||
function autoCommit($mode)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Run an SQL query with the specified parameters, if any.
|
||||
*
|
||||
* @param string $sql An SQL string with placeholders. The
|
||||
* placeholders are assumed to be specific to the database engine
|
||||
* for this connection.
|
||||
*
|
||||
* @param array $params An array of parameters to insert into the
|
||||
* SQL string using this connection's escaping mechanism.
|
||||
*
|
||||
* @return mixed $result The result of calling this connection's
|
||||
* internal query function. The type of result depends on the
|
||||
* underlying database engine. This method is usually used when
|
||||
* the result of a query is not important, like a DDL query.
|
||||
*/
|
||||
function query($sql, $params = array())
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a transaction on this connection, if supported.
|
||||
*/
|
||||
function begin()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Commits a transaction on this connection, if supported.
|
||||
*/
|
||||
function commit()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a rollback on this connection, if supported.
|
||||
*/
|
||||
function rollback()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Run an SQL query and return the first column of the first row
|
||||
* of the result set, if any.
|
||||
*
|
||||
* @param string $sql An SQL string with placeholders. The
|
||||
* placeholders are assumed to be specific to the database engine
|
||||
* for this connection.
|
||||
*
|
||||
* @param array $params An array of parameters to insert into the
|
||||
* SQL string using this connection's escaping mechanism.
|
||||
*
|
||||
* @return mixed $result The value of the first column of the
|
||||
* first row of the result set. False if no such result was
|
||||
* found.
|
||||
*/
|
||||
function getOne($sql, $params = array())
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Run an SQL query and return the first row of the result set, if
|
||||
* any.
|
||||
*
|
||||
* @param string $sql An SQL string with placeholders. The
|
||||
* placeholders are assumed to be specific to the database engine
|
||||
* for this connection.
|
||||
*
|
||||
* @param array $params An array of parameters to insert into the
|
||||
* SQL string using this connection's escaping mechanism.
|
||||
*
|
||||
* @return array $result The first row of the result set, if any,
|
||||
* keyed on column name. False if no such result was found.
|
||||
*/
|
||||
function getRow($sql, $params = array())
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Run an SQL query with the specified parameters, if any.
|
||||
*
|
||||
* @param string $sql An SQL string with placeholders. The
|
||||
* placeholders are assumed to be specific to the database engine
|
||||
* for this connection.
|
||||
*
|
||||
* @param array $params An array of parameters to insert into the
|
||||
* SQL string using this connection's escaping mechanism.
|
||||
*
|
||||
* @return array $result An array of arrays representing the
|
||||
* result of the query; each array is keyed on column name.
|
||||
*/
|
||||
function getAll($sql, $params = array())
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
181
modules/member/php-openid-1.2.3/Auth/OpenID/DiffieHellman.php
Normal file
181
modules/member/php-openid-1.2.3/Auth/OpenID/DiffieHellman.php
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* The OpenID library's Diffie-Hellman implementation.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: See the COPYING file included in this distribution.
|
||||
*
|
||||
* @access private
|
||||
* @package OpenID
|
||||
* @author JanRain, Inc. <openid@janrain.com>
|
||||
* @copyright 2005 Janrain, Inc.
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL
|
||||
*/
|
||||
|
||||
require_once 'Auth/OpenID/BigMath.php';
|
||||
require_once 'Auth/OpenID/HMACSHA1.php';
|
||||
|
||||
function Auth_OpenID_getDefaultMod()
|
||||
{
|
||||
return '155172898181473697471232257763715539915724801'.
|
||||
'966915404479707795314057629378541917580651227423'.
|
||||
'698188993727816152646631438561595825688188889951'.
|
||||
'272158842675419950341258706556549803580104870537'.
|
||||
'681476726513255747040765857479291291572334510643'.
|
||||
'245094715007229621094194349783925984760375594985'.
|
||||
'848253359305585439638443';
|
||||
}
|
||||
|
||||
function Auth_OpenID_getDefaultGen()
|
||||
{
|
||||
return '2';
|
||||
}
|
||||
|
||||
/**
|
||||
* The Diffie-Hellman key exchange class. This class relies on
|
||||
* {@link Auth_OpenID_MathLibrary} to perform large number operations.
|
||||
*
|
||||
* @access private
|
||||
* @package OpenID
|
||||
*/
|
||||
class Auth_OpenID_DiffieHellman {
|
||||
|
||||
var $mod;
|
||||
var $gen;
|
||||
var $private;
|
||||
var $lib = null;
|
||||
|
||||
function Auth_OpenID_DiffieHellman($mod = null, $gen = null,
|
||||
$private = null, $lib = null)
|
||||
{
|
||||
if ($lib === null) {
|
||||
$this->lib =& Auth_OpenID_getMathLib();
|
||||
} else {
|
||||
$this->lib =& $lib;
|
||||
}
|
||||
|
||||
if ($mod === null) {
|
||||
$this->mod = $this->lib->init(Auth_OpenID_getDefaultMod());
|
||||
} else {
|
||||
$this->mod = $mod;
|
||||
}
|
||||
|
||||
if ($gen === null) {
|
||||
$this->gen = $this->lib->init(Auth_OpenID_getDefaultGen());
|
||||
} else {
|
||||
$this->gen = $gen;
|
||||
}
|
||||
|
||||
if ($private === null) {
|
||||
$r = $this->lib->rand($this->mod);
|
||||
$this->private = $this->lib->add($r, 1);
|
||||
} else {
|
||||
$this->private = $private;
|
||||
}
|
||||
|
||||
$this->public = $this->lib->powmod($this->gen, $this->private,
|
||||
$this->mod);
|
||||
}
|
||||
|
||||
function getSharedSecret($composite)
|
||||
{
|
||||
return $this->lib->powmod($composite, $this->private, $this->mod);
|
||||
}
|
||||
|
||||
function getPublicKey()
|
||||
{
|
||||
return $this->public;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the arguments for an OpenID Diffie-Hellman association
|
||||
* request
|
||||
*/
|
||||
function getAssocArgs()
|
||||
{
|
||||
$cpub = $this->lib->longToBase64($this->getPublicKey());
|
||||
$args = array(
|
||||
'openid.dh_consumer_public' => $cpub,
|
||||
'openid.session_type' => 'DH-SHA1'
|
||||
);
|
||||
|
||||
if ($this->lib->cmp($this->mod, Auth_OpenID_getDefaultMod()) ||
|
||||
$this->lib->cmp($this->gen, Auth_OpenID_getDefaultGen())) {
|
||||
$args['openid.dh_modulus'] = $this->lib->longToBase64($this->mod);
|
||||
$args['openid.dh_gen'] = $this->lib->longToBase64($this->gen);
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
function usingDefaultValues()
|
||||
{
|
||||
return ($this->mod == Auth_OpenID_getDefaultMod() &&
|
||||
$this->gen == Auth_OpenID_getDefaultGen());
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform the server side of the OpenID Diffie-Hellman association
|
||||
*/
|
||||
function serverAssociate($consumer_args, $assoc_secret)
|
||||
{
|
||||
$lib =& Auth_OpenID_getMathLib();
|
||||
|
||||
if (isset($consumer_args['openid.dh_modulus'])) {
|
||||
$mod = $lib->base64ToLong($consumer_args['openid.dh_modulus']);
|
||||
} else {
|
||||
$mod = null;
|
||||
}
|
||||
|
||||
if (isset($consumer_args['openid.dh_gen'])) {
|
||||
$gen = $lib->base64ToLong($consumer_args['openid.dh_gen']);
|
||||
} else {
|
||||
$gen = null;
|
||||
}
|
||||
|
||||
$cpub64 = @$consumer_args['openid.dh_consumer_public'];
|
||||
if (!isset($cpub64)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$dh = new Auth_OpenID_DiffieHellman($mod, $gen);
|
||||
$cpub = $lib->base64ToLong($cpub64);
|
||||
$mac_key = $dh->xorSecret($cpub, $assoc_secret);
|
||||
$enc_mac_key = base64_encode($mac_key);
|
||||
$spub64 = $lib->longToBase64($dh->getPublicKey());
|
||||
|
||||
$server_args = array(
|
||||
'session_type' => 'DH-SHA1',
|
||||
'dh_server_public' => $spub64,
|
||||
'enc_mac_key' => $enc_mac_key
|
||||
);
|
||||
|
||||
return $server_args;
|
||||
}
|
||||
|
||||
function consumerFinish($reply)
|
||||
{
|
||||
$spub = $this->lib->base64ToLong($reply['dh_server_public']);
|
||||
if ($this->lib->cmp($spub, 0) <= 0) {
|
||||
return false;
|
||||
}
|
||||
$enc_mac_key = base64_decode($reply['enc_mac_key']);
|
||||
return $this->xorSecret($spub, $enc_mac_key);
|
||||
}
|
||||
|
||||
function xorSecret($composite, $secret)
|
||||
{
|
||||
$dh_shared = $this->getSharedSecret($composite);
|
||||
$dh_shared_str = $this->lib->longToBinary($dh_shared);
|
||||
$sha1_dh_shared = Auth_OpenID_SHA1($dh_shared_str);
|
||||
|
||||
$xsecret = "";
|
||||
for ($i = 0; $i < strlen($secret); $i++) {
|
||||
$xsecret .= chr(ord($secret[$i]) ^ ord($sha1_dh_shared[$i]));
|
||||
}
|
||||
|
||||
return $xsecret;
|
||||
}
|
||||
}
|
||||
258
modules/member/php-openid-1.2.3/Auth/OpenID/Discover.php
Normal file
258
modules/member/php-openid-1.2.3/Auth/OpenID/Discover.php
Normal file
|
|
@ -0,0 +1,258 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* The OpenID and Yadis discovery implementation for OpenID 1.2.
|
||||
*/
|
||||
|
||||
require_once "Auth/OpenID.php";
|
||||
require_once "Auth/OpenID/Parse.php";
|
||||
require_once "Services/Yadis/XRIRes.php";
|
||||
require_once "Services/Yadis/Yadis.php";
|
||||
|
||||
define('_OPENID_1_0_NS', 'http://openid.net/xmlns/1.0');
|
||||
define('_OPENID_1_2_TYPE', 'http://openid.net/signon/1.2');
|
||||
define('_OPENID_1_1_TYPE', 'http://openid.net/signon/1.1');
|
||||
define('_OPENID_1_0_TYPE', 'http://openid.net/signon/1.0');
|
||||
|
||||
/**
|
||||
* Object representing an OpenID service endpoint.
|
||||
*/
|
||||
class Auth_OpenID_ServiceEndpoint {
|
||||
function Auth_OpenID_ServiceEndpoint()
|
||||
{
|
||||
$this->identity_url = null;
|
||||
$this->server_url = null;
|
||||
$this->type_uris = array();
|
||||
$this->delegate = null;
|
||||
$this->canonicalID = null;
|
||||
$this->used_yadis = false; // whether this came from an XRDS
|
||||
}
|
||||
|
||||
function usesExtension($extension_uri)
|
||||
{
|
||||
return in_array($extension_uri, $this->type_uris);
|
||||
}
|
||||
|
||||
function parseService($yadis_url, $uri, $type_uris, $service_element)
|
||||
{
|
||||
// Set the state of this object based on the contents of the
|
||||
// service element.
|
||||
$this->type_uris = $type_uris;
|
||||
$this->identity_url = $yadis_url;
|
||||
$this->server_url = $uri;
|
||||
$this->delegate = Auth_OpenID_ServiceEndpoint::findDelegate(
|
||||
$service_element);
|
||||
$this->used_yadis = true;
|
||||
}
|
||||
|
||||
function findDelegate($service)
|
||||
{
|
||||
// Extract a openid:Delegate value from a Yadis Service
|
||||
// element. If no delegate is found, returns null.
|
||||
|
||||
// Try to register new namespace.
|
||||
$service->parser->registerNamespace('openid',
|
||||
'http://openid.net/xmlns/1.0');
|
||||
|
||||
// XXX: should this die if there is more than one delegate
|
||||
// element?
|
||||
$delegates = $service->getElements("openid:Delegate");
|
||||
|
||||
if ($delegates) {
|
||||
return $service->parser->content($delegates[0]);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function getServerID()
|
||||
{
|
||||
// Return the identifier that should be sent as the
|
||||
// openid.identity_url parameter to the server.
|
||||
if ($this->delegate === null) {
|
||||
if ($this->canonicalID) {
|
||||
return $this->canonicalID;
|
||||
} else {
|
||||
return $this->identity_url;
|
||||
}
|
||||
} else {
|
||||
return $this->delegate;
|
||||
}
|
||||
}
|
||||
|
||||
function fromHTML($uri, $html)
|
||||
{
|
||||
// Parse the given document as HTML looking for an OpenID <link
|
||||
// rel=...>
|
||||
$urls = Auth_OpenID_legacy_discover($html);
|
||||
if ($urls === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
list($delegate_url, $server_url) = $urls;
|
||||
|
||||
$service = new Auth_OpenID_ServiceEndpoint();
|
||||
$service->identity_url = $uri;
|
||||
$service->delegate = $delegate_url;
|
||||
$service->server_url = $server_url;
|
||||
$service->type_uris = array(_OPENID_1_0_TYPE);
|
||||
return $service;
|
||||
}
|
||||
}
|
||||
|
||||
function filter_MatchesAnyOpenIDType(&$service)
|
||||
{
|
||||
$uris = $service->getTypes();
|
||||
|
||||
foreach ($uris as $uri) {
|
||||
if (in_array($uri,
|
||||
array(_OPENID_1_0_TYPE,
|
||||
_OPENID_1_1_TYPE,
|
||||
_OPENID_1_2_TYPE))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function Auth_OpenID_makeOpenIDEndpoints($uri, $endpoints)
|
||||
{
|
||||
$s = array();
|
||||
|
||||
if (!$endpoints) {
|
||||
return $s;
|
||||
}
|
||||
|
||||
foreach ($endpoints as $service) {
|
||||
$type_uris = $service->getTypes();
|
||||
$uris = $service->getURIs();
|
||||
|
||||
// If any Type URIs match and there is an endpoint URI
|
||||
// specified, then this is an OpenID endpoint
|
||||
if ($type_uris &&
|
||||
$uris) {
|
||||
|
||||
foreach ($uris as $service_uri) {
|
||||
$openid_endpoint = new Auth_OpenID_ServiceEndpoint();
|
||||
$openid_endpoint->parseService($uri,
|
||||
$service_uri,
|
||||
$type_uris,
|
||||
$service);
|
||||
|
||||
$s[] = $openid_endpoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
|
||||
function Auth_OpenID_discoverWithYadis($uri, &$fetcher)
|
||||
{
|
||||
// Discover OpenID services for a URI. Tries Yadis and falls back
|
||||
// on old-style <link rel='...'> discovery if Yadis fails.
|
||||
|
||||
// Might raise a yadis.discover.DiscoveryFailure if no document
|
||||
// came back for that URI at all. I don't think falling back to
|
||||
// OpenID 1.0 discovery on the same URL will help, so don't bother
|
||||
// to catch it.
|
||||
$openid_services = array();
|
||||
|
||||
$http_response = null;
|
||||
$response = Services_Yadis_Yadis::discover($uri, $http_response,
|
||||
$fetcher);
|
||||
|
||||
if ($response) {
|
||||
$identity_url = $response->uri;
|
||||
$openid_services =
|
||||
$response->xrds->services(array('filter_MatchesAnyOpenIDType'));
|
||||
}
|
||||
|
||||
if (!$openid_services) {
|
||||
return @Auth_OpenID_discoverWithoutYadis($uri,
|
||||
$fetcher);
|
||||
}
|
||||
|
||||
if (!$openid_services) {
|
||||
$body = $response->body;
|
||||
|
||||
// Try to parse the response as HTML to get OpenID 1.0/1.1
|
||||
// <link rel="...">
|
||||
$service = Auth_OpenID_ServiceEndpoint::fromHTML($identity_url,
|
||||
$body);
|
||||
|
||||
if ($service !== null) {
|
||||
$openid_services = array($service);
|
||||
}
|
||||
} else {
|
||||
$openid_services = Auth_OpenID_makeOpenIDEndpoints($response->uri,
|
||||
$openid_services);
|
||||
}
|
||||
|
||||
return array($identity_url, $openid_services, $http_response);
|
||||
}
|
||||
|
||||
function _Auth_OpenID_discoverServiceList($uri, &$fetcher)
|
||||
{
|
||||
list($url, $services, $resp) = Auth_OpenID_discoverWithYadis($uri,
|
||||
$fetcher);
|
||||
|
||||
return $services;
|
||||
}
|
||||
|
||||
function _Auth_OpenID_discoverXRIServiceList($uri, &$fetcher)
|
||||
{
|
||||
list($url, $services, $resp) = _Auth_OpenID_discoverXRI($uri,
|
||||
$fetcher);
|
||||
return $services;
|
||||
}
|
||||
|
||||
function Auth_OpenID_discoverWithoutYadis($uri, &$fetcher)
|
||||
{
|
||||
$http_resp = @$fetcher->get($uri);
|
||||
|
||||
if ($http_resp->status != 200) {
|
||||
return array(null, array(), $http_resp);
|
||||
}
|
||||
|
||||
$identity_url = $http_resp->final_url;
|
||||
|
||||
// Try to parse the response as HTML to get OpenID 1.0/1.1 <link
|
||||
// rel="...">
|
||||
$endpoint =& new Auth_OpenID_ServiceEndpoint();
|
||||
$service = $endpoint->fromHTML($identity_url, $http_resp->body);
|
||||
if ($service === null) {
|
||||
$openid_services = array();
|
||||
} else {
|
||||
$openid_services = array($service);
|
||||
}
|
||||
|
||||
return array($identity_url, $openid_services, $http_resp);
|
||||
}
|
||||
|
||||
function _Auth_OpenID_discoverXRI($iname, &$fetcher)
|
||||
{
|
||||
$services = new Services_Yadis_ProxyResolver($fetcher);
|
||||
list($canonicalID, $service_list) = $services->query($iname,
|
||||
array(_OPENID_1_0_TYPE,
|
||||
_OPENID_1_1_TYPE,
|
||||
_OPENID_1_2_TYPE),
|
||||
array('filter_MatchesAnyOpenIDType'));
|
||||
|
||||
$endpoints = Auth_OpenID_makeOpenIDEndpoints($iname, $service_list);
|
||||
|
||||
for ($i = 0; $i < count($endpoints); $i++) {
|
||||
$endpoints[$i]->canonicalID = $canonicalID;
|
||||
}
|
||||
|
||||
// FIXME: returned xri should probably be in some normal form
|
||||
return array($iname, $endpoints, null);
|
||||
}
|
||||
|
||||
function Auth_OpenID_discover($uri, &$fetcher)
|
||||
{
|
||||
return @Auth_OpenID_discoverWithYadis($uri, $fetcher);
|
||||
}
|
||||
|
||||
?>
|
||||
116
modules/member/php-openid-1.2.3/Auth/OpenID/DumbStore.php
Normal file
116
modules/member/php-openid-1.2.3/Auth/OpenID/DumbStore.php
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file supplies a dumb store backend for OpenID servers and
|
||||
* consumers.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Import the interface for creating a new store class.
|
||||
*/
|
||||
require_once 'Auth/OpenID/Interface.php';
|
||||
require_once 'Auth/OpenID/HMACSHA1.php';
|
||||
|
||||
/**
|
||||
* This is a store for use in the worst case, when you have no way of
|
||||
* saving state on the consumer site. Using this store makes the
|
||||
* consumer vulnerable to replay attacks, as it's unable to use
|
||||
* nonces. Avoid using this store if it is at all possible.
|
||||
*
|
||||
* Most of the methods of this class are implementation details.
|
||||
* Users of this class need to worry only about the constructor.
|
||||
*
|
||||
* @package OpenID
|
||||
*/
|
||||
class Auth_OpenID_DumbStore extends Auth_OpenID_OpenIDStore {
|
||||
|
||||
/**
|
||||
* Creates a new {@link Auth_OpenID_DumbStore} instance. For the security
|
||||
* of the tokens generated by the library, this class attempts to
|
||||
* at least have a secure implementation of getAuthKey.
|
||||
*
|
||||
* When you create an instance of this class, pass in a secret
|
||||
* phrase. The phrase is hashed with sha1 to make it the correct
|
||||
* length and form for an auth key. That allows you to use a long
|
||||
* string as the secret phrase, which means you can make it very
|
||||
* difficult to guess.
|
||||
*
|
||||
* Each {@link Auth_OpenID_DumbStore} instance that is created for use by
|
||||
* your consumer site needs to use the same $secret_phrase.
|
||||
*
|
||||
* @param string secret_phrase The phrase used to create the auth
|
||||
* key returned by getAuthKey
|
||||
*/
|
||||
function Auth_OpenID_DumbStore($secret_phrase)
|
||||
{
|
||||
$this->auth_key = Auth_OpenID_SHA1($secret_phrase);
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation does nothing.
|
||||
*/
|
||||
function storeAssociation($server_url, $association)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation always returns null.
|
||||
*/
|
||||
function getAssociation($server_url, $handle = null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation always returns false.
|
||||
*/
|
||||
function removeAssociation($server_url, $handle)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This implementation does nothing.
|
||||
*/
|
||||
function storeNonce($nonce)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* In a system truly limited to dumb mode, nonces must all be
|
||||
* accepted. This therefore always returns true, which makes
|
||||
* replay attacks feasible.
|
||||
*/
|
||||
function useNonce($nonce)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the auth key generated by the constructor.
|
||||
*/
|
||||
function getAuthKey()
|
||||
{
|
||||
return $this->auth_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* This store is a dumb mode store, so this method is overridden
|
||||
* to return true.
|
||||
*/
|
||||
function isDumb()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
674
modules/member/php-openid-1.2.3/Auth/OpenID/FileStore.php
Normal file
674
modules/member/php-openid-1.2.3/Auth/OpenID/FileStore.php
Normal file
|
|
@ -0,0 +1,674 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file supplies a Memcached store backend for OpenID servers and
|
||||
* consumers.
|
||||
*
|
||||
* 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 base class for creating a new interface.
|
||||
*/
|
||||
require_once 'Auth/OpenID.php';
|
||||
require_once 'Auth/OpenID/Interface.php';
|
||||
require_once 'Auth/OpenID/HMACSHA1.php';
|
||||
|
||||
/**
|
||||
* This is a filesystem-based store for OpenID associations and
|
||||
* nonces. This store should be safe for use in concurrent systems on
|
||||
* both windows and unix (excluding NFS filesystems). There are a
|
||||
* couple race conditions in the system, but those failure cases have
|
||||
* been set up in such a way that the worst-case behavior is someone
|
||||
* having to try to log in a second time.
|
||||
*
|
||||
* Most of the methods of this class are implementation details.
|
||||
* People wishing to just use this store need only pay attention to
|
||||
* the constructor.
|
||||
*
|
||||
* @package OpenID
|
||||
*/
|
||||
class Auth_OpenID_FileStore extends Auth_OpenID_OpenIDStore {
|
||||
|
||||
/**
|
||||
* Initializes a new {@link Auth_OpenID_FileStore}. This
|
||||
* initializes the nonce and association directories, which are
|
||||
* subdirectories of the directory passed in.
|
||||
*
|
||||
* @param string $directory This is the directory to put the store
|
||||
* directories in.
|
||||
*/
|
||||
function Auth_OpenID_FileStore($directory)
|
||||
{
|
||||
if (!Auth_OpenID::ensureDir($directory)) {
|
||||
trigger_error('Not a directory and failed to create: '
|
||||
. $directory, E_USER_ERROR);
|
||||
}
|
||||
$directory = realpath($directory);
|
||||
|
||||
$this->directory = $directory;
|
||||
$this->active = true;
|
||||
|
||||
$this->nonce_dir = $directory . DIRECTORY_SEPARATOR . 'nonces';
|
||||
|
||||
$this->association_dir = $directory . DIRECTORY_SEPARATOR .
|
||||
'associations';
|
||||
|
||||
// Temp dir must be on the same filesystem as the assciations
|
||||
// $directory and the $directory containing the auth key file.
|
||||
$this->temp_dir = $directory . DIRECTORY_SEPARATOR . 'temp';
|
||||
|
||||
$this->auth_key_name = $directory . DIRECTORY_SEPARATOR . 'auth_key';
|
||||
|
||||
$this->max_nonce_age = 6 * 60 * 60; // Six hours, in seconds
|
||||
|
||||
if (!$this->_setup()) {
|
||||
trigger_error('Failed to initialize OpenID file store in ' .
|
||||
$directory, E_USER_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
function destroy()
|
||||
{
|
||||
Auth_OpenID_FileStore::_rmtree($this->directory);
|
||||
$this->active = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that the directories in which we store our data
|
||||
* exist.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _setup()
|
||||
{
|
||||
return (Auth_OpenID::ensureDir(dirname($this->auth_key_name)) &&
|
||||
Auth_OpenID::ensureDir($this->nonce_dir) &&
|
||||
Auth_OpenID::ensureDir($this->association_dir) &&
|
||||
Auth_OpenID::ensureDir($this->temp_dir));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a temporary file on the same filesystem as
|
||||
* $this->auth_key_name and $this->association_dir.
|
||||
*
|
||||
* The temporary directory should not be cleaned if there are any
|
||||
* processes using the store. If there is no active process using
|
||||
* the store, it is safe to remove all of the files in the
|
||||
* temporary directory.
|
||||
*
|
||||
* @return array ($fd, $filename)
|
||||
* @access private
|
||||
*/
|
||||
function _mktemp()
|
||||
{
|
||||
$name = Auth_OpenID_FileStore::_mkstemp($dir = $this->temp_dir);
|
||||
$file_obj = @fopen($name, 'wb');
|
||||
if ($file_obj !== false) {
|
||||
return array($file_obj, $name);
|
||||
} else {
|
||||
Auth_OpenID_FileStore::_removeIfPresent($name);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the auth key from the auth key file. Will return None if
|
||||
* there is currently no key.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
function readAuthKey()
|
||||
{
|
||||
if (!$this->active) {
|
||||
trigger_error("FileStore no longer active", E_USER_ERROR);
|
||||
return null;
|
||||
}
|
||||
|
||||
$auth_key_file = @fopen($this->auth_key_name, 'rb');
|
||||
if ($auth_key_file === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$key = fread($auth_key_file, filesize($this->auth_key_name));
|
||||
fclose($auth_key_file);
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a new random auth key and safely store it in the
|
||||
* location specified by $this->auth_key_name.
|
||||
*
|
||||
* @return string $key
|
||||
*/
|
||||
function createAuthKey()
|
||||
{
|
||||
if (!$this->active) {
|
||||
trigger_error("FileStore no longer active", E_USER_ERROR);
|
||||
return null;
|
||||
}
|
||||
|
||||
$auth_key = Auth_OpenID_CryptUtil::randomString($this->AUTH_KEY_LEN);
|
||||
|
||||
list($file_obj, $tmp) = $this->_mktemp();
|
||||
|
||||
fwrite($file_obj, $auth_key);
|
||||
fflush($file_obj);
|
||||
fclose($file_obj);
|
||||
|
||||
if (function_exists('link')) {
|
||||
// Posix filesystem
|
||||
$saved = link($tmp, $this->auth_key_name);
|
||||
Auth_OpenID_FileStore::_removeIfPresent($tmp);
|
||||
} else {
|
||||
// Windows filesystem
|
||||
$saved = rename($tmp, $this->auth_key_name);
|
||||
}
|
||||
|
||||
if (!$saved) {
|
||||
// The link failed, either because we lack the permission,
|
||||
// or because the file already exists; try to read the key
|
||||
// in case the file already existed.
|
||||
$auth_key = $this->readAuthKey();
|
||||
}
|
||||
|
||||
return $auth_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the auth key from the file specified by
|
||||
* $this->auth_key_name, creating it if it does not exist.
|
||||
*
|
||||
* @return string $key
|
||||
*/
|
||||
function getAuthKey()
|
||||
{
|
||||
if (!$this->active) {
|
||||
trigger_error("FileStore no longer active", E_USER_ERROR);
|
||||
return null;
|
||||
}
|
||||
|
||||
$auth_key = $this->readAuthKey();
|
||||
if ($auth_key === null) {
|
||||
$auth_key = $this->createAuthKey();
|
||||
|
||||
if (strlen($auth_key) != $this->AUTH_KEY_LEN) {
|
||||
$fmt = 'Got an invalid auth key from %s. Expected '.
|
||||
'%d-byte string. Got: %s';
|
||||
$msg = sprintf($fmt, $this->auth_key_name, $this->AUTH_KEY_LEN,
|
||||
$auth_key);
|
||||
trigger_error($msg, E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return $auth_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a unique filename for a given server url and
|
||||
* handle. This implementation does not assume anything about the
|
||||
* format of the handle. The filename that is returned will
|
||||
* contain the domain name from the server URL for ease of human
|
||||
* inspection of the data directory.
|
||||
*
|
||||
* @return string $filename
|
||||
*/
|
||||
function getAssociationFilename($server_url, $handle)
|
||||
{
|
||||
if (!$this->active) {
|
||||
trigger_error("FileStore no longer active", E_USER_ERROR);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (strpos($server_url, '://') === false) {
|
||||
trigger_error(sprintf("Bad server URL: %s", $server_url),
|
||||
E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
|
||||
list($proto, $rest) = explode('://', $server_url, 2);
|
||||
$parts = explode('/', $rest);
|
||||
$domain = Auth_OpenID_FileStore::_filenameEscape($parts[0]);
|
||||
$url_hash = Auth_OpenID_FileStore::_safe64($server_url);
|
||||
if ($handle) {
|
||||
$handle_hash = Auth_OpenID_FileStore::_safe64($handle);
|
||||
} else {
|
||||
$handle_hash = '';
|
||||
}
|
||||
|
||||
$filename = sprintf('%s-%s-%s-%s', $proto, $domain, $url_hash,
|
||||
$handle_hash);
|
||||
|
||||
return $this->association_dir. DIRECTORY_SEPARATOR . $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store an association in the association directory.
|
||||
*/
|
||||
function storeAssociation($server_url, $association)
|
||||
{
|
||||
if (!$this->active) {
|
||||
trigger_error("FileStore no longer active", E_USER_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
$association_s = $association->serialize();
|
||||
$filename = $this->getAssociationFilename($server_url,
|
||||
$association->handle);
|
||||
list($tmp_file, $tmp) = $this->_mktemp();
|
||||
|
||||
if (!$tmp_file) {
|
||||
trigger_error("_mktemp didn't return a valid file descriptor",
|
||||
E_USER_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
fwrite($tmp_file, $association_s);
|
||||
|
||||
fflush($tmp_file);
|
||||
|
||||
fclose($tmp_file);
|
||||
|
||||
if (@rename($tmp, $filename)) {
|
||||
return true;
|
||||
} else {
|
||||
// In case we are running on Windows, try unlinking the
|
||||
// file in case it exists.
|
||||
@unlink($filename);
|
||||
|
||||
// Now the target should not exist. Try renaming again,
|
||||
// giving up if it fails.
|
||||
if (@rename($tmp, $filename)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// If there was an error, don't leave the temporary file
|
||||
// around.
|
||||
Auth_OpenID_FileStore::_removeIfPresent($tmp);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an association. If no handle is specified, return the
|
||||
* association with the most recent issue time.
|
||||
*
|
||||
* @return mixed $association
|
||||
*/
|
||||
function getAssociation($server_url, $handle = null)
|
||||
{
|
||||
if (!$this->active) {
|
||||
trigger_error("FileStore no longer active", E_USER_ERROR);
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($handle === null) {
|
||||
$handle = '';
|
||||
}
|
||||
|
||||
// The filename with the empty handle is a prefix of all other
|
||||
// associations for the given server URL.
|
||||
$filename = $this->getAssociationFilename($server_url, $handle);
|
||||
|
||||
if ($handle) {
|
||||
return $this->_getAssociation($filename);
|
||||
} else {
|
||||
$association_files =
|
||||
Auth_OpenID_FileStore::_listdir($this->association_dir);
|
||||
$matching_files = array();
|
||||
|
||||
// strip off the path to do the comparison
|
||||
$name = basename($filename);
|
||||
foreach ($association_files as $association_file) {
|
||||
if (strpos($association_file, $name) === 0) {
|
||||
$matching_files[] = $association_file;
|
||||
}
|
||||
}
|
||||
|
||||
$matching_associations = array();
|
||||
// read the matching files and sort by time issued
|
||||
foreach ($matching_files as $name) {
|
||||
$full_name = $this->association_dir . DIRECTORY_SEPARATOR .
|
||||
$name;
|
||||
$association = $this->_getAssociation($full_name);
|
||||
if ($association !== null) {
|
||||
$matching_associations[] = array($association->issued,
|
||||
$association);
|
||||
}
|
||||
}
|
||||
|
||||
$issued = array();
|
||||
$assocs = array();
|
||||
foreach ($matching_associations as $key => $assoc) {
|
||||
$issued[$key] = $assoc[0];
|
||||
$assocs[$key] = $assoc[1];
|
||||
}
|
||||
|
||||
array_multisort($issued, SORT_DESC, $assocs, SORT_DESC,
|
||||
$matching_associations);
|
||||
|
||||
// return the most recently issued one.
|
||||
if ($matching_associations) {
|
||||
list($issued, $assoc) = $matching_associations[0];
|
||||
return $assoc;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _getAssociation($filename)
|
||||
{
|
||||
if (!$this->active) {
|
||||
trigger_error("FileStore no longer active", E_USER_ERROR);
|
||||
return null;
|
||||
}
|
||||
|
||||
$assoc_file = @fopen($filename, 'rb');
|
||||
|
||||
if ($assoc_file === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$assoc_s = fread($assoc_file, filesize($filename));
|
||||
fclose($assoc_file);
|
||||
|
||||
if (!$assoc_s) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$association =
|
||||
Auth_OpenID_Association::deserialize('Auth_OpenID_Association',
|
||||
$assoc_s);
|
||||
|
||||
if (!$association) {
|
||||
Auth_OpenID_FileStore::_removeIfPresent($filename);
|
||||
return null;
|
||||
}
|
||||
|
||||
if ($association->getExpiresIn() == 0) {
|
||||
Auth_OpenID_FileStore::_removeIfPresent($filename);
|
||||
return null;
|
||||
} else {
|
||||
return $association;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an association if it exists. Do nothing if it does not.
|
||||
*
|
||||
* @return bool $success
|
||||
*/
|
||||
function removeAssociation($server_url, $handle)
|
||||
{
|
||||
if (!$this->active) {
|
||||
trigger_error("FileStore no longer active", E_USER_ERROR);
|
||||
return null;
|
||||
}
|
||||
|
||||
$assoc = $this->getAssociation($server_url, $handle);
|
||||
if ($assoc === null) {
|
||||
return false;
|
||||
} else {
|
||||
$filename = $this->getAssociationFilename($server_url, $handle);
|
||||
return Auth_OpenID_FileStore::_removeIfPresent($filename);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark this nonce as present.
|
||||
*/
|
||||
function storeNonce($nonce)
|
||||
{
|
||||
if (!$this->active) {
|
||||
trigger_error("FileStore no longer active", E_USER_ERROR);
|
||||
return null;
|
||||
}
|
||||
|
||||
$filename = $this->nonce_dir . DIRECTORY_SEPARATOR . $nonce;
|
||||
$nonce_file = fopen($filename, 'w');
|
||||
if ($nonce_file === false) {
|
||||
return false;
|
||||
}
|
||||
fclose($nonce_file);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether this nonce is present. As a side effect, mark it
|
||||
* as no longer present.
|
||||
*
|
||||
* @return bool $present
|
||||
*/
|
||||
function useNonce($nonce)
|
||||
{
|
||||
if (!$this->active) {
|
||||
trigger_error("FileStore no longer active", E_USER_ERROR);
|
||||
return null;
|
||||
}
|
||||
|
||||
$filename = $this->nonce_dir . DIRECTORY_SEPARATOR . $nonce;
|
||||
$st = @stat($filename);
|
||||
|
||||
if ($st === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Either it is too old or we are using it. Either way, we
|
||||
// must remove the file.
|
||||
if (!unlink($filename)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$now = time();
|
||||
$nonce_age = $now - $st[9];
|
||||
|
||||
// We can us it if the age of the file is less than the
|
||||
// expiration time.
|
||||
return $nonce_age <= $this->max_nonce_age;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove expired entries from the database. This is potentially
|
||||
* expensive, so only run when it is acceptable to take time.
|
||||
*/
|
||||
function clean()
|
||||
{
|
||||
if (!$this->active) {
|
||||
trigger_error("FileStore no longer active", E_USER_ERROR);
|
||||
return null;
|
||||
}
|
||||
|
||||
$nonces = Auth_OpenID_FileStore::_listdir($this->nonce_dir);
|
||||
$now = time();
|
||||
|
||||
// Check all nonces for expiry
|
||||
foreach ($nonces as $nonce) {
|
||||
$filename = $this->nonce_dir . DIRECTORY_SEPARATOR . $nonce;
|
||||
$st = @stat($filename);
|
||||
|
||||
if ($st !== false) {
|
||||
// Remove the nonce if it has expired
|
||||
$nonce_age = $now - $st[9];
|
||||
if ($nonce_age > $this->max_nonce_age) {
|
||||
Auth_OpenID_FileStore::_removeIfPresent($filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$association_filenames =
|
||||
Auth_OpenID_FileStore::_listdir($this->association_dir);
|
||||
|
||||
foreach ($association_filenames as $association_filename) {
|
||||
$association_file = fopen($association_filename, 'rb');
|
||||
|
||||
if ($association_file !== false) {
|
||||
$assoc_s = fread($association_file,
|
||||
filesize($association_filename));
|
||||
fclose($association_file);
|
||||
|
||||
// Remove expired or corrupted associations
|
||||
$association =
|
||||
Auth_OpenID_Association::deserialize(
|
||||
'Auth_OpenID_Association', $assoc_s);
|
||||
|
||||
if ($association === null) {
|
||||
Auth_OpenID_FileStore::_removeIfPresent(
|
||||
$association_filename);
|
||||
} else {
|
||||
if ($association->getExpiresIn() == 0) {
|
||||
Auth_OpenID_FileStore::_removeIfPresent(
|
||||
$association_filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _rmtree($dir)
|
||||
{
|
||||
if ($dir[strlen($dir) - 1] != DIRECTORY_SEPARATOR) {
|
||||
$dir .= DIRECTORY_SEPARATOR;
|
||||
}
|
||||
|
||||
if ($handle = opendir($dir)) {
|
||||
while ($item = readdir($handle)) {
|
||||
if (!in_array($item, array('.', '..'))) {
|
||||
if (is_dir($dir . $item)) {
|
||||
|
||||
if (!Auth_OpenID_FileStore::_rmtree($dir . $item)) {
|
||||
return false;
|
||||
}
|
||||
} else if (is_file($dir . $item)) {
|
||||
if (!unlink($dir . $item)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir($handle);
|
||||
|
||||
if (!@rmdir($dir)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// Couldn't open directory.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _mkstemp($dir)
|
||||
{
|
||||
foreach (range(0, 4) as $i) {
|
||||
$name = tempnam($dir, "php_openid_filestore_");
|
||||
|
||||
if ($name !== false) {
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _mkdtemp($dir)
|
||||
{
|
||||
foreach (range(0, 4) as $i) {
|
||||
$name = $dir . strval(DIRECTORY_SEPARATOR) . strval(getmypid()) .
|
||||
"-" . strval(rand(1, time()));
|
||||
if (!mkdir($name, 0700)) {
|
||||
return false;
|
||||
} else {
|
||||
return $name;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _listdir($dir)
|
||||
{
|
||||
$handle = opendir($dir);
|
||||
$files = array();
|
||||
while (false !== ($filename = readdir($handle))) {
|
||||
$files[] = $filename;
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _isFilenameSafe($char)
|
||||
{
|
||||
$_Auth_OpenID_filename_allowed = Auth_OpenID_letters .
|
||||
Auth_OpenID_digits . ".";
|
||||
return (strpos($_Auth_OpenID_filename_allowed, $char) !== false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _safe64($str)
|
||||
{
|
||||
$h64 = base64_encode(Auth_OpenID_SHA1($str));
|
||||
$h64 = str_replace('+', '_', $h64);
|
||||
$h64 = str_replace('/', '.', $h64);
|
||||
$h64 = str_replace('=', '', $h64);
|
||||
return $h64;
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _filenameEscape($str)
|
||||
{
|
||||
$filename = "";
|
||||
for ($i = 0; $i < strlen($str); $i++) {
|
||||
$c = $str[$i];
|
||||
if (Auth_OpenID_FileStore::_isFilenameSafe($c)) {
|
||||
$filename .= $c;
|
||||
} else {
|
||||
$filename .= sprintf("_%02X", ord($c));
|
||||
}
|
||||
}
|
||||
return $filename;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to remove a file, returning whether the file existed at
|
||||
* the time of the call.
|
||||
*
|
||||
* @access private
|
||||
* @return bool $result True if the file was present, false if not.
|
||||
*/
|
||||
function _removeIfPresent($filename)
|
||||
{
|
||||
return @unlink($filename);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
72
modules/member/php-openid-1.2.3/Auth/OpenID/HMACSHA1.php
Normal file
72
modules/member/php-openid-1.2.3/Auth/OpenID/HMACSHA1.php
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This is the HMACSHA1 implementation for the OpenID library.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: See the COPYING file included in this distribution.
|
||||
*
|
||||
* @access private
|
||||
* @package OpenID
|
||||
* @author JanRain, Inc. <openid@janrain.com>
|
||||
* @copyright 2005 Janrain, Inc.
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL
|
||||
*/
|
||||
|
||||
/**
|
||||
* SHA1_BLOCKSIZE is this module's SHA1 blocksize used by the fallback
|
||||
* implementation.
|
||||
*/
|
||||
define('Auth_OpenID_SHA1_BLOCKSIZE', 64);
|
||||
|
||||
if (!function_exists('sha1')) {
|
||||
/**
|
||||
* Return a raw SHA1 hash of the given string
|
||||
*
|
||||
* XXX: include the SHA1 code from Dan Libby's OpenID library
|
||||
*/
|
||||
function Auth_OpenID_SHA1($text)
|
||||
{
|
||||
trigger_error('No SHA1 function found', E_USER_ERROR);
|
||||
}
|
||||
} else {
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
function Auth_OpenID_SHA1($text)
|
||||
{
|
||||
$hex = sha1($text);
|
||||
$raw = '';
|
||||
for ($i = 0; $i < 40; $i += 2) {
|
||||
$hexcode = substr($hex, $i, 2);
|
||||
$charcode = (int)base_convert($hexcode, 16, 10);
|
||||
$raw .= chr($charcode);
|
||||
}
|
||||
return $raw;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute an HMAC/SHA1 hash.
|
||||
*
|
||||
* @access private
|
||||
* @param string $key The HMAC key
|
||||
* @param string $text The message text to hash
|
||||
* @return string $mac The MAC
|
||||
*/
|
||||
function Auth_OpenID_HMACSHA1($key, $text)
|
||||
{
|
||||
if (strlen($key) > Auth_OpenID_SHA1_BLOCKSIZE) {
|
||||
$key = Auth_OpenID_SHA1($key, true);
|
||||
}
|
||||
|
||||
$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);
|
||||
$hash1 = Auth_OpenID_SHA1(($key ^ $ipad) . $text, true);
|
||||
$hmac = Auth_OpenID_SHA1(($key ^ $opad) . $hash1, true);
|
||||
return $hmac;
|
||||
}
|
||||
|
||||
?>
|
||||
188
modules/member/php-openid-1.2.3/Auth/OpenID/Interface.php
Normal file
188
modules/member/php-openid-1.2.3/Auth/OpenID/Interface.php
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This file specifies the interface for PHP OpenID store implementations.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* This is the interface for the store objects the OpenID library
|
||||
* uses. It is a single class that provides all of the persistence
|
||||
* mechanisms that the OpenID library needs, for both servers and
|
||||
* consumers. If you want to create an SQL-driven store, please see
|
||||
* then {@link Auth_OpenID_SQLStore} class.
|
||||
*
|
||||
* @package OpenID
|
||||
* @author JanRain, Inc. <openid@janrain.com>
|
||||
*/
|
||||
class Auth_OpenID_OpenIDStore {
|
||||
/**
|
||||
* @var integer The length of the auth key that should be returned
|
||||
* by the getAuthKey method.
|
||||
*/
|
||||
var $AUTH_KEY_LEN = 20;
|
||||
|
||||
/**
|
||||
* This method puts an Association object into storage,
|
||||
* retrievable by server URL and handle.
|
||||
*
|
||||
* @param string $server_url The URL of the identity server that
|
||||
* this association is with. Because of the way the server portion
|
||||
* of the library uses this interface, don't assume there are any
|
||||
* limitations on the character set of the input string. In
|
||||
* particular, expect to see unescaped non-url-safe characters in
|
||||
* the server_url field.
|
||||
*
|
||||
* @param Association $association The Association to store.
|
||||
*/
|
||||
function storeAssociation($server_url, $association)
|
||||
{
|
||||
trigger_error("Auth_OpenID_OpenIDStore::storeAssociation ".
|
||||
"not implemented", E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns an Association object from storage that
|
||||
* matches the server URL and, if specified, handle. It returns
|
||||
* null if no such association is found or if the matching
|
||||
* association is expired.
|
||||
*
|
||||
* If no handle is specified, the store may return any association
|
||||
* which matches the server URL. If multiple associations are
|
||||
* valid, the recommended return value for this method is the one
|
||||
* that will remain valid for the longest duration.
|
||||
*
|
||||
* This method is allowed (and encouraged) to garbage collect
|
||||
* expired associations when found. This method must not return
|
||||
* expired associations.
|
||||
*
|
||||
* @param string $server_url The URL of the identity server to get
|
||||
* the association for. Because of the way the server portion of
|
||||
* the library uses this interface, don't assume there are any
|
||||
* limitations on the character set of the input string. In
|
||||
* particular, expect to see unescaped non-url-safe characters in
|
||||
* the server_url field.
|
||||
*
|
||||
* @param mixed $handle This optional parameter is the handle of
|
||||
* the specific association to get. If no specific handle is
|
||||
* provided, any valid association matching the server URL is
|
||||
* returned.
|
||||
*
|
||||
* @return Association The Association for the given identity
|
||||
* server.
|
||||
*/
|
||||
function getAssociation($server_url, $handle = null)
|
||||
{
|
||||
trigger_error("Auth_OpenID_OpenIDStore::getAssociation ".
|
||||
"not implemented", E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method removes the matching association if it's found, and
|
||||
* returns whether the association was removed or not.
|
||||
*
|
||||
* @param string $server_url The URL of the identity server the
|
||||
* association to remove belongs to. Because of the way the server
|
||||
* portion of the library uses this interface, don't assume there
|
||||
* are any limitations on the character set of the input
|
||||
* string. In particular, expect to see unescaped non-url-safe
|
||||
* characters in the server_url field.
|
||||
*
|
||||
* @param string $handle This is the handle of the association to
|
||||
* remove. If there isn't an association found that matches both
|
||||
* the given URL and handle, then there was no matching handle
|
||||
* found.
|
||||
*
|
||||
* @return mixed Returns whether or not the given association existed.
|
||||
*/
|
||||
function removeAssociation($server_url, $handle)
|
||||
{
|
||||
trigger_error("Auth_OpenID_OpenIDStore::removeAssociation ".
|
||||
"not implemented", E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores a nonce. This is used by the consumer to prevent replay
|
||||
* attacks.
|
||||
*
|
||||
* @param string $nonce The nonce to store.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
function storeNonce($nonce)
|
||||
{
|
||||
trigger_error("Auth_OpenID_OpenIDStore::storeNonce ".
|
||||
"not implemented", E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when the library is attempting to use a
|
||||
* nonce. If the nonce is in the store, this method removes it and
|
||||
* returns a value which evaluates as true. Otherwise it returns a
|
||||
* value which evaluates as false.
|
||||
*
|
||||
* This method is allowed and encouraged to treat nonces older
|
||||
* than some period (a very conservative window would be 6 hours,
|
||||
* for example) as no longer existing, and return False and remove
|
||||
* them.
|
||||
*
|
||||
* @param string $nonce The nonce to use.
|
||||
*
|
||||
* @return bool Whether or not the nonce was valid.
|
||||
*/
|
||||
function useNonce($nonce)
|
||||
{
|
||||
trigger_error("Auth_OpenID_OpenIDStore::useNonce ".
|
||||
"not implemented", E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a key used to sign the tokens, to ensure
|
||||
* that they haven't been tampered with in transit. It should
|
||||
* return the same key every time it is called. The key returned
|
||||
* should be {@link AUTH_KEY_LEN} bytes long.
|
||||
*
|
||||
* @return string The key. It should be {@link AUTH_KEY_LEN} bytes in
|
||||
* length, and use the full range of byte values. That is, it
|
||||
* should be treated as a lump of binary data stored in a string.
|
||||
*/
|
||||
function getAuthKey()
|
||||
{
|
||||
trigger_error("Auth_OpenID_OpenIDStore::getAuthKey ".
|
||||
"not implemented", E_USER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method must return true if the store is a dumb-mode-style
|
||||
* store. Unlike all other methods in this class, this one
|
||||
* provides a default implementation, which returns false.
|
||||
*
|
||||
* In general, any custom subclass of {@link Auth_OpenID_OpenIDStore}
|
||||
* won't override this method, as custom subclasses are only likely to
|
||||
* be created when the store is fully functional.
|
||||
*
|
||||
* @return bool true if the store works fully, false if the
|
||||
* consumer will have to use dumb mode to use this store.
|
||||
*/
|
||||
function isDumb()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all entries from the store; implementation is optional.
|
||||
*/
|
||||
function reset()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
?>
|
||||
112
modules/member/php-openid-1.2.3/Auth/OpenID/KVForm.php
Normal file
112
modules/member/php-openid-1.2.3/Auth/OpenID/KVForm.php
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* OpenID protocol key-value/comma-newline format parsing and
|
||||
* serialization
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: See the COPYING file included in this distribution.
|
||||
*
|
||||
* @access private
|
||||
* @package OpenID
|
||||
* @author JanRain, Inc. <openid@janrain.com>
|
||||
* @copyright 2005 Janrain, Inc.
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL
|
||||
*/
|
||||
|
||||
/**
|
||||
* Container for key-value/comma-newline OpenID format and parsing
|
||||
*/
|
||||
class Auth_OpenID_KVForm {
|
||||
/**
|
||||
* Convert an OpenID colon/newline separated string into an
|
||||
* associative array
|
||||
*
|
||||
* @static
|
||||
* @access private
|
||||
*/
|
||||
function toArray($kvs, $strict=false)
|
||||
{
|
||||
$lines = explode("\n", $kvs);
|
||||
|
||||
$last = array_pop($lines);
|
||||
if ($last !== '') {
|
||||
array_push($lines, $last);
|
||||
if ($strict) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$values = array();
|
||||
|
||||
for ($lineno = 0; $lineno < count($lines); $lineno++) {
|
||||
$line = $lines[$lineno];
|
||||
$kv = explode(':', $line, 2);
|
||||
if (count($kv) != 2) {
|
||||
if ($strict) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
$key = $kv[0];
|
||||
$tkey = trim($key);
|
||||
if ($tkey != $key) {
|
||||
if ($strict) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$value = $kv[1];
|
||||
$tval = trim($value);
|
||||
if ($tval != $value) {
|
||||
if ($strict) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$values[$tkey] = $tval;
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an array into an OpenID colon/newline separated string
|
||||
*
|
||||
* @static
|
||||
* @access private
|
||||
*/
|
||||
function fromArray($values)
|
||||
{
|
||||
if ($values === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ksort($values);
|
||||
|
||||
$serialized = '';
|
||||
foreach ($values as $key => $value) {
|
||||
if (is_array($value)) {
|
||||
list($key, $value) = array($value[0], $value[1]);
|
||||
}
|
||||
|
||||
if (strpos($key, ':') !== false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (strpos($key, "\n") !== false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (strpos($value, "\n") !== false) {
|
||||
return null;
|
||||
}
|
||||
$serialized .= "$key:$value\n";
|
||||
}
|
||||
return $serialized;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
78
modules/member/php-openid-1.2.3/Auth/OpenID/MySQLStore.php
Normal file
78
modules/member/php-openid-1.2.3/Auth/OpenID/MySQLStore.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* A MySQL store.
|
||||
*
|
||||
* @package OpenID
|
||||
*/
|
||||
|
||||
/**
|
||||
* Require the base class file.
|
||||
*/
|
||||
require_once "Auth/OpenID/SQLStore.php";
|
||||
|
||||
/**
|
||||
* An SQL store that uses MySQL as its backend.
|
||||
*
|
||||
* @package OpenID
|
||||
*/
|
||||
class Auth_OpenID_MySQLStore extends Auth_OpenID_SQLStore {
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function setSQL()
|
||||
{
|
||||
$this->sql['nonce_table'] =
|
||||
"CREATE TABLE %s (nonce CHAR(8) UNIQUE PRIMARY KEY, ".
|
||||
"expires INTEGER) TYPE=InnoDB";
|
||||
|
||||
$this->sql['assoc_table'] =
|
||||
"CREATE TABLE %s (server_url BLOB, handle VARCHAR(255), ".
|
||||
"secret BLOB, issued INTEGER, lifetime INTEGER, ".
|
||||
"assoc_type VARCHAR(64), PRIMARY KEY (server_url(255), handle)) ".
|
||||
"TYPE=InnoDB";
|
||||
|
||||
$this->sql['settings_table'] =
|
||||
"CREATE TABLE %s (setting VARCHAR(128) UNIQUE PRIMARY KEY, ".
|
||||
"value BLOB) TYPE=InnoDB";
|
||||
|
||||
$this->sql['create_auth'] =
|
||||
"INSERT INTO %s VALUES ('auth_key', !)";
|
||||
|
||||
$this->sql['get_auth'] =
|
||||
"SELECT value FROM %s WHERE setting = 'auth_key'";
|
||||
|
||||
$this->sql['set_assoc'] =
|
||||
"REPLACE INTO %s VALUES (?, ?, !, ?, ?, ?)";
|
||||
|
||||
$this->sql['get_assocs'] =
|
||||
"SELECT handle, secret, issued, lifetime, assoc_type FROM %s ".
|
||||
"WHERE server_url = ?";
|
||||
|
||||
$this->sql['get_assoc'] =
|
||||
"SELECT handle, secret, issued, lifetime, assoc_type FROM %s ".
|
||||
"WHERE server_url = ? AND handle = ?";
|
||||
|
||||
$this->sql['remove_assoc'] =
|
||||
"DELETE FROM %s WHERE server_url = ? AND handle = ?";
|
||||
|
||||
$this->sql['add_nonce'] =
|
||||
"REPLACE INTO %s (nonce, expires) VALUES (?, ?)";
|
||||
|
||||
$this->sql['get_nonce'] =
|
||||
"SELECT * FROM %s WHERE nonce = ?";
|
||||
|
||||
$this->sql['remove_nonce'] =
|
||||
"DELETE FROM %s WHERE nonce = ?";
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function blobEncode($blob)
|
||||
{
|
||||
return "0x" . bin2hex($blob);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
308
modules/member/php-openid-1.2.3/Auth/OpenID/Parse.php
Normal file
308
modules/member/php-openid-1.2.3/Auth/OpenID/Parse.php
Normal file
|
|
@ -0,0 +1,308 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* This module implements a VERY limited parser that finds <link> tags
|
||||
* in the head of HTML or XHTML documents and parses out their
|
||||
* attributes according to the OpenID spec. It is a liberal parser,
|
||||
* but it requires these things from the data in order to work:
|
||||
*
|
||||
* - There must be an open <html> tag
|
||||
*
|
||||
* - There must be an open <head> tag inside of the <html> tag
|
||||
*
|
||||
* - Only <link>s that are found inside of the <head> tag are parsed
|
||||
* (this is by design)
|
||||
*
|
||||
* - The parser follows the OpenID specification in resolving the
|
||||
* attributes of the link tags. This means that the attributes DO
|
||||
* NOT get resolved as they would by an XML or HTML parser. In
|
||||
* particular, only certain entities get replaced, and href
|
||||
* attributes do not get resolved relative to a base URL.
|
||||
*
|
||||
* From http://openid.net/specs.bml:
|
||||
*
|
||||
* - The openid.server URL MUST be an absolute URL. OpenID consumers
|
||||
* MUST NOT attempt to resolve relative URLs.
|
||||
*
|
||||
* - The openid.server URL MUST NOT include entities other than &,
|
||||
* <, >, and ".
|
||||
*
|
||||
* The parser ignores SGML comments and <![CDATA[blocks]]>. Both kinds
|
||||
* of quoting are allowed for attributes.
|
||||
*
|
||||
* The parser deals with invalid markup in these ways:
|
||||
*
|
||||
* - Tag names are not case-sensitive
|
||||
*
|
||||
* - The <html> tag is accepted even when it is not at the top level
|
||||
*
|
||||
* - The <head> tag is accepted even when it is not a direct child of
|
||||
* the <html> tag, but a <html> tag must be an ancestor of the
|
||||
* <head> tag
|
||||
*
|
||||
* - <link> tags are accepted even when they are not direct children
|
||||
* of the <head> tag, but a <head> tag must be an ancestor of the
|
||||
* <link> tag
|
||||
*
|
||||
* - If there is no closing tag for an open <html> or <head> tag, the
|
||||
* remainder of the document is viewed as being inside of the
|
||||
* tag. If there is no closing tag for a <link> tag, the link tag is
|
||||
* treated as a short tag. Exceptions to this rule are that <html>
|
||||
* closes <html> and <body> or <head> closes <head>
|
||||
*
|
||||
* - Attributes of the <link> tag are not required to be quoted.
|
||||
*
|
||||
* - In the case of duplicated attribute names, the attribute coming
|
||||
* last in the tag will be the value returned.
|
||||
*
|
||||
* - Any text that does not parse as an attribute within a link tag
|
||||
* will be ignored. (e.g. <link pumpkin rel='openid.server' /> will
|
||||
* ignore pumpkin)
|
||||
*
|
||||
* - If there are more than one <html> or <head> tag, the parser only
|
||||
* looks inside of the first one.
|
||||
*
|
||||
* - The contents of <script> tags are ignored entirely, except
|
||||
* unclosed <script> tags. Unclosed <script> tags are ignored.
|
||||
*
|
||||
* - Any other invalid markup is ignored, including unclosed SGML
|
||||
* comments and unclosed <![CDATA[blocks.
|
||||
*
|
||||
* PHP versions 4 and 5
|
||||
*
|
||||
* LICENSE: See the COPYING file included in this distribution.
|
||||
*
|
||||
* @access private
|
||||
* @package OpenID
|
||||
* @author JanRain, Inc. <openid@janrain.com>
|
||||
* @copyright 2005 Janrain, Inc.
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL
|
||||
*/
|
||||
|
||||
/**
|
||||
* Require Auth_OpenID::arrayGet().
|
||||
*/
|
||||
require_once "Auth/OpenID.php";
|
||||
|
||||
class Auth_OpenID_Parse {
|
||||
|
||||
/**
|
||||
* Specify some flags for use with regex matching.
|
||||
*/
|
||||
var $_re_flags = "si";
|
||||
|
||||
/**
|
||||
* Stuff to remove before we start looking for tags
|
||||
*/
|
||||
var $_removed_re =
|
||||
"<!--.*?-->|<!\[CDATA\[.*?\]\]>|<script\b(?!:)[^>]*>.*?<\/script>";
|
||||
|
||||
/**
|
||||
* Starts with the tag name at a word boundary, where the tag name
|
||||
* is not a namespace
|
||||
*/
|
||||
var $_tag_expr = "<%s\b(?!:)([^>]*?)(?:\/>|>(.*?)(?:<\/?%s\s*>|\Z))";
|
||||
|
||||
var $_attr_find = '\b(\w+)=("[^"]*"|\'[^\']*\'|[^\'"\s\/<>]+)';
|
||||
|
||||
function Auth_OpenID_Parse()
|
||||
{
|
||||
$this->_link_find = sprintf("/<link\b(?!:)([^>]*)(?!<)>/%s",
|
||||
$this->_re_flags);
|
||||
|
||||
$this->_entity_replacements = array(
|
||||
'amp' => '&',
|
||||
'lt' => '<',
|
||||
'gt' => '>',
|
||||
'quot' => '"'
|
||||
);
|
||||
|
||||
$this->_attr_find = sprintf("/%s/%s",
|
||||
$this->_attr_find,
|
||||
$this->_re_flags);
|
||||
|
||||
$this->_removed_re = sprintf("/%s/%s",
|
||||
$this->_removed_re,
|
||||
$this->_re_flags);
|
||||
|
||||
$this->_ent_replace =
|
||||
sprintf("&(%s);", implode("|",
|
||||
$this->_entity_replacements));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a regular expression that will match a given tag in an
|
||||
* SGML string.
|
||||
*/
|
||||
function tagMatcher($tag_name, $close_tags = null)
|
||||
{
|
||||
if ($close_tags) {
|
||||
$options = implode("|", array_merge(array($tag_name), $close_tags));
|
||||
$closer = sprintf("(?:%s)", $options);
|
||||
} else {
|
||||
$closer = $tag_name;
|
||||
}
|
||||
|
||||
$expr = sprintf($this->_tag_expr, $tag_name, $closer);
|
||||
return sprintf("/%s/%s", $expr, $this->_re_flags);
|
||||
}
|
||||
|
||||
function htmlFind()
|
||||
{
|
||||
return $this->tagMatcher('html');
|
||||
}
|
||||
|
||||
function headFind()
|
||||
{
|
||||
return $this->tagMatcher('head', array('body'));
|
||||
}
|
||||
|
||||
function replaceEntities($str)
|
||||
{
|
||||
foreach ($this->_entity_replacements as $old => $new) {
|
||||
$str = preg_replace(sprintf("/&%s;/", $old), $new, $str);
|
||||
}
|
||||
return $str;
|
||||
}
|
||||
|
||||
function removeQuotes($str)
|
||||
{
|
||||
$matches = array();
|
||||
$double = '/^"(.*)"$/';
|
||||
$single = "/^\'(.*)\'$/";
|
||||
|
||||
if (preg_match($double, $str, $matches)) {
|
||||
return $matches[1];
|
||||
} else if (preg_match($single, $str, $matches)) {
|
||||
return $matches[1];
|
||||
} else {
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all link tags in a string representing a HTML document and
|
||||
* return a list of their attributes.
|
||||
*
|
||||
* @param string $html The text to parse
|
||||
* @return array $list An array of arrays of attributes, one for each
|
||||
* link tag
|
||||
*/
|
||||
function parseLinkAttrs($html)
|
||||
{
|
||||
$stripped = preg_replace($this->_removed_re,
|
||||
"",
|
||||
$html);
|
||||
|
||||
// Try to find the <HTML> tag.
|
||||
$html_re = $this->htmlFind();
|
||||
$html_matches = array();
|
||||
if (!preg_match($html_re, $stripped, $html_matches)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
// Try to find the <HEAD> tag.
|
||||
$head_re = $this->headFind();
|
||||
$head_matches = array();
|
||||
if (!preg_match($head_re, $html_matches[0], $head_matches)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$link_data = array();
|
||||
$link_matches = array();
|
||||
|
||||
if (!preg_match_all($this->_link_find, $head_matches[0],
|
||||
$link_matches)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
foreach ($link_matches[0] as $link) {
|
||||
$attr_matches = array();
|
||||
preg_match_all($this->_attr_find, $link, $attr_matches);
|
||||
$link_attrs = array();
|
||||
foreach ($attr_matches[0] as $index => $full_match) {
|
||||
$name = $attr_matches[1][$index];
|
||||
$value = $this->replaceEntities(
|
||||
$this->removeQuotes($attr_matches[2][$index]));
|
||||
|
||||
$link_attrs[strtolower($name)] = $value;
|
||||
}
|
||||
$link_data[] = $link_attrs;
|
||||
}
|
||||
|
||||
return $link_data;
|
||||
}
|
||||
|
||||
function relMatches($rel_attr, $target_rel)
|
||||
{
|
||||
// Does this target_rel appear in the rel_str?
|
||||
// XXX: TESTME
|
||||
$rels = preg_split("/\s+/", trim($rel_attr));
|
||||
foreach ($rels as $rel) {
|
||||
$rel = strtolower($rel);
|
||||
if ($rel == $target_rel) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
function linkHasRel($link_attrs, $target_rel)
|
||||
{
|
||||
// Does this link have target_rel as a relationship?
|
||||
// XXX: TESTME
|
||||
$rel_attr = Auth_OpeniD::arrayGet($link_attrs, 'rel', null);
|
||||
return ($rel_attr && $this->relMatches($rel_attr,
|
||||
$target_rel));
|
||||
}
|
||||
|
||||
function findLinksRel($link_attrs_list, $target_rel)
|
||||
{
|
||||
// Filter the list of link attributes on whether it has
|
||||
// target_rel as a relationship.
|
||||
// XXX: TESTME
|
||||
$result = array();
|
||||
foreach ($link_attrs_list as $attr) {
|
||||
if ($this->linkHasRel($attr, $target_rel)) {
|
||||
$result[] = $attr;
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
function findFirstHref($link_attrs_list, $target_rel)
|
||||
{
|
||||
// Return the value of the href attribute for the first link
|
||||
// tag in the list that has target_rel as a relationship.
|
||||
// XXX: TESTME
|
||||
$matches = $this->findLinksRel($link_attrs_list,
|
||||
$target_rel);
|
||||
if (!$matches) {
|
||||
return null;
|
||||
}
|
||||
$first = $matches[0];
|
||||
return Auth_OpenID::arrayGet($first, 'href', null);
|
||||
}
|
||||
}
|
||||
|
||||
function Auth_OpenID_legacy_discover($html_text)
|
||||
{
|
||||
$p = new Auth_OpenID_Parse();
|
||||
|
||||
$link_attrs = $p->parseLinkAttrs($html_text);
|
||||
|
||||
$server_url = $p->findFirstHref($link_attrs,
|
||||
'openid.server');
|
||||
|
||||
if ($server_url === null) {
|
||||
return false;
|
||||
} else {
|
||||
$delegate_url = $p->findFirstHref($link_attrs,
|
||||
'openid.delegate');
|
||||
return array($delegate_url, $server_url);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
136
modules/member/php-openid-1.2.3/Auth/OpenID/PostgreSQLStore.php
Normal file
136
modules/member/php-openid-1.2.3/Auth/OpenID/PostgreSQLStore.php
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* A PostgreSQL store.
|
||||
*
|
||||
* @package OpenID
|
||||
*/
|
||||
|
||||
/**
|
||||
* Require the base class file.
|
||||
*/
|
||||
require_once "Auth/OpenID/SQLStore.php";
|
||||
|
||||
/**
|
||||
* An SQL store that uses PostgreSQL as its backend.
|
||||
*
|
||||
* @package OpenID
|
||||
*/
|
||||
class Auth_OpenID_PostgreSQLStore extends Auth_OpenID_SQLStore {
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function setSQL()
|
||||
{
|
||||
$this->sql['nonce_table'] =
|
||||
"CREATE TABLE %s (nonce CHAR(8) UNIQUE PRIMARY KEY, ".
|
||||
"expires INTEGER)";
|
||||
|
||||
$this->sql['assoc_table'] =
|
||||
"CREATE TABLE %s (server_url VARCHAR(2047), handle VARCHAR(255), ".
|
||||
"secret BYTEA, issued INTEGER, lifetime INTEGER, ".
|
||||
"assoc_type VARCHAR(64), PRIMARY KEY (server_url, handle), ".
|
||||
"CONSTRAINT secret_length_constraint CHECK ".
|
||||
"(LENGTH(secret) <= 128))";
|
||||
|
||||
$this->sql['settings_table'] =
|
||||
"CREATE TABLE %s (setting VARCHAR(128) UNIQUE PRIMARY KEY, ".
|
||||
"value BYTEA, ".
|
||||
"CONSTRAINT value_length_constraint CHECK (LENGTH(value) <= 20))";
|
||||
|
||||
$this->sql['create_auth'] =
|
||||
"INSERT INTO %s VALUES ('auth_key', '!')";
|
||||
|
||||
$this->sql['get_auth'] =
|
||||
"SELECT value FROM %s WHERE setting = 'auth_key'";
|
||||
|
||||
$this->sql['set_assoc'] =
|
||||
array(
|
||||
'insert_assoc' => "INSERT INTO %s (server_url, handle, ".
|
||||
"secret, issued, lifetime, assoc_type) VALUES ".
|
||||
"(?, ?, '!', ?, ?, ?)",
|
||||
'update_assoc' => "UPDATE %s SET secret = '!', issued = ?, ".
|
||||
"lifetime = ?, assoc_type = ? WHERE server_url = ? AND ".
|
||||
"handle = ?"
|
||||
);
|
||||
|
||||
$this->sql['get_assocs'] =
|
||||
"SELECT handle, secret, issued, lifetime, assoc_type FROM %s ".
|
||||
"WHERE server_url = ?";
|
||||
|
||||
$this->sql['get_assoc'] =
|
||||
"SELECT handle, secret, issued, lifetime, assoc_type FROM %s ".
|
||||
"WHERE server_url = ? AND handle = ?";
|
||||
|
||||
$this->sql['remove_assoc'] =
|
||||
"DELETE FROM %s WHERE server_url = ? AND handle = ?";
|
||||
|
||||
$this->sql['add_nonce'] =
|
||||
array(
|
||||
'insert_nonce' => "INSERT INTO %s (nonce, expires) VALUES ".
|
||||
"(?, ?)",
|
||||
'update_nonce' => "UPDATE %s SET expires = ? WHERE nonce = ?"
|
||||
);
|
||||
|
||||
$this->sql['get_nonce'] =
|
||||
"SELECT * FROM %s WHERE nonce = ?";
|
||||
|
||||
$this->sql['remove_nonce'] =
|
||||
"DELETE FROM %s WHERE nonce = ?";
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _set_assoc($server_url, $handle, $secret, $issued, $lifetime,
|
||||
$assoc_type)
|
||||
{
|
||||
$result = $this->_get_assoc($server_url, $handle);
|
||||
if ($result) {
|
||||
// Update the table since this associations already exists.
|
||||
$this->connection->query($this->sql['set_assoc']['update_assoc'],
|
||||
array($secret, $issued, $lifetime,
|
||||
$assoc_type, $server_url, $handle));
|
||||
} else {
|
||||
// Insert a new record because this association wasn't
|
||||
// found.
|
||||
$this->connection->query($this->sql['set_assoc']['insert_assoc'],
|
||||
array($server_url, $handle, $secret,
|
||||
$issued, $lifetime, $assoc_type));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _add_nonce($nonce, $expires)
|
||||
{
|
||||
if ($this->_get_nonce($nonce)) {
|
||||
return $this->resultToBool($this->connection->query(
|
||||
$this->sql['add_nonce']['update_nonce'],
|
||||
array($expires, $nonce)));
|
||||
} else {
|
||||
return $this->resultToBool($this->connection->query(
|
||||
$this->sql['add_nonce']['insert_nonce'],
|
||||
array($nonce, $expires)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function blobEncode($blob)
|
||||
{
|
||||
return $this->_octify($blob);
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function blobDecode($blob)
|
||||
{
|
||||
return $this->_unoctify($blob);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
658
modules/member/php-openid-1.2.3/Auth/OpenID/SQLStore.php
Normal file
658
modules/member/php-openid-1.2.3/Auth/OpenID/SQLStore.php
Normal file
|
|
@ -0,0 +1,658 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* SQL-backed OpenID stores.
|
||||
*
|
||||
* 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 the PEAR DB module because we'll need it for the SQL-based
|
||||
* stores implemented here. We silence any errors from the inclusion
|
||||
* because it might not be present, and a user of the SQL stores may
|
||||
* supply an Auth_OpenID_DatabaseConnection instance that implements
|
||||
* its own storage.
|
||||
*/
|
||||
global $__Auth_OpenID_PEAR_AVAILABLE;
|
||||
$__Auth_OpenID_PEAR_AVAILABLE = @include_once 'DB.php';
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
require_once 'Auth/OpenID/Interface.php';
|
||||
|
||||
/**
|
||||
* This is the parent class for the SQL stores, which contains the
|
||||
* logic common to all of the SQL stores.
|
||||
*
|
||||
* The table names used are determined by the class variables
|
||||
* settings_table_name, 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.
|
||||
*
|
||||
* This class shouldn't be used directly. Use one of its subclasses
|
||||
* instead, as those contain the code necessary to use a specific
|
||||
* database. If you're an OpenID integrator and you'd like to create
|
||||
* an SQL-driven store that wraps an application's database
|
||||
* abstraction, be sure to create a subclass of
|
||||
* {@link Auth_OpenID_DatabaseConnection} that calls the application's
|
||||
* database abstraction calls. Then, pass an instance of your new
|
||||
* database connection class to your SQLStore subclass constructor.
|
||||
*
|
||||
* All methods other than the constructor and createTables should be
|
||||
* considered implementation details.
|
||||
*
|
||||
* @package OpenID
|
||||
*/
|
||||
class Auth_OpenID_SQLStore extends Auth_OpenID_OpenIDStore {
|
||||
|
||||
/**
|
||||
* This creates a new SQLStore 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 either be an PEAR DB
|
||||
* connection handle or an instance of a subclass of
|
||||
* Auth_OpenID_DatabaseConnection.
|
||||
*
|
||||
* @param string $settings_table This is an optional parameter to
|
||||
* specify the name of the table used for this store's settings.
|
||||
* The default value is 'oid_settings'.
|
||||
*
|
||||
* @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_SQLStore($connection, $settings_table = null,
|
||||
$associations_table = null,
|
||||
$nonces_table = null)
|
||||
{
|
||||
global $__Auth_OpenID_PEAR_AVAILABLE;
|
||||
|
||||
$this->settings_table_name = "oid_settings";
|
||||
$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, 'db_common') ||
|
||||
is_subclass_of($connection,
|
||||
'auth_openid_databaseconnection')))) {
|
||||
trigger_error("Auth_OpenID_SQLStore 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 is a PEAR
|
||||
// constant, so only try to use it if PEAR is present. Note
|
||||
// that Auth_Openid_Databaseconnection instances need not
|
||||
// implement ::setFetchMode for this reason.
|
||||
if ($__Auth_OpenID_PEAR_AVAILABLE) {
|
||||
$this->connection->setFetchMode(DB_FETCHMODE_ASSOC);
|
||||
}
|
||||
|
||||
if ($settings_table) {
|
||||
$this->settings_table_name = $settings_table;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// Be sure to run the database queries with auto-commit mode
|
||||
// turned OFF, because we want every function to run in a
|
||||
// transaction, implicitly. As a rule, methods named with a
|
||||
// leading underscore will NOT control transaction behavior.
|
||||
// Callers of these methods will worry about transactions.
|
||||
$this->connection->autoCommit(false);
|
||||
|
||||
// Create an empty SQL strings array.
|
||||
$this->sql = array();
|
||||
|
||||
// Call this method (which should be overridden by subclasses)
|
||||
// to populate the $this->sql array with SQL strings.
|
||||
$this->setSQL();
|
||||
|
||||
// Verify that all required SQL statements have been set, and
|
||||
// raise an error if any expected SQL strings were either
|
||||
// absent or empty.
|
||||
list($missing, $empty) = $this->_verifySQL();
|
||||
|
||||
if ($missing) {
|
||||
trigger_error("Expected keys in SQL query list: " .
|
||||
implode(", ", $missing),
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
if ($empty) {
|
||||
trigger_error("SQL list keys have no SQL strings: " .
|
||||
implode(", ", $empty),
|
||||
E_USER_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add table names to queries.
|
||||
$this->_fixSQL();
|
||||
}
|
||||
|
||||
function tableExists($table_name)
|
||||
{
|
||||
return !$this->isError(
|
||||
$this->connection->query("SELECT * FROM %s LIMIT 0",
|
||||
$table_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if $value constitutes a database error; returns
|
||||
* false otherwise.
|
||||
*/
|
||||
function isError($value)
|
||||
{
|
||||
return PEAR::isError($value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a query result to a boolean. If the result is a
|
||||
* database error according to $this->isError(), this returns
|
||||
* false; otherwise, this returns true.
|
||||
*/
|
||||
function resultToBool($obj)
|
||||
{
|
||||
if ($this->isError($obj)) {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method should be overridden by subclasses. This method is
|
||||
* called by the constructor to set values in $this->sql, which is
|
||||
* an array keyed on sql name.
|
||||
*/
|
||||
function setSQL()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* 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));
|
||||
|
||||
$this->connection->query(sprintf("DELETE FROM %s",
|
||||
$this->settings_table_name));
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _verifySQL()
|
||||
{
|
||||
$missing = array();
|
||||
$empty = array();
|
||||
|
||||
$required_sql_keys = array(
|
||||
'nonce_table',
|
||||
'assoc_table',
|
||||
'settings_table',
|
||||
'get_auth',
|
||||
'create_auth',
|
||||
'set_assoc',
|
||||
'get_assoc',
|
||||
'get_assocs',
|
||||
'remove_assoc',
|
||||
'add_nonce',
|
||||
'get_nonce',
|
||||
'remove_nonce'
|
||||
);
|
||||
|
||||
foreach ($required_sql_keys as $key) {
|
||||
if (!array_key_exists($key, $this->sql)) {
|
||||
$missing[] = $key;
|
||||
} else if (!$this->sql[$key]) {
|
||||
$empty[] = $key;
|
||||
}
|
||||
}
|
||||
|
||||
return array($missing, $empty);
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _fixSQL()
|
||||
{
|
||||
$replacements = array(
|
||||
array(
|
||||
'value' => $this->nonces_table_name,
|
||||
'keys' => array('nonce_table',
|
||||
'add_nonce',
|
||||
'get_nonce',
|
||||
'remove_nonce')
|
||||
),
|
||||
array(
|
||||
'value' => $this->associations_table_name,
|
||||
'keys' => array('assoc_table',
|
||||
'set_assoc',
|
||||
'get_assoc',
|
||||
'get_assocs',
|
||||
'remove_assoc')
|
||||
),
|
||||
array(
|
||||
'value' => $this->settings_table_name,
|
||||
'keys' => array('settings_table',
|
||||
'get_auth',
|
||||
'create_auth')
|
||||
)
|
||||
);
|
||||
|
||||
foreach ($replacements as $item) {
|
||||
$value = $item['value'];
|
||||
$keys = $item['keys'];
|
||||
|
||||
foreach ($keys as $k) {
|
||||
if (is_array($this->sql[$k])) {
|
||||
foreach ($this->sql[$k] as $part_key => $part_value) {
|
||||
$this->sql[$k][$part_key] = sprintf($part_value,
|
||||
$value);
|
||||
}
|
||||
} else {
|
||||
$this->sql[$k] = sprintf($this->sql[$k], $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function blobDecode($blob)
|
||||
{
|
||||
return $blob;
|
||||
}
|
||||
|
||||
function blobEncode($str)
|
||||
{
|
||||
return $str;
|
||||
}
|
||||
|
||||
function createTables()
|
||||
{
|
||||
$this->connection->autoCommit(true);
|
||||
$n = $this->create_nonce_table();
|
||||
$a = $this->create_assoc_table();
|
||||
$s = $this->create_settings_table();
|
||||
$this->connection->autoCommit(false);
|
||||
|
||||
if ($n && $a && $s) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function create_nonce_table()
|
||||
{
|
||||
if (!$this->tableExists($this->nonces_table_name)) {
|
||||
$r = $this->connection->query($this->sql['nonce_table']);
|
||||
return $this->resultToBool($r);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function create_assoc_table()
|
||||
{
|
||||
if (!$this->tableExists($this->associations_table_name)) {
|
||||
$r = $this->connection->query($this->sql['assoc_table']);
|
||||
return $this->resultToBool($r);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function create_settings_table()
|
||||
{
|
||||
if (!$this->tableExists($this->settings_table_name)) {
|
||||
$r = $this->connection->query($this->sql['settings_table']);
|
||||
return $this->resultToBool($r);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _get_auth()
|
||||
{
|
||||
return $this->connection->getOne($this->sql['get_auth']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _create_auth($str)
|
||||
{
|
||||
return $this->connection->query($this->sql['create_auth'],
|
||||
array($str));
|
||||
}
|
||||
|
||||
function getAuthKey()
|
||||
{
|
||||
$value = $this->_get_auth();
|
||||
if (!$value) {
|
||||
$auth_key =
|
||||
Auth_OpenID_CryptUtil::randomString($this->AUTH_KEY_LEN);
|
||||
|
||||
$auth_key_s = $this->blobEncode($auth_key);
|
||||
$this->_create_auth($auth_key_s);
|
||||
} else {
|
||||
$auth_key_s = $value;
|
||||
$auth_key = $this->blobDecode($auth_key_s);
|
||||
}
|
||||
|
||||
$this->connection->commit();
|
||||
|
||||
if (strlen($auth_key) != $this->AUTH_KEY_LEN) {
|
||||
$fmt = "Expected %d-byte string for auth key. Got key of length %d";
|
||||
trigger_error(sprintf($fmt, $this->AUTH_KEY_LEN, strlen($auth_key)),
|
||||
E_USER_WARNING);
|
||||
return null;
|
||||
}
|
||||
|
||||
return $auth_key;
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _set_assoc($server_url, $handle, $secret, $issued,
|
||||
$lifetime, $assoc_type)
|
||||
{
|
||||
return $this->connection->query($this->sql['set_assoc'],
|
||||
array(
|
||||
$server_url,
|
||||
$handle,
|
||||
$secret,
|
||||
$issued,
|
||||
$lifetime,
|
||||
$assoc_type));
|
||||
}
|
||||
|
||||
function storeAssociation($server_url, $association)
|
||||
{
|
||||
if ($this->resultToBool($this->_set_assoc(
|
||||
$server_url,
|
||||
$association->handle,
|
||||
$this->blobEncode(
|
||||
$association->secret),
|
||||
$association->issued,
|
||||
$association->lifetime,
|
||||
$association->assoc_type
|
||||
))) {
|
||||
$this->connection->commit();
|
||||
} else {
|
||||
$this->connection->rollback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _get_assoc($server_url, $handle)
|
||||
{
|
||||
$result = $this->connection->getRow($this->sql['get_assoc'],
|
||||
array($server_url, $handle));
|
||||
if ($this->isError($result)) {
|
||||
return null;
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _get_assocs($server_url)
|
||||
{
|
||||
$result = $this->connection->getAll($this->sql['get_assocs'],
|
||||
array($server_url));
|
||||
|
||||
if ($this->isError($result)) {
|
||||
return array();
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
function removeAssociation($server_url, $handle)
|
||||
{
|
||||
if ($this->_get_assoc($server_url, $handle) == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($this->resultToBool($this->connection->query(
|
||||
$this->sql['remove_assoc'],
|
||||
array($server_url, $handle)))) {
|
||||
$this->connection->commit();
|
||||
} else {
|
||||
$this->connection->rollback();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getAssociation($server_url, $handle = null)
|
||||
{
|
||||
if ($handle !== null) {
|
||||
$assoc = $this->_get_assoc($server_url, $handle);
|
||||
|
||||
$assocs = array();
|
||||
if ($assoc) {
|
||||
$assocs[] = $assoc;
|
||||
}
|
||||
} else {
|
||||
$assocs = $this->_get_assocs($server_url);
|
||||
}
|
||||
|
||||
if (!$assocs || (count($assocs) == 0)) {
|
||||
return null;
|
||||
} else {
|
||||
$associations = array();
|
||||
|
||||
foreach ($assocs as $assoc_row) {
|
||||
$assoc = new Auth_OpenID_Association($assoc_row['handle'],
|
||||
$assoc_row['secret'],
|
||||
$assoc_row['issued'],
|
||||
$assoc_row['lifetime'],
|
||||
$assoc_row['assoc_type']);
|
||||
|
||||
$assoc->secret = $this->blobDecode($assoc->secret);
|
||||
|
||||
if ($assoc->getExpiresIn() == 0) {
|
||||
$this->removeAssociation($server_url, $assoc->handle);
|
||||
} else {
|
||||
$associations[] = array($assoc->issued, $assoc);
|
||||
}
|
||||
}
|
||||
|
||||
if ($associations) {
|
||||
$issued = array();
|
||||
$assocs = array();
|
||||
foreach ($associations as $key => $assoc) {
|
||||
$issued[$key] = $assoc[0];
|
||||
$assocs[$key] = $assoc[1];
|
||||
}
|
||||
|
||||
array_multisort($issued, SORT_DESC, $assocs, SORT_DESC,
|
||||
$associations);
|
||||
|
||||
// return the most recently issued one.
|
||||
list($issued, $assoc) = $associations[0];
|
||||
return $assoc;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _add_nonce($nonce, $expires)
|
||||
{
|
||||
$sql = $this->sql['add_nonce'];
|
||||
$result = $this->connection->query($sql, array($nonce, $expires));
|
||||
return $this->resultToBool($result);
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function storeNonce($nonce)
|
||||
{
|
||||
if ($this->_add_nonce($nonce, time())) {
|
||||
$this->connection->commit();
|
||||
} else {
|
||||
$this->connection->rollback();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _get_nonce($nonce)
|
||||
{
|
||||
$result = $this->connection->getRow($this->sql['get_nonce'],
|
||||
array($nonce));
|
||||
|
||||
if ($this->isError($result)) {
|
||||
return null;
|
||||
} else {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @access private
|
||||
*/
|
||||
function _remove_nonce($nonce)
|
||||
{
|
||||
$this->connection->query($this->sql['remove_nonce'],
|
||||
array($nonce));
|
||||
}
|
||||
|
||||
function useNonce($nonce)
|
||||
{
|
||||
$row = $this->_get_nonce($nonce);
|
||||
|
||||
if ($row !== null) {
|
||||
$nonce = $row['nonce'];
|
||||
$timestamp = $row['expires'];
|
||||
$nonce_age = time() - $timestamp;
|
||||
|
||||
if ($nonce_age > $this->max_nonce_age) {
|
||||
$present = 0;
|
||||
} else {
|
||||
$present = 1;
|
||||
}
|
||||
|
||||
$this->_remove_nonce($nonce);
|
||||
} else {
|
||||
$present = 0;
|
||||
}
|
||||
|
||||
$this->connection->commit();
|
||||
|
||||
return $present;
|
||||
}
|
||||
|
||||
/**
|
||||
* "Octifies" a binary string by returning a string with escaped
|
||||
* octal bytes. This is used for preparing binary data for
|
||||
* PostgreSQL BYTEA fields.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _octify($str)
|
||||
{
|
||||
$result = "";
|
||||
for ($i = 0; $i < strlen($str); $i++) {
|
||||
$ch = substr($str, $i, 1);
|
||||
if ($ch == "\\") {
|
||||
$result .= "\\\\\\\\";
|
||||
} else if (ord($ch) == 0) {
|
||||
$result .= "\\\\000";
|
||||
} else {
|
||||
$result .= "\\" . strval(decoct(ord($ch)));
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* "Unoctifies" octal-escaped data from PostgreSQL and returns the
|
||||
* resulting ASCII (possibly binary) string.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
function _unoctify($str)
|
||||
{
|
||||
$result = "";
|
||||
$i = 0;
|
||||
while ($i < strlen($str)) {
|
||||
$char = $str[$i];
|
||||
if ($char == "\\") {
|
||||
// Look to see if the next char is a backslash and
|
||||
// append it.
|
||||
if ($str[$i + 1] != "\\") {
|
||||
$octal_digits = substr($str, $i + 1, 3);
|
||||
$dec = octdec($octal_digits);
|
||||
$char = chr($dec);
|
||||
$i += 4;
|
||||
} else {
|
||||
$char = "\\";
|
||||
$i += 2;
|
||||
}
|
||||
} else {
|
||||
$i += 1;
|
||||
}
|
||||
|
||||
$result .= $char;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
66
modules/member/php-openid-1.2.3/Auth/OpenID/SQLiteStore.php
Normal file
66
modules/member/php-openid-1.2.3/Auth/OpenID/SQLiteStore.php
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* An SQLite store.
|
||||
*
|
||||
* @package OpenID
|
||||
*/
|
||||
|
||||
/**
|
||||
* Require the base class file.
|
||||
*/
|
||||
require_once "Auth/OpenID/SQLStore.php";
|
||||
|
||||
/**
|
||||
* An SQL store that uses SQLite as its backend.
|
||||
*
|
||||
* @package OpenID
|
||||
*/
|
||||
class Auth_OpenID_SQLiteStore extends Auth_OpenID_SQLStore {
|
||||
function setSQL()
|
||||
{
|
||||
$this->sql['nonce_table'] =
|
||||
"CREATE TABLE %s (nonce CHAR(8) UNIQUE PRIMARY KEY, ".
|
||||
"expires INTEGER)";
|
||||
|
||||
$this->sql['assoc_table'] =
|
||||
"CREATE TABLE %s (server_url VARCHAR(2047), handle VARCHAR(255), ".
|
||||
"secret BLOB(128), issued INTEGER, lifetime INTEGER, ".
|
||||
"assoc_type VARCHAR(64), PRIMARY KEY (server_url, handle))";
|
||||
|
||||
$this->sql['settings_table'] =
|
||||
"CREATE TABLE %s (setting VARCHAR(128) UNIQUE PRIMARY KEY, ".
|
||||
"value BLOB(20))";
|
||||
|
||||
$this->sql['create_auth'] =
|
||||
"INSERT INTO %s VALUES ('auth_key', ?)";
|
||||
|
||||
$this->sql['get_auth'] =
|
||||
"SELECT value FROM %s WHERE setting = 'auth_key'";
|
||||
|
||||
$this->sql['set_assoc'] =
|
||||
"INSERT OR REPLACE INTO %s VALUES (?, ?, ?, ?, ?, ?)";
|
||||
|
||||
$this->sql['get_assocs'] =
|
||||
"SELECT handle, secret, issued, lifetime, assoc_type FROM %s ".
|
||||
"WHERE server_url = ?";
|
||||
|
||||
$this->sql['get_assoc'] =
|
||||
"SELECT handle, secret, issued, lifetime, assoc_type FROM %s ".
|
||||
"WHERE server_url = ? AND handle = ?";
|
||||
|
||||
$this->sql['remove_assoc'] =
|
||||
"DELETE FROM %s WHERE server_url = ? AND handle = ?";
|
||||
|
||||
$this->sql['add_nonce'] =
|
||||
"INSERT OR REPLACE INTO %s (nonce, expires) VALUES (?, ?)";
|
||||
|
||||
$this->sql['get_nonce'] =
|
||||
"SELECT * FROM %s WHERE nonce = ?";
|
||||
|
||||
$this->sql['remove_nonce'] =
|
||||
"DELETE FROM %s WHERE nonce = ?";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
1307
modules/member/php-openid-1.2.3/Auth/OpenID/Server.php
Normal file
1307
modules/member/php-openid-1.2.3/Auth/OpenID/Server.php
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,37 @@
|
|||
<?php
|
||||
/**
|
||||
* OpenID Server Request
|
||||
*
|
||||
* @see Auth_OpenID_Server
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* Imports
|
||||
*/
|
||||
require_once "Auth/OpenID.php";
|
||||
|
||||
/**
|
||||
* Object that holds the state of a request to the OpenID server
|
||||
*
|
||||
* With accessor functions to get at the internal request data.
|
||||
*
|
||||
* @see Auth_OpenID_Server
|
||||
* @package OpenID
|
||||
*/
|
||||
class Auth_OpenID_ServerRequest {
|
||||
function Auth_OpenID_ServerRequest()
|
||||
{
|
||||
$this->mode = null;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
243
modules/member/php-openid-1.2.3/Auth/OpenID/TrustRoot.php
Normal file
243
modules/member/php-openid-1.2.3/Auth/OpenID/TrustRoot.php
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
<?php
|
||||
/**
|
||||
* Functions for dealing with OpenID trust roots
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* A regular expression that matches a domain ending in a top-level domains.
|
||||
* Used in checking trust roots for sanity.
|
||||
*
|
||||
* @access private
|
||||
*/
|
||||
define('Auth_OpenID___TLDs',
|
||||
'/\.(com|edu|gov|int|mil|net|org|biz|info|name|museum|coop|aero|ac|' .
|
||||
'ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|' .
|
||||
'bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|' .
|
||||
'cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|' .
|
||||
'fi|fj|fk|fm|fo|fr|ga|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|' .
|
||||
'gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|' .
|
||||
'ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|' .
|
||||
'ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|' .
|
||||
'nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|' .
|
||||
'ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|' .
|
||||
'so|sr|st|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|' .
|
||||
'ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)$/');
|
||||
|
||||
/**
|
||||
* A wrapper for trust-root related functions
|
||||
*/
|
||||
class Auth_OpenID_TrustRoot {
|
||||
/**
|
||||
* Parse a URL into its trust_root parts.
|
||||
*
|
||||
* @static
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @param string $trust_root The url to parse
|
||||
*
|
||||
* @return mixed $parsed Either an associative array of trust root
|
||||
* parts or false if parsing failed.
|
||||
*/
|
||||
function _parse($trust_root)
|
||||
{
|
||||
$parts = @parse_url($trust_root);
|
||||
if ($parts === false) {
|
||||
return false;
|
||||
}
|
||||
$required_parts = array('scheme', 'host');
|
||||
$forbidden_parts = array('user', 'pass', 'fragment');
|
||||
$keys = array_keys($parts);
|
||||
if (array_intersect($keys, $required_parts) != $required_parts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (array_intersect($keys, $forbidden_parts) != array()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return false if the original trust root value has more than
|
||||
// one port specification.
|
||||
if (preg_match("/:\/\/[^:]+(:\d+){2,}(\/|$)/", $trust_root)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$scheme = strtolower($parts['scheme']);
|
||||
$allowed_schemes = array('http', 'https');
|
||||
if (!in_array($scheme, $allowed_schemes)) {
|
||||
return false;
|
||||
}
|
||||
$parts['scheme'] = $scheme;
|
||||
|
||||
$host = strtolower($parts['host']);
|
||||
$hostparts = explode('*', $host);
|
||||
switch (count($hostparts)) {
|
||||
case 1:
|
||||
$parts['wildcard'] = false;
|
||||
break;
|
||||
case 2:
|
||||
if ($hostparts[0] ||
|
||||
($hostparts[1] && substr($hostparts[1], 0, 1) != '.')) {
|
||||
return false;
|
||||
}
|
||||
$host = $hostparts[1];
|
||||
$parts['wildcard'] = true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
if (strpos($host, ':') !== false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$parts['host'] = $host;
|
||||
|
||||
if (isset($parts['path'])) {
|
||||
$path = strtolower($parts['path']);
|
||||
if (substr($path, -1) != '/') {
|
||||
$path .= '/';
|
||||
}
|
||||
} else {
|
||||
$path = '/';
|
||||
}
|
||||
$parts['path'] = $path;
|
||||
if (!isset($parts['port'])) {
|
||||
$parts['port'] = false;
|
||||
}
|
||||
return $parts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this trust root sane?
|
||||
*
|
||||
* A trust root is sane if it is syntactically valid and it has a
|
||||
* reasonable domain name. Specifically, the domain name must be
|
||||
* more than one level below a standard TLD or more than two
|
||||
* levels below a two-letter tld.
|
||||
*
|
||||
* For example, '*.com' is not a sane trust root, but '*.foo.com'
|
||||
* is. '*.co.uk' is not sane, but '*.bbc.co.uk' is.
|
||||
*
|
||||
* This check is not always correct, but it attempts to err on the
|
||||
* side of marking sane trust roots insane instead of marking
|
||||
* insane trust roots sane. For example, 'kink.fm' is marked as
|
||||
* insane even though it "should" (for some meaning of should) be
|
||||
* marked sane.
|
||||
*
|
||||
* This function should be used when creating OpenID servers to
|
||||
* alert the users of the server when a consumer attempts to get
|
||||
* the user to accept a suspicious trust root.
|
||||
*
|
||||
* @static
|
||||
* @param string $trust_root The trust root to check
|
||||
* @return bool $sanity Whether the trust root looks OK
|
||||
*/
|
||||
function isSane($trust_root)
|
||||
{
|
||||
$parts = Auth_OpenID_TrustRoot::_parse($trust_root);
|
||||
if ($parts === false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Localhost is a special case
|
||||
if ($parts['host'] == 'localhost') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the top-level domain of the host. If it is not a valid TLD,
|
||||
// it's not sane.
|
||||
preg_match(Auth_OpenID___TLDs, $parts['host'], $matches);
|
||||
if (!$matches) {
|
||||
return false;
|
||||
}
|
||||
$tld = $matches[1];
|
||||
|
||||
// Require at least two levels of specificity for non-country
|
||||
// tlds and three levels for country tlds.
|
||||
$elements = explode('.', $parts['host']);
|
||||
$n = count($elements);
|
||||
if ($parts['wildcard']) {
|
||||
$n -= 1;
|
||||
}
|
||||
if (strlen($tld) == 2) {
|
||||
$n -= 1;
|
||||
}
|
||||
if ($n <= 1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does this URL match the given trust root?
|
||||
*
|
||||
* Return whether the URL falls under the given trust root. This
|
||||
* does not check whether the trust root is sane. If the URL or
|
||||
* trust root do not parse, this function will return false.
|
||||
*
|
||||
* @param string $trust_root The trust root to match against
|
||||
*
|
||||
* @param string $url The URL to check
|
||||
*
|
||||
* @return bool $matches Whether the URL matches against the
|
||||
* trust root
|
||||
*/
|
||||
function match($trust_root, $url)
|
||||
{
|
||||
$trust_root_parsed = Auth_OpenID_TrustRoot::_parse($trust_root);
|
||||
$url_parsed = Auth_OpenID_TrustRoot::_parse($url);
|
||||
if (!$trust_root_parsed || !$url_parsed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check hosts matching
|
||||
if ($url_parsed['wildcard']) {
|
||||
return false;
|
||||
}
|
||||
if ($trust_root_parsed['wildcard']) {
|
||||
$host_tail = $trust_root_parsed['host'];
|
||||
$host = $url_parsed['host'];
|
||||
if ($host_tail &&
|
||||
substr($host, -(strlen($host_tail))) != $host_tail &&
|
||||
substr($host_tail, 1) != $host) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if ($trust_root_parsed['host'] != $url_parsed['host']) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check path and query matching
|
||||
$base_path = $trust_root_parsed['path'];
|
||||
$path = $url_parsed['path'];
|
||||
if (!isset($trust_root_parsed['query'])) {
|
||||
if (substr($path, 0, strlen($base_path)) != $base_path) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
$base_query = $trust_root_parsed['query'];
|
||||
$query = @$url_parsed['query'];
|
||||
$qplus = substr($query, 0, strlen($base_query) + 1);
|
||||
$bqplus = $base_query . '&';
|
||||
if ($base_path != $path ||
|
||||
($base_query != $query && $qplus != $bqplus)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// The port and scheme need to match exactly
|
||||
return ($trust_root_parsed['scheme'] == $url_parsed['scheme'] &&
|
||||
$url_parsed['port'] === $trust_root_parsed['port']);
|
||||
}
|
||||
}
|
||||
?>
|
||||
231
modules/member/php-openid-1.2.3/Auth/OpenID/URINorm.php
Normal file
231
modules/member/php-openid-1.2.3/Auth/OpenID/URINorm.php
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* URI normalization routines.
|
||||
*
|
||||
* @package OpenID
|
||||
* @author JanRain, Inc. <openid@janrain.com>
|
||||
* @copyright 2005 Janrain, Inc.
|
||||
* @license http://www.gnu.org/copyleft/lesser.html LGPL
|
||||
*/
|
||||
|
||||
require_once 'Services/Yadis/Misc.php';
|
||||
|
||||
// from appendix B of rfc 3986 (http://www.ietf.org/rfc/rfc3986.txt)
|
||||
function Auth_OpenID_getURIPattern()
|
||||
{
|
||||
return '&^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?&';
|
||||
}
|
||||
|
||||
function Auth_OpenID_getAuthorityPattern()
|
||||
{
|
||||
return '/^([^@]*@)?([^:]*)(:.*)?/';
|
||||
}
|
||||
|
||||
function Auth_OpenID_getEncodedPattern()
|
||||
{
|
||||
return '/%([0-9A-Fa-f]{2})/';
|
||||
}
|
||||
|
||||
function Auth_OpenID_getUnreserved()
|
||||
{
|
||||
$_unreserved = array();
|
||||
for ($i = 0; $i < 256; $i++) {
|
||||
$_unreserved[$i] = false;
|
||||
}
|
||||
|
||||
for ($i = ord('A'); $i <= ord('Z'); $i++) {
|
||||
$_unreserved[$i] = true;
|
||||
}
|
||||
|
||||
for ($i = ord('0'); $i <= ord('9'); $i++) {
|
||||
$_unreserved[$i] = true;
|
||||
}
|
||||
|
||||
for ($i = ord('a'); $i <= ord('z'); $i++) {
|
||||
$_unreserved[$i] = true;
|
||||
}
|
||||
|
||||
$_unreserved[ord('-')] = true;
|
||||
$_unreserved[ord('.')] = true;
|
||||
$_unreserved[ord('_')] = true;
|
||||
$_unreserved[ord('~')] = true;
|
||||
|
||||
return $_unreserved;
|
||||
}
|
||||
|
||||
function Auth_OpenID_getEscapeRE()
|
||||
{
|
||||
$parts = array();
|
||||
foreach (array_merge(Services_Yadis_getUCSChars(),
|
||||
Services_Yadis_getIPrivateChars()) as $pair) {
|
||||
list($m, $n) = $pair;
|
||||
$parts[] = sprintf("%s-%s", chr($m), chr($n));
|
||||
}
|
||||
|
||||
return sprintf('[%s]', implode('', $parts));
|
||||
}
|
||||
|
||||
function Auth_OpenID_pct_encoded_replace_unreserved($mo)
|
||||
{
|
||||
$_unreserved = Auth_OpenID_getUnreserved();
|
||||
|
||||
$i = intval($mo[1], 16);
|
||||
if ($_unreserved[$i]) {
|
||||
return chr($i);
|
||||
} else {
|
||||
return strtoupper($mo[0]);
|
||||
}
|
||||
|
||||
return $mo[0];
|
||||
}
|
||||
|
||||
function Auth_OpenID_pct_encoded_replace($mo)
|
||||
{
|
||||
return chr(intval($mo[1], 16));
|
||||
}
|
||||
|
||||
function Auth_OpenID_remove_dot_segments($path)
|
||||
{
|
||||
$result_segments = array();
|
||||
|
||||
while ($path) {
|
||||
if (Services_Yadis_startswith($path, '../')) {
|
||||
$path = substr($path, 3);
|
||||
} else if (Services_Yadis_startswith($path, './')) {
|
||||
$path = substr($path, 2);
|
||||
} else if (Services_Yadis_startswith($path, '/./')) {
|
||||
$path = substr($path, 2);
|
||||
} else if ($path == '/.') {
|
||||
$path = '/';
|
||||
} else if (Services_Yadis_startswith($path, '/../')) {
|
||||
$path = substr($path, 3);
|
||||
if ($result_segments) {
|
||||
array_pop($result_segments);
|
||||
}
|
||||
} else if ($path == '/..') {
|
||||
$path = '/';
|
||||
if ($result_segments) {
|
||||
array_pop($result_segments);
|
||||
}
|
||||
} else if (($path == '..') ||
|
||||
($path == '.')) {
|
||||
$path = '';
|
||||
} else {
|
||||
$i = 0;
|
||||
if ($path[0] == '/') {
|
||||
$i = 1;
|
||||
}
|
||||
$i = strpos($path, '/', $i);
|
||||
if ($i === false) {
|
||||
$i = strlen($path);
|
||||
}
|
||||
$result_segments[] = substr($path, 0, $i);
|
||||
$path = substr($path, $i);
|
||||
}
|
||||
}
|
||||
|
||||
return implode('', $result_segments);
|
||||
}
|
||||
|
||||
function Auth_OpenID_urinorm($uri)
|
||||
{
|
||||
$uri_matches = array();
|
||||
preg_match(Auth_OpenID_getURIPattern(), $uri, $uri_matches);
|
||||
|
||||
if (count($uri_matches) < 9) {
|
||||
for ($i = count($uri_matches); $i <= 9; $i++) {
|
||||
$uri_matches[] = '';
|
||||
}
|
||||
}
|
||||
|
||||
$scheme = $uri_matches[2];
|
||||
if ($scheme) {
|
||||
$scheme = strtolower($scheme);
|
||||
}
|
||||
|
||||
$scheme = $uri_matches[2];
|
||||
if ($scheme === '') {
|
||||
// No scheme specified
|
||||
return null;
|
||||
}
|
||||
|
||||
$scheme = strtolower($scheme);
|
||||
if (!in_array($scheme, array('http', 'https'))) {
|
||||
// Not an absolute HTTP or HTTPS URI
|
||||
return null;
|
||||
}
|
||||
|
||||
$authority = $uri_matches[4];
|
||||
if ($authority === '') {
|
||||
// Not an absolute URI
|
||||
return null;
|
||||
}
|
||||
|
||||
$authority_matches = array();
|
||||
preg_match(Auth_OpenID_getAuthorityPattern(),
|
||||
$authority, $authority_matches);
|
||||
if (count($authority_matches) === 0) {
|
||||
// URI does not have a valid authority
|
||||
return null;
|
||||
}
|
||||
|
||||
if (count($authority_matches) < 4) {
|
||||
for ($i = count($authority_matches); $i <= 4; $i++) {
|
||||
$authority_matches[] = '';
|
||||
}
|
||||
}
|
||||
|
||||
list($_whole, $userinfo, $host, $port) = $authority_matches;
|
||||
|
||||
if ($userinfo === null) {
|
||||
$userinfo = '';
|
||||
}
|
||||
|
||||
if (strpos($host, '%') !== -1) {
|
||||
$host = strtolower($host);
|
||||
$host = preg_replace_callback(
|
||||
Auth_OpenID_getEncodedPattern(),
|
||||
'Auth_OpenID_pct_encoded_replace', $host);
|
||||
// NO IDNA.
|
||||
// $host = unicode($host, 'utf-8').encode('idna');
|
||||
} else {
|
||||
$host = strtolower($host);
|
||||
}
|
||||
|
||||
if ($port) {
|
||||
if (($port == ':') ||
|
||||
($scheme == 'http' && $port == ':80') ||
|
||||
($scheme == 'https' && $port == ':443')) {
|
||||
$port = '';
|
||||
}
|
||||
} else {
|
||||
$port = '';
|
||||
}
|
||||
|
||||
$authority = $userinfo . $host . $port;
|
||||
|
||||
$path = $uri_matches[5];
|
||||
$path = preg_replace_callback(
|
||||
Auth_OpenID_getEncodedPattern(),
|
||||
'Auth_OpenID_pct_encoded_replace_unreserved', $path);
|
||||
|
||||
$path = Auth_OpenID_remove_dot_segments($path);
|
||||
if (!$path) {
|
||||
$path = '/';
|
||||
}
|
||||
|
||||
$query = $uri_matches[6];
|
||||
if ($query === null) {
|
||||
$query = '';
|
||||
}
|
||||
|
||||
$fragment = $uri_matches[8];
|
||||
if ($fragment === null) {
|
||||
$fragment = '';
|
||||
}
|
||||
|
||||
return $scheme . '://' . $authority . $path . $query . $fragment;
|
||||
}
|
||||
|
||||
?>
|
||||
Loading…
Add table
Add a link
Reference in a new issue