Page 1 of 1

Unbreakable login script?

Posted: Wed Mar 25, 2009 6:49 pm
by ben.artiss
Hi,

I have been expanding on the same basic principle for a login system for a while now, and I'm wondering whether it's actually reached a 'bulletproof' stage. The globals.inc.php file is included in every main script/page of the website, and db.inc.php is included within the global file. I'm interested to see what other programmers think of this approach to managing sessions, where users of different privileges (i.e. admin, staff, members) can login from the same place using the same scripts.

/lib/db.inc.php

Code: Select all

<?php
$hostname = "localhost";
$database = "database";
$dbuser   = "user";
$dbpass   = "pass";
$db = mysql_pconnect($hostname, $dbuser, $dbpass) or trigger_error(mysql_error(),E_USER_ERROR);
mysql_select_db($database, $db);
?>
/lib/globals.inc.php

Code: Select all

<?php
# start the session
if (!isset($_SESSION)) {session_start();}
 
# current file information
$currentUrl   = strtolower($_SERVER['PHP_SELF']);
$currentFile  = explode('/', $currentUrl);
$currentFile  = $currentFile[count($currentFile) - 1];
$currentQuery = strtolower($_SERVER['QUERY_STRING']);
empty($currentQuery) ? $current = $currentFile : $current = $currentFile."?".$currentQuery;
 
if ($currentFile=='globals.inc.php') {
    header('Location: ../index.php'); exit;
}
 
# locate and connect to database
$findDb = array('db.inc.php','lib/db.inc.php','../lib/db.inc.php');
 
foreach ($findDb as $loc) {
    if (file_exists($loc)) {
        require_once($loc); break;
    }
}
 
if (!$db) {die('The database could not be loaded! Please check back soon.');}
 
# global functions
function getHost($returnName=false) {
    if (isset($_SERVER['HTTP_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } else {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
 
    if ($returnName) {
        return gethostbyaddr($ip);
    } else {
        return $ip;
    }
}
 
function makeSafe($input) {
    if (get_magic_quotes_gpc()) {
        $input = stripslashes($input);
    }
 
    return htmlspecialchars(trim($input));
}
 
function escape($input) {
    if (!get_magic_quotes_gpc()) {
        $input = addslashes($input);
    }
 
    if (phpversion()>='4.3.0') {
        $input = mysql_real_escape_string($input);
    } else {
        $input = mysql_escape_string($input);
    }
 
    return $input;
}
 
 
function generateEncPass($date, $pass) {
    $encpass = md5($date.$pass); # Note: real function much more complex!
    return $encpass;
}
 
# declare some global variables
$error = false;
$onload = false;
$login = false;
$userlevel = false;
 
# check login status based on url
if (stristr($currentUrl, 'admin') || stristr($currentUrl, 'staff') || stristr($currentUrl, 'members')) {
    if (!isset($_SESSION['login']) || $_SESSION['login']!=session_id() || !isset($_SESSION['session_user']) || !isset($_SESSION['session_userid'])) {
        header("Location: ../login.php?e=7"); exit;
    }
 
    $session_user = $_SESSION['session_user'];
    $session_userid = $_SESSION['session_userid'];
 
    if (stristr($currentUrl, 'admin')) {$userlevel=1;}
    if (stristr($currentUrl, 'staff')) {$userlevel=2;}
    if (stristr($currentUrl, 'members')) {$userlevel=3;}
 
    $sql = mysql_query(sprintf("SELECT `users`.`admin`,`users`.`staff` FROM `users` WHERE `users`.`user_id`='%s' LIMIT 1", escape($session_userid)), $db) or die(mysql_error());
 
    if (!mysql_num_rows($sql)) {
        $error = true;
    } else {
        $row = mysql_fetch_assoc($sql);
        $admin = $row['admin'];
        $staff = $row['staff'];
    }
 
    mysql_free_result($sql);
 
    if ($error) {header("Location: ../login.php?e=8"); exit;}
}
 
# check login location and user level
switch ($userlevel) {
    case 1: if ($admin!=1) {header("Location: ../login.php?e=8"); exit;} else {$login = true;} break;
    case 2: if ($admin!=1 && $staff!=1) {header("Location: ../login.php?e=8"); exit;} else {$login = true;} break;
    case 3: $login = true; break;
}
?>
/lib/login.php

Code: Select all

<?php
if (!isset($_POST['username']) || !isset($_POST['password']) || !isset($_POST['login'])) {
    header("Location: ../index.php"); exit;
}
 
require_once('globals.inc.php');
 
$username = makeSafe($_POST['username']);
$password = makeSafe($_POST['password']);
 
if (!$username) {
    header("Location: ../login.php?e=1"); exit;
}
 
$_SESSION['session_user'] = $username;
 
$sql = mysql_query(sprintf("SELECT `users`.`user_id`,`users`.`admin`,`users`.`staff`,`users`.`active`,`users`.`date_activated`,`users`.`date_created`,`users`.`password` FROM `users` WHERE `users`.`email`='%s' LIMIT 1", escape($username)), $db) or die(mysql_error());
 
if (!mysql_num_rows($sql)) {
    mysql_free_result($sql);
    header("Location: ../login.php?e=2");
}
 
$row = mysql_fetch_assoc($sql);
$id = $row['user_id'];
$admin = $row['admin'];
$staff = $row['staff'];
$active = $row['active'];
$activated = $row['date_activated'];
$created = $row['date_created'];
$dbpass = $row['password'];
 
mysql_free_result($sql);
 
if ($active!=1 && !$activated) {
    header("Location: ../login.php?e=5"); exit;
} elseif ($active!=1 && $activated) {
    header("Location: ../login.php?e=6"); exit;
}
 
if (!$password) {
    header("Location: ../login.php?e=3"); exit;
}
 
$password = generateEncPass($created,$password);
 
if ($password!==$dbpass) {
    header("Location: ../login.php?e=4"); exit;
}
 
$sql = mysql_query(sprintf("SELECT * FROM `user_history` WHERE `user_history`.`user_id`='%s' AND `user_history`.`action`='login' ORDER BY `user_history`.`date_created` DESC LIMIT 1", escape($id)), $db) or die(mysql_error());
 
if (!mysql_num_rows($sql)) {
    $_SESSION['firstlogin'] = true;
}
 
mysql_free_result($sql);
 
$action = 'login';
$ip = getHost();
$sid = session_id();
 
$sql = mysql_query(sprintf("INSERT INTO `user_history` (`user_history`.`user_id`,`user_history`.`date_created`,`user_history`.`action`,`user_history`.`ip_address`,`user_history`.`session_id`) VALUES ('%s',NOW(),'%s','%s','%s')",
    escape($id),
    escape($action),
    escape($ip),
    escape($sid)
), $db) or die(mysql_error());
 
$_SESSION['login'] = $sid;
$_SESSION['session_userid'] = $id;
 
$redirArray = array(
    'account.php',
    'reservations.php'
);
 
if ($admin==1) {
    header("Location: ../admin"); exit;
} elseif ($staff==1) {
    header("Location: ../staff"); exit;
} else {
    if (isset($_SESSION['redirect']) && in_array($_SESSION['redirect'],$redirArray)) {
        header("Location: ../members/".$_SESSION['redirect']); exit;
    } else {
        header("Location: ../members"); exit;   
    }
}
?>

Re: Unbreakable login script?

Posted: Thu Mar 26, 2009 6:42 am
by ben.artiss
Not quite a snippet I know :oops: apologies if I'm being a bit presumptuous.

Re: Unbreakable login script?

Posted: Mon Apr 06, 2009 2:46 pm
by adelbarham
very nice

what about the rest of it??
login page?? register page?? remember me features and so on??
i would love to have your script...can you manage to complete it?