Auth_HTTP
[ class tree: Auth_HTTP ] [ index: Auth_HTTP ] [ all elements ]

Source for file Auth_HTTP.php

Documentation is available at Auth_HTTP.php

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2004 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Martin Jansen <mj@php.net>                                  |
  17. // |          Rui Hirokawa <hirokawa@php.net>                             |
  18. // |          David Costa  <gurugeek@php.net>                             |
  19. // +----------------------------------------------------------------------+
  20. //
  21. //  $Id: Auth_HTTP.php,v 1.22 2004/12/23 00:53:27 hirokawa Exp $ 
  22. //
  23.  
  24. require_once "Auth/Auth.php";
  25.  
  26. define('AUTH_HTTP_NONCE_TIME_LEN'16);
  27. define('AUTH_HTTP_NONCE_HASH_LEN'32);
  28.  
  29. // {{{ class Auth_HTTP
  30.  
  31. /**
  32.  * PEAR::Auth_HTTP
  33.  *
  34.  * The PEAR::Auth_HTTP class provides methods for creating an
  35.  * HTTP authentication system based on RFC-2617 using PHP.
  36.  *
  37.  * Instead of generating an HTML driven form like PEAR::Auth
  38.  * does, this class sends header commands to the clients which
  39.  * cause them to present a login box like they are e.g. used
  40.  * in Apache's .htaccess mechanism.
  41.  *
  42.  * This class requires the PEAR::Auth package.
  43.  *
  44.  * @notes The HTTP Diegest Authentication part is based on
  45.  *   authentication class written by Tom Pike <tom.pike@xiven.com>
  46.  *
  47.  * @author  Martin Jansen <mj@php.net>
  48.  * @author  Rui Hirokawa <hirokawa@php.net>
  49.  * @author  David Costa <gurugeek@php.net>
  50.  * @package Auth_HTTP
  51.  * @extends Auth
  52.  * @version $Revision: 1.22 $
  53.  */
  54. class Auth_HTTP extends Auth
  55. {
  56.    
  57.     // {{{ properties
  58.  
  59.     /**
  60.      * Authorization method: 'basic' or 'digest'
  61.      *
  62.      * @access public
  63.      * @var    string 
  64.      */
  65.     var $authType = 'basic';
  66.  
  67.     /**
  68.      * Name of the realm for Basic Authentication
  69.      *
  70.      * @access public
  71.      * @var    string 
  72.      * @see    drawLogin()
  73.      */
  74.     var $realm = "protected area";
  75.  
  76.     /**
  77.      * Text to send if user hits cancel button
  78.      *
  79.      * @access public
  80.      * @var    string 
  81.      * @see    drawLogin()
  82.      */
  83.     var $CancelText = "Error 401 - Access denied";
  84.  
  85.     /**
  86.      * option array
  87.      *
  88.      * @access public
  89.      * @var    array 
  90.      */
  91.     var $options = array();
  92.  
  93.     /**
  94.      * flag to indicate the nonce was stale.
  95.      *
  96.      * @access public
  97.      * @var    bool 
  98.      */
  99.     var $stale = false;
  100.  
  101.     /**
  102.      * opaque string for digest authentication
  103.      *
  104.      * @access public
  105.      * @var    string 
  106.      */
  107.     var $opaque = 'dummy';
  108.  
  109.     /**
  110.      * digest URI
  111.      *
  112.      * @access public
  113.      * @var    string 
  114.      */
  115.     var $uri = '';
  116.  
  117.     /**
  118.      * authorization info returned by the client
  119.      *
  120.      * @access public
  121.      * @var    array 
  122.      */
  123.     var $auth = array();
  124.  
  125.     /**
  126.      * next nonce value
  127.      *
  128.      * @access public
  129.      * @var    string 
  130.      */
  131.     var $nextNonce = '';
  132.  
  133.     /**
  134.      * nonce value
  135.      *
  136.      * @access public
  137.      * @var    string 
  138.      */
  139.     var $nonce = '';
  140.  
  141.     /**
  142.      * Holds a reference to the global server variable
  143.      * @var array 
  144.      */
  145.     var $server;
  146.  
  147.     /**
  148.      * Holds a reference to the global post variable
  149.      * @var array 
  150.      */
  151.     var $post;
  152.  
  153.     /**
  154.      * Holds a reference to the global cookie variable
  155.      * @var array 
  156.      */
  157.     var $cookie;
  158.  
  159.  
  160.     // }}}
  161.     // {{{ Constructor
  162.  
  163.     /**
  164.      * Constructor
  165.      *
  166.      * @param string    Type of the storage driver
  167.      * @param mixed     Additional options for the storage driver
  168.      *                   (example: if you are using DB as the storage
  169.      *                    driver, you have to pass the dsn string here)
  170.      *
  171.      * @return void 
  172.      */
  173.     function Auth_HTTP($storageDriver$options ''
  174.     {
  175.         /* set default values for options */
  176.         $this->options = array('cryptType' => 'md5',
  177.                                'algorithm' => 'MD5',
  178.                                'qop' => 'auth-int,auth',
  179.                                'opaquekey' => 'moo',
  180.                                'noncekey' => 'moo',
  181.                                'digestRealm' => 'protected area',
  182.                                'forceDigestOnly' => false,
  183.                                'nonceLife' => 300,
  184.                                'sessionSharing' => true,
  185.                                );
  186.         
  187.         if (!empty($options['authType'])) {
  188.             $this->authType = strtolower($options['authType']);
  189.         }
  190.         
  191.         if (is_array($options)) {
  192.             foreach($options as $key => $value{
  193.                 if (array_key_exists$key$this->options)) {
  194.                     $this->options[$key$value;
  195.                 }
  196.             }
  197.         
  198.             if (!empty($this->options['opaquekey'])) {
  199.                 $this->opaque = md5($this->options['opaquekey']);
  200.             }
  201.         }
  202.         
  203.         $this->Auth($storageDriver$options);
  204.     }
  205.     
  206.     // }}}
  207.     // {{{ assignData()
  208.  
  209.     /**
  210.      * Assign values from $PHP_AUTH_USER and $PHP_AUTH_PW or 'Authorization' header
  211.      * to internal variables and sets the session id based
  212.      * on them
  213.      *
  214.      * @return void 
  215.      */
  216.     function assignData()
  217.     {
  218.         if (method_exists($this'_importGlobalVariable')) {
  219.             $this->server = &$this->_importGlobalVariable('server');
  220.         }
  221.         
  222.         
  223.         if ($this->authType == 'basic'{
  224.             if (!empty($this->server['PHP_AUTH_USER'])) {
  225.                 $this->username $this->server['PHP_AUTH_USER'];
  226.             }
  227.             
  228.             if (!empty($this->server['PHP_AUTH_PW'])) {
  229.                 $this->password $this->server['PHP_AUTH_PW'];
  230.             }
  231.             
  232.             /**
  233.              * Try to get authentication information from IIS
  234.              */
  235.             if  (empty($this->username&& empty($this->password)) {
  236.                 if (!empty($this->server['HTTP_AUTHORIZATION'])) {
  237.                     list($this->username$this->password
  238.                         explode(':'base64_decode(substr($this->server['HTTP_AUTHORIZATION']6)));
  239.                 }
  240.             }
  241.         elseif ($this->authType == 'digest'{
  242.          $this->username '';
  243.          $this->password '';
  244.  
  245.             $headers = getallheaders();
  246.             if(isset($headers['Authorization']&& !empty($headers['Authorization'])) {
  247.                 $authtemp explode(','substr($headers['Authorization'],
  248.                                                 strpos($headers['Authorization'],' ')+1));
  249.                 $auth = array();
  250.                 foreach($authtemp as $key => $value{
  251.                     $value trim($value);
  252.                     if(strpos($value,'='!== false{
  253.                         $lhs substr($value,0,strpos($value,'='));
  254.                         $rhs substr($value,strpos($value,'=')+1);
  255.                         if(substr($rhs,0,1== '"' && substr($rhs,-1,1== '"'{
  256.                             $rhs substr($rhs,1,-1);
  257.                         }
  258.                         $auth[$lhs$rhs;
  259.                     }
  260.                 }
  261.             }
  262.             if (!isset($auth['uri']|| !isset($auth['realm'])) {
  263.                 return;
  264.             }
  265.             
  266.             if ($this->selfURI(== $auth['uri']{
  267.                 $this->uri = $auth['uri'];
  268.                 if (substr($headers['Authorization'],0,7== 'Digest '{
  269.                     
  270.                     $this->authType = 'digest';
  271.  
  272.                     if (!isset($auth['nonce']|| !isset($auth['username']|| 
  273.                   !isset($auth['response']|| !isset($auth['qop']|| 
  274.                   !isset($auth['nc']|| !isset($auth['cnonce'])){
  275.                         return;
  276.                     }
  277.  
  278.                if ($auth['qop'!= 'auth' && $auth['qop'!= 'auth-int'{
  279.                         return;
  280.                }
  281.                     
  282.                     $this->stale = $this->_judgeStale($auth['nonce']);
  283.  
  284.                if ($this->nextNonce == false{
  285.                   return;
  286.                }
  287.  
  288.                     $this->username $auth['username'];
  289.                     $this->password $auth['response'];
  290.                     $this->auth['nonce'$auth['nonce'];
  291.                     
  292.                $this->auth['qop'$auth['qop'];
  293.                $this->auth['nc'$auth['nc'];
  294.                $this->auth['cnonce'$auth['cnonce'];
  295.  
  296.                     if (isset($auth['opaque'])) {
  297.                         $this->auth['opaque'$auth['opaque'];
  298.                     }
  299.                     
  300.                 elseif (substr($headers['Authorization'],0,6== 'Basic '{
  301.                     if ($this->options['forceDigestOnly']{
  302.                         return// Basic authentication is not allowed.
  303.                     }
  304.                     
  305.                     $this->authType = 'basic';
  306.                     list($username$password
  307.                         explode(':',base64_decode(substr($headers['Authorization'],6)));
  308.                     $this->username $username;
  309.                     $this->password $password;
  310.                 }
  311.             }
  312.         else {
  313.             return PEAR::raiseError('authType is invalid.');
  314.         }
  315.  
  316.         if ($this->options['sessionSharing'&& 
  317.             isset($this->username&& isset($this->password)) {
  318.             session_id(md5('Auth_HTTP' $this->username $this->password));
  319.         }
  320.         
  321.         /**
  322.          * set sessionName for AUTH, so that the sessionName is different 
  323.          * for distinct realms 
  324.          */
  325.          $this->_sessionName "_authhttp".md5($this->realm);
  326.     }
  327.  
  328.     // }}}
  329.     // {{{ login()
  330.  
  331.     /**
  332.      * Login function
  333.      *
  334.      * @access private
  335.      * @return void 
  336.      */
  337.     function login(
  338.     {
  339.         $login_ok = false;
  340.         if (method_exists($this'_loadStorage')) {
  341.             $this->_loadStorage();
  342.         }
  343.  
  344.         /**
  345.          * When the user has already entered a username,
  346.          * we have to validate it.
  347.          */
  348.         if (!empty($this->username&& !empty($this->password)) {
  349.             if ($this->authType == 'basic' && !$this->options['forceDigestOnly']{
  350.                 if (true === $this->storage->fetchData($this->username$this->password)) {
  351.                     $login_ok = true;
  352.                 }
  353.             else /* digest authentication */
  354.  
  355.                 if (!$this->getAuth(|| $this->getAuthData('a1'== null{
  356.                     /* 
  357.                      * note:
  358.                      *  - only PEAR::DB is supported as container.
  359.                      *  - password should be stored in container as plain-text 
  360.                      *    (if $options['cryptType'] == 'none') or 
  361.                      *     A1 hashed form (md5('username:realm:password')) 
  362.                      *    (if $options['cryptType'] == 'md5')
  363.                      */
  364.                     $dbs $this->storage;
  365.                     if (!DB::isConnection($dbs->db)) {
  366.                         $dbs->_connect($dbs->options['dsn']);
  367.                     }
  368.                     
  369.                     $query 'SELECT '.$dbs->options['passwordcol']." FROM ".$dbs->options['table'].
  370.                         ' WHERE '.$dbs->options['usernamecol']." = '".
  371.                         $dbs->db->quoteString($this->username)."' ";
  372.                     
  373.                     $pwd $dbs->db->getOne($query)// password stored in container.
  374.                     
  375.                     if (DB::isError($pwd)) {
  376.                         return PEAR::raiseError($pwd->getMessage()$pwd->getCode());
  377.                     }
  378.                     
  379.                     if ($this->options['cryptType'== 'none'{
  380.                         $a1 md5($this->username.':'.$this->options['digestRealm'].':'.$pwd);
  381.                     else {
  382.                         $a1 $pwd;
  383.                     }
  384.                     
  385.                     $this->setAuthData('a1'$a1true);
  386.                 else {
  387.                     $a1 $this->getAuthData('a1');
  388.                 }
  389.                 
  390.                 $login_ok $this->validateDigest($this->password$a1);
  391.                 if ($this->nextNonce == false{
  392.                     $login_ok = false;
  393.                 }
  394.             }
  395.             
  396.             if (!$login_ok && is_callable($this->loginFailedCallback)) {
  397.                 call_user_func($this->loginFailedCallback,$this->username$this);
  398.             }
  399.         }
  400.         
  401.         if (!empty($this->username&& $login_ok{
  402.             $this->setAuth($this->username);
  403.             if (is_callable($this->loginCallback)) {
  404.                 call_user_func($this->loginCallback,$this->username$this);
  405.             }
  406.         }
  407.         
  408.         /**
  409.          * If the login failed or the user entered no username,
  410.          * output the login screen again.
  411.          */
  412.         if (!empty($this->username&& !$login_ok{
  413.             $this->status = AUTH_WRONG_LOGIN;
  414.         }
  415.         
  416.         if ((empty($this->username|| !$login_ok&& $this->showLogin{
  417.             $this->drawLogin($this->storage->activeUser);
  418.             return;
  419.         }
  420.  
  421.       if (!empty($this->username&& $login_ok && $this->authType == 'digest'
  422.          && $this->auth['qop'== 'auth'
  423.          $this->authenticationInfo();
  424.       }
  425.     }
  426.     
  427.     // }}}
  428.     // {{{ drawLogin()
  429.  
  430.     /**
  431.      * Launch the login box
  432.      *
  433.      * @param  string $username  Username
  434.      * @return void 
  435.      */
  436.     function drawLogin($username "")
  437.     {
  438.         /**
  439.          * Send the header commands
  440.          */
  441.         if ($this->authType == 'basic'{
  442.             header("WWW-Authenticate: Basic realm=\"".$this->realm."\"");
  443.             header('HTTP/1.0 401 Unauthorized');            
  444.         else if ($this->authType == 'digest'{
  445.             $this->nonce = $this->_getNonce();
  446.  
  447.             $wwwauth 'WWW-Authenticate: Digest ';
  448.             $wwwauth .= 'qop="'.$this->options['qop'].'", ';
  449.             $wwwauth .= 'algorithm='.$this->options['algorithm'].', ';
  450.             $wwwauth .= 'realm="'.$this->options['digestRealm'].'", ';
  451.             $wwwauth .= 'nonce="'.$this->nonce.'", ';
  452.             if ($this->stale{
  453.                 $wwwauth .= 'stale=true, ';
  454.             }
  455.             if (!empty($this->opaque)) {
  456.                 $wwwauth .= 'opaque="'.$this->opaque.'"' ;
  457.             }
  458.             $wwwauth .= "\r\n";
  459.             if (!$this->options['forceDigestOnly']{
  460.                 $wwwauth .= 'WWW-Authenticate: Basic realm="'.$this->realm.'"';
  461.             }
  462.             header($wwwauth);
  463.             header('HTTP/1.0 401 Unauthorized');            
  464.         }
  465.  
  466.         /**
  467.          * This code is only executed if the user hits the cancel
  468.          * button or if he enters wrong data 3 times.
  469.          */
  470.         if ($this->stale{
  471.             echo 'Stale nonce value, please re-authenticate.';
  472.         else {
  473.             echo $this->CancelText;
  474.         }
  475.         exit;
  476.     }
  477.  
  478.     // }}}
  479.     // {{{ setRealm()
  480.  
  481.     /**
  482.      * Set name of the current realm
  483.      *
  484.      * @access public
  485.      * @param  string $realm  Name of the realm
  486.      * @param  string $digestRealm  Name of the realm for digest authentication
  487.      * @return void 
  488.      */
  489.     function setRealm($realm$digestRealm '')
  490.     {
  491.         $this->realm = $realm;
  492.         if (!empty($digestRealm)) {
  493.             $this->options['digestRealm'$digestRealm;
  494.         }
  495.     }
  496.  
  497.     // }}}
  498.     // {{{ setCancelText()
  499.  
  500.     /**
  501.      * Set the text to send if user hits the cancel button
  502.      *
  503.      * @access public
  504.      * @param  string $text  Text to send
  505.      * @return void 
  506.      */
  507.     function setCancelText($text)
  508.     {
  509.         $this->CancelText = $text;
  510.     }
  511.  
  512.     // }}}
  513.     // {{{ validateDigest()
  514.     
  515.     /**
  516.      * judge if the client response is valid.
  517.      *
  518.      * @access public
  519.      * @param  string $response  client response
  520.      * @param  string $a1 password or hashed password stored in container
  521.      * @return bool true if success, false otherwise
  522.      */
  523.     function validateDigest($response$a1)    
  524.     {
  525.         if (method_exists($this'_importGlobalVariable')) {
  526.             $this->server = &$this->_importGlobalVariable('server');
  527.         }
  528.  
  529.         $a2unhashed $this->server['REQUEST_METHOD'].":".$this->selfURI();
  530.         if($this->auth['qop'== 'auth-int'{
  531.             if(isset($GLOBALS["HTTP_RAW_POST_DATA"])) {
  532.                 // In PHP < 4.3 get raw POST data from this variable
  533.                 $body $GLOBALS["HTTP_RAW_POST_DATA"];
  534.             else if($lines @file('php://input')) {
  535.                 // In PHP >= 4.3 get raw POST data from this file
  536.                 $body implode("\n"$lines);
  537.             else {
  538.                 if (method_exists($this'_importGlobalVariable')) {
  539.                     $this->post = &$this->_importGlobalVariable('post');
  540.                 }
  541.                 $body '';
  542.                 foreach($this->post as $key => $value{
  543.                     if($body != ''$body .= '&';
  544.                     $body .= rawurlencode($key'=' rawurlencode($value);
  545.                 }
  546.             }
  547.  
  548.             $a2unhashed .= ':'.md5($body);
  549.         }
  550.         
  551.         $a2 md5($a2unhashed);
  552.         $combined $a1.':'.
  553.             $this->auth['nonce'].':'.
  554.             $this->auth['nc'].':'.
  555.             $this->auth['cnonce'].':'.
  556.             $this->auth['qop'].':'.
  557.             $a2;
  558.         $expectedResponse md5($combined);
  559.         
  560.         if(!isset($this->auth['opaque']|| $this->auth['opaque'== $this->opaque{
  561.             if($response == $expectedResponse// password is valid
  562.                 if(!$this->stale{
  563.                     return true;
  564.                 else {
  565.                     $this->drawLogin();
  566.                 }
  567.             }
  568.         }
  569.         
  570.         return false;
  571.     }
  572.     
  573.     // }}}
  574.     // {{{ _judgeStale()
  575.     
  576.     /**
  577.      * judge if nonce from client is stale.
  578.      *
  579.      * @access private
  580.      * @param  string $nonce  nonce value from client
  581.      * @return bool stale
  582.      */
  583.     function _judgeStale($nonce
  584.     {
  585.         $stale = false;
  586.         
  587.         if(!$this->_decodeNonce($nonce$time$hash_cli)) {
  588.          $this->nextNonce = false;
  589.          $stale = true;
  590.             return $stale;
  591.         }
  592.  
  593.         if ($time time($this->options['nonceLife']{
  594.          $this->nextNonce = $this->_getNonce();
  595.             $stale = true;
  596.         else {
  597.          $this->nextNonce = $nonce;
  598.       }
  599.  
  600.         return $stale;
  601.     }
  602.     
  603.     // }}}
  604.     // {{{ _nonceDecode()
  605.     
  606.     /**
  607.      * decode nonce string
  608.      *
  609.      * @access private
  610.      * @param  string $nonce nonce value from client
  611.      * @param  string $time decoded time
  612.      * @param  string $hash decoded hash
  613.      * @return bool false if nonce is invalid
  614.      */
  615.     function _decodeNonce($nonce&$time&$hash
  616.     {
  617.         if (method_exists($this'_importGlobalVariable')) {
  618.             $this->server = &$this->_importGlobalVariable('server');
  619.         }
  620.  
  621.         if (strlen($nonce!= AUTH_HTTP_NONCE_TIME_LEN + AUTH_HTTP_NONCE_HASH_LEN{
  622.             return false;
  623.         }
  624.  
  625.         $time =  base64_decode(substr($nonce0AUTH_HTTP_NONCE_TIME_LEN));
  626.         $hash_cli substr($nonceAUTH_HTTP_NONCE_TIME_LENAUTH_HTTP_NONCE_HASH_LEN);
  627.  
  628.         $hash md5($time $this->server['HTTP_USER_AGENT'$this->options['noncekey']);
  629.  
  630.         if ($hash_cli != $hash{
  631.             return false;
  632.         }
  633.         
  634.         return true;
  635.     }
  636.  
  637.     // }}}
  638.     // {{{ _getNonce()
  639.     
  640.     /**
  641.      * return nonce to detect timeout
  642.      *
  643.      * @access private
  644.      * @return string nonce value
  645.      */
  646.     function _getNonce(
  647.     {
  648.         if (method_exists($this'_importGlobalVariable')) {
  649.             $this->server = &$this->_importGlobalVariable('server');
  650.         }
  651.  
  652.         $time time();
  653.         $hash md5($time $this->server['HTTP_USER_AGENT'$this->options['noncekey']);
  654.  
  655.         return base64_encode($time$hash;  
  656.     }
  657.  
  658.     // }}}
  659.     // {{{ authenticationInfo()
  660.     
  661.     /**
  662.      * output HTTP Authentication-Info header
  663.      *
  664.      * @notes md5 hash of contents is required if 'qop' is 'auth-int'
  665.      *
  666.      * @access public
  667.      * @param string MD5 hash of content
  668.      */
  669.     function authenticationInfo($contentMD5 ''{
  670.         
  671.         if($this->getAuth(&& ($this->getAuthData('a1'!= null)) {
  672.             $a1 $this->getAuthData('a1');
  673.  
  674.             // Work out authorisation response
  675.             $a2unhashed ":".$this->selfURI();
  676.             if($this->auth['qop'== 'auth-int'{
  677.                 $a2unhashed .= ':'.$contentMD5;
  678.             }
  679.             $a2 md5($a2unhashed);
  680.             $combined $a1.':'.
  681.                         $this->nonce.':'.
  682.                         $this->auth['nc'].':'.
  683.                         $this->auth['cnonce'].':'.
  684.                         $this->auth['qop'].':'.
  685.                         $a2;
  686.             
  687.             // Send authentication info
  688.             $wwwauth 'Authentication-Info: ';
  689.             if($this->nonce != $this->nextNonce{
  690.                 $wwwauth .= 'nextnonce="'.$this->nextNonce.'", ';
  691.             }
  692.             $wwwauth .= 'qop='.$this->auth['qop'].', ';
  693.             $wwwauth .= 'rspauth="'.md5($combined).'", ';
  694.             $wwwauth .= 'cnonce="'.$this->auth['cnonce'].'", ';
  695.             $wwwauth .= 'nc='.$this->auth['nc'].'';
  696.             header($wwwauth);
  697.         }
  698.     }
  699.     // }}}
  700.     // {{{ setOption()
  701.     /**
  702.      * set authentication option
  703.      *
  704.      * @access public
  705.      * @param mixed $name key of option
  706.      * @param mixed $value value of option
  707.      * @return void 
  708.      */
  709.     function setOption($name$value = null
  710.     {
  711.         if (is_array($name)) {
  712.             foreach($name as $key => $value{
  713.                 if (array_key_exists$key$this->options)) {
  714.                     $this->options[$key$value;
  715.                 }
  716.             }
  717.         else {
  718.             if (array_key_exists$name$this->options)) {
  719.                     $this->options[$name$value;
  720.             }
  721.         }
  722.     }
  723.  
  724.     // }}}
  725.     // {{{ getOption()
  726.     /**
  727.      * get authentication option
  728.      *
  729.      * @access public
  730.      * @param string $name key of option
  731.      * @return mixed option value
  732.      */
  733.     function getOption($name
  734.     {
  735.         if (array_key_exists$name$this->options)) {
  736.             return $this->options[$name];
  737.         }
  738.         if ($name == 'CancelText'{
  739.             return $this->CancelText;
  740.         }
  741.         if ($name == 'Realm'{
  742.             return $this->realm;
  743.         }
  744.         return false;
  745.     }
  746.  
  747.     // }}}
  748.     // {{{ selfURI()
  749.     /**
  750.      * get self URI
  751.      *
  752.      * @access public
  753.      * @return string self URI
  754.      */
  755.     function selfURI(
  756.     {
  757.         if (method_exists($this'_importGlobalVariable')) {
  758.             $this->server = &$this->_importGlobalVariable('server');
  759.         }
  760.  
  761.         if (preg_match("/MSIE/",$this->server['HTTP_USER_AGENT'])) {
  762.             // query string should be removed for MSIE
  763.             $uri preg_replace("/^(.*)\?/","\\1",$this->server['REQUEST_URI']);
  764.         else {
  765.             $uri $this->server['REQUEST_URI'];
  766.         }
  767.         return $uri;
  768.     }
  769.  
  770.     // }}}
  771.  
  772. }
  773.  
  774. // }}}
  775.  
  776. /*
  777.  * Local variables:
  778.  * tab-width: 4
  779.  * c-basic-offset: 4
  780.  * End:
  781.  */
  782. ?>

Documentation generated on Mon, 11 Mar 2019 14:16:10 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.