login: replace http authentication by cookie system
authorMischa POSLAWSKY <perl@shiar.org>
Tue, 12 Sep 2017 21:39:35 +0000 (23:39 +0200)
committerMischa POSLAWSKY <perl@shiar.org>
Mon, 18 Sep 2017 18:21:28 +0000 (20:21 +0200)
Extend PHP_AUTH/.htpasswd parser to also control input and storage
for complete control.  No longer shares Apache access control; should be
replaced if still needed to prevent duplicate login requests.

auth.inc.php
edit.php
foot.inc.php
login.php
logout.php [deleted file]
page.inc.php
page.php

index ecd29b5cc36ca971c9183f9a11ddd31d180d9f24..363fc71538b0527be14ac901fe3fb9c99692c604 100755 (executable)
@@ -1,19 +1,13 @@
 <?php
-global $User, $Admin;
-
-call_user_func(function () {
-       if (isset($_SERVER['PHP_AUTH_USER'])) {
-               $authinfo = [ $_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'] ];
-       }
-       elseif (isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
-               // cgi compatibility
-               $authinfo = explode(':' , base64_decode(substr($_SERVER['REDIRECT_HTTP_AUTHORIZATION'], 6)));
-       }
-       else {
-               return;
+function login($inuser, $inpass = NULL)
+{
+       if (empty($inuser)) return;
+       if (!isset($inpass)) {
+               @list ($inuser, $inauth) = explode(':', $inuser, 2);
        }
 
-       $pwdata = file_get_contents(__DIR__.'/.htpasswd');
+       # create pwlist table from htpasswd
+       $pwdata = file_get_contents('./.htpasswd');
        $pwlist = [];
        foreach (explode("\n", $pwdata) as $line) {
                if (!$line) continue;
@@ -21,15 +15,28 @@ call_user_func(function () {
                $pwlist[$username] = $pass;
        }
 
-       list ($authname, $authpass) = $authinfo;
-       $usertest = $pwlist[ strtolower($authname) ];
+       # find user by name
+       $usertest = @$pwlist[ strtolower($inuser) ];
        if (!$usertest) return;
 
-       $salt = substr($usertest, 0, 2);
-       if (crypt($authpass, $salt) != $usertest) return;
+       # verify password
+       $authhash = md5($usertest);
+       if (isset($inpass)) {
+               if (!password_verify($inpass, $usertest)) return;
+       }
+       else {
+               if ($inauth !== $authhash) return;
+       }
+
+       return [
+               'name'  => $inuser,
+               'admin' => !empty($inuser) && strtolower($inuser) != 'lid',
+               'auth'  => "$inuser:$authhash",
+       ];
+}
 
-       global $User, $Admin;
-       $User = $authname;
-       $Admin = !empty($User) && $User != 'lid' ? $User : FALSE;
-});
+if (isset($_COOKIE['login'])) {
+       global $User;
+       $User = login($_COOKIE['login']);
+}
 
index fe80528a7d1c83faca00ef8e751cf5e271baae72..01d83dfa64f602dcf71ca38f2049f7f188432058 100755 (executable)
--- a/edit.php
+++ b/edit.php
@@ -5,8 +5,7 @@ function abort($status, $body) {
        exit;
 }
 
-require 'auth.inc.php';
-if (!$Admin)
+if (!$User['admin'])
        abort('401 unauthorised', "geen beheersrechten");
 
 if (!$_POST)
index a7f52d692a1c5930d86724bfdbb6e6ee09a240a1..493dcc9ee72c1967943af17265331818d5a811aa 100755 (executable)
@@ -2,9 +2,9 @@
 <?php
 define('N', "\n");
 
-global $Page, $User, $Admin, $Edit;
+global $Page, $User, $Edit;
 
-if ($Admin) {
+if ($User['admin']) {
        $notfound = $Page == '404';
 
        if ($Edit) {
@@ -21,7 +21,7 @@ EOT;
        }
 
        echo '<p class="footer">'.N;
-       echo "Beheer toegestaan voor $User:".N;
+       echo "Beheer toegestaan voor {$User['name']}:".N;
        printf('<a href="?%s">%s</a>'.N,
                $Edit ? '' : 'edit',
                $Edit ? 'lezen' : ($notfound ? 'aanmaken' : 'aanpassen')
index eb09f8a571dbb80e765d0f11ae9df9554549b488..042dea94f9ea0c1331c38ff7e9948f0f2c7aef42 100644 (file)
--- a/login.php
+++ b/login.php
@@ -1,17 +1,25 @@
+<h2>Inloggen</h2>
+
 <?php
-require 'auth.inc.php';
+if (isset($_POST['login'])) {
+       if ($user = login($_POST['login'], $_POST['pass'])) {
+               setcookie('login', $user['auth'], 0, '/');
+
+               header("Location: /"); //TODO: goto
+               http_response_code(302);
+               exit;
+       }
 
-if (!$Admin) {
-       require 'logout.php';
-       exit;
+       echo '<p class="warn">Ongeldige gebruikersnaam of wachtwoord.</p>'."\n\n";
+}
+elseif ($User) {
+       setcookie('login', '', time(), '/'); # expire immediately
+       echo '<p class="warn">Uitgelogd.</p>'."\n\n";
 }
 
-include 'head.inc.php';
 ?>
-
-<h2>Sitebeheer</h2>
-
-<p>
-Welkom, je bent ingelogd als <em><?php echo $User; ?></em>. Onderaan elke pagina staat een link om inhoud aan te passen.
-</p>
-
+<form action="" method="post">
+       <input id="login" name="login" placeholder="Huisnummer" />
+       <input id="pass" name="pass" type="password" value="" placeholder="Wachtwoord" />
+       <input type="submit" value="Log in" />
+</form>
diff --git a/logout.php b/logout.php
deleted file mode 100644 (file)
index 112bb9b..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?php
-header('WWW-Authenticate: Basic realm=""');
-http_response_code(401);
-
-// fallback page shown on authentication failure
-include 'head.inc.php';
-$Admin = $User = FALSE; // ignore old user headers
-?>
-<h2>Niet ingelogd</h2>
-<p>Voor sitebeheer moet worden ingelogd met een gerechtigde gebruiker.</p>
-
index b3fa5f7780b70d272b2844e592bcb29f74eb78ea..dcb0573223a06f4f9e6601a857ef2e1314b384a7 100644 (file)
@@ -15,8 +15,6 @@ print "</header>\n\n";
 
 print '<div class="article">'."\n\n";
 
-include_once 'auth.inc.php';
-
 register_shutdown_function(function () {
        print "</div>\n\n";
        include 'foot.inc.php';
index c88852416c9ccc531b015ce25eec163157d1e452..f6088dd859dcb2906477307b99a52088610ee554 100644 (file)
--- a/page.php
+++ b/page.php
@@ -2,6 +2,9 @@
 error_reporting(E_ALL);
 ini_set('display_errors', TRUE);
 
+include_once 'auth.inc.php';
+$Edit = isset($_GET['edit']);
+
 $Args = '';
 $Page = preg_replace('/\?.*/', '', $_SERVER['REQUEST_URI']);
 $Page = urldecode(trim($Page, '/')) ?: 'index';
@@ -29,6 +32,4 @@ while (TRUE) {
        $Page = substr($Page, 0, $up);
 }
 
-$Edit = isset($_GET['edit']);
-
 include 'page.inc.php';