A hint: This file contains one or more very long lines, so maybe it is better readable using the pure text view mode that shows the contents as wrapped lines within the browser window.
1 <? 2 # * htpasstool v1.0.3 3 # * 4 # * Copyright (C) 2006,2007 Ward Vandewege (ward AT pong DOT be) 5 # * 6 # * This program is free software; you can redistribute it and/or modify 7 # * it under the terms of the GNU General Public License as published by 8 # * the Free Software Foundation; either version 2 of the License, or 9 # * (at your option) any later version. 10 # * 11 # * This program is distributed in the hope that it will be useful, 12 # * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 # * GNU General Public License for more details. 15 # * 16 # * You should have received a copy of the GNU General Public License 17 # * along with this program; if not, write to the Free Software 18 # * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 19 # * 20 21 # *************************************************************************** 22 # Start of configuration settings 23 24 // If you want to manage directories that are not strictly lower than this 25 // directory in your webspace, change BASE_DIRECTORY: replace realpath('.') 26 // with a path on your filesystem. 27 28 define("BASE_DIRECTORY", realpath('.')); 29 30 // If you change BASE_DIRECTORY above, you should also set $url_prefix below. 31 // Generally speaking, you should put the url that correspondes with 32 // BASE_DIRECTORY as the value of $url_prefix. For instance, if you are 33 // setting BASE_DIRECTORY to '/var/www', and that is the DocumentRoot for 34 // your web server, you should set $url_prefix to '/' - in that case you can 35 // use a relative URL. But you may have to define $url_prefix to be a fully 36 // fledged URL, depending on what URL BASE_DIRECTORY corresponds to for your 37 // setup. You don't have to end $url_prefix with a slash. 38 $url_prefix = ''; 39 40 // The e-mail address of the sender for the password reset/assign e-mails 41 $admin_email = ''; 42 43 // The template subject for the password reset/assign e-mails 44 $password_subject = "Login information"; 45 46 // The template message for the password reset/assign e-mails 47 $password_body = " 48 49 Your login information is: 50 51 url: %%url%% 52 53 login: %%login%% 54 password: %%password%% 55 56 "; 57 58 59 # End of user-modifiable code. Change nothing below this line unless you know 60 # what you are doing! 61 # *************************************************************************** 62 63 // return images 64 if (isset($_REQUEST['image'])) { 65 $imagesEncoded = Array( 66 "padlock" => "iVBORw0KGgoAAAANSUhEUgAAAA4AAAALCAYAAABPhbxiAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsNAAALDQHtB8AsAAAAB3RJTUUH1AQFFhQ155Nu3wAAAFRJREFUeJxjZMAE/5HYjFjkGRgYGBiYcGhiROMTBOgKcWpEt5GBgYGBjVhbYIAVagM65sGmGNnz+PyDEUjYnEoUwKrx/3/CgUm2jVTxIwcOTczYBAEMQw8nZ2fMggAAAABJRU5ErkJggg==", 67 "padlock-open" => "iVBORw0KGgoAAAANSUhEUgAAAA4AAAALCAYAAABPhbxiAAAABmJLR0QA/wAAAAAzJ3zzAAAACXBIWXMAAAsNAAALDQHtB8AsAAAAB3RJTUUH1AQFFhYN/ae0wwAAAFFJREFUeJxjYMAETGj0fySMFzAisZE1EKUZWSNWPhOaBAsDAwMrsabCACsDqn9gmAebYnT/4AKM6ALoTiUaYNX4/z/hwCPbRqr4kQOHJmZsggBvtxMm/Y4B+AAAAABJRU5ErkJggg==", 68 ); 69 $imageDataEnc = $imagesEncoded[$_GET["image"]]; 70 if ($imageDataEnc) { 71 $maxAge = 31536000; // one year 72 $imageDataRaw = base64_decode($imageDataEnc); 73 Header("Content-Type: image/png"); 74 Header("Content-Length: ".strlen($imageDataRaw)); 75 Header("Cache-Control: public, max-age=$maxAge, must-revalidate"); 76 echo $imageDataRaw; 77 } 78 exit; 79 } 80 81 ?> 82 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" 83 "http://www.w3.org/TR/html4/strict.dtd"> 84 <html> 85 <head> 86 <title>htpasstool</title> 87 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 88 <meta http-equiv="pragma" content="no-cache"> 89 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 90 <meta http-equiv="pragma" content="no-cache"> 91 <STYLE TYPE="text/css"> 92 <!-- 93 body { 94 background: #f9fcfe; 95 color: #000; 96 margin: 3; 97 padding: 0; 98 } 99 100 body, td { 101 font: 13px "Lucida Grande", "Lucida Sans Unicode", Tahoma, Verdana; 102 } 103 104 div.centered { 105 text-align: center; 106 } 107 108 div.centered table#outside { 109 border: solid 1px #000000; 110 margin: 0 auto; 111 text-align: left; 112 border-collapse:collapse; 113 } 114 115 td.outside { 116 border-bottom: solid 1px #000000; 117 } 118 119 td { 120 border-bottom: solid 0px #000000; 121 } 122 123 div.centerbold { 124 text-align: center; 125 font-weight: bold; 126 padding: 2px 2px 2px 2px; 127 margin: 5px; 128 font-size: 12px; 129 background-color: #ffffff; 130 color: #000000; 131 } 132 133 div#notice { 134 text-align: center; 135 font-weight: bold; 136 padding: 2px 2px 2px 2px; 137 font-size: 12px; 138 background-color: #00c000; 139 color: #ffffff; 140 } 141 142 span.ok { 143 text-align: center; 144 font-weight: bold; 145 padding: 2px 2px 2px 2px; 146 font-size: 12px; 147 background-color: #00c000; 148 color: #ffffff; 149 } 150 span.warn { 151 text-align: center; 152 font-weight: bold; 153 padding: 2px 2px 2px 2px; 154 font-size: 12px; 155 background-color: #ff3300; 156 color: #ffffff; 157 } 158 159 span.required { 160 font-weight: bold; 161 color: #ff0000; 162 } 163 div#error { 164 text-align: center; 165 font-weight: bold; 166 padding: 2px 2px 2px 2px; 167 font-size: 12px; 168 background-color: #c00000; 169 color: #ffffff; 170 } 171 --> 172 </STYLE> 173 </head> 174 <body> 175 176 <div class="centered"> 177 <table id="outside" width="600"> 178 <? 179 180 define("HTACCESS", ".htaccess"); 181 define("HTPASSWD", ".htpasswd"); 182 define("VERSION", "v1.02"); 183 184 $dir = $_REQUEST['dir']; 185 $action = $_REQUEST['action']; 186 $login = $_REQUEST['login']; 187 $newlogin = $_REQUEST['newlogin']; 188 $password = $_REQUEST['password']; 189 $password2 = $_REQUEST['password2']; 190 $assign_random_password = $_REQUEST['assign_random_password']; 191 $email = $_REQUEST['email']; 192 $sender = $_REQUEST['sender']; 193 $subject = $_REQUEST['subject']; 194 $body = $_REQUEST['body']; 195 $comment = $_REQUEST['comment']; 196 $message = ''; 197 $pwd_printed = 0; 198 199 # Sanitize the input 200 $dir = preg_replace('/[^_a-zA-Z0-9\/]/','',$dir); 201 $dir = preg_replace('/\/{1,}/','/',$dir); 202 203 # We need this later 204 $pattern = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 205 206 if (!isset($_REQUEST['dir'])) $dir = ''; 207 208 if (($url_prefix != '') && (!preg_match('/\/$/',$url_prefix))) $url_prefix .= '/'; 209 define("URL_PREFIX", $url_prefix); 210 211 $orig_cwd = BASE_DIRECTORY; 212 $wdir = BASE_DIRECTORY . "/" . $dir; 213 $wdir = preg_replace('/\/{1,}/','/',$wdir); 214 215 function redirect($url) { 216 header("HTTP/1.0 302 Redirect"); 217 header("Location: $url"); 218 header("Content-type:text/html"); 219 ?> 220 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"> 221 <HTML><HEAD> 222 <TITLE>302 Found</TITLE> 223 </HEAD><BODY> 224 <H1>Found</H1> 225 The document has moved <A HREF="<?=$url?>">here</A>.<P> 226 <HR> 227 </BODY></HTML> 228 229 <?php 230 exit; 231 } 232 233 function test_secured($path) { 234 // Returns 1 if 'path' is .htaccess protected. 235 // Returns 2 if 'path' is .htaccess protected, but the .htaccess file was not generated by htpasstool 236 $secured = 0; 237 if (file_exists("$path/" . HTACCESS) && is_file("$path/" . HTACCESS)) { 238 // we deliberately don't check for the presence of a HTPASSWD file here! 239 $htaccess = @file_get_contents("$path/" . HTACCESS); 240 if (preg_match("/^ *require valid-user/m",$htaccess)) $secured = 1; # This check is fairly basic... 241 # we did not make this htaccess file! 242 if (!preg_match("/^# htpasstool v\d.\d protected/",$htaccess)) $secured = 2; 243 } 244 return $secured; 245 } 246 247 function in_htpasstool_dir() { 248 global $orig_cwd; 249 global $wdir; 250 251 $tmp1 = $orig_cwd; 252 $tmp2 = $wdir; 253 254 # Follow symlinks 255 if (is_link($tmp1)) $tmp1 = readlink($tmp1); 256 if (is_link($tmp2)) $tmp2 = readlink($tmp2); 257 258 # Deal with relative symlinks 259 if (!preg_match('/^\//',$tmp1)) $tmp1 = preg_replace('/\/[^\/]*$/',"/$tmp1",$orig_cwd); 260 if (!preg_match('/^\//',$tmp2)) $tmp2 = preg_replace('/\/[^\/]*$/',"/$tmp2",$wdir); 261 262 $tmp1 = preg_replace("/\/$/",'',$tmp1); 263 $tmp2 = preg_replace("/\/$/",'',$tmp2); 264 265 return ($tmp1 == $tmp2); 266 } 267 268 function linkit($dir,$action,$user,$pretty='') { 269 if ($pretty == '') $pretty = ucfirst($action); 270 $deletestr = ''; 271 if ($action == 'delete') { 272 $deletestr = " onclick=\"return confirm('Do you really want to delete this user?')\""; 273 } 274 return "<a href=\"${$_SERVER['SCRIPT_NAME']}?action=$action&dir=$dir&login=$user\"$deletestr>$pretty</a>"; 275 } 276 277 function warn($desc,$no_overview=0) { 278 global $wdir, $dir; 279 global $pwd_printed; 280 if (file_exists($wdir) and (!$pwd_printed)) { 281 pwd(); 282 $pwd_printed = 1; 283 } 284 print "<tr><td class=\"outside\">"; 285 print "<div id=\"error\">$desc</div>\n"; 286 print "</td></tr>"; 287 if (!$no_overview) overview($wdir,$dir); 288 289 } 290 291 function fail($desc,$no_overview=0) { 292 global $wdir, $dir; 293 global $pwd_printed; 294 if (file_exists($wdir) and (!$pwd_printed)) { 295 pwd(); 296 $pwd_printed = 1; 297 } 298 print "<tr><td class=\"outside\">"; 299 print "<div id=\"error\">$desc</div>\n"; 300 print "</td></tr>"; 301 if (!$no_overview) overview($wdir,$dir); 302 303 print "</table>"; 304 print "</div>"; 305 306 exit; 307 } 308 309 function php4_scandir($dir, $sort = 0) { 310 if (PHP_VERSION >= '5') return scandir($dir, $sort); 311 $dirmap = array(); 312 if(!is_dir($dir)) 313 { 314 trigger_error("lib::scandir($dir): failed to open dir: Invalid argument", E_USER_WARNING); 315 return false; 316 } 317 $dir = opendir($dir); 318 while (false !== ($file = readdir($dir))) 319 $dirmap[] = $file; 320 closedir($dir); 321 ($sort == 1) ? rsort($dirmap) : sort($dirmap); 322 return $dirmap; 323 } 324 325 function pwd() { 326 global $wdir, $dir; 327 $wd_link = URL_PREFIX . $dir; 328 $wd_link2 = ''; 329 if (strlen($wd_link) != 0) { 330 $wd_link = '<a href="' . $wd_link . '">'; 331 $wd_link2 = '</a>'; 332 } 333 ?> 334 <tr> 335 <td align="center" class="outside"> 336 <a href="http://patch.be/htpasstool">htpasstool <?= VERSION ?></a> 337 </td> 338 </tr> 339 <tr> 340 <td class="outside"> 341 <table width="100%"> 342 <tr> 343 <td colspan="2">Base directory: <?= BASE_DIRECTORY ?></td> 344 </tr> 345 <tr> 346 <td>Working directory: <?= $wd_link ?><?=$dir?><?= $wd_link2 ?> [<a href="<?=$_SERVER['SCRIPT_NAME']?>?action=changewdform&dir=<?=$dir?>">change</a>]</td> 347 <? 348 349 350 $test_secured = test_secured($wdir); 351 if ($test_secured >= 1) { 352 print "<td align=\"right\"><a href=\"${$_SERVER['SCRIPT_NAME']}?dir=$dir&action=removehtaccessfileform\"><span class=\"ok\"><img src=\"$PHP_SELF?image=padlock\" alt=\"closed padlock icon\" border=0>Protected</span></a></td></tr>"; 353 } else { 354 print "<td align=\"right\"><a href=\"${$_SERVER['SCRIPT_NAME']}?dir=$dir&action=installhtaccessfile\"><span class=\"warn\"><img src=\"$PHP_SELF?image=padlock-open\" alt=\"open padlock icon\" border=0>Unprotected</span></a></td></tr>"; 355 } 356 ?> 357 </table> 358 </td> 359 </tr> 360 <? 361 362 if (!@php4_scandir($wdir)) { 363 if ($_REQUEST['action'] != 'changewdform') { 364 fail("The working directory $dir does not exist",1); 365 366 } else { 367 warn("The working directory $dir does not exist",1); 368 } 369 } 370 } 371 372 function overview($wdir,$dir) { 373 global $message; 374 375 if (is_file("$wdir/" . HTPASSWD) and !is_readable("$wdir/" . HTPASSWD)) { 376 fail("The $wdir/" . HTPASSWD . " file is not readable. Please check the permissions.\n",1); 377 } 378 379 if (!is_writeable($wdir)) { 380 fail("The $wdir directory is not writeable. Please check the permissions.\n",1); 381 } 382 if (is_file("$wdir/" . HTPASSWD) and !is_writeable("$wdir/" . HTPASSWD)) { 383 fail("The $wdir/" . HTPASSWD . " file is not writeable. Please check the permissions.\n",1); 384 } 385 386 $output = ''; 387 388 if ($message != '') { 389 $output .= "<tr><td class=\"outside\">"; 390 if ($message != '') $output .= "<div id=\"notice\">$message</div>"; 391 $output .= "</td></tr>"; 392 } 393 $output .= "<tr><td class=\"outside\">"; 394 395 $output .= "<div class=\"centerbold\">Users: [<a href=\"${$_SERVER['SCRIPT_NAME']}?action=addform&dir=$dir\">add</a>]</div>"; 396 397 if (is_readable("$wdir/" . HTPASSWD)) { 398 $fp = openfile("$wdir/" . HTPASSWD); 399 $lines = readhtpasswd($fp); 400 closefile($fp); 401 $output .= "<div class=\"centered\">\n<table width=80% align=\"center\">"; 402 if (count($lines) != 0) { 403 foreach ($lines as $k=>$v) { 404 $output .= "<tr bgcolor=\"#FFFFFF\" onMouseOver=\"this.style.backgroundColor='#DDDDDD'\" onMouseOut=\"this.style.backgroundColor=''\">"; 405 $output .= "<td align=\"left\">$k</td><td>{$lines[$k]['comment']}</td><td>" . linkit($dir,'editform',$k,'Edit') . " " . linkit($dir,'passwordform',$k,'Password') . " " . linkit($dir,'delete',$k) . " " . linkit($dir,'assignpasswordform',$k,'Assign random password') . " </td></tr>\n"; 406 } 407 $output .= "</table>\n</div>\n"; 408 } else { 409 $output .= "<tr><td><div class=\"centered\">The " . HTPASSWD . " file is currently empty.</div></td></tr>\n"; 410 $output .= "</table>"; 411 $output .= "</div>"; 412 } 413 } else { 414 $output .= "<div class=\"centered\">The " . HTPASSWD . " file does not exist yet.</div>\n"; 415 } 416 $output .= "</td></tr>"; 417 print $output; 418 } 419 420 function openfile($path) { 421 $fp = @fopen("$path", "r+") or fail("File $path could not be opened",1); 422 423 if (flock($fp, LOCK_EX)) { // do an exclusive lock 424 return $fp; 425 } else { 426 fclose($fp); 427 fail("Couldn't lock the file !"); 428 } 429 } 430 431 function createfile($path) { 432 $path = preg_replace('/\/{1,}/','/',$path); 433 $fp = @fopen("$path", "w") or fail("File $path could not be created",1); 434 435 if (flock($fp, LOCK_EX)) { // do an exclusive lock 436 return $fp; 437 } else { 438 fclose($fp); 439 fail("Couldn't lock the file !"); 440 } 441 } 442 443 function removehtaccessfile($dir) { 444 if (!file_exists("$dir/" . HTACCESS)) fail("The $dir/" . HTACCESS . " file does not exist"); 445 446 @unlink("$dir/" . HTACCESS) or fail("Could not remove $dir/" . HTACCESS); 447 } 448 449 function installhtaccessfile($dir) { 450 451 if (file_exists("$dir/" . HTACCESS)) fail("The $dir/" . HTACCESS . " file/dir exists"); 452 453 $fp = createfile("$dir/" . HTACCESS); 454 455 $output = "# htpasstool v1.0 protected\nAuthType Basic\nAuthName \"Restricted Area\"\nAuthUserFile \"$dir/" . HTPASSWD . "\"\nrequire valid-user\n"; 456 fwrite($fp,$output); 457 closefile($fp); 458 459 } 460 461 function readhtpasswd($fp) { 462 while (!feof($fp)) { 463 $data = fgets($fp, 4096); # We assume no line is longer than 4096 characters 464 if (preg_match("/^\s*$/",$data)) continue; # We don't need blank lines 465 $data = preg_replace("/\n/",'',$data); 466 $tmp = preg_split('/:/', $data); 467 if ($tmp[0] == '') continue; # Skip blank lines or lines with empty logins 468 $lines[$tmp[0]]['password'] = $tmp[1]; 469 $lines[$tmp[0]]['email'] = $tmp[2]; 470 $lines[$tmp[0]]['comment'] = $tmp[3]; 471 } 472 return $lines; 473 } 474 475 function writehtpasswd($fp,$lines) { 476 fseek($fp, 0); 477 ksort($lines); 478 foreach ($lines as $key => $value) { 479 #print "line to write: $key:$value\n<p>"; 480 $output .= $key . ':' . $lines[$key]['password'] . ':' . $lines[$key]['email'] . ':' . $lines[$key]['comment'] . "\n"; 481 } 482 # $output = preg_replace("/\n$/",'',$output); 483 fwrite($fp,$output); 484 ftruncate($fp,ftell($fp)); # We want to erase any additional content in the file 485 } 486 487 function closefile($fp) { 488 flock($fp, LOCK_UN); // release the lock 489 fclose($fp); 490 } 491 492 function assignpasswordform() { 493 global $wdir, $dir, $pwd_printed, $url_prefix; 494 global $login, $admin_email, $password_subject, $password_body, $pattern; 495 pwd(); 496 $pwd_printed = 1; 497 498 $fp = openfile("$wdir/" . HTPASSWD); 499 $lines = readhtpasswd($fp); 500 closefile($fp); 501 502 if (!array_key_exists($login ,$lines)) { 503 fail("This user does not exist"); 504 } 505 506 $password_parsed_subject = $password_subject; 507 508 $tmp_pass = $pattern{rand(0,61)} . $pattern{rand(0,61)} . $pattern{rand(0,61)} . $pattern{rand(0,61)} . $pattern{rand(0,61)} . $pattern{rand(0,61)} . $pattern{rand(0,61)} . $pattern{rand(0,61)}; 509 510 511 if ($url_prefix == '') { 512 $http = 'http://'; 513 if ($_SERVER['HTTPS'] != '') $http = 'https://'; 514 515 $tmpa = preg_replace('/\/[^\/]+$/','/',$_SERVER['REQUEST_URI']); 516 $tmpurl = $http . $_SERVER['SERVER_NAME'] . "$tmpa$dir"; 517 } else { 518 $tmpurl = $url_prefix . $dir; 519 } 520 521 $patterns = array("/%%admin_email%%/","/%%url%%/","/%%login%%/","/%%password%%/"); 522 $replacements = array($admin_email,$tmpurl,$login,$tmp_pass); 523 524 $password_parsed_body = preg_replace($patterns,$replacements,$password_body); 525 526 ?> 527 <tr> 528 <td class="outside"> 529 <form action="<?=$_SERVER['SCRIPT_NAME']?>"> 530 <input type="hidden" name="action" value="assignpassword"> 531 <input type="hidden" name="dir" value="<?=$dir?>"> 532 <input type="hidden" name="login" value="<?=$login?>"> 533 <input type="hidden" name="password" value="<?=$tmp_pass?>"> 534 <div class="centerbold">Assign and e-mail a new password:</div> 535 536 <div class="centered"> 537 <table width=80% align="center"> 538 <tr> 539 <td align="left">User:</td><td align="left"><?= $login ?></td> 540 </tr> 541 <tr> 542 <td align="left">E-mail address:</td><td align="left"><input type="text" size="20" name="email" value="<?= $lines[$login]['email'] ?>"></td> 543 </tr> 544 <tr> 545 <td align="left">Sender e-mail address:</td><td align="left"><input type="text" size="40" name="sender" value="<?= $admin_email ?>"></td> 546 </tr> 547 <tr> 548 <td align="left">Subject:</td><td align="left"><input type="text" size="40" name="subject" value="<?= $password_parsed_subject ?>"></td> 549 </tr> 550 <tr> 551 <td align="left" colspan="2">Message:</td> 552 </tr> 553 <tr> 554 <td align="left" colspan="2"><textarea cols="80" rows="15" name="body"><?= $password_parsed_body ?></textarea></td> 555 </tr> 556 <tr><td colspan="2"><input type="submit" value="Assign and send"></td></tr> 557 </table> 558 </div> 559 </form> 560 </td> 561 </tr> 562 <? 563 } 564 565 function verify_address($email) { 566 $valid = 0; 567 # According to RFC 2822, these characters are valid 'atext' chars - valid for the localpart of an e-mail address 568 # [a-z0-9!#\$%&'*+\-\/=?\^_`{\|}~.] 569 if (preg_match("/^[a-z0-9!#\$%&'*+\-\/=?\^_\`{\|}~.]+@[a-z0-9!#\$%&'*+\-\/=?\^_\`{\|}~.]+\.[a-z0-9!#\$%&'*+\-\/=?\^_\`{\|}~]{2,}$/",$email)) $valid = 1; 570 return $valid; 571 } 572 573 574 if ($action == 'addform') { 575 pwd(); 576 $pwd_printed = 1; 577 ?> 578 <tr> 579 <td class="outside"> 580 <form action="<?=$_SERVER['SCRIPT_NAME']?>"> 581 <input type="hidden" name="action" value="add"> 582 <input type="hidden" name="dir" value="<?=$dir?>"> 583 <div class="centerbold">Add user:</div> 584 <div class="centered"> 585 <table width=80% align="center"> 586 <tr> 587 <td align="left"><span class="required">*</span>Login:</td><td align="left"><input type="text" size="20" name="login"></td> 588 </tr> 589 <tr> 590 <td align="left">Assign random password:</td><td align="left"><input type="checkbox" size="40" name="assign_random_password" onclick="document.getElementById('password').style.visibility = this.checked ? 'hidden' : 'visible'; document.getElementById('confirm_password').style.visibility = this.checked ? 'hidden' : 'visible'"></td> 591 </tr> 592 <tr id="password"> 593 <td align="left"><span class="required">*</span>Password:</td><td align="left"><input type="password" size="20" name="password"></div></td> 594 </tr> 595 <tr id="confirm_password"> 596 <td align="left"><span class="required">*</span>Password (confirm):</td><td align="left"><input type="password" size="20" name="password2"></td> 597 </tr> 598 <tr> 599 <td align="left">E-mail:</td><td align="left"><input type="text" size="40" name="email"></td> 600 </tr> 601 <tr> 602 <td align="left">Comment:</td><td align="left"><input type="text" size="40" name="comment"></td> 603 </tr> 604 <tr><td colspan="2"><input type="submit" value="Add"></td></tr> 605 </table> 606 </div> 607 </form> 608 </td> 609 </tr> 610 <? 611 } elseif ($action == 'add') { 612 if (strlen($login) < 1) fail("The login can not be empty"); 613 if ($assign_random_password == '') { 614 if (strlen($password) < 6) fail("The password needs to be at least 6 characters long"); 615 if ($password != $password2) fail("The passwords you have supplied do not match"); 616 if ($password == '') fail("Missing parameter"); 617 if ($password2 == '') fail("Missing parameter"); 618 } else { 619 # Temporarily assign a random password. This is just to make sure that we 620 # don't end up with accounts without passwords if the user doesn't follow 621 # up on the 'assign & send' page. 622 $password = $pattern{rand(0,61)} . $pattern{rand(0,61)} . $pattern{rand(0,61)} . $pattern{rand(0,61)} . $pattern{rand(0,61)} . $pattern{rand(0,61)} . $pattern{rand(0,61)} . $pattern{rand(0,61)}; 623 } 624 625 if (is_readable("$wdir/" . HTPASSWD)) { 626 $fp = openfile("$wdir/" . HTPASSWD); 627 $lines = readhtpasswd($fp); 628 } else { 629 $fp = createfile("$wdir/" . HTPASSWD); 630 $lines = array(); 631 } 632 633 if ((count($lines) != 0) and (array_key_exists($login,$lines))) { 634 closefile($fp); 635 fail("Failed: this login is in use"); 636 } 637 638 if ($email != '') { 639 if (verify_address($email) == 0) { 640 closefile($fp); 641 fail("Failed: this e-mail address is not valid."); 642 } 643 } 644 645 $lines[$login]['password'] = crypt($password,$pattern{rand(0,61)} . $pattern{rand(0,61)}); 646 $lines[$login]['email'] = $email; 647 $lines[$login]['comment'] = $comment; 648 writehtpasswd($fp,$lines); 649 closefile($fp); 650 if ($assign_random_password != '') { 651 assignpasswordform(); 652 } else { 653 $message = "User $name has been created successfully"; 654 } 655 } elseif ($action == 'changewdform') { 656 pwd(); 657 $pwd_printed = 1; 658 ?> 659 <tr> 660 <td class="outside"> 661 <form action="<?=$_SERVER['SCRIPT_NAME']?>"> 662 <div class="centerbold">Change working directory:</div> 663 664 <div class="centered"> 665 <table width=80% align="center"> 666 <tr> 667 <td align="left">New working directory:</td><td align="left"><input type="text" size="60" name="dir"></td> 668 </tr> 669 <tr><td colspan="2"><input type="submit" value="Change"></td></tr> 670 </table> 671 </div> 672 </form> 673 </td> 674 </tr> 675 <? 676 } elseif ($action == 'assignpasswordform') { 677 assignpasswordform(); 678 } elseif ($action == 'assignpassword') { 679 if ($login == '') fail("Missing parameter"); 680 if ($email == '') fail("Destination e-mail address may not be empty"); 681 if ($sender == '') fail("Sender e-mail address may not be empty"); 682 if ($subject == '') fail("Subjet may not be empty"); 683 if ($body == '') fail("Body may not be empty"); 684 if (verify_address($email) == 0) fail("Destination e-mail address invalid"); 685 if (verify_address($sender) == 0) fail("Sender e-mail address invalid"); 686 687 $fp = openfile("$wdir/" . HTPASSWD); 688 $lines = readhtpasswd($fp); 689 690 if (!array_key_exists($login ,$lines)) { 691 closefile($fp); 692 fail("This user does not exist"); 693 } 694 695 $lines[$login]['password'] = crypt($password,$pattern{rand(0,61)} . $pattern{rand(0,61)}); 696 # If the e-mail address on file is empty, replace it with the one that was given here. Otherwise, ignore the one that was given here. 697 if ($lines[$login]['email'] == '') { 698 $lines[$login]['email'] = $email; 699 } 700 $lines[$login]['password'] = crypt($password,$pattern{rand(0,61)} . $pattern{rand(0,61)}); 701 writehtpasswd($fp,$lines); 702 closefile($fp); 703 704 $headers = "From: $sender\r\nTo: $email\r\nReply-To: $sender\r\n"; 705 $extra = "-f $sender"; 706 707 mail($email,$subject,$body,$headers,$extra); 708 mail($sender,"(carbon copy): $subject",$body,$headers,$extra); 709 710 $message = "The new password for user $login has been assigned, and the e-mail has been sent. You have been sent a carbon copy for your records."; 711 } elseif ($action == 'passwordform') { 712 pwd(); 713 $pwd_printed = 1; 714 ?> 715 <tr> 716 <td class="outside"> 717 <form action="<?=$_SERVER['SCRIPT_NAME']?>"> 718 <input type="hidden" name="action" value="password"> 719 <input type="hidden" name="dir" value="<?=$dir?>"> 720 <input type="hidden" name="login" value="<?=$login?>"> 721 <div class="centerbold">Change password:</div> 722 723 <div class="centered"> 724 <table width=60% align="center"> 725 <tr> 726 <td align="left">User:</td><td align="left"><?= $login ?></td> 727 </tr> 728 <tr> 729 <td align="left">New password:</td><td align="left"><input type="password" size="20" name="password"></td> 730 </tr> 731 <tr> 732 <td align="left">New password (confirm):</td><td align="left"><input type="password" size="20" name="password2"></td> 733 </tr> 734 <tr><td colspan="2"><input type="submit" value="Change"></td></tr> 735 </table> 736 </div> 737 </form> 738 </td> 739 </tr> 740 <? 741 } elseif ($action == 'password') { 742 if ($login == '') fail("Missing parameter"); 743 if (strlen($password) < 6) fail("The password needs to be at least 6 characters long"); 744 if ($password == '') fail("Missing parameter"); 745 if ($password2 == '') fail("Missing parameter"); 746 if ($password != $password2) fail("The passwords you have supplied do not match"); 747 748 $fp = openfile("$wdir/" . HTPASSWD); 749 $lines = readhtpasswd($fp); 750 751 if (!array_key_exists($login ,$lines)) { 752 closefile($fp); 753 fail("This user does not exist"); 754 } 755 756 $lines[$login]['password'] = crypt($password,$pattern{rand(0,61)} . $pattern{rand(0,61)}); 757 writehtpasswd($fp,$lines); 758 closefile($fp); 759 $message = "The password for user $login has been updated"; 760 } elseif ($action == 'editform') { 761 pwd(); 762 $pwd_printed = 1; 763 $fp = openfile("$wdir/" . HTPASSWD); 764 $lines = readhtpasswd($fp); 765 closefile($fp); 766 if (!array_key_exists($login,$lines)) { 767 fail("This user does not exist"); 768 } 769 ?> 770 <tr> 771 <td class="outside"> 772 <form action="<?=$_SERVER['SCRIPT_NAME']?>"> 773 <input type="hidden" name="action" value="update"> 774 <input type="hidden" name="dir" value="<?=$dir?>"> 775 <input type="hidden" name="login" value="<?=$login?>"> 776 <div class="centerbold">Edit user:</div> 777 <div class="centered"> 778 <table width=60% align="center"> 779 <tr> 780 <td align="left">Login:</td><td align="left"><input type="text" size="20" name="newlogin" value="<?=$login?>"></td> 781 </tr> 782 <tr> 783 <td align="left">E-mail:</td><td align="left"><input type="text" size="40" name="email" value="<?=$lines[$login]['email']?>"></td> 784 </tr> 785 <tr> 786 <td align="left">Comment:</td><td align="left"><input type="text" size="40" name="comment" value="<?=$lines[$login]['comment']?>"></td> 787 </tr> 788 <tr><td colspan="2"><input type="submit" value="Update"></td></tr> 789 </table> 790 </div> 791 </form> 792 </td> 793 </tr> 794 <? 795 } elseif ($action == 'update') { 796 if ($login == '') fail("Missing parameter"); 797 if ($newlogin == '') fail("Missing parameter"); 798 $fp = openfile("$wdir/" . HTPASSWD); 799 $lines = readhtpasswd($fp); 800 801 if ($email != '') { 802 if (verify_address($email) == 0) { 803 closefile($fp); 804 fail("Update failed: this e-mail address is not valid."); 805 } 806 } 807 808 $lines[$login]['email'] = $email; 809 $lines[$login]['comment'] = $comment; 810 if ($login != $newlogin) { 811 $lines[$newlogin] = $lines[$login]; 812 unset($lines[$login]); 813 } 814 writehtpasswd($fp,$lines); 815 closefile($fp); 816 $message = "User $newlogin has been updated."; 817 } elseif ($action == 'delete') { 818 if ($login == '') fail("Missing parameter"); 819 820 $fp = openfile("$wdir/" . HTPASSWD); 821 $lines = readhtpasswd($fp); 822 823 if (!array_key_exists($login,$lines)) { 824 closefile($fp); 825 fail("This user does not exist"); 826 } 827 828 unset($lines[$login]); 829 if (in_htpasstool_dir() and(count($lines) == 0)) { 830 closefile($fp); 831 fail("You can not remove the last user from the .htaccess file that governs the htpasstool directory"); 832 } 833 writehtpasswd($fp,$lines); 834 closefile($fp); 835 $message = "User $login has been removed"; 836 } elseif ($action == 'removehtaccessfileform') { 837 pwd(); 838 $pwd_printed = 1; 839 ?> 840 <tr> 841 <td class="outside"> 842 <form action="<?=$_SERVER['SCRIPT_NAME']?>"> 843 <input type="hidden" name="action" value="removehtaccessfile"> 844 <input type="hidden" name="dir" value="<?=$dir?>"> 845 <input type="hidden" name="login" value="<?=$login?>"> 846 <div class="centerbold">Remove .htaccess file:</div> 847 <div class="centered"> 848 <table width=60% align="center"> 849 <tr> 850 <td align="left" colspan="2"> 851 You are about to remove the .htaccess file from the directory <?=$dir?>. This will make this directory accessible for anyone on the network, without a password prompt. Are you sure you want to do this? 852 <? 853 if (test_secured($dir) == 2) { 854 ?> 855 <p><span class="warn">WARNING!</span> This .htaccess file was NOT created by htpasstool. Are you sure? 856 <? 857 } 858 if (in_htpasstool_dir()) { 859 ?> 860 <p><span class="warn">WARNING!</span> This .htaccess file protects htpasstool. If you remove this .htaccess file, ANYONE will be able to set/remove passwords in your webspace, because htpasstool will no longer be password protected. Are you sure? 861 <? 862 } 863 ?> 864 </td> 865 </tr> 866 <tr><td><input type="submit" name="submit" value="Cancel"></td><td><input type="submit" name="submit" value="OK"></td></tr> 867 </table> 868 </div> 869 </form> 870 </td> 871 </tr> 872 <? 873 } elseif ($action == 'removehtaccessfile') { 874 if ($_REQUEST['submit'] == 'OK') { 875 removehtaccessfile("$wdir"); 876 $message = "The directory $dir is no longer protected\n"; 877 } 878 } elseif ($action == 'installhtaccessfile') { 879 # Now; IF we are working on the htpasstool directory, refuse to activate 880 # protection unless there is one user defined (the minimum HTPASSWD file 881 # length is 15 chars: one for the username, one for the colon, and 13 for 882 # the crypt'ed password). 883 if (!in_htpasstool_dir() or (is_readable("$wdir/" . HTPASSWD) and (filesize("$wdir/" . HTPASSWD) >= 15))) { 884 installhtaccessfile("$wdir"); 885 $message = "The directory $dir has been protected\n"; 886 } else { 887 fail("When protecting the directory that governs htpasstool, you need to define at least one user first"); 888 } 889 } 890 891 if (!$pwd_printed) { 892 pwd(); 893 $pwd_printed = 1; 894 } 895 896 overview($wdir,$dir); 897 898 ?> 899 </table> 900 </div> 901 902 </body> 903 </html>