• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • Examples
  • File List

E:/E/GEAMP/www/openbiz/openbiz/others/Zend/OpenId.php

00001 <?php
00002 
00026 require_once "Zend/Controller/Response/Abstract.php";
00027 
00041 class Zend_OpenId
00042 {
00046     const DH_P   = 'dcf93a0b883972ec0e19989ac5a2ce310e1d37717e8d9571bb7623731866e61ef75a2e27898b057f9891c2e27a639c3f29b60814581cd3b2ca3986d2683705577d45c2e7e52dc81c7a171876e5cea74b1448bfdfaf18828efd2519f14e45e3826634af1949e5b535cc829a483b8a76223e5d490a257f05bdff16f2fb22c583ab';
00047 
00051     const DH_G   = '02';
00052 
00057     const NS_2_0 = 'http://specs.openid.net/auth/2.0';
00058 
00062     static public $exitOnRedirect = true;
00063 
00068     static public $selfUrl = null;
00069 
00077     static public function setSelfUrl($selfUrl = null)
00078     {
00079         $ret = self::$selfUrl;
00080         self::$selfUrl = $selfUrl;
00081         return $ret;
00082     }
00083 
00089     static public function selfUrl()
00090     {
00091         if (self::$selfUrl !== null) {
00092             return self::$selfUrl;
00093         } if (isset($_SERVER['SCRIPT_URI'])) {
00094             return $_SERVER['SCRIPT_URI'];
00095         }
00096         $url = '';
00097         $port = '';
00098         if (isset($_SERVER['HTTP_HOST'])) {
00099             if (($pos = strpos($_SERVER['HTTP_HOST'], ':')) === false) {
00100                 if (isset($_SERVER['SERVER_PORT'])) {
00101                     $port = ':' . $_SERVER['SERVER_PORT'];
00102                 }
00103                 $url = $_SERVER['HTTP_HOST'];
00104             } else {
00105                 $url = substr($_SERVER['HTTP_HOST'], 0, $pos);
00106                 $port = substr($_SERVER['HTTP_HOST'], $pos);
00107             }
00108         } else if (isset($_SERVER['SERVER_NAME'])) {
00109             $url = $_SERVER['SERVER_NAME'];
00110             if (isset($_SERVER['SERVER_PORT'])) {
00111                 $port = ':' . $_SERVER['SERVER_PORT'];
00112             }
00113         }
00114         if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
00115             $url = 'https://' . $url;
00116             if ($port == ':443') {
00117                 $port = '';
00118             }
00119         } else {
00120             $url = 'http://' . $url;
00121             if ($port == ':80') {
00122                 $port = '';
00123             }
00124         }
00125 
00126         $url .= $port;
00127         if (isset($_SERVER['HTTP_X_REWRITE_URL'])) {
00128             $url .= $_SERVER['HTTP_X_REWRITE_URL'];
00129         } elseif (isset($_SERVER['REQUEST_URI'])) {
00130             $query = strpos($_SERVER['REQUEST_URI'], '?');
00131             if ($query === false) {
00132                 $url .= $_SERVER['REQUEST_URI'];
00133             } else {
00134                 $url .= substr($_SERVER['REQUEST_URI'], 0, $query);
00135             }
00136         } else if (isset($_SERVER['SCRIPT_URL'])) {
00137             $url .= $_SERVER['SCRIPT_URL'];
00138         } else if (isset($_SERVER['REDIRECT_URL'])) {
00139             $url .= $_SERVER['REDIRECT_URL'];
00140         } else if (isset($_SERVER['PHP_SELF'])) {
00141             $url .= $_SERVER['PHP_SELF'];
00142         } else if (isset($_SERVER['SCRIPT_NAME'])) {
00143             $url .= $_SERVER['SCRIPT_NAME'];
00144             if (isset($_SERVER['PATH_INFO'])) {
00145                 $url .= $_SERVER['PATH_INFO'];
00146             }
00147         }
00148         return $url;
00149     }
00150 
00157     static public function absoluteUrl($url)
00158     {
00159         if (empty($url)) {
00160             return Zend_OpenId::selfUrl();
00161         } else if (!preg_match('|^([^:]+)://|', $url)) {
00162             if (preg_match('|^([^:]+)://([^:@]*(?:[:][^@]*)?@)?([^/:@?#]*)(?:[:]([^/?#]*))?(/[^?]*)?((?:[?](?:[^#]*))?(?:#.*)?)$|', Zend_OpenId::selfUrl(), $reg)) {
00163                 $scheme = $reg[1];
00164                 $auth = $reg[2];
00165                 $host = $reg[3];
00166                 $port = $reg[4];
00167                 $path = $reg[5];
00168                 $query = $reg[6];
00169                 if ($url[0] == '/') {
00170                     return $scheme
00171                         . '://'
00172                         . $auth
00173                         . $host
00174                         . (empty($port) ? '' : (':' . $port))
00175                         . $url;
00176                 } else {
00177                     $dir = dirname($path);
00178                     return $scheme
00179                         . '://'
00180                         . $auth
00181                         . $host
00182                         . (empty($port) ? '' : (':' . $port))
00183                         . (strlen($dir) > 1 ? $dir : '')
00184                         . '/'
00185                         . $url;
00186                 }
00187             }
00188         }
00189         return $url;
00190     }
00191 
00198     static public function paramsToQuery($params)
00199     {
00200         foreach($params as $key => $value) {
00201             if (isset($query)) {
00202                 $query .= '&' . $key . '=' . urlencode($value);
00203             } else {
00204                 $query = $key . '=' . urlencode($value);
00205             }
00206         }
00207         return isset($query) ? $query : '';
00208     }
00209 
00218     static public function normalizeUrl(&$id)
00219     {
00220         // RFC 3986, 6.2.2.  Syntax-Based Normalization
00221 
00222         // RFC 3986, 6.2.2.2 Percent-Encoding Normalization
00223         $i = 0;
00224         $n = strlen($id);
00225         $res = '';
00226         while ($i < $n) {
00227             if ($id[$i] == '%') {
00228                 if ($i + 2 >= $n) {
00229                     return false;
00230                 }
00231                 ++$i;
00232                 if ($id[$i] >= '0' && $id[$i] <= '9') {
00233                     $c = ord($id[$i]) - ord('0');
00234                 } else if ($id[$i] >= 'A' && $id[$i] <= 'F') {
00235                     $c = ord($id[$i]) - ord('A') + 10;
00236                 } else if ($id[$i] >= 'a' && $id[$i] <= 'f') {
00237                     $c = ord($id[$i]) - ord('a') + 10;
00238                 } else {
00239                     return false;
00240                 }
00241                 ++$i;
00242                 if ($id[$i] >= '0' && $id[$i] <= '9') {
00243                     $c = ($c << 4) | (ord($id[$i]) - ord('0'));
00244                 } else if ($id[$i] >= 'A' && $id[$i] <= 'F') {
00245                     $c = ($c << 4) | (ord($id[$i]) - ord('A') + 10);
00246                 } else if ($id[$i] >= 'a' && $id[$i] <= 'f') {
00247                     $c = ($c << 4) | (ord($id[$i]) - ord('a') + 10);
00248                 } else {
00249                     return false;
00250                 }
00251                 ++$i;
00252                 $ch = chr($c);
00253                 if (($ch >= 'A' && $ch <= 'Z') ||
00254                     ($ch >= 'a' && $ch <= 'z') ||
00255                     $ch == '-' ||
00256                     $ch == '.' ||
00257                     $ch == '_' ||
00258                     $ch == '~') {
00259                     $res .= $ch;
00260                 } else {
00261                     $res .= '%';
00262                     if (($c >> 4) < 10) {
00263                         $res .= chr(($c >> 4) + ord('0'));
00264                     } else {
00265                         $res .= chr(($c >> 4) - 10 + ord('A'));
00266                     }
00267                     $c = $c & 0xf;
00268                     if ($c < 10) {
00269                         $res .= chr($c + ord('0'));
00270                     } else {
00271                         $res .= chr($c - 10 + ord('A'));
00272                     }
00273                 }
00274             } else {
00275                 $res .= $id[$i++];
00276             }
00277         }
00278 
00279         if (!preg_match('|^([^:]+)://([^:@]*(?:[:][^@]*)?@)?([^/:@?#]*)(?:[:]([^/?#]*))?(/[^?#]*)?((?:[?](?:[^#]*))?)((?:#.*)?)$|', $res, $reg)) {
00280             return false;
00281         }
00282         $scheme = $reg[1];
00283         $auth = $reg[2];
00284         $host = $reg[3];
00285         $port = $reg[4];
00286         $path = $reg[5];
00287         $query = $reg[6];
00288         $fragment = $reg[7]; /* strip it */
00289 
00290         if (empty($scheme) || empty($host)) {
00291             return false;
00292         }
00293 
00294         // RFC 3986, 6.2.2.1.  Case Normalization
00295         $scheme = strtolower($scheme);
00296         $host = strtolower($host);
00297 
00298         // RFC 3986, 6.2.2.3.  Path Segment Normalization
00299         if (!empty($path)) {
00300             $i = 0;
00301             $n = strlen($path);
00302             $res = "";
00303             while ($i < $n) {
00304                 if ($path[$i] == '/') {
00305                     ++$i;
00306                     while ($i < $n && $path[$i] == '/') {
00307                         ++$i;
00308                     }
00309                     if ($i < $n && $path[$i] == '.') {
00310                         ++$i;
00311                         if ($i < $n && $path[$i] == '.') {
00312                             ++$i;
00313                             if ($i == $n || $path[$i] == '/') {
00314                                 if (($pos = strrpos($res, '/')) !== false) {
00315                                     $res = substr($res, 0, $pos);
00316                                 }
00317                             } else {
00318                                     $res .= '/..';
00319                             }
00320                         } else if ($i != $n && $path[$i] != '/') {
00321                             $res .= '/.';
00322                         }
00323                     } else {
00324                         $res .= '/';
00325                     }
00326                 } else {
00327                     $res .= $path[$i++];
00328                 }
00329             }
00330             $path = $res;
00331         }
00332 
00333         // RFC 3986,6.2.3.  Scheme-Based Normalization
00334         if ($scheme == 'http') {
00335             if ($port == 80) {
00336                 $port = '';
00337             }
00338         } else if ($scheme == 'https') {
00339             if ($port == 443) {
00340                 $port = '';
00341             }
00342         }
00343         if (empty($path)) {
00344             $path = '/';
00345         }
00346 
00347         $id = $scheme
00348             . '://'
00349             . $auth
00350             . $host
00351             . (empty($port) ? '' : (':' . $port))
00352             . $path
00353             . $query;
00354         return true;
00355     }
00356 
00378     static public function normalize(&$id)
00379     {
00380         $id = trim($id);
00381         if (strlen($id) === 0) {
00382             return true;
00383         }
00384 
00385         // 7.2.1
00386         if (strpos($id, 'xri://$ip*') === 0) {
00387             $id = substr($id, strlen('xri://$ip*'));
00388         } else if (strpos($id, 'xri://$dns*') === 0) {
00389             $id = substr($id, strlen('xri://$dns*'));
00390         } else if (strpos($id, 'xri://') === 0) {
00391             $id = substr($id, strlen('xri://'));
00392         }
00393 
00394         // 7.2.2
00395         if ($id[0] == '=' ||
00396             $id[0] == '@' ||
00397             $id[0] == '+' ||
00398             $id[0] == '$' ||
00399             $id[0] == '!') {
00400             return true;
00401         }
00402 
00403         // 7.2.3
00404         if (strpos($id, "://") === false) {
00405             $id = 'http://' . $id;
00406         }
00407 
00408         // 7.2.4
00409         return self::normalizeURL($id);
00410     }
00411 
00422     static public function redirect($url, $params = null,
00423         Zend_Controller_Response_Abstract $response = null, $method = 'GET')
00424     {
00425         $url = Zend_OpenId::absoluteUrl($url);
00426         $body = "";
00427         if (null === $response) {
00428             require_once "Zend/Controller/Response/Http.php";
00429             $response = new Zend_Controller_Response_Http();
00430         }
00431 
00432         if ($method == 'POST') {
00433             $body = "<html><body onLoad=\"document.forms[0].submit();\">\n";
00434             $body .= "<form method=\"POST\" action=\"$url\">\n";
00435             if (is_array($params) && count($params) > 0) {
00436                 foreach($params as $key => $value) {
00437                     $body .= '<input type="hidden" name="' . $key . '" value="' . $value . "\">\n";
00438                 }
00439             }
00440             $body .= "<input type=\"submit\" value=\"Continue OpenID transaction\">\n";
00441             $body .= "</form></body></html>\n";
00442         } else if (is_array($params) && count($params) > 0) {
00443             if (strpos($url, '?') === false) {
00444                 $url .= '?' . self::paramsToQuery($params);
00445             } else {
00446                 $url .= '&' . self::paramsToQuery($params);
00447             }
00448         }
00449         if (!empty($body)) {
00450             $response->setBody($body);
00451         } else if (!$response->canSendHeaders()) {
00452             $response->setBody("<script language=\"JavaScript\"" .
00453                  " type=\"text/javascript\">window.location='$url';" .
00454                  "</script>");
00455         } else {
00456             $response->setRedirect($url);
00457         }
00458         $response->sendResponse();
00459         if (self::$exitOnRedirect) {
00460             exit();
00461         }
00462     }
00463 
00470     static public function randomBytes($len)
00471     {
00472         $key = '';
00473         for($i=0; $i < $len; $i++) {
00474             $key .= chr(mt_rand(0, 255));
00475         }
00476         return $key;
00477     }
00478 
00492     static public function digest($func, $data)
00493     {
00494         if (function_exists('openssl_digest')) {
00495             return openssl_digest($data, $func, true);
00496         } else if (function_exists('hash')) {
00497             return hash($func, $data, true);
00498         } else if ($func === 'sha1') {
00499             return sha1($data, true);
00500         } else if ($func === 'sha256') {
00501             if (function_exists('mhash')) {
00502                 return mhash(MHASH_SHA256 , $data);
00503             }
00504         }
00505         require_once "Zend/OpenId/Exception.php";
00506         throw new Zend_OpenId_Exception(
00507             'Unsupported digest algorithm "' . $func . '".',
00508             Zend_OpenId_Exception::UNSUPPORTED_DIGEST);
00509     }
00510 
00522     static public function hashHmac($macFunc, $data, $secret)
00523     {
00524 //        require_once "Zend/Crypt/Hmac.php";
00525 //        return Zend_Crypt_Hmac::compute($secret, $macFunc, $data, Zend_Crypt_Hmac::BINARY);
00526         if (function_exists('hash_hmac')) {
00527             return hash_hmac($macFunc, $data, $secret, 1);
00528         } else {
00529             if (Zend_OpenId::strlen($secret) > 64) {
00530                 $secret = self::digest($macFunc, $secret);
00531             }
00532             $secret = str_pad($secret, 64, chr(0x00));
00533             $ipad = str_repeat(chr(0x36), 64);
00534             $opad = str_repeat(chr(0x5c), 64);
00535             $hash1 = self::digest($macFunc, ($secret ^ $ipad) . $data);
00536             return self::digest($macFunc, ($secret ^ $opad) . $hash1);
00537         }
00538     }
00539 
00548     static protected function binToBigNum($bin)
00549     {
00550         if (extension_loaded('gmp')) {
00551             return gmp_init(bin2hex($bin), 16);
00552         } else if (extension_loaded('bcmath')) {
00553             $bn = 0;
00554             $len = Zend_OpenId::strlen($bin);
00555             for ($i = 0; $i < $len; $i++) {
00556                 $bn = bcmul($bn, 256);
00557                 $bn = bcadd($bn, ord($bin[$i]));
00558             }
00559             return $bn;
00560         }
00561         require_once "Zend/OpenId/Exception.php";
00562         throw new Zend_OpenId_Exception(
00563             'The system doesn\'t have proper big integer extension',
00564             Zend_OpenId_Exception::UNSUPPORTED_LONG_MATH);
00565     }
00566 
00575     static protected function bigNumToBin($bn)
00576     {
00577         if (extension_loaded('gmp')) {
00578             $s = gmp_strval($bn, 16);
00579             if (strlen($s) % 2 != 0) {
00580                 $s = '0' . $s;
00581             } else if ($s[0] > '7') {
00582                 $s = '00' . $s;
00583             }
00584             return pack("H*", $s);
00585         } else if (extension_loaded('bcmath')) {
00586             $cmp = bccomp($bn, 0);
00587             if ($cmp == 0) {
00588                 return (chr(0));
00589             } else if ($cmp < 0) {
00590                 require_once "Zend/OpenId/Exception.php";
00591                 throw new Zend_OpenId_Exception(
00592                     'Big integer arithmetic error',
00593                     Zend_OpenId_Exception::ERROR_LONG_MATH);
00594             }
00595             $bin = "";
00596             while (bccomp($bn, 0) > 0) {
00597                 $bin = chr(bcmod($bn, 256)) . $bin;
00598                 $bn = bcdiv($bn, 256);
00599             }
00600             if (ord($bin[0]) > 127) {
00601                 $bin = chr(0) . $bin;
00602             }
00603             return $bin;
00604         }
00605         require_once "Zend/OpenId/Exception.php";
00606         throw new Zend_OpenId_Exception(
00607             'The system doesn\'t have proper big integer extension',
00608             Zend_OpenId_Exception::UNSUPPORTED_LONG_MATH);
00609     }
00610 
00623     static public function createDhKey($p, $g, $priv_key = null)
00624     {
00625         if (function_exists('openssl_dh_compute_key')) {
00626             $dh_details = array(
00627                     'p' => $p,
00628                     'g' => $g
00629                 );
00630             if ($priv_key !== null) {
00631                 $dh_details['priv_key'] = $priv_key;
00632             }
00633             return openssl_pkey_new(array('dh'=>$dh_details));
00634         } else {
00635             $bn_p        = self::binToBigNum($p);
00636             $bn_g        = self::binToBigNum($g);
00637             if ($priv_key === null) {
00638                 $priv_key    = self::randomBytes(Zend_OpenId::strlen($p));
00639             }
00640             $bn_priv_key = self::binToBigNum($priv_key);
00641             if (extension_loaded('gmp')) {
00642                 $bn_pub_key  = gmp_powm($bn_g, $bn_priv_key, $bn_p);
00643             } else if (extension_loaded('bcmath')) {
00644                 $bn_pub_key  = bcpowmod($bn_g, $bn_priv_key, $bn_p);
00645             }
00646             $pub_key     = self::bigNumToBin($bn_pub_key);
00647 
00648             return array(
00649                 'p'        => $bn_p,
00650                 'g'        => $bn_g,
00651                 'priv_key' => $bn_priv_key,
00652                 'pub_key'  => $bn_pub_key,
00653                 'details'  => array(
00654                     'p'        => $p,
00655                     'g'        => $g,
00656                     'priv_key' => $priv_key,
00657                     'pub_key'  => $pub_key));
00658         }
00659     }
00660 
00670     static public function getDhKeyDetails($dh)
00671     {
00672         if (function_exists('openssl_dh_compute_key')) {
00673             $details = openssl_pkey_get_details($dh);
00674             if (isset($details['dh'])) {
00675                 return $details['dh'];
00676             }
00677         } else {
00678             return $dh['details'];
00679         }
00680     }
00681 
00691     static public function computeDhSecret($pub_key, $dh)
00692     {
00693         if (function_exists('openssl_dh_compute_key')) {
00694             $ret = openssl_dh_compute_key($pub_key, $dh);
00695             if (ord($ret[0]) > 127) {
00696                 $ret = chr(0) . $ret;
00697             }
00698             return $ret;
00699         } else if (extension_loaded('gmp')) {
00700             $bn_pub_key = self::binToBigNum($pub_key);
00701             $bn_secret  = gmp_powm($bn_pub_key, $dh['priv_key'], $dh['p']);
00702             return self::bigNumToBin($bn_secret);
00703         } else if (extension_loaded('bcmath')) {
00704             $bn_pub_key = self::binToBigNum($pub_key);
00705             $bn_secret  = bcpowmod($bn_pub_key, $dh['priv_key'], $dh['p']);
00706             return self::bigNumToBin($bn_secret);
00707         }
00708         require_once "Zend/OpenId/Exception.php";
00709         throw new Zend_OpenId_Exception(
00710             'The system doesn\'t have proper big integer extension',
00711             Zend_OpenId_Exception::UNSUPPORTED_LONG_MATH);
00712     }
00713 
00729     static public function btwoc($str)
00730     {
00731         if (ord($str[0]) > 127) {
00732             return chr(0) . $str;
00733         }
00734         return $str;
00735     }
00736 
00743     static public function strlen($str)
00744     {
00745         if (extension_loaded('mbstring') &&
00746             (((int)ini_get('mbstring.func_overload')) & 2)) {
00747             return mb_strlen($str, 'latin1');
00748         } else {
00749             return strlen($str);
00750         }
00751     }
00752 
00753 }

Generated on Thu Apr 19 2012 17:01:18 for openbiz by  doxygen 1.7.2