home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / File / Passwd / Authdigest.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  10.9 KB  |  362 lines

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3.  
  4. /**
  5.  * File::Passwd::Authdigest
  6.  * 
  7.  * PHP versions 4 and 5
  8.  *
  9.  * LICENSE: This source file is subject to version 3.0 of the PHP license
  10.  * that is available through the world-wide-web at the following URI:
  11.  * http://www.php.net/license/3_0.txt.  If you did not receive a copy of
  12.  * the PHP License and are unable to obtain it through the web, please
  13.  * send a note to license@php.net so we can mail you a copy immediately.
  14.  *
  15.  * @category   FileFormats
  16.  * @package    File_Passwd
  17.  * @author     Michael Wallner <mike@php.net>
  18.  * @copyright  2003-2005 Michael Wallner
  19.  * @license    http://www.php.net/license/3_0.txt  PHP License 3.0
  20.  * @version    CVS: $Id: Authdigest.php,v 1.13 2005/09/27 06:26:08 mike Exp $
  21.  * @link       http://pear.php.net/package/File_Passwd
  22.  */
  23.  
  24. /**
  25. * Requires File::Passwd::Common
  26. */
  27. require_once 'File/Passwd/Common.php';
  28.  
  29. /**
  30. * Manipulate AuthDigestFiles as used for HTTP Digest Authentication.
  31. *
  32. * <kbd><u>
  33. *   Usage Example:
  34. * </u></kbd>
  35. * <code>
  36. *   $htd = &File_Passwd::factory('Authdigest');
  37. *   $htd->setFile('/www/mike/auth/.htdigest');
  38. *   $htd->load();
  39. *   $htd->addUser('mike', 'myRealm', 'secret');
  40. *   $htd->save();
  41. * </code>
  42. *
  43. * <kbd><u>
  44. *   Output of listUser()
  45. * </u></kbd>
  46. * <pre>
  47. *      array
  48. *       + user  => array
  49. *                   + realm => crypted_passwd
  50. *                   + realm => crypted_passwd
  51. *       + user  => array
  52. *                   + realm => crypted_passwd
  53. * </pre>
  54. * @author   Michael Wallner <mike@php.net>
  55. * @package  File_Passwd
  56. * @version  $Revision: 1.13 $
  57. * @access   public
  58. */
  59. class File_Passwd_Authdigest extends File_Passwd_Common
  60. {
  61.     /** 
  62.     * Path to AuthDigestFile
  63.     *
  64.     * @var string
  65.     * @access private
  66.     */
  67.     var $_file = '.htdigest';
  68.  
  69.     /** 
  70.     * Constructor
  71.     * 
  72.     * @access public
  73.     * @param string $file       path to AuthDigestFile
  74.     */
  75.     function File_Passwd_Authdigest($file = '.htdigest')
  76.     {
  77.         parent::__construct($file);
  78.     }
  79.  
  80.     /**
  81.     * Fast authentication of a certain user
  82.     * 
  83.     * Returns a PEAR_Error if:
  84.     *   o file doesn't exist
  85.     *   o file couldn't be opened in read mode
  86.     *   o file couldn't be locked exclusively
  87.     *   o file couldn't be unlocked (only if auth fails)
  88.     *   o file couldn't be closed (only if auth fails)
  89.     *
  90.     * @static   call this method statically for a reasonable fast authentication
  91.     * 
  92.     * @throws   PEAR_Error
  93.     * @access   public
  94.     * @return   mixed   true if authenticated, false if not or PEAR_Error
  95.     * @param    string  $file   path to passwd file
  96.     * @param    string  $user   user to authenticate
  97.     * @param    string  $pass   plaintext password
  98.     * @param    string  $realm  the realm the user is in
  99.     */
  100.     function staticAuth($file, $user, $pass, $realm)
  101.     {
  102.         $line = File_Passwd_Common::_auth($file, $user.':'.$realm);
  103.         if (!$line || PEAR::isError($line)) {
  104.             return $line;
  105.         }
  106.         @list(,,$real)= explode(':', $line);
  107.         return (md5("$user:$realm:$pass") === $real);
  108.     }
  109.     
  110.     /** 
  111.     * Apply changes and rewrite AuthDigestFile
  112.     *
  113.     * Returns a PEAR_Error if:
  114.     *   o directory in which the file should reside couldn't be created
  115.     *   o file couldn't be opened in write mode
  116.     *   o file couldn't be locked exclusively
  117.     *   o file couldn't be unlocked
  118.     *   o file couldn't be closed
  119.     * 
  120.     * @throws PEAR_Error
  121.     * @access public
  122.     * @return mixed true on success or a PEAR_Error
  123.     */
  124.     function save()
  125.     {
  126.         $content = '';
  127.         if (count($this->_users)) {
  128.             foreach ($this->_users as $user => $realm) {
  129.                 foreach ($realm as $r => $pass){
  130.                   $content .= "$user:$r:$pass\n";
  131.                 }
  132.             }
  133.         }
  134.         return $this->_save($content);
  135.     }
  136.  
  137.     /** 
  138.     * Add an user
  139.     *
  140.     * Returns a PEAR_Error if:
  141.     *   o the user already exists in the supplied realm
  142.     *   o the user or realm contain illegal characters
  143.     * 
  144.     * $user and $realm must start with an alphabetical charachter and must NOT
  145.     * contain any other characters than alphanumerics, the underline and dash.
  146.     * 
  147.     * @throws PEAR_Error
  148.     * @access public
  149.     * @return mixed true on success or a PEAR_Error
  150.     * @param string $user   the user to add
  151.     * @param string $realm  the realm the user should be in
  152.     * @param string $pass   the plaintext password
  153.     */
  154.     function addUser($user, $realm, $pass)
  155.     {
  156.         if ($this->userInRealm($user, $realm)) {
  157.             return PEAR::raiseError(
  158.                 "User '$user' already exists in realm '$realm'.", 0
  159.             );
  160.         }
  161.         if (!preg_match($this->_pcre, $user)) {
  162.             return PEAR::raiseError(
  163.                 sprintf(FILE_PASSWD_E_INVALID_CHARS_STR, 'User ', $user),
  164.                 FILE_PASSWD_E_INVALID_CHARS
  165.             );
  166.         }
  167.         if (!preg_match($this->_pcre, $realm)) {
  168.             return PEAR::raiseError(
  169.                 sprintf(FILE_PASSWD_E_INVALID_CHARS_STR, 'Realm ', $realm),
  170.                 FILE_PASSWD_E_INVALID_CHARS
  171.             );
  172.         }
  173.         $this->_users[$user][$realm] = md5("$user:$realm:$pass");
  174.         return true;
  175.     }
  176.  
  177.     /**
  178.     * List all user of (a | all) realm(s)
  179.     * 
  180.     * Returns:
  181.     *   o associative array of users of ONE realm if $inRealm was supplied
  182.     *     <pre>
  183.     *       realm1
  184.     *        + user1 => pass
  185.     *        + user2 => pass
  186.     *        + user3 => pass
  187.     *     </pre>
  188.     *   o associative array of all realms with all users
  189.     *     <pre>
  190.     *       array
  191.     *        + realm1 => array
  192.     *                     + user1 => pass
  193.     *                     + user2 => pass
  194.     *                     + user3 => pass
  195.     *        + realm2 => array
  196.     *                     + user3 => pass
  197.     *        + realm3 => array
  198.     *                     + user1 => pass
  199.     *                     + user2 => pass
  200.     *     </pre>
  201.     * 
  202.     * @access public
  203.     * @return array
  204.     * @param string $inRealm    the realm to list users of;
  205.     *                           if omitted, you'll get all realms
  206.     */
  207.     function listUserInRealm($inRealm = '')
  208.     {
  209.         $result = array();
  210.         foreach ($this->_users as $user => $realms){
  211.             foreach ($realms as $realm => $pass){
  212.                 if (!empty($inRealm) && ($inRealm !== $realm)) {
  213.                     continue;
  214.                 }
  215.                 if (!isset($result[$realm])) {
  216.                     $result[$realm] = array();
  217.                 }
  218.                 $result[$realm][$user] = $pass;
  219.             }
  220.         }
  221.         return $result;
  222.     }
  223.     
  224.     /** 
  225.     * Change the password of a certain user
  226.     *
  227.     * Returns a PEAR_Error if:
  228.     *   o user doesn't exist in the supplied realm
  229.     *   o user or realm contains illegal characters
  230.     * 
  231.     * This method in fact adds the user whith the new password
  232.     * after deleting the user.
  233.     * 
  234.     * @throws PEAR_Error
  235.     * @access public
  236.     * @return mixed true on success or a PEAR_Error
  237.     * @param string $user   the user whose password should be changed
  238.     * @param string $realm  the realm the user is in
  239.     * @param string $pass   the new plaintext password
  240.     */
  241.     function changePasswd($user, $realm, $pass)
  242.     {
  243.         if (PEAR::isError($error = $this->delUserInRealm($user, $realm))) {
  244.             return $error;
  245.         } else {
  246.             return $this->addUser($user, $realm, $pass);
  247.         }
  248.     }
  249.  
  250.     /** 
  251.     * Verifiy password
  252.     *
  253.     * Returns a PEAR_Error if the user doesn't exist in the supplied realm.
  254.     * 
  255.     * @throws PEAR_Error
  256.     * @access public
  257.     * @return mixed true if passwords equal, false if they don't, or PEAR_Error
  258.     * @param string $user   the user whose password should be verified
  259.     * @param string $realm  the realm the user is in
  260.     * @param string $pass   the plaintext password to verify
  261.     */
  262.     function verifyPasswd($user, $realm, $pass)
  263.     {
  264.         if (!$this->userInRealm($user, $realm)) {
  265.             return PEAR::raiseError(
  266.                 sprintf(FILE_PASSWD_E_USER_NOT_IN_REALM_STR, $user, $realm),
  267.                 FILE_PASSWD_E_USER_NOT_IN_REALM
  268.             );
  269.         }
  270.         return ($this->_users[$user][$realm] === md5("$user:$realm:$pass"));
  271.     }
  272.  
  273.     /**
  274.     * Ckeck if a certain user is in a specific realm
  275.     * 
  276.     * @throws PEAR_Error
  277.     * @access public
  278.     * @return boolean
  279.     * @param string $user   the user to check
  280.     * @param string $realm  the realm the user shuold be in
  281.     */
  282.     function userInRealm($user, $realm)
  283.     {
  284.       return (isset($this->_users[$user][$realm]));
  285.     }
  286.     
  287.     /**
  288.     * Delete a certain user in a specific realm
  289.     *
  290.     * Returns a PEAR_Error if <var>$user</var> doesn't exist <var>$inRealm</var>.
  291.     * 
  292.     * @throws PEAR_Error
  293.     * @access public
  294.     * @return mixed true on success or PEAR_Error
  295.     * @param  string    $user       the user to remove
  296.     * @param  string    $inRealm    the realm the user should be in
  297.     */
  298.     function delUserInRealm($user, $inRealm)
  299.     {
  300.         if (!$this->userInRealm($user, $inRealm)) {
  301.             return PEAR::raiseError(
  302.                 sprintf(FILE_PASSWD_E_USER_NOT_IN_REALM_STR, $user, $inRealm),
  303.                 FILE_PASSWD_E_USER_NOT_IN_REALM
  304.             );
  305.         }
  306.         unset($this->_users[$user][$inRealm]);
  307.         return true;
  308.     }
  309.     
  310.     /** 
  311.     * Parse the AuthDigestFile
  312.     *
  313.     * Returns a PEAR_Error if AuthDigestFile has invalid format.
  314.     * 
  315.     * @throws PEAR_Error
  316.     * @access public
  317.     * @return mixed true on success or PEAR_Error
  318.     */
  319.     function parse()
  320.     {
  321.         $this->_users = array();
  322.         foreach ($this->_contents as $line) {
  323.             $user = explode(':', $line);
  324.             if (count($user) != 3) {
  325.                 return PEAR::raiseError(
  326.                     FILE_PASSWD_E_INVALID_FORMAT_STR,
  327.                     FILE_PASSWD_E_INVALID_FORMAT
  328.                 );
  329.             }
  330.             list($user, $realm, $pass) = $user;
  331.             $this->_users[$user][$realm] = trim($pass);
  332.         }
  333.         $this->_contents = array();
  334.         return true;
  335.     }
  336.     
  337.     /**
  338.     * Generate Password
  339.     *
  340.     * @static
  341.     * @access   public
  342.     * @return   string  The crypted password.
  343.     * @param    string  $user The username.
  344.     * @param    string  $realm The realm the user is in.
  345.     * @param    string  $pass The plaintext password.
  346.     */
  347.     function generatePasswd($user, $realm, $pass)
  348.     {
  349.         return md5("$user:$realm:$pass");
  350.     }
  351.     
  352.     /**
  353.      * @ignore
  354.      * @deprecated
  355.      */
  356.     function generatePassword($user, $realm, $pass)
  357.     {
  358.         return File_Passwd_Authdigest::generatePasswd($user, $realm, $pass);
  359.     }
  360. }
  361. ?>