zoukankan      html  css  js  c++  java
  • .htpasswd在线生成PHP程序

    在线管理.htpasswd里的用户和密码,有验证,添加,删除,更改的功能.

    这是我写的应用例子:

    <style type="text/css">
    * {font: 12px Tahoma;}
    h1 {font: 14px Tahoma bold; text-align: center; color: blue;}
    h2 {font: 14px Tahoma bold ; text-align: center; color: blue;}
    body {padding: 0; text-align: center;}
    strong {color: blue;}
    em {color: red;}
    #form {margin: 20px auto; text-align: left;  260px; padding: 10px 30px; background: #F9F9F9; border: 8px solid #EEE;}
    #
    msg {margin: 20px auto; text-align: center;  260px; padding: 30px; background: #F9F9F9; border: 8px solid #EEE;}
    hr {border: 1px solid #EEE; height: 1px;}
    </style>
    <div id="form">
    <h1>.htpasswd用户管理</h1>
    <form action="<?php echo $_SERVER['PHP_SELF']?>" method="post">
    用户 : <input name="username" type="text" /><br />
    密码 : <input name="password" type="text" /><br />
    <input name="action" value="verify" checked="checked" type="radio" /> 校验密码 <br />
    <input name="action" value="add" type="radio" /> 添加新用户<br />
    <input name="action" value="delete" type="radio" /> 删除用户 <br />
    <input name="action" value="change" type="radio" /> 更改密码 <br /><br />
    <input type="submit" name="Submit" value="提交" />
    </form>
    </div>
    <?php
     
        include("class_htpasswd.php");
        $htpasswdfile = ".htpasswd";
     
        if (!$_POSTexit;
        if (!$_POST['action'] || !$_POST['username'] || !$_POST['password']) exit('<h1>提交数据不完整!</h1>');
     
        $action = $_POST['action'];
        $username = $_POST['username'];
        $password = $_POST['password'];
     
        $hp = new Htpasswd($htpasswdfile);
     
        switch ($action) {
            case 'add':
                $action_txt = '添加用户';
                $retval = $hp->addUser($username$password);
                if($retval) {
                    $msg = "<strong>用户 $username 密码 $password 添加成功!</strong>";
                } else {
                    $msg = "<em>用户 $username 密码 $password 添加失败.</em>";
                }
            break;
     
            case 'change':
                $action_txt = '更改密码';
                $retval = $hp->changePass($username$password);
                if($retval) {
                    $msg = "<strong>用户 $username 的密码更改为 $password 成功!</strong>";
                } else {
                    $msg = "<em>用户 $username 的密码更改为 $password 失败.</em>";
                }
     
            case 'delete':
                $action_txt = '删除用户';
                $retval = $hp->deleteUser($username);
                if($retval) {
                    $msg = "<strong>用户 $username 删除成功!</strong>";
                } else {
                    $msg = "<em>用户 $username 删除失败.</em>";
                }
            break;
     
            case 'verify':
                $action_txt = '校验密码';
                $retval = $hp->verifyUser($username$password);
                if($retval) {
                    $msg = "<strong>用户 $username 密码 $password 校验成功!</strong>";
                } else {
                    $msg = "<em>用户 $username 密码 $password 校验失败.</em>";
                }
            break;
     
            default:
            break;
        }
     
    echo <<< ANDY
    <div id="msg">
    您刚进行了此项操作,请核查<hr />
    <h2>$action_txt</h2>
    <p>$msg</p>
    </div>
    ANDY;

    ?> 

    导入

    <?php
    /*    **************************************************************
     *    
    $Id: class.htpasswd.php,v 1.5 2002/11/11 07:27:40 phps Exp $
     
        Revision 0.9 1999/01/27 16:41:00 
    cdi@thewebmasters.net
     
        Public Methods:
     
            initialize    version
            sane        do_not_blame_cdi    cryptPass
            isUser        getPass                verifyUser
            changePass    addUser                genSalt
            deleteUser    getUserNum            assignPass
            renameUser
     
        Internal Methods:
     
            utime    htReadFile    htWriteFile
            error    genPass
     
    */

     
     
    //    **************************************************************
    /*    History
     
        **************************************************************
     
        Rev 0.9            +renameUser(), -$UID
     
                        Added the renameUser() method per a request
                        from Rainer Scholz <
    jrs@startrek.franken.de>
                        (A good idea :)
     
                        Cleaned up some variables that were declared
                        but no longer in use. Changed a few error msgs.
                        It's amazing how much junk you can spot if you
                        step away from the code for a week. :)
     
                        Removed the UID global. It was used during some
                        of the more anal sane() checks and should have
                        been removed when sane() was changed in 0.7
     
     
        **************************************************************
     
        **************************************************************
        Revision 0.8 1999/01/17 15:20:00 
    cdi@thewebmasters.net
     
        Rev 0.8            Fixed the new() method so that it could
                        be called with an empty value, rather
                        than requiring the htpasswd file info.
     
     
        **************************************************************
        Revision 0.7 1999/01/14 15:34:00 
    cdi@thewebmasters.net
     
     
        Rev 0.7            -chconvert(), +Htpasswd()
     
                        Added the Htpasswd() method. Initialize() can
                        now be done if the new() method is given the
                        path and filename as in
     
                            $Htpasswd = new Htpasswd("/path/to/file");
     
                        This makes it easier to port Perl programs that
                        used Apache::Htpasswd. Besides, the method is
                        much cleaner this way. Initialize() can still
                        be called manually if you want to force a
                        refresh on the $FILE contents.
     
                        Removed a LOT of the sane() stuff. It finally
                        dawned on me that it just isn't my job to make
                        sure the programmer knows what the hell they're doing.
     
                        sane() now only makes 4 basic checks. (is_writeable,
                        is_readable, is_directory and is_symlink). If the
                        first 2 fail or if the last 2 succeed, sane() fails.
     
                        The mods to sane() removed the need for chconvert()
     
                        Added some Win32 checking. Basicly it won't try to
                        do a "*nix" thing to a Win box if WIN32 is set to
                        true. Other than that, you're on your own.
     
                        Fixed genSalt() to keep it from generating invalid
                        salts. (Outside the range [a-zA-Z./] )
     
                        Fixed cryptPass() so that it no longer needs the
                        salt passed to it, even if the salt is empty.
                        It will use the salt it's given and if no salt
                        is given, will generate a random one.
     
                        Started work on the man page.
     
        **************************************************************
        Revision 0.6 1999/01/13 19:21:00 
    cdi@thewebmasters.net
     
        Rev    0.6            +assignPass(), +genPass(), +genUser()
     
                        Cleaned up the rand() functions. Now it's
                        properly seeded in the initialize() method
                        and much more robust. Effects genPass() and genSalt()
     
                        genPass() generates a random 5 to 8 char password
                        genUser() generates a random 5 to 8 char UserID
     
                        assignPass(UserID) adds $UserID to password file
                        using a genPass() password. Returns the plain text
                        version of the password. genUser() just returns
                        a randomly generated User Name using A-Za-z0-9
                        genPass() generates a random password using
                        A-Za-z0-9 and the !@#$%^&*()-+./ characters.
     
        **************************************************************
        Revision 0.5 1999/01/12 21:07:00 
    cdi@thewebmasters.net
     
        Rev    0.5            +verifyUser(), -checkPass()
     
                        Deprecated checkPass() in favor of verifyUser()
     
                        Removed the need for the $salt in verifyUser()
                        If salt not passed to cryptPass(), it now
                        automatically calls genSalt()
     
                        Removed the need for the $salt in addUser()
     
                        Added global DEBUG - set to false to not
                        log errors.
     
                        General code clean up, better commenting
     
        **************************************************************
        Revision 0.4 1999/01/08 14:20:00 
    cdi@thewebmasters.net
     
        Rev 0.4            Hey neat - it works.
     
     
        **************************************************************
        Revision 0.3 1999/01/08 13:10:00 
    cdi@thewebmasters.net
     
        Rev 0.3            +addUser(), +genSalt(), +deleteUser(), +utime(),
                        +getUserNum()
     
        **************************************************************
        Revision 0.2 1999/01/07 09:55:00 
    cdi@thewebmasters.net
     
        Rev 0.2            +isUser(), +getPass(), +checkPass(), +htWriteFile(),
                        +changePass()
     
     
        **************************************************************
        Revision 0.1 1999/01/05 12:34:00 
    cdi@thewebmasters.net
     
        Rev 0.1    Start - +initialize(), +version(), +error(), +sane(),
                        +do_not_blame_cdi(), +cryptPass(), +htReadFile(),
                        +chconvert()
     
    */

     
    //    **************************************************************
    //
    //
     
    class Htpasswd {
     
        
    // Globally accessable variables
     
        
    var    $VERSION    = 'Revision 0.8 1999/01/17 15:20:00 cdi@thewebmasters.net';
     
        
    //var $UID        = getmyuid();
     
                                    
    // Set this to the user ID of the process
                                    
    // this program runs as. Used for sanity
                                    
    // checking. Defaults to same ID as
                                    
    // the file calling it.
     
        
    //    UID deprecated 0.9 - it was used for some of the more anal
        
    //    sane() routines - forgot to take it out in 0.7 when I should have
     
        
    var $WIN32        = false;    // Set to true for M$ BloatWare servers
     
     
        
    var $FILE        = "";        // Filename Holder
        
    var $ERROR        = "";        // Last error message
        
    var $EMPTY        = false;    // Is the FILE empty?
        
    var $CONTENTS    = "";        // Raw htpasswd contents
        
    var $EXISTS        = false;    // Boolean. True if $FILE exists
        
    var $SANE        = false;    // Boolean. True if $FILE passes all tests
        
    var $IDIOT        = false;    // Boolean. True if user is an idiot.
        
    var $DEBUG        = false;    // Boolean. Logs errors to error_log if set
        
    var $USERS        = array();    // Array of [index#][(user|pass)]=value
        
    var $USERCOUNT    = 0;        // Counter - total number of users in $FILE
                                    
    // Zero based indexing on $USERS
     
     
    //    **************************************************************
    //    An auto-constructor, can initilize the filename when
    //    called from new()
     
     
        
    function Htpasswd ($passwdFile = "")
        
    {
            
    if(!empty($passwdFile))
            
    {
                
    $this->initialize($passwdFile);
            
    }
            
    return;
        
    }
     
     
    //    **************************************************************
    //    The Initialize function sets up the FILE, checks it
    //    for sanity, then loads it into the processes memory
    //    htReadFile() should only be called using this method.
     
        
    function initialize ($passwdFile)
        
    {
            
    $this->FILE    =    $passwdFile;
     
            
    srand((double)microtime()*1000000)// Seed the random number gen
     
            
    if(empty($passwdFile))
            
    {
                
    // PHP is going to bitch about this, this is here just because
     
                
    $this->error("Invalid initialize() or new() method: No file specified!",1);
                
    exit// Just in case
            
    }
     
            
    if(file_exists($this->FILE))
            
    {
                
    $this->EXISTS = true;
                
    if($this->sane($this->FILE))
                
    {
                    
    $this->SANE = true;
                    
    $this->htReadFile();
                
    }
                
    else
                
    {
                    
    // Preserve the error generated by sane()
                    
    return;
                
    }
            
    }
            
    else
            
    {
                
    $this->SANE=true;    // Non-existant files are safe
            
    }
            
    return;
        
    }
     
    //    **************************************************************
    //    Turns off sanity checking. Needless to say if you do this
    //    you're an idiot, but I'll give you the rope...
     
     
        
    function do_not_blame_cdi ()
        
    {
            
    $this->IDIOT = true;
            
    $this->error("No sanity checking on files",0);
            
    return;
        
    }
     
     
    //    **************************************************************
    //    Checks file sanity. Can be called publicly, giving the
    //    full path to the file to be checked.
    //    Can be disabled if you're an idiot by
    //    calling $Htpasswd->do_not_blame_cdi() 
     
    //    Tons of junk removed Rev 0.7
     
        
    function sane ($filename)
        
    {
            
    if ($this->IDIOT)
            
    {
                
    return true;
            
    }
     
            
    // If it's a Win32 box, there's no sense in doing all this
     
            
    if ($this->WIN32)
            
    {
                
    // You're on your own
                
    return true;
            
    }
     
            
    //    Some kind of *nix machine - let's do some
            
    //    rudimentary checks
     
            
    if (!(is_readable($filename)))
            
    {
                
    $this->error("File [$filename] not readable",0);
                
    return false;
            
    }
            
    if (!(is_writeable($filename)))
            
    {
                
    $this->error("File [$filename] not writeable",0);
                
    return false;
            
    }
            
    if(is_dir($filename))
            
    {
                
    $this->error("File [$filename] is a directory",0);
                
    return false;
            
    }
            
    if(is_link($filename))
            
    {
                
    $this->error("File [$filename] is a symlink",0);
                
    return false;
            
    }
     
            
    //    I had a lot of routines in here to do a lot of checking
            
    //    on the file permissions and you know what? That
            
    //    ain't my job. It's yours.
     
            
    // File is assumed to be sane - too bad I'm not.
     
            
    return true;
        
    }
     
    //    **************************************************************
    //    Not really needed but it's a legacy thing...
     
        
    function version ()
        
    {
            
    return $this->VERSION;
        
    }
     
    //    **************************************************************
    //    Error handling. Fatals immediately exit the program (very
    //    few errors generate a fatal exit. Most just carp a warning
    //    and continue. Logged via error_log method.
     
        
    function error ($errMsg,$die)
        
    {
            
    $this->ERROR = $errMsg;
     
            
    //    croak or carp?
     
            
    //    If logging is turned off AND this is not
            
    //    a Fatal error, just return
     
            
    if( (!($this->DEBUG)) && ($die != 1) ){
                
    return;
            
    }
     
            
    if ($this->DEBUG)
            
    {
                
    error_log($this->ERROR,0);
            
    }
     
            
    if($die == 1)
            
    {
                
    echo "<b> ERROR $this->ERROR </b> <br /> \n";
                
    exit;
            
    }
     
            
    return;
        
    }
     
    //    **************************************************************
    //    Internal function to read the FILE and process it's contents
    //    Can be called publicly to re-read the file, but why would
    //    you want to introduce another series of system calls like that?
     
    //    This does the lions share of the work. This should only be
    //    called once per process, and it should be called internally
    //    by the initialize method. Have I mentioned that enough yet?
     
        
    function htReadFile ()
        
    {
            
    global    $php_errormsg;
     
            
    $Mytemp        = array();
            
    $Myjunk     = array();
            
    $Junk        = array();
            
    $count        = 0;
            
    $user       = "";
            
    $pass        = "";
            
    $temp        = "";
            
    $key        = "";
            
    $val        = "";
            
    $filesize     = 0;
            
    $errno        = 0;
            
    $empty        = false;
            
    $contents     = "";
     
            
    $filename     = $this->FILE;
            
    $filesize     = filesize($filename);
     
            
    if($filesize < 3) { $empty = true}
     
            
    //    Why did I pick 3? I dunno - seemed like the number
            
    //    to use at the time.
            
    //    (Actually, think [char]:[\n], the absolute smallest
            
    //    size a "legitimate" password file can ever be.)
     
            
    if(!($empty))
            
    {
                
    $this->EMPTY = false;
     
                
    $fd = fopen( $filename"r" );
     
                
    if(empty($fd))
                
    {
                    
    $this->error("FATAL File access error [$php_errormsg]",1);
                    
    exit// Just in case
                
    }
     
                
    $contents = fread( $fdfilesize( $filename ) );
                
    fclose( $fd );
     
                
    $this->CONTENTS = $contents;
                
    $Mytemp    = split("\n",$contents);
                
    for($count=0;$count<count($Mytemp);$count++)
                
    {
                    
    $user = "";
                    
    $pass = "";
     
                    
    if(empty($Mytemp[$count]))                    { break}
                    
    if(ereg("^(\n|\W)(.?)",$Mytemp[$count]))    { break}
     
                    
    if(!(ereg(":",$Mytemp[$count])))
                    
    {
                        
    $user = $Mytemp[$count];
                        
    $errno=($count+1);
                        
    $this->error("FATAL invalid user [$user] on line [$errno] in [$filename]",1);
                    
    }
     
                    
    list ($user,$pass) = split(":",$Mytemp[$count]);
     
                    
    if ( ($user != "") and ($pass != "") )
                    
    {
                        
    $Myjunk[$count]["user"]    = $user;
                        
    $Myjunk[$count]["pass"]    = $pass;
                    
    }
     
                
    }
     
                
    $this->USERS        = $Myjunk;
                
    $this->USERCOUNT    = $count;
     
            
    }
            
    else
            
    {
                
    // Empty file. Label it as such
     
                
    $this->USERS        = $Myjunk;
                
    $this->USERCOUNT    = -1;
                
    $this->EMPTY        = true;
            
    }
     
            
    return;
     
        
    }    // end htReadFile()
     
     
    //    **************************************************************
    //    Given a plain text password and salt, returns crypt() encrypted
    //    version. If salt is not passed or referenced, it will generate
    //    a random salt automatically.
     
        
    function cryptPass ($passwd$salt = "")
        
    {
            
    if (!($passwd))
            
    {
                
    // Return what we were given
     
                
    // If calling this directly, do something like
                
    // $enc_pass = $Htpasswd->cryptPass($pass);
                
    // if (empty($enc_pass)) { BARF! }
     
                
    // You should really verify the data before calling
                
    // this though - I do.            
     
                
    return "";
     
            
    }
     
            
    if (!empty($salt))
            
    {
                
    //# Make sure only use 2 chars
     
                
    $salt = substr ($salt02);
            
    }
            
    else
            
    {
                
    // If no salt, generate a (pseudo) random one
     
                
    $salt = $this->genSalt();
            
    }
     
            
    return (crypt($passwd$salt));
     
        
    } // end cryptPass
     
     
    //    **************************************************************
    //    Returns true if UserID is found in the password file. False
    //    otherwise.
     
        
    function isUser ($UserID)
        
    {
            
    $key = "";
            
    $val = "";
            
    $user = "";
            
    $pass = "";
            
    $found = false;
     
            
    if (empty($UserID))    { return false}
            
    if ($this->EMPTY)    { return false}
     
            
    for($count=0$count < $this->USERCOUNT$count++ )
            
    {
                
    if($UserID == $this->USERS[$count]["user"])
                
    {
                    
    $found = true;
                
    }
            
    }
     
            
    return $found;
     
        
    } // end isUser
     
    //    **************************************************************
    //    Fetches the encrypted password from the password file and
    //    returns it. Returns null on failure.
     
        
    function getPass ($UserID)
        
    {
            
    $key = "";
            
    $val = "";
            
    $user = "";
            
    $pass = "";
            
    $usernum = -1;
     
            
    if ($this->EMPTY)                { return $pass}
            
    if (empty($UserID))                { return $pass}
            
    if (!($this->isUser($UserID)))     { return $pass}
     
            
    $usernum = $this->getUserNum($UserID);
            
    if($usernum == -1)  {   return false}
     
            
    $pass = $this->USERS[$usernum]["pass"];
     
            
    return $pass;
     
        
    } // end getPass
     
    //    **************************************************************
    //    Returns true if Users password matches the password in 
    //    the password file.
    //
    //    method deprecated 0.5 <cdi>
    //    use verifyUser() instead
    //
        
    function checkPass ($UserID$Pass)
        
    {
            
    $retval = $this->verifyUser($UserID,$Pass);
            
    return $retval;
     
        
    } // end checkPass
     
     
    //    **************************************************************
    //    Returns true if Users password is authenticated, false otherwise
    //
    //    $Pass should be passed in un-encrypted
     
        
    function verifyUser ($UserID,$Pass)
        
    {
            
    $pass = "";
            
    $match = false;
            
    $usernum = -1;
            
    $salt = "";
     
            
    if ($this->EMPTY)                { return false}
            
    if (empty($UserID))                { return false}
            
    if (empty($Pass))                { return false}
            
    if (!($this->isUser($UserID)))    { return false}
     
            
    $usernum = $this->getUserNum($UserID);
            
    if($usernum == -1)  {   return false}
     
            
    $pass = $this->USERS[$usernum]["pass"];
            
    $salt = substr($pass,0,2);
            
    $Pass =    $this->cryptPass($Pass,$salt)
     
            
    if ($pass == $Pass)
            
    {
                
    $match = true;
            
    }
     
            
    return $match;
     
        
    } // end verifyUser
     
    //    **************************************************************
     
    //    Changes an existing users password. If "oldPass" is null, or 
    //    if oldPass is not passed to this method, there is no checking 
    //    to be sure it matches their old password.
    //
    //    Needless to say, you shouldn't do dat, but I'll give you
    //    the rope...
    //
    //    NewPass should be passed to this method un-encrypted.
    //
    //    Returns true on success, false on failure
     
        
    function changePass ($UserID$newPass$oldPass = "")
        
    {
            
    // global $php_errormsg;
     
            
    $passwdFile    =    $this->FILE;
            
    $pass        =    "";
            
    $newname;
            
    $newpass;
     
            
    // Can't very well change the password of a non-existant
            
    // user now can we?
     
            
    if ($this->EMPTY)                { return false}
            
    if (empty($UserID))                { return false}
     
            
    if (!($this->isUser($UserID)))
            
    {
                
    // No sniffing for valid user IDs please
                
    $this->error("changePass failure for [$UserID]: Authentication Failure",0);
                
    return false;
            
    }
     
            
    if(empty($newPass))
            
    {
                
    $this->error("changePass failure - no new password submitted",0);
                
    return false;
            
    }
     
            
    $newname = strtolower($UserID);
            
    $newpass = strtolower($newPass);
     
            
    if($newname == $newpass)
            
    {
                
    $this->error("changePass failure: UserID and password cannot be the same",0);
                
    return false;
            
    }
     
            
    // If no old Password, don't force it to match
            
    // their existing password. NOT RECOMMENDED!
            
    // Be SURE to always send the oldPass!
     
            
    if(!(empty($oldPass)))
            
    {
                
    //    Must validate the user now
     
                
    if (!($this->verifyUser($UserID,$oldPass)))
                
    {
                    
    $this->error("changePass failure for [$UserID] : Authentication Failed",0);
                    
    return false;
                
    }
     
                
    // OK - so the password is valid - are we planning
                
    // on actually changing it ?
     
                
    if($newPass == $oldPass)
                
    {
                    
    // Passwords are the same, no sense wasting time here
                
                    
    return true;
                
    }
            
    }
     
            
    // Valid user with new password, OK to change.
     
            
    $usernum = $this->getUserNum($UserID);
     
            
    if($usernum == -1)  {   return false}
     
            
    // No salt to cryptPass - generates a random one for us
            
    $this->USERS[$usernum]["pass"] = $this->cryptPass($newPass);
     
            
    if(!($this->htWriteFile()))
            
    {
                
    $this->error("FATAL could not save new password file! [$php_errormsg]",1);
                
    exit;    // just in case
            
    }
     
            
    return true;
     
        
    } // end changePass
     
     
    //    **************************************************************
    //    A modified copy of changePass - changes the users name.
    //    If $Pass is sent, it authenticates before allowing the change.
    //    Returns true on success, false if; 
    //
    //        The OldID is not found
    //        The NewID already exists
    //        The Password is sent and auth fails
     
        
    function renameUser ($OldID$NewID$Pass = "")
        
    {
            
    if ($this->EMPTY)                { return false}
            
    if (empty($OldID))                { return false}
            
    if (empty($NewID))                { return false}
     
            
    if (!($this->isUser($OldID)))
            
    {
                
    //    Send an auth failure - prevents people from fishing for
                
    //    valid userIDs.
                
    //    YOU will know its's because User is Unknown - 
                
    //    this error is slightly different than the real
                
    //    authentication failure message. Compare the two.
                
    //    Security through obscurity sucks but oh well..
     
                
    $this->error("renameUser failure for [$OldID]: Authentication Failure",0);
                
    return false;
            
    }
            
    if($this->isUser($NewID))
            
    {
                
    $this->error("Cannot change UserID, [$NewID] already exists",0);
                
    return false;
            
    }
     
            
    // If no Password, force a name change,
            
    // otherwise authenticate first.
     
            
    // Be SURE to always send the Pass!
     
            
    if(!(empty($Pass)))
            
    {
                
    //    Must validate the user now
     
                
    if (!($this->verifyUser($OldID,$Pass)))
                
    {
                    
    $this->error("renameUser failure for [$OldID] : Authentication Failed",0);
                    
    return false;
                
    }
     
                
    // OK - so the password is valid - are we planning
                
    // on actually changing our name ?
     
                
    if($NewID == $OldID)
                
    {
                    
    // Nice new name ya got there Homer...
                    
    return true;
                
    }
            
    }
     
            
    // Valid user, OK to change.
     
            
    $usernum = $this->getUserNum($OldID);
     
            
    if($usernum == -1)    {    return false}
     
            
    $this->USERS[$usernum]["user"] = $NewID;
     
            
    if(!($this->htWriteFile()))
            
    {
                
    $this->error("FATAL could not save password file! [$php_errormsg]",1);
                
    exit;    // just in case
            
    }
     
            
    return true;
     
        
    } // end renameUser
     
     
     
    //    **************************************************************
    //    Writes the new password file. Writes a temp file first,
    //    then attempts to copy the temp file over the existing file
    //    Original file not harmed if this fails.
     
    //    Also kinda sorta gets around the lack of file locking in PHP
    //    Hey, You there - PHP maintainer - FLOCK damn it! Not -everything-
    //    in life is inside a friggen database.
     
    //    On success, re-calls the initialize method to re-read
    //    the new password file and returns true. False on failure
     
        
    function htWriteFile ()
        
    {
            
    global $php_errormsg;
     
            
    $filename    = $this->FILE;
     
            
    // On WIN32 box this should -still- work OK,
            
    // but it'll generate the tempfile in the system
            
    // temporary directory (usually c:\windows\temp)
            
    // YMMV
     
            
    $tempfile    = tempnam( "/tmp""fort" );
     
            
    $name        = "";
            
    $pass        = "";
            
    $count        = 0;
            
    $fd;
            
    $myerror    = "";
     
            
    if($this->EMPTY)
            
    {
                
    $this->USERCOUNT = 0;
            
    }
     
            
    if (!copy($filename$tempfile))
            
    {
                
    $this->error("FATAL cannot create backup file [$tempfile] [$php_errormsg]",1);
                
    exit// Just in case
            
    }
     
            
    $fd = fopen( $tempfile"w" );
     
            
    if(empty($fd))
            
    {
                
    $myerror = $php_errormsg;    // In case the unlink generates
                                            
    // a new one - we don't care if
                                            
    // the unlink fails - we're
                                            
    // already screwed anyway
                
    unlink($tempfile);
                
    $this->error("FATAL File [$tempfile] access error [$myerror]",1);
                
    exit// Just in case
            
    }
     
            
    for($count=0$count <= $this->USERCOUNT$count++ )
            
    {
                
    $name = $this->USERS[$count]["user"];
                
    $pass = $this->USERS[$count]["pass"];
     
                
    if ( ($name != "") && ($pass != "") )
                
    {
                    
    fwrite($fd"$name:$pass\n");
                
    }
            
    }
     
            
    fclose( $fd );
     
            
    if (!copy($tempfile$filename))
            
    {
                
    $myerror = $php_errormsg;    // Stash the error, see above
                
    unlink($tempfile);
                
    $this->error("FATAL cannot copy file [$filename] [$myerror]",1);
                
    exit;    // Just in case
            
    }
     
            
    // Update successful
     
            
    unlink($tempfile);
     
            
    if(file_exists($tempfile))
            
    {
                
    // Not fatal but it should be noted
                
    $this->error("Could not unlink [$tempfile] : [$php_errormsg]",0);
            
    }
     
            
    // Update the information in memory with the
            
    // new file contents.
     
            
    $this->initialize($filename);
     
            
    return true;
        
    }
     
     
     
    //    **************************************************************
    //    Should be fairly obvious - adds a user to the htpasswd file
    //    Returns true on success, false on failure
     
        
    function addUser ($UserID$newPass)
        
    {
            
    // global $php_errormsg;
     
            
    $count = $this->USERCOUNT;
     
            
    if(empty($UserID))
            
    {
                
    $this->error("addUser fail. No UserID",0);
                
    return false;
            
    }
            
    if(empty($newPass))
            
    {
                
    $this->error("addUser fail. No password",0);
                
    return false;
            
    }
     
            
    if($this->isUser($UserID))
            
    {
                
    $this->error("addUser fail. UserID already exists",0);
                
    return false;
            
    }
     
            
    if($this->EMPTY)
            
    {
                
    $count = 0;
            
    }
     
            
    $this->USERS[$count]["user"] = $UserID;
     
            
    //    No salt to cryptPass() - will generate a random one for us
     
            
    $this->USERS[$count]["pass"] = $this->cryptPass($newPass);
     
            
    if(!($this->htWriteFile()))
            
    {
                
    $this->error("FATAL could not add user due to file error! [$php_errormsg]",1);
                
    exit;    // Just in case
            
    }
     
            
    // Successfully added user
     
            
    return true;
     
        
    } // end addUser
     
    //    **************************************************************
    //    Same as addUser, but adds the user to the password file
    //    with a randomly generated password.
    //
    //    Returns plain text password on success, null on failure
     
        
    function assignPass ($UserID)
        
    {
            
            
    $pass    = "";
            
    $count    = $this->USERCOUNT;
     
            
    if(empty($UserID))
            
    {
                
    $this->error("assignPass fail. No UserID",0);
                
    return "";
            
    }
            
    if($this->EMPTY)
            
    {
                
    $count = 0;
            
    }
     
            
    if($this->isUser($UserID))
            
    {
                
    $this->error("assignPass fail. UserID already exists. Use genPass instead",0);
                
    return "";
            
    }
     
            
    $pass = $this->genPass();
     
            
    $this->USERS[$count]["user"] = $UserID;
     
            
    //    No salt to cryptPass() - will generate a random one for us
     
            
    $this->USERS[$count]["pass"] = $this->cryptPass($pass);
     
            
    if(!($this->htWriteFile()))
            
    {
                
    $this->error("FATAL could not add user due to file error! [$php_errormsg]",1);
                
    exit;    // Just in case
            
    }
     
            
    // Successfully added user
     
            
    return($pass);
     
        
    } // end assignPass
     
     
     
    //    **************************************************************
    //    Again, fairly obvious - deletes a user from the htpasswd file
    //    Returns true on success, false on failure
     
        
    function deleteUser ($UserID)
        
    {
            
    // global $php_errormsg;
     
            
    $found = false;
     
            
    // Can't delete non-existant UserIDs
     
            
    if($this->EMPTY)    { return false}
            
    if(empty($UserID))
            
    {
                
    // PHP should complain about this, but just in case
                
    $this->error("deleteUser fail. No UserID to delete.",0);
                
    return false;
            
    }
            
    if(!($this->isUser($UserID)))
            
    {
                
    $this->error("Cannot delete : [$UserID] not found.",0);
                
    return false;
            
    }
     
            
    $usernum = $this->getUserNum($UserID);
     
            
    if($usernum == -1)  {   return false}
     
            
    $this->USERS[$usernum]["user"] = "";
            
    $this->USERS[$usernum]["pass"] = "";
     
            
    if(!($this->htWriteFile()))
            
    {
                
    $this->error("FATAL could not remove user due to file error! [$php_errormsg]",1);
                
    exit;    // Just in case
            
    }
     
            
    // Successfully deleted user
     
            
    return true;
     
        
    } // end deleteUser
     
     
    //    **************************************************************
    //    Returns the user's UserID in the password file.
    //    (Glorified line number)
    //    Returns -1 if not found or errors
     
        
    function getUserNum ($UserID)
        
    {
            
    $count = 0;
            
    $usernum = -1;
            
    $name = "";
     
            
    if ($this->EMPTY)                { return $usernum}
            
    if (empty($UserID))                { return $usernum}
     
            
    if (!($this->isUser($UserID)))    { return $usernum}
     
            
    for($count=0$count <= $this->USERCOUNT$count++ )
            
    {
     
                
    $name = $this->USERS[$count]["user"];
     
                
    if ($name != "")
                
    {
                    
    if ($name == $UserID)
                    
    {
                        
    $usernum = $count;
                        
    break;
                    
    }
                
    }
            
    }
     
            
    return $usernum;
        
    }
     
     
    //    **************************************************************
    //    Calculates current microtime
     
        
    function utime()
        
    {
            
    $time = explode( " "microtime());
            
    $usec = (double)$time[0];
            
    $sec = (double)$time[1];
            
    return $sec + $usec;
        
    }
     
    //    **************************************************************
    //    Generates a pseudo random 2 digit salt. Method will 
    //    generate different salts when called multiple times by
    //    the same process.
     
     
        
    function genSalt ()
        
    {
            
    $random = 0;
            
    $rand64 = "";
            
    $salt = "";
     
            
    $random=rand();    // Seeded via initialize()
     
            
    // Crypt(3) can only handle A-Z a-z ./
     
            
    $rand64"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
            
    $salt=substr($rand64,$random  %  64,1).substr($rand64,($random/64)64,1);
            
    $salt=substr($salt,0,2)// Just in case
     
            
    return($salt);
     
        
    }
     
     
    //    **************************************************************
    //    Generates a pseudo random 5 to 8 digit password. Method will even
    //    generate different passwords when called multiple times by
    //    the same process.
     
        
    function genPass ()
        
    {
     
            
    $random = 0;
            
    $rand78 = "";
            
    $randpass = "";
            
    $pass = "";
     
            
    $maxcount = rand(4,9);
     
            
    // The rand() limits (min 4, max 9) don't actually limit the number
            
    // returned by rand, so keep looping until we have a password that's
            
    // more than 4 characters and less than 9.
     
            
    if ( ($maxcount > 8) or ($maxcount < 5) )
            
    {
                
    do
                
    {
                    
    $maxcount = rand(4,9);
     
                
    } while ( ($maxcount > 8) or ($maxcount < 5) );
            
    }
     
            
    $rand78"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()-=_+abcdefghijklmnopqrstuvwxyz";
            
    for($count=0$count <= $maxcount$count++)
            
    {
                
    $random=rand(0,77);
                
    $randpass=substr($rand78,$random,1);
                
    $pass = $pass.$randpass;
            
    }
     
            
    $pass = substr($pass,0,8);    // Just in case
     
            
    return($pass);
     
        
    }    // end genPass
     
     
    //    **************************************************************
    //    Generates a pseudo random 5 to 8 digit User ID. Method will 
    //    generate different User IDs when called multiple times by
    //    the same process.
     
        
    function genUser ()
        
    {
     
            
    $random = 0;
            
    $rand78 = "";
            
    $randuser = "";
            
    $userid = "";
     
            
    $maxcount = rand(4,9);
     
            
    if ( ($maxcount > 8) or ($maxcount < 5) )
            
    {
                
    do
                
    {
                    
    $maxcount = rand(4,9);
     
                
    } while ( ($maxcount > 8) or ($maxcount < 5) );
            
    }
     
            
    $rand62"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
            
    for($count=0$count <= $maxcount$count++)
            
    {
                
    $random=rand(0,61);
                
    $randuser=substr($rand62,$random,1);
                
    $userid = $userid.$randuser;
            
    }
     
            
    $userid = substr($userid,0,8);    // Just in case
     
            
    return($userid);
     
        
    }    // end genUser
     
     
     
    //    **************************************************************
     
     
    //    **************************************************************
     
     
    }   // END CLASS.HTPASSWD
     
     
     
    ?> 
  • 相关阅读:
    Mybatis入门
    结合模板导出PDF文件
    生成Excel文件
    生成PDF文件
    BeanFactory not initialized or already closed
    Oracle数据库的视图
    ORACLE简介
    Cookie和session
    【cookie的使用】&【Session】
    过滤器的相关知识
  • 原文地址:https://www.cnblogs.com/mutuan/p/2611537.html
Copyright © 2011-2022 走看看