Support Joomla!

Joomla! 1.5 Documentation

Packages

Package: OpenID

Developer Network License

The Joomla! Developer Network content is © copyright 2006 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution- NonCommercial- ShareAlike 2.5
Source code for file /openid/Auth/OpenID/TrustRoot.php

Documentation is available at TrustRoot.php

  1. <?php
  2. /**
  3.  * Functions for dealing with OpenID trust roots
  4.  *
  5.  * PHP versions 4 and 5
  6.  *
  7.  * LICENSE: See the COPYING file included in this distribution.
  8.  *
  9.  * @package OpenID
  10.  * @author JanRain, Inc. <[email protected]>
  11.  * @copyright 2005 Janrain, Inc.
  12.  * @license http://www.gnu.org/copyleft/lesser.html LGPL
  13.  */
  14.  
  15. /**
  16.  * A regular expression that matches a domain ending in a top-level domains.
  17.  * Used in checking trust roots for sanity.
  18.  *
  19.  * @access private
  20.  */
  21. define('Auth_OpenID___TLDs',
  22.        '/\.(com|edu|gov|int|mil|net|org|biz|info|name|museum|coop|aero|ac|' .
  23.        'ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|' .
  24.        'bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|' .
  25.        'cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|' .
  26.        'fi|fj|fk|fm|fo|fr|ga|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|' .
  27.        'gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|' .
  28.        'ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|' .
  29.        'ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|' .
  30.        'nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|' .
  31.        'ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|' .
  32.        'so|sr|st|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|' .
  33.        'ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw)$/');
  34.  
  35. /**
  36.  * A wrapper for trust-root related functions
  37.  */
  38.     /**
  39.      * Parse a URL into its trust_root parts.
  40.      *
  41.      * @static
  42.      *
  43.      * @access private
  44.      *
  45.      * @param string $trust_root The url to parse
  46.      *
  47.      * @return mixed $parsed Either an associative array of trust root
  48.      *  parts or false if parsing failed.
  49.      */
  50.     function _parse($trust_root)
  51.     {
  52.         $parts = @parse_url($trust_root);
  53.         if ($parts === false) {
  54.             return false;
  55.         }
  56.         $required_parts = array('scheme', 'host');
  57.         $forbidden_parts = array('user', 'pass', 'fragment');
  58.         $keys = array_keys($parts);
  59.         if (array_intersect($keys, $required_parts) != $required_parts) {
  60.             return false;
  61.         }
  62.  
  63.         if (array_intersect($keys, $forbidden_parts) != array()) {
  64.             return false;
  65.         }
  66.  
  67.         // Return false if the original trust root value has more than
  68.         // one port specification.
  69.         if (preg_match("/:\/\/[^:]+(:\d+){2,}(\/|$)/", $trust_root)) {
  70.             return false;
  71.         }
  72.  
  73.         $scheme = strtolower($parts['scheme']);
  74.         $allowed_schemes = array('http', 'https');
  75.         if (!in_array($scheme, $allowed_schemes)) {
  76.             return false;
  77.         }
  78.         $parts['scheme'] = $scheme;
  79.  
  80.         $host = strtolower($parts['host']);
  81.         $hostparts = explode('*', $host);
  82.         switch (count($hostparts)) {
  83.         case 1:
  84.             $parts['wildcard'] = false;
  85.             break;
  86.         case 2:
  87.             if ($hostparts[0] ||
  88.                 ($hostparts[1] && substr($hostparts[1], 0, 1) != '.')) {
  89.                 return false;
  90.             }
  91.             $host = $hostparts[1];
  92.             $parts['wildcard'] = true;
  93.             break;
  94.         default:
  95.             return false;
  96.         }
  97.         if (strpos($host, ':') !== false) {
  98.             return false;
  99.         }
  100.  
  101.         $parts['host'] = $host;
  102.  
  103.         if (isset($parts['path'])) {
  104.             $path = strtolower($parts['path']);
  105.             if (substr($path, -1) != '/') {
  106.                 $path .= '/';
  107.             }
  108.         } else {
  109.             $path = '/';
  110.         }
  111.         $parts['path'] = $path;
  112.         if (!isset($parts['port'])) {
  113.             $parts['port'] = false;
  114.         }
  115.         return $parts;
  116.     }
  117.  
  118.     /**
  119.      * Is this trust root sane?
  120.      *
  121.      * A trust root is sane if it is syntactically valid and it has a
  122.      * reasonable domain name. Specifically, the domain name must be
  123.      * more than one level below a standard TLD or more than two
  124.      * levels below a two-letter tld.
  125.      *
  126.      * For example, '*.com' is not a sane trust root, but '*.foo.com'
  127.      * is.  '*.co.uk' is not sane, but '*.bbc.co.uk' is.
  128.      *
  129.      * This check is not always correct, but it attempts to err on the
  130.      * side of marking sane trust roots insane instead of marking
  131.      * insane trust roots sane. For example, 'kink.fm' is marked as
  132.      * insane even though it "should" (for some meaning of should) be
  133.      * marked sane.
  134.      *
  135.      * This function should be used when creating OpenID servers to
  136.      * alert the users of the server when a consumer attempts to get
  137.      * the user to accept a suspicious trust root.
  138.      *
  139.      * @static
  140.      * @param string $trust_root The trust root to check
  141.      * @return bool $sanity Whether the trust root looks OK
  142.      */
  143.     function isSane($trust_root)
  144.     {
  145.         $parts = Auth_OpenID_TrustRoot::_parse($trust_root);
  146.         if ($parts === false) {
  147.             return false;
  148.         }
  149.  
  150.         // Localhost is a special case
  151.         if ($parts['host'] == 'localhost') {
  152.             return true;
  153.         }
  154.  
  155.         // Get the top-level domain of the host. If it is not a valid TLD,
  156.         // it's not sane.
  157.         preg_match(Auth_OpenID___TLDs, $parts['host'], $matches);
  158.         if (!$matches) {
  159.             return false;
  160.         }
  161.         $tld = $matches[1];
  162.  
  163.         // Require at least two levels of specificity for non-country
  164.         // tlds and three levels for country tlds.
  165.         $elements = explode('.', $parts['host']);
  166.         $n = count($elements);
  167.         if ($parts['wildcard']) {
  168.             $n -= 1;
  169.         }
  170.         if (strlen($tld) == 2) {
  171.             $n -= 1;
  172.         }
  173.         if ($n <= 1) {
  174.             return false;
  175.         }
  176.         return true;
  177.     }
  178.  
  179.     /**
  180.      * Does this URL match the given trust root?
  181.      *
  182.      * Return whether the URL falls under the given trust root. This
  183.      * does not check whether the trust root is sane. If the URL or
  184.      * trust root do not parse, this function will return false.
  185.      *
  186.      * @param string $trust_root The trust root to match against
  187.      *
  188.      * @param string $url The URL to check
  189.      *
  190.      * @return bool $matches Whether the URL matches against the
  191.      *  trust root
  192.      */
  193.     function match($trust_root, $url)
  194.     {
  195.         $trust_root_parsed = Auth_OpenID_TrustRoot::_parse($trust_root);
  196.         $url_parsed = Auth_OpenID_TrustRoot::_parse($url);
  197.         if (!$trust_root_parsed || !$url_parsed) {
  198.             return false;
  199.         }
  200.  
  201.         // Check hosts matching
  202.         if ($url_parsed['wildcard']) {
  203.             return false;
  204.         }
  205.         if ($trust_root_parsed['wildcard']) {
  206.             $host_tail = $trust_root_parsed['host'];
  207.             $host = $url_parsed['host'];
  208.             if ($host_tail &&
  209.                 substr($host, -(strlen($host_tail))) != $host_tail &&
  210.                 substr($host_tail, 1) != $host) {
  211.                 return false;
  212.             }
  213.         } else {
  214.             if ($trust_root_parsed['host'] != $url_parsed['host']) {
  215.                 return false;
  216.             }
  217.         }
  218.  
  219.         // Check path and query matching
  220.         $base_path = $trust_root_parsed['path'];
  221.         $path = $url_parsed['path'];
  222.         if (!isset($trust_root_parsed['query'])) {
  223.             if (substr($path, 0, strlen($base_path)) != $base_path) {
  224.                 return false;
  225.             }
  226.         } else {
  227.             $base_query = $trust_root_parsed['query'];
  228.             $query = @$url_parsed['query'];
  229.             $qplus = substr($query, 0, strlen($base_query) + 1);
  230.             $bqplus = $base_query . '&';
  231.             if ($base_path != $path ||
  232.                 ($base_query != $query && $qplus != $bqplus)) {
  233.                 return false;
  234.             }
  235.         }
  236.  
  237.         // The port and scheme need to match exactly
  238.         return ($trust_root_parsed['scheme'] == $url_parsed['scheme'] &&
  239.                 $url_parsed['port'] === $trust_root_parsed['port']);
  240.     }
  241. }
  242. ?>

Documentation generated on Mon, 05 Mar 2007 21:29:54 +0000 by phpDocumentor 1.3.1