Keep Server Online
If you find the Apache Lounge, the downloads and overall help useful, please express your satisfaction with a donation.
or
A donation makes a contribution towards the costs, the time and effort that's going in this site and building.
Thank You! Steffen
Your donations will help to keep this site alive and well, and continuing building binaries. Apache Lounge is not sponsored.
| |
|
Topic: [PHP] .htpasswd manager |
|
Author |
|
Jorge
Joined: 12 Mar 2006 Posts: 376 Location: Belgium
|
Posted: Mon 31 Jul '06 18:59 Post subject: [PHP] .htpasswd manager |
|
|
This little class allows you to manage and validate against .htpasswd files.
The class should be fairly self explaining if you look at the code.
Updated: 19/03/2007
Create new file:
Code: |
$htpw = new htpasswd(./.htpasswd);
$htpw->create("user", "pass");
$htpw->save();
|
Update file:
Code: |
$htpw = new htpasswd(./.htpasswd);
$htpw->remove('user');
$htpw->create('new_user', 'password');
$htpw->save();
|
Validate User:
Code: |
$htpw = new htpasswd(./.htpasswd);
if($htpw->validate('user', 'pass'){
echo 'Welcome';
}else{
echo 'Get Lost';
}
|
The class:
Code: |
<?php
/*************************************\
| htpasswd class |
| By Jorge Schrauwen 2007 |
| http://www.blackdot.be |
\*************************************/
/*
Requires:
- PHP >= 4.3.0
Usage:
require('htpasswd.php');
$pwmanager = new htpasswd('.htpasswd');
$pwmanager->create('test', 'pass');
$pwmanager->save();
Functions:
create('MyUser', 'Pass') : create MyUser with password Pass. (true/false)
remove('MyUser') : remove MyUser. (true/false)
validate('MyUser', 'Pass') : will validate the user. (true/false)
users() : return and array with the usernames.
save() : save the password file. (true/false)
save('/server/www/.htpasswd') : save the password file to /server/www/.htpasswd. (true/false)
Error Handling:
when a function returns false you can get more information via
echo $pwmanager->error;
*/
class htpasswd{
public $users;
public $error;
private $_path;
function htpasswd($file=false){
if(!$file){
die('Please specify a file!');
}else{
//configure
$this->_path = $file;
$this->users = '';
//load database
if(file_exists($file)){
$data = array();
$fcontents = file($file);
while(list($line_num, $line) = each($fcontents)){
$user = explode(':',$line);
//$user = $arraydata[0];
$data[$user[0]] = rtrim($user[1]);
}
$this->users = $data;
}
}
}
function create($user, $passwd, $update=false){
$this->error = '';
if(isset($this->users[$user]) && !$update){
$this->error = 'User <strong>'.$user.'</strong> exists! To update the user set the update parameter to true.';
return false;
}
$this->users[$user] = $this->non_salted_sha1($passwd);
return true;
}
function remove($user){
$this->error = '';
if(isset($this->users[$user])){
unset($this->users[$user]);
return true;
}else{
$this->error = 'User <strong>'.$user.'</strong> does not exist!';
return false;
}
}
function users(){
$this->error = '';
$rval = Array();
if(is_array($this->users)){
foreach(array_keys($this->users) as $uid){
$rval[count($rval)] = $uid;
}
}
return $rval;
}
function validate($user, $pass){
$this->error = '';
if(!isset($this->users[$user])) return False;
$crypted = $this->users[$user];
if(substr($crypted, 0, 6) == "{SSHA}"){
$ohash = base64_decode(substr($crypted, 6));
return substr($ohash, 0, 20) == pack("H*", sha1($pass . substr($ohash, 20)));
}elseif(substr($crypted, 0, 5) == "{SHA}"){
return ($this->non_salted_sha1($pass) == $crypted);
}else{
return ($pass == $crypted);
}
}
function save($file=false){
$fcontents = "";
if($file == false) $file = $this->_path;
foreach(array_keys($this->users) as $user){
$fcontents .= $user.":".$this->users[$user]."\n";
}
if(file_put_contents($file, $fcontents)){
$this->error = '';
return true;
}else{
$this->error = 'Couln\'t save the file!';
return false;
}
}
//encryption functions
function rand_salt_crypt($pass){
$salt = "";
mt_srand((double)microtime()*1000000);
for ($i=0; $i<CRYPT_SALT_LENGTH; $i++)
$salt .= substr("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./", mt_rand() & 63, 1);
return "$apr1$".crypt($pass, $salt);
}
function rand_salt_sha1($pass){
mt_srand((double)microtime()*1000000);
$salt = pack("CCCC", mt_rand(), mt_rand(), mt_rand(), mt_rand());
return "{SSHA}".base64_encode(pack("H*", sha1($pass . $salt)) . $salt);
}
function non_salted_sha1($pass){
return "{SHA}".base64_encode(pack("H*", sha1($pass)));
}
}
//php4 work around
if(!function_exists('file_put_contents')){
function file_put_contents($filename, $content, $flags = null, $resource_context = null){
if(is_array($content)){
$content = implode('', $content);
}
if(!is_scalar($content)){
trigger_error('file_put_contents() The 2nd parameter should be either a string or an array', E_USER_WARNING);
return false;
}
$length = strlen($content);
$mode = ($flags &FILE_APPEND) ? 'a' : 'w';
$use_inc_path = ($flags &FILE_USE_INCLUDE_PATH) ? true : false;
if(($fh = @fopen($filename, $mode, $use_inc_path)) === false){
trigger_error('file_put_contents() failed to open stream: Permission denied', E_USER_WARNING);
return false;
}
$bytes = 0;
if(($bytes = @fwrite($fh, $content)) === false){
$errormsg = sprintf('file_put_contents() Failed to write %d bytes to %s',
$length,
$filename);
trigger_error($errormsg, E_USER_WARNING);
return false;
}
@fclose($fh);
if($bytes != $length){
$errormsg = sprintf('file_put_contents() Only %d of %d bytes written, possibly out of free disk space.',
$bytes,
$length);
trigger_error($errormsg, E_USER_WARNING);
return false;
}
return $bytes;
}
}
?>
|
Last edited by Jorge on Mon 19 Mar '07 10:31; edited 6 times in total |
|
Back to top |
|
James Blond Moderator
Joined: 19 Jan 2006 Posts: 7371 Location: Germany, Next to Hamburg
|
Posted: Wed 02 Aug '06 16:09 Post subject: |
|
|
To use this under PHP4 you need file_put_contents (since php 5)
Here the code to emulate that
Code: |
<?php
function file_put_contents($filename, $content, $flags = null, $resource_context = null)
{
if (is_array($content)) {
$content = implode('', $content);
}
if (!is_scalar($content)) {
user_error('file_put_contents() The 2nd parameter should be either a string or an array',
E_USER_WARNING);
return false;
}
$length = strlen($content);
$mode = ($flags &FILE_APPEND) ? 'a' : 'w';
$use_inc_path = ($flags &FILE_USE_INCLUDE_PATH) ? true : false;
if (($fh = @fopen($filename, $mode, $use_inc_path)) === false) {
user_error('file_put_contents() failed to open stream: Permission denied',
E_USER_WARNING);
return false;
}
$bytes = 0;
if (($bytes = @fwrite($fh, $content)) === false) {
$errormsg = sprintf('file_put_contents() Failed to write %d bytes to %s',
$length,
$filename);
user_error($errormsg, E_USER_WARNING);
return false;
}
@fclose($fh);
if ($bytes != $length) {
$errormsg = sprintf('file_put_contents() Only %d of %d bytes written, possibly out of free disk space.',
$bytes,
$length);
user_error($errormsg, E_USER_WARNING);
return false;
}
return $bytes;
}
?>
|
|
|
Back to top |
|
Jorge
Joined: 12 Mar 2006 Posts: 376 Location: Belgium
|
Posted: Wed 14 Feb '07 15:08 Post subject: |
|
|
Update check first post.
Admin/Mod: maybe clean it up a bit since all problems should be fixed and it should be more user friendly now.
Mod note: clean up |
|
Back to top |
|
condev1972
Joined: 09 Mar 2007 Posts: 1 Location: Germany
|
Posted: Sat 10 Mar '07 0:31 Post subject: |
|
|
Hello Jorge,
I just found your posts, thanks so much for your work!
Just wanted to provide some feedback:
- a requirement note at the top of the file saying that the class requires at least PHP >= 4.3.0 (due to the use of "sha1") would be good
- it might be cleaner to use "trigger_error" instead of "user_error" and "rtrim" instead of "chop" as these are just aliases and could perish.
Thanks,
Tobias |
|
Back to top |
|
Jorge
Joined: 12 Mar 2006 Posts: 376 Location: Belgium
|
Posted: Sat 10 Mar '07 11:55 Post subject: |
|
|
thanks for the feedback.
Changed it |
|
Back to top |
|
|
|
|
|
|