code.fastix.org

Dateiansicht:

Datei:Projekte -> Apache,PHP:htpasswd -> htpasswd.php
md5:7f78c5bf895b4ff574b92cb0dd7efd87
sha1:337327301221df0e80919721a2c761bca431cac8
  1. <?php
  2.  
  3. /**
  4. * @author: Jörg Reinholz, fastix WebDesign & Consult, Kassel - http://www.fastix.org/
  5. * @version: 3.3.1
  6. **/
  7.  
  8. ### Konfiguration:
  9. ## Freier String:
  10. define('FTX_AUTHNAME', 'Geschlossener Bereich');
  11.  
  12. ## Wohin soll das Userfile gespeichert werden?
  13. define('FTX_USERFILE', __DIR__ . '/.htpasswd');
  14.  
  15. ## Die folgende Einstellung ist auf einem Apache Webserver
  16. ## normalerweise so vorkonfiguriert. Ändern sie diese,
  17. ## dann wird das Skript zwar funktionieren - aber der
  18. ## Webserver wird Ihre Einstellungen ignorieren:
  19. define('FTX_HTACCESSFILE', __DIR__ . '/.htaccess');
  20.  
  21. ## Stärke des Hashes:
  22. # Default:1
  23. # Apache 2.4 kann bcrypt, dehalb: 1
  24. # Bei 0 wird das veraltete Apache-MD5 mit einem Salt benutzt!
  25. # Für den Apache 2.2 oder älter muss 0 (also Apache-MD5) benutzt werden:
  26. DEFINE('FTX_USE_BCRYPT', 1);
  27.  
  28.  
  29. ## Soll die Konfiguration angezeigt werden? (true / false)
  30. # Spielzeug/Debug/Lernen ... muss man nicht haben, kann man aber:
  31. define('FTX_SHOWCONFIG', 1);
  32.  
  33. ### Ende der Konfiguration ###
  34. header('Cache-Control: max-age=0');
  35. header('Cache-Control: no-cache');
  36. header('Pragma: no-cache');
  37. header('Content-Type:text/html; charset=UTF-8');
  38.  
  39.  
  40.  
  41. $warnung = '';
  42.  
  43. if ( ! file_exists( FTX_USERFILE ) ) {
  44.         touch ( FTX_USERFILE );
  45. }
  46.  
  47. if ( ! file_exists(FTX_HTACCESSFILE ) ) {
  48.         touch ( FTX_HTACCESSFILE );
  49. }
  50.  
  51. if ( ! file_exists( FTX_USERFILE ) ) {
  52.         die( 'Fatal: Die Datei "' . FTX_USERFILE . '" konnte nicht angelegt werden. überprüfen Sie, ob der Webserver Schreibrechte am Verzeichnis "' . dirname($_SERVER['SCRIPT_FILENAME']) . '" hat.' );
  53. }
  54.  
  55. if ( ! file_exists( FTX_HTACCESSFILE ) ) {
  56.         die( 'Fatal: Die Datei "'.FTX_HTACCESSFILE .'" konnte nicht angelegt werden. überprüfen Sie, ob der Webserver Schreibrechte am Verzeichnis "' . dirname($_SERVER['SCRIPT_FILENAME']) . '" hat.' );
  57. }
  58.  
  59. if ( ! is_readable( FTX_USERFILE ) ) {
  60.         die( 'Fatal: Die Datei "' . FTX_USERFILE . '" existiert, der Webserver hat aber keine Leserechte. (Lösung: Setzen mit "chmod 666 ' . FTX_USERFILE . '"' );
  61. }
  62.  
  63. if ( ! is_readable( FTX_HTACCESSFILE ) ) {
  64.         die('Fatal: Die Datei "' . FTX_HTACCESSFILE . '" existiert, der Webserver hat aber keine Leserechte. (Lösung: Setzen mit "chmod 666 '.FTX_HTACCESSFILE.'"' );
  65. }
  66.  
  67. if ( ! is_writable( FTX_USERFILE ) ) {
  68.         die('Fatal: Die Datei "' . FTX_USERFILE . '" existiert, der Webserver hat aber keine Schreibrechte. (Lösung: Setzen mit "chmod 666 ' . FTX_USERFILE . '"' );
  69. }
  70.  
  71. if ( ! is_writable( FTX_HTACCESSFILE ) ) {
  72.         die( 'Fatal: Die Datei "' . FTX_HTACCESSFILE . '" existiert, der Webserver hat aber keine Schreibrechte. (Lösung: Setzen mit "chmod 666 ' . FTX_HTACCESSFILE . '"' );
  73. }
  74.  
  75.  
  76. if ( isset( $_POST['user'] ) && $_POST['user'] && isset( $_POST['pass'] ) && ( $_POST['pass'] ) ) {
  77.         #Benutzer anlegen
  78.        $user = trim( $_POST['user'] );
  79.         $pass = trim( $_POST['pass'] );
  80.         if (! AddUser( $user, $pass ) ) {
  81.                 $warnung = '<script type="text/javascript">
  82.                alert("Der Benutzer wurde nicht angelegt. (Enthält der Benutzername unzulässige Zeichen wie den Punkt, den Doppelpunkt an beliebiger Stelle oder die Raute am Anfang?)")
  83.                </script>';
  84.         }
  85. }
  86.  
  87.  
  88. if ( isset( $_GET['kill'] ) && $_GET['kill'] ) {
  89.         $strUser = trim( $_GET['kill'] );
  90.         if (
  91.                 ! CheckHtaccess( FTX_HTACCESSFILE )
  92.                 || (
  93.                         isset( $_SERVER["PHP_AUTH_USER"] )
  94.                         && $strUser != $_SERVER["PHP_AUTH_USER"]
  95.                 )
  96.         ) {
  97.                 KillUser($strUser);
  98.         } else {
  99.                 $warnung .= '<script type="text/javascript">
  100.                alert("Sie können sich selbst nicht löschen! Sie können aber Ihr Passwort ändern.")
  101.                </script>';
  102.         }
  103. }
  104.  
  105. if ( isset( $_POST['Ein'] ) && $_POST['Ein'] ) {
  106.         $arUsers = GetUserArray();
  107.         if ( isset($arUsers[0])  && $arUsers[0] ) {
  108.                 AddToHtaccess();
  109.                 header( 'Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . '?tw=' . uniqid() );
  110.                 exit;
  111.         } else {
  112.                 $warnung .= '<script type="text/javascript">
  113.                alert("Der Schutz kann nicht aktiviert werden, weil (noch) keine Benutzer existieren. Legen Sie mindestens einen Benutzer an.")
  114.                </script>';
  115.  
  116.         }
  117. }
  118.  
  119. if ( isset( $_POST['Aus'] ) && $_POST['Aus'] ) {
  120.         DelFromHtaccess();
  121. }
  122.  
  123. if ( CheckHtaccess() ) {
  124.         $strSchutz = "Der Verzeichnisschutz ist eingeschaltet.";
  125.         $strShowEinbutton = "none";
  126.         $strShowAusbutton = "inline";
  127. } else {
  128.         $strSchutz = "Der Verzeichnisschutz ist ausgeschaltet.";
  129.         $strShowEinbutton = "inline";
  130.         $strShowAusbutton = "none";
  131. }
  132.  
  133. /*
  134.         Funktionen
  135.  
  136. */
  137.  
  138. function GetUserArray() {
  139.         $users = array();
  140.         $arLines = file( FTX_USERFILE );
  141.         foreach ( $arLines as $strLine ) {
  142.                 $parts = array();
  143.                 $parts = explode( ':', $strLine, 2 );
  144.                 $parts[0] = trim($parts[0] );
  145.                 if ( '' != $parts[0] ) {
  146.                         $users[] = $parts[0];
  147.                 }
  148.         }
  149.         $dummy = sort($users);
  150.         return $users;
  151. }
  152.  
  153. function PrintUserList() {
  154.         $arUsers=GetUserArray();
  155.         print "         <ul type=\"none\">\n";
  156.                 foreach ( $arUsers as $strUser ) {
  157.                         $strUser = trim( $strUser );
  158.                         if (
  159.                                 ! CheckHtaccess()
  160.                                 || (
  161.                                         isset( $_SERVER["PHP_AUTH_USER"] )
  162.                                         && $strUser != $_SERVER["PHP_AUTH_USER"]
  163.                                 )
  164.                         ) {
  165.                                 print '                 <li class="t2" title="Diesen Benutzer löschen ..." onclick="Ask(\''.$strUser.'\')">' . htmlspecialchars( $strUser ) ."</li>\n";
  166.                         } else {
  167.                                 print '                 <li title="Aktueller Benutzer ist nicht löschbar." class="t2i">' . htmlspecialchars( $strUser ) . "</li>\n";
  168.                         }
  169.                 }
  170.         print "         </ul>\n";
  171. }
  172.  
  173.  
  174. function PrintFile( $file ) {
  175.         echo '<pre>' . htmlspecialchars( file_get_contents( $file ) ) . '</pre>';
  176. }
  177.  
  178. function KillUser( $user ) {
  179.         $newFile = '';
  180.         $arFile = file(FTX_USERFILE);
  181.         foreach ( $arFile as $strLine ) {
  182.                 $arLine = explode( ':' , $strLine , 2 );
  183.                 if ( $arLine[0] != $user && $arLine[0] != '' && isset( $arLine[1] ) ) {
  184.                         $newFile .= $arLine[0] . ':' . trim($arLine[1]) . "\n";
  185.                 }
  186.         }
  187.         file_put_contents( FTX_USERFILE, $newFile, LOCK_EX );
  188. }
  189.  
  190. function AddUser($user, $password) {
  191.         if ( 255 > strlen( $user ) )        $user = substr( $user, 0, 255 );
  192.         if ( 255 > strlen( $password ) )    $password = substr( $password, 0, 255 );
  193.         KillUser( $user );
  194.         if ( false !== strpos( ':', $user ) or false !== strpos( '.', $user ) or 0 === strpos( '#', $user ) ) {
  195.                 return false;
  196.         }
  197.         if ( FTX_USE_BCRYPT ) {
  198.                 if ( function_exists('password_hash' ) ) {
  199.                     $apachepassword  = password_hash( $password, PASSWORD_BCRYPT );
  200.                 } else {
  201.                     $apachepassword  = crypt( $password, '$y$10$' );
  202.                 }
  203.         } else {
  204.                 $apachepassword  = crypt_apr1_md5( $password );
  205.         }
  206.         $newline=$user . ':' . $apachepassword ;
  207.         file_put_contents( FTX_USERFILE, $newline=$user . ':' . $apachepassword, FILE_APPEND | LOCK_EX );
  208.         return true;
  209. }
  210.  
  211. function AddToHtaccess() {
  212.         $text='
  213. AuthType basic
  214. AuthName "' . FTX_AUTHNAME . '"
  215. AuthUserFile ' . FTX_USERFILE . '
  216. Require valid-user
  217. ';
  218.         file_put_contents( FTX_HTACCESSFILE, $text, FILE_APPEND | LOCK_EX );
  219. }
  220.  
  221. function DelFromHtaccess() {
  222.         $text='';
  223.         $arFile=array();
  224.         $arFile=file( FTX_HTACCESSFILE );
  225.         foreach ( $arFile as $strLine ) {
  226.                 $strLine = trim( $strLine );
  227.                 if ( $strLine !='' ) {
  228.                         if ( ! strpos( $strLine, 'uth' ) ) {
  229.                                 if ( ! strpos( $strLine, 'valid-user' ) ) {
  230.                                     $text .= $strLine."\n";
  231.                                 }
  232.                         }
  233.                 }
  234.         }
  235.         file_put_contents( FTX_HTACCESSFILE, $text, LOCK_EX );
  236. }
  237.  
  238. function CheckHtaccess() {
  239.         $arFile = file( FTX_HTACCESSFILE );
  240.         foreach ( $arFile as $strLine ) {
  241.                 $strLine = trim( $strLine );
  242.                 if ( $strLine !='' ) {
  243.                         if ( strpos( $strLine, 'uth' ) )        { return true; }
  244.                         if ( strpos( $strLine, 'valid-user' ) ) { return true; }
  245.                 }
  246.  
  247.         }
  248.         return false;
  249. }
  250.  
  251. function crypt_apr1_md5( $plainpasswd, $salt = false ) {
  252.     $translateTo = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
  253.     if ( ! $salt ) { $salt = substr( str_shuffle( $translateTo ), 0, 8 ); }
  254.     $len = strlen( $plainpasswd );
  255.     $text = $plainpasswd . '$apr1$' . $salt;
  256.     $bin = pack( "H32", md5( $plainpasswd . $salt . $plainpasswd ) );
  257.     for( $i = $len; $i > 0; $i -= 16 ) { $text .= substr( $bin, 0, min( 16, $i ) ); }
  258.     for( $i = $len; $i > 0; $i >>= 1 ) { $text .= ( $i & 1 ) ? chr(0) : $plainpasswd{0}; }
  259.     $bin = pack( "H32", md5( $text ) );
  260.     for( $i = 0; $i < 1000; $i++ ) {
  261.         $new = ( $i & 1 ) ? $plainpasswd : $bin;
  262.         if ( $i % 3 ) $new .= $salt;
  263.         if ( $i % 7 ) $new .= $plainpasswd;
  264.         $new .= ( $i & 1 ) ? $bin : $plainpasswd;
  265.         $bin = pack( "H32", md5( $new ) );
  266.     }
  267.     for ( $i = 0; $i < 5; $i++ ) {
  268.         $k = $i + 6;
  269.         $j = $i + 12;
  270.         if ( $j == 16 ) $j = 5;
  271.         $tmp = $bin[$i] . $bin[$k] . $bin[$j] . $tmp;
  272.     }
  273.     $tmp = chr(0).chr(0).$bin[11].$tmp;
  274.     $tmp = strtr (
  275.         strrev(substr(base64_encode($tmp), 2)),
  276.         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
  277.         $translateTo
  278.         );
  279.     return '$apr1$' . $salt . '$' . $tmp;
  280. }
  281.  
  282.  
  283.  
  284. ?><!doctype html>
  285. <html>
  286.         <head>
  287.                 <title>Passwortverwaltung</title>
  288.                 <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
  289.                 <meta charset="utf-8"/>
  290.                 <meta name="Author" content="Jörg Reinholz, fastix Webdesign &amp; Consult">
  291.                 <meta name="Publisher" content="Jörg Reinholz, fastix Webdesign &amp; Consult">
  292.                 <meta name="Copyright" content="Jörg Reinholz, fastix Webdesign &amp; Consult">
  293.                 <meta name="Robots" content="NOINDEX,NOFOLLOW">
  294.                 <style type="text/css">
  295.                         body, html, form {
  296.                                 padding:0;
  297.                                 margin:0;
  298.                                 font-family:helvetica, arial, sans-serif;
  299.                                 background-color:#ddd;
  300.                                 font-size:1em;
  301.                         }
  302.  
  303.                         header {
  304.                                 padding-left:1em;
  305.                                 background-color:#006;
  306.                                 color:#fff;
  307.                                 border-bottom:2px solid #000;
  308.                                 font-family: times, serif;
  309.                                 font-weight:bold;
  310.                         }
  311.  
  312.                         h1 {
  313.                                 margin-top:0;
  314.                                 margin-bottom:0;
  315.                                 font-size:2em;
  316.                                 padding-left:.7em;
  317.                                 padding-top:.1em;
  318.                                 padding-bottom:.1em;
  319.                                 font-family: times, serif;
  320.                         }
  321.                         .subline {
  322.                                 line-height:1em;
  323.                                 padding-left:1.4em;
  324.                                 padding-bottom:.3em;
  325.                         }
  326.                         #inhalt {
  327.                                 position:absolute;
  328.                                 top:6em;
  329.                                 left:1.4em;
  330.                                 bottom:4em;
  331.                                 width:25em;
  332.                                 padding:.25em;
  333.                                 overflow:auto;
  334.                         }
  335.  
  336.                         #inhalt2 {
  337.                                 position:absolute;
  338.                                 top:6em;
  339.                                 left:30em;
  340.                                 bottom:4em;
  341.                                 padding:1em;
  342.                                 overflow:auto;
  343.                         }
  344.                         .t1 {
  345.                                 display:block;
  346.                                 width:6em;
  347.                                 float:left;
  348.                         }
  349.                         .t2 {
  350.                                 background-color:#fff;
  351.                                 padding:.3em;
  352.                                 border:1px solid #cc0;
  353.                                 margin-top:-1px;
  354.                                 cursor:pointer;
  355.                         }
  356.  
  357.                         .t2:hover {
  358.                                 background-color:#ffa;
  359.                         }
  360.                         .t2i {
  361.                                 background-color:#ddd;
  362.                                 color:888;
  363.                                 padding:.3em;
  364.                                 border:1px solid #cc0;
  365.                                 margin-top:-1px;
  366.                         }
  367.                         .t3 {
  368.                                 text-align:center;
  369.                                 font-weight:bold;
  370.                                 color:red;
  371.                         }
  372.                         legend {
  373.                                 font-weight:bold;
  374.                                 font-size:.8em;
  375.                                 font-family:times, serif;
  376.                         }
  377.                         fieldset {
  378.                                 margin-bottom:2em;
  379.                                 border-radius:.1em;
  380.                         }
  381.                         #fastix {
  382.                                 position:absolute;
  383.                                 top:100%;
  384.                                 left:0;
  385.                                 right:0;
  386.                                 margin-top:-3.2em;
  387.                                 font-size:.8em;
  388.                                 padding:.7em;
  389.                                 padding-left:1em;
  390.                                 background-color:#006;
  391.                                 color:#fff;
  392.                                 border-top:.2em solid #000;
  393.                         }
  394.                         #fastix a:link, #fastix a:visited , #fastix a:hover , #fastix a:focus {
  395.                                 color: #fff;
  396.                         }
  397.  
  398.                         input {
  399.                                 font-family:helvetica, arial, sans-serif;
  400.                         }
  401.                         #Ein {
  402.                                 width:10em;
  403.                                 display:<?=$strShowEinbutton;?>
  404.                         }
  405.                         #Aus {
  406.                                 width:10em;
  407.                                 display:<?=$strShowAusbutton;?>
  408.                         }
  409.                 </style>
  410.                 <script type="text/javascript">
  411.                         function Ask(user) {
  412.                                 if (confirm('Wollen Sie den Benutzer "'+user+'" wirklich löschen?')) {
  413.                                         this.location.href="<?=$_SERVER['PHP_SELF'];?>?kill="+encodeURIComponent(user);
  414.                                 } else {
  415.                                         return 0;
  416.                                 }
  417.                         }
  418.                 </script>
  419.                 <?=$warnung;?>
  420.         </head>
  421.         <body onload="document.getElementById('user').focus();">
  422.                 <header>
  423.                         <h1 id="js_on" style="display:none">Benutzerverwaltung</h1>
  424.                         <div class="subline">für das Verzeichnis: <?=htmlspecialchars(dirname($_SERVER['SCRIPT_FILENAME']));?></div>
  425.                 </header>
  426.                 <script type="text/javascript">
  427.                         document.getElementById('js_on').style.display='block';
  428.                 </script>
  429.  
  430.                 <noscript><h1 style="position:absolute;top:0;left:0;z-index:99">Bitte aktivieren Sie Java-Script!<span class="subline"><br>(Sonst wird hier nicht alles funktionieren...)</span></h1></noscript>
  431.  
  432.                 <div id="inhalt">
  433.                 <p><strong>Hinweis:</strong> Um einem Benutzer ein neues Passwort zuzuweisen legen Sie diesen neu an. Vorheriges Löschen ist <em>nicht</em> notwendig.</p>
  434.                 <form action="<?=$_SERVER['PHP_SELF'];?>?tw=<?=md5(microtime());?>" method="post">
  435.                         <fieldset><legend>Verzeichnisschutz:</legend>
  436.                         <div class='t3'><?=$strSchutz;?><br>
  437.                         <input id="Ein" type="submit" name="Ein" value="Einschalten">&nbsp;<input id="Aus" type="submit" name="Aus" value="Ausschalten"></div>
  438.                         </fieldset>
  439.                 </form>
  440.                 <form action="<?=$_SERVER['PHP_SELF'];?>?tw=<?=md5(microtime());?>" method="post">
  441.                         <fieldset><legend>Neuen Benutzer anlegen:</legend>
  442.                                 <label class="t1">Benutzer:</label><input type="text" id='user' name="user"><br clear="all">
  443.                                 <label class="t1">Passwort:</label><input type="text" name="pass"><br clear="all">
  444.                                 <label class="t1">&nbsp;</label><input type="submit" name="neu" value="Eintragen">
  445.                                 <br clear="all">
  446.                         </fieldset>
  447.                 </form>
  448.                 <fieldset><legend>Benutzer löschen:</legend>
  449.                 <?=PrintUserList(FTX_USERFILE,$_SERVER['PHP_SELF'].'?kill=ELEMENT', 'Ask()');?>
  450.                 </fieldset>
  451.                 </div>
  452.  
  453. <?php if (FTX_SHOWCONFIG) { ?>
  454.                 <div id="inhalt2">
  455.                 <p>Hier sehen Sie Dateien, die mit diesem Skript bearbeitet werden.<br>
  456.                 Welche das sind bestimmen Sie im Konfigurationsteil.</p>
  457.                 <fieldset><legend>Inhalt der Datei <?=FTX_USERFILE;?>:</legend>
  458. <?php PrintFile(FTX_USERFILE);?>
  459.                 </fieldset>
  460.  
  461.                 <fieldset><legend>Inhalt der Datei <?=FTX_HTACCESSFILE;?>:</legend>
  462. <?=PrintFile(FTX_HTACCESSFILE);?>
  463.                 </fieldset>
  464.  
  465.                 </div>
  466. <?php } ?>
  467.                 <p id="fastix">Version 3.3.1 von Jörg Reinholz (<a href="http://www.fastix.org">http://www.fastix.org</a>)</p>
  468.         </body>
  469. </html>
  470.