Following is a script I’m working on for a “flat file” user login thingy. I’m tired and going to bed soon, so thought I’d throw out what I have to this point to see if anyone can poke any holes in it. It’s not intended to be the ultimate in security, just a way to add user logins to a site that does not need extreme security.
The users.txt file is just a tab-delimited file with two fields: user name and md5-encrypted password. I.E.: using the password “password”, I tested it with:
[code]
# comment line
nogdog 5f4dcc3b5aa765d61d8327deb882cf99
The first line of any PHP file to be login controlled by this script would be:
[code=php]
<?php include $_SERVER[‘DOCUMENT_ROOT’].”/login/login.inc” ?>
(Changing the directory as needed to point to the login.inc file)
Still to do: the form for editing the users.txt file.
Anyway, if you’ve read this far, thanks, and here’s the login.inc script:
[code=php]
<?php
/***************************************************************************
login.inc — PHP include file for login control of web pages
Usage: at the very beginning of each file to be controlled, add the
following line with no spaces or linefeeds before it:
<?php include $_SERVER[‘DOCUMENT_ROOT’].”/login/login.inc” ?>
If you choose to put these files in a different subdirectory below your base
public html directory, then the format would be:
<?php include $_SERVER[‘DOCUMENT_ROOT’]/directory/subdirectory/login.inc ?>
The controlled files must be named such that they will be processed by the
PHP interpreter, typically by giving it a .php suffix.
If you install these files in a directory other than “/login” just beneath
your base public html directory, change the definition of LOGIN_DIR in the
CONSTANTS section just below these comments.
***************************************************************************/
### CONSTANTS ###
# change the next line if you install in a directory other than “/login”
define(“LOGIN_DIR”, $_SERVER[‘DOCUMENT_ROOT’].”/login”);
# Do not change the next line unless you want the users.txt file (which
# has the user names and passwords) in a different place, and you know what
# you’re doing.
define(“USER_FILE”, LOGIN_DIR.”/users.txt”);
# >>> DO NOT MAKE CHANGES BELOW THIS POINT UNLESS YOU KNOW WHAT YOU’RE DOING <<<
### FUNCTIONS ###
######################################################################
# bool display_login([str error])
#
# Outputs the login form. If the optional error argument is given, that
# string is displayed as an error message at the top of the form.
#
# Always returns TRUE
######################################################################
function display_login($error = “”)
{
?>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”>
<html lang=’en’>
<head>
<META HTTP-EQUIV=’Content-Type’ CONTENT=’text/html; charset=ISO-8859-1′>
<title>Page title</title>
<style type=”text/css”>
<!–
body {
margin: 0;
padding: 10px;
font: 90% arial, helvetica, sans-serif;
background-color: #f0f6f6;
color: black;
}
#container {
width: 20em;
margin: 10% auto 0;
padding: 3px;
background-color: #ccc;
color: black;
border: outset 2px #666;
}
input[type=”submit”] {
background-color: #ccc;
color: black;
font-weight: bold;
}
legend {font-weight: bold;}
form { margin: 0; padding: 0;}
fieldset { padding: margin: 3px; padding: 3px; }
label {
float: left;
width: 6em;
clear: left;
}
#submit {
text-align: center;
}
#error {
color: #c33;
background-color: transparent;
font-weight: bold;
}
#collophon {
font-size: small;
text-align: center;
margin-top: 100px;
}
–>
</style>
</head>
<body>
<div id=”container”>
<form action=”<?php echo $_POST[‘PHP_SELF’] ?>” method=”post”>
<fieldset>
<legend>Please Log In</legend>
<?php
if(!empty($error))
{
echo “<p id=’error’>$error</p>”;
}
?>
<p>
<label for=”name”>Name: </label>
<input type=”text” name=”name” id=”name” size=”16″ maxlength=”16″>
</p>
<p>
<label for=”password”>Password: </label>
<input type=”password” name=”password” id=”password” size=”16″ maxlength=”16″>
</p>
<p id=”submit”><input type=”submit” name=”login” value=”Log In”></p>
</fieldset>
</form>
</div>
<p id=”collophon”>Login processing provided by
<a href=”http://www.charles-reace.com/”>Charles-Reace.com</a>
(<a href=”http://www.charles-reace.com/mail.php”>email</a>).</p>
</body>
</html>
<?php
return(TRUE);
} # end display_login function
######################################################################
# int read_user_file(array &$users)
#
# reads in data from users file and populates an array with it.
######################################################################
function read_user_file(&$users)
{
$lines = @file(USER_FILE) or display_error(“Could not read users file”, TRUE);
if(count($lines) >= 1)
{
foreach($lines as $line)
{
$line = trim($line);
if(!empty($line) and $line{0} != “#”)
{
$parts = explode(“t”, $line);
if(count($parts == 2))
{
$users[$parts[0]] = $parts[1];
}
}
}
# return FALSE if no data, else number of elements in array
$result = count($users);
if($result == 0)
{
$result = FALSE;
}
}
else
{
$result = FALSE; # unable to read file, or file empty
}
return($result);
} # end read_user_file()
######################################################################
# bool display_error(str message [, bool fatal])
#
# quick and dirty error message display.
#
# if second arg given and it’s, error is displayed and processing exits
#
# Always returns TRUE (if not fatal)
#
# Things to do: make it prettier and valid HTML
######################################################################
function display_error($message, $fatal = FALSE)
{
if($fatal)
{
echo “<html><head><title>ERROR</title></head><body><h1>Error</h1></body>n”;
}
echo “<p><strong>ERROR:</strong> $message</p>n”;
if($fatal)
{
echo “</body></html>”;
exit();
}
return(TRUE);
} # end display_error()
######################################################################
# MAIN PROCESSING
######################################################################
# determine/handle login status:
session_start();
if(!isset($_SESSION[‘login’]) or $_SESSION[‘login’] != TRUE) # not logged in
{
if(isset($_POST[‘login’])) # process login request
{
read_user_file($users) or display_error(“Unable to get user data”, TRUE);
$valid = (array_key_exists($_POST[‘name’], $users) and
md5($_POST[‘password’]) == $users[$_POST[‘name’]]) ? TRUE : FALSE;
if($valid)
{
$_SESSION[‘login’] = TRUE;
}
else # display login with error message
{
display_login(“Invalid login name and/or password”);
}
}
else # display login form
{
display_login();
}
if(!$_SESSION[‘login’])
{
exit; # not logged in, so don’t display anything that follows
}
}
?>