<?php // >= 4.3 (C) Andrea Giammarchi 2007

/**
 * SecurityForm example page
 * These functions are the same used to manage login.html page.
 * This file is called loginFunctions.php and is required from 
 * serverlogin.php
 * ------------------------------------------------------------
 * serverlogin.php page
 *    <?php
 *
 *    $dbhost = 'localhost:3307';    // database host
 *    $dbuser = 'root';        // database user
 *    $dbpass = '';            //database password
 *    $dbname = 'test';        // database name
 *    $user = 'user';            // name of form user
 *    $pass = 'pass';            // name of form password
 *    $hash = 'md5';            // name of used hash (md5, sha1, others)
 *
 *    require 'loginFunctions.php';
 *    pageOperationsExample($dbhost, $dbuser, $dbpass, $dbname, $user, $pass, $hash);
 *
 *    ?>
 * ------------------------------------------------------------
 * createExampleTable.php (to test this application locally)
 *    <?php
 *    // please change mysql_connect informations
 *    $db = mysql_connect('localhost:3307', 'root', '') or exit('any connection');
 *    mysql_select_db('test', $db) or exit('db test not found');
 *    @mysql_unbuffered_query('DROP TABLE securityform_user_list', $db);
 *    @mysql_unbuffered_query('DROP TABLE securityform_user_salt', $db);
 *    mysql_unbuffered_query('CREATE TABLE securityform_user_list (id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, user VARCHAR(100), pass CHAR(32))', $db);
 *    mysql_unbuffered_query('CREATE TABLE securityform_user_salt (user VARCHAR(100), salt VARCHAR(255), expire INT(10))', $db);
 *    mysql_unbuffered_query('INSERT INTO securityform_user_list VALUES(0, "guest", "'.md5('4lphaNum3ric').'")', $db);
 *    $query = mysql_unbuffered_query('SELECT * FROM securityform_user_list', $db);
 *    while($row = mysql_fetch_assoc($query))
 *        echo "User: {$row['user']}<br />Pass: {$row['pass']}";
 *    mysql_close($db);
 *    ?>
 * ------------------------------------------------------------
 */

function pageOperationsExample(&$dbhost, &$dbuser, &$dbpass, &$dbname, &$user, &$pass, &$hash){
    
$result false;
    
$db mysql_connect($dbhost$dbuser$dbpass) or exit('connection error');
    
mysql_select_db($dbname$db) or exit('database name error');
    if(isset(
$_GET['salt'])) { // user asked a salt

        // remove old salt
        
mysql_query(sprintf('DELETE FROM securityform_user_salt WHERE salt = expire < %d'time() - 30), $db);
        
        
// create a new salt and save them
        
mysql_query(sprintf(
            
'INSERT INTO securityform_user_salt (user, salt, expire) VALUES ("%s", "%s", %d)',
            
mysql_real_escape_string($_GET['salt']), $result uniqid(rand(), true), time()
        ), 
$db);
        
        
// close database
        
mysql_close($db);
        
        
// create a valid javascript callback for SecurityForm function
        
$result "SecurityForm.onload('{$result}');";
        
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
        
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
        
header('Cache-Control: no-store, no-cache, must-revalidate');
        
header('Cache-Control: post-check=0, pre-check=0'false);
        
header('Pragma: no-cache');
        
header('Content-Type: text/javascript');
        
header('Content-Length: '.strlen($result));
        exit(
$result);
    }
    else {
        
$result verifyLoginExample($db$user$pass$hash);
        
mysql_close($db);
        if(
$result)    // user auth successful
            // do stuff, for example ...
            
exit(str_replace(array('{user}''{request}'), array(htmlentities($_REQUEST[$user]), $_SERVER['REQUEST_URI']), file_get_contents('serverlogin.html')));
        
        else {    
// crack attack or wrong informations
            
sleep(2);
            
header('Location: login.html');
        }
    }
}

function 
verifyLoginExample(&$db, &$user, &$pass, &$hash){
    
$query '';
    
$result null;
    
    
// if user has sent every information
    
if(isset($_GET['uniqid'], $_GET[$user], $_GET[$pass])) {
    
        
// correctly escape these informations
        
$_GET['uniqid'] = mysql_real_escape_string($_GET['uniqid']);
        
$_GET[$user] = mysql_real_escape_string($_GET[$user]);
        
$_GET[$pass] = mysql_real_escape_string($_GET[$pass]);
        
        
// verify if salt table contains sent uniqid
        
$query sprintf(
            
'SELECT user FROM securityform_user_salt WHERE salt = "%s"',
            
$_GET['uniqid']
        );
        
$result mysql_query($query$db);
        if(
mysql_num_rows($result) === 1) {
        
            
// verify that user (get with salt) is the same
            
while($row mysql_fetch_assoc($result))
                
$query $row['user'];
            if(
$query === $_GET[$user])
                
// all right, verify that user and pass, hashed using salt, are present
                
$query sprintf(
                    
'SELECT id FROM securityform_user_list WHERE user = "%s" AND %s(CONCAT("%s", pass)) = "%s"',
                    
$_GET[$user], strtoupper($hash), $_GET['uniqid'], $_GET[$pass]
                );
            else
                
$query '';
            
            
// remove used salt and other old expired salt
            
mysql_query(sprintf(
                
'DELETE FROM securityform_user_salt WHERE salt = "%s" OR expire < %d',
                
$_GET['uniqid'], time() - 30
            
), $db);
        }
    }
    
// unobtrusive alternative ... less secure but useful
    
elseif(isset($_POST[$user], $_POST[$pass]))
        
$query sprintf(
            
'SELECT id FROM securityform_user_list WHERE user = "%s" AND pass = "%s"',
            
mysql_real_escape_string($_POST[$user]),
            
md5($_POST[$pass])
        );
    
    
// if query is empty or last used uery doesn't have one record return false
    
return !empty($query) && mysql_num_rows(mysql_query($query$db)) === 1;
}
?>