Jump to content

Password Reset Not Working


SalientAnimal

Recommended Posts

Hi All,

 

So I managed to get through all the other errors my form was giving me and everything seems to be working as intended. The only problem I'm having now is that when the password gets updated in the table (I have checked to see that the hashed password changes, and it does), the new password does not work.

 

I am using SHA512 to encrypt my passwords in my table.

 

Here are all my functions that I currently have for my forms. The lower part (Heading Password Reset) are all the functions pertaining to the form in question:

<?php

// includes/functions.php -->

//
//ERROR CHECKING FUNCTIONS - ADD TO PAGES TO CHECK FOR POSSIBLE ERRORS
//	var_dump(login_check($mysqli));
//	var_dump($_SESSION); exit; 
//	var_dump($_POST);exit; 

include_once 'psl-config.php';

function sec_session_start() {
    $session_name = 'sec_session_id';   // Set a custom session name
    $secure = SECURE;
    // This stops JavaScript being able to access the session id.
    $httponly = true;
    // Forces sessions to only use cookies.
    if (ini_set('session.use_only_cookies', 1) === FALSE) {
        header("Location: ../error.php?err=Could not initiate a safe session (ini_set)");
        exit();
    }
    // Gets current cookies params.
    $cookieParams = session_get_cookie_params();
    session_set_cookie_params($cookieParams["lifetime"],
        $cookieParams["path"], 
        $cookieParams["domain"], 
        $secure,
        $httponly);
    // Sets the session name to the one set above.
    session_name($session_name);
    session_start();            // Start the PHP session 
    session_regenerate_id();    // regenerated the session, delete the old one. 
}



function login($email, $password, $mysqli) {
    // Using prepared statements means that SQL injection is not possible. 
    if ($stmt = $mysqli->prepare("SELECT id, username, password, email, level, salt 
        FROM members
       WHERE username = ?
        LIMIT 1")) {
        $stmt->bind_param('s', $email);  // Bind "$email" to parameter.
        $stmt->execute();    // Execute the prepared query.
        $stmt->store_result();

        // get variables from result.
        $stmt->bind_result($user_id, $username, $db_password, $email, $level, $salt);
        $stmt->fetch();

        // hash the password with the unique salt.
        $password = hash('sha512', $password . $salt);
        if ($stmt->num_rows == 1) {
            // If the user exists we check if the account is locked
            // from too many login attempts 
 
            if (checkbrute($user_id, $mysqli) == true) {
                // Account is locked 
                // Send an email to user saying their account is locked
                return false;
            } else {
                // Check if the password in the database matches
                // the password the user submitted.
                if ($db_password == $password) {
                    // Password is correct!
                    // Get the user-agent string of the user.
                    $user_browser = $_SERVER['HTTP_USER_AGENT'];
                    // XSS protection as we might print this value
                    $user_id = preg_replace("/[^0-9]+/", "", $user_id);
                    $_SESSION['user_id'] = $user_id;
                    // XSS protection as we might print this value
                    $username = preg_replace("/[^a-zA-Z0-9_\-]+/", 
                                                                "", 
                                                                $username);
                    $_SESSION['username'] = $username;
                    $_SESSION['login_string'] = hash('sha512',$password . $user_browser);
					$_SESSION['email'] = $email;
					$_SESSION['level'] = $level;
					$_SESSION['session_status'] = $session_status;
                    $mysqli->query("SELECT * FROM login_success WHERE user_id = '$user_id'");
					if			  (mysql_num_rows($mysqli) > 0)
						{
						$mysqli->query("UPDATE login_success SET time = NOW() WHERE user_id = '$user_id'");
						}
					else
						{
						$mysqli->query("INSERT INTO login_success(user_id, time) VALUES ('$user_id', now()");
						}
					//UPDATE login_success SET time = now() where user_id = '$user_id'");							  
                    // Login successful.
                    return true;
                } else {
                    // Password is not correct
                    // We record this attempt in the database
                    //$now = time();
                    $mysqli->query("INSERT INTO login_attempts(user_id, time)
                                    VALUES ('$user_id', now())");
                    return false;
                }
            }
        } else {
            // No user exists.
            return false;
        }
    }
}



function checkbrute($user_id, $mysqli) {
    // Get timestamp of current time 
    $now = time();

    // All login attempts are counted from the past 2 hours. 
    $valid_attempts = $now - (2 * 60 * 60);

    if ($stmt = $mysqli->prepare("SELECT time 
                             FROM login_attempts 
                             WHERE user_id = ? 
                            AND time > '$valid_attempts'")) {
        $stmt->bind_param('i', $user_id);

        // Execute the prepared query. 
        $stmt->execute();
        $stmt->store_result();

        // If there have been more than 5 failed logins 
        if ($stmt->num_rows > 5) {
            return true;
        } else {
            return false;
        }
    }
}



function login_check($mysqli) 
	{
    // Check if all session variables are set 
    if (isset($_SESSION['user_id'], 
			  $_SESSION['username'], 
			  $_SESSION['login_string'],
			  $_SESSION['email'],
			  $_SESSION['level']
			  //$_SESSION['session_status']
			  )) 
	{

    $user_id = $_SESSION['user_id'];
    $login_string = $_SESSION['login_string'];
    $username = $_SESSION['username'];
	$email = $_SESSION['email'];
	$level = $_SESSION['level'];
	//$status = $_SESSON['session_status'];
		

        // Get the user-agent string of the user.
        $user_browser = $_SERVER['HTTP_USER_AGENT'];

        if ($stmt = $mysqli->prepare("SELECT password 
                                      FROM members 
                                      WHERE id = ? LIMIT 1")) {
            // Bind "$user_id" to parameter. 
            $stmt->bind_param('i', $user_id);
            $stmt->execute();   // Execute the prepared query.
            $stmt->store_result();

            if ($stmt->num_rows == 1) {
                // If the user exists get variables from result.
                $stmt->bind_result($password);
                $stmt->fetch();
                $login_check = hash('sha512', $password . $user_browser);

                if ($login_check == $login_string) {
                    // Logged In!!!! 
					//echo 'logged in';
                    return true;
                } else {
                    // Not logged in 
					echo 1;
                    return false;
                }
            } else {
                // Not logged in
					echo 2;
                return false;
            }
        } else {
            // Not logged in 
			echo 3;
            return false;
        }
    } else {
        // Not logged in 
		//echo 4;
        return false;
    }
}



function esc_url($url) {

    if ('' == $url) {
        return $url;
    }

    $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url);

    $strip = array('%0d', '%0a', '%0D', '%0A');
    $url = (string) $url;

    $count = 1;
    while ($count) {
        $url = str_replace($strip, '', $url, $count);
   }

    $url = str_replace(';//', '://', $url);

    $url = htmlentities($url);

    $url = str_replace('&', '&', $url);
    $url = str_replace("'", ''', $url);

    if ($url[0] !== '/') {
        // We're only interested in relative links from $_SERVER['PHP_SELF']
        return '';
    } else {
        return $url;
    }
}





function crypto_rand_secure($min, $max) {
        $range = $max - $min;
        if ($range < 0) return $min; // not so random...
        $log = log($range, 2);
        $bytes = (int) ($log /  + 1; // length in bytes
        $bits = (int) $log + 1; // length in bits
        $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
        do {
            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
            $rnd = $rnd & $filter; // discard irrelevant bits
        } while ($rnd >= $range);
        return $min + $rnd;
}

function getToken($length=32){
    $token = "";
    $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
    $codeAlphabet.= "0123456789";
    for($i=0;$i<$length;$i++){
        $token .= $codeAlphabet[crypto_rand_secure(0,strlen($codeAlphabet))];
    }
    return $token;
}






/* RESTRICTED ACCESS LEVEL MANAGEMENT */


	
	function checkLoginLevel() {
        $allowed = array(
            '0' => array('register.addinfo.php','process/*','includes/*','index.php','index.html'), /* NEW REGISTRATION ACCESS LEVELS */
            '1' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','walkin_form.php','walkin_delete.php'),		/* ACCESS LEVELS FROM RECEPTION */
            '2' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','first-page.php'),
            '3' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','retail_view.php','retail_viewer.php','walkin_form.php','retail_form.php'),
			'4' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','premier_form.php', 'second-page.php', 'third-page.php'), /* SUPERVISOR ACCESS LEVELS */
            '5' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','premier_form.php', 'second-page.php', 'third-page.php'), /* SUPERVISOR ACCESS LEVELS */
			'99' => true, /* ADMINISTRATION ACCESS LEVELS */
        );

    if(!isset($allowed[$_SESSION['level']])) {
        echo 'Your access level has not been set. Please return to the Login / Registration Page.';
        exit;
    }
	
	if($_SESSION['level'] == 0) {
	header('Location:register.addinfo.php');
	exit;
	}

    if(is_array($allowed[$_SESSION['level']])) {

        $file = $_SERVER["PHP_SELF"];
        $filearray = explode('/', $file);
        $filename = array_pop($filearray);
        $directory = array_pop($filearray);

        foreach($allowed[$_SESSION['level']] as $access) {
            if(strpos($access,'*')) {
                if($access == $directory . '/*') {
                    return true;
                }
            } elseif($access == $filename) {
                return true;
            }
        }
    }

    if(is_bool($allowed[$_SESSION['level']])) {
        return true;
    }

    echo 'You are not authorised to view this page. Please contact your manager to have your access level adjusted';
    exit;
}





//PSSWORD RESET FUNCTIONS




//define(PW_SALT,'(+3%_');
 
function checkUNEmail($username,$email)
{
    global $mysqli;
    $error = array('status'=>false,'user_id'=>0);
    if (isset($email) && trim($email) != '') {
        //email was entered
        if ($stmt = $mysqli->prepare("SELECT id FROM members WHERE email = ? LIMIT 1"))
        {
            $stmt->bind_param('s',trim($email));
            $stmt->execute();
            $stmt->store_result();
            $numRows = $stmt->num_rows();
            $stmt->bind_result($user_id);
            $stmt->fetch();
            $stmt->close();
            if ($numRows >= 1) return array('status'=>true,'id'=>$user_id);
        } else { return $error; }
    } elseif (isset($username) && trim($username) != '') {
        //username was entered
        if ($stmt = $mysqli->prepare("SELECT id FROM members WHERE username = ? LIMIT 1"))
        {
            $stmt->bind_param('s',trim($username));
            $stmt->execute();
            $stmt->store_result();
            $numRows = $stmt->num_rows();
            $stmt->bind_result($user_id);
            $stmt->fetch();
            $stmt->close();
            if ($numRows >= 1) return array('status'=>true,'id'=>$user_id);
        } else { return $error; }
    } else {
        //nothing was entered;
        return $error;
    }
}



function getSecurityQuestion($user_id)
{
    global $mysqli;
    $questions = array();
    $questions[0] = "What is your mother's maiden name?";
    $questions[1] = "What city were you born in?";
    $questions[2] = "What is your favorite colour?";
    $questions[3] = "What year did you graduate from High School?";
    $questions[4] = "What is your pet's name?";
    $questions[5] = "What is your favorite model of car?";
    if ($stmt = $mysqli->prepare("SELECT security_q FROM members WHERE id = ? LIMIT 1"))
    {
        $stmt->bind_param('i',$user_id);
        $stmt->execute();
        $stmt->store_result();
        $stmt->bind_result($security_q);
        $stmt->fetch();
        $stmt->close();
		return $security_q;
    } else {
        return false;
    }
}
 
function checkSecAnswer($user_id, $security_a)
{
    global $mysqli;
    if ($stmt = $mysqli->prepare("SELECT username FROM members WHERE id = ? AND LOWER(security_a) = ? LIMIT 1"))
    {
        $security_a = strtolower($security_a);
        $stmt->bind_param('is',$user_id, $security_a);
        $stmt->execute();
        $stmt->store_result();
        $numRows = $stmt->num_rows();
        $stmt->close();
        if ($numRows >= 1) { return true; }
    } else {
        return false;
    }
}




function sendPasswordEmail($user_id)
{
    global $mysqli;
    if ($stmt = $mysqli->prepare("SELECT username, email, password FROM members WHERE id = ? LIMIT 1"))
    {
        $stmt->bind_param('i',$user_id);
        $stmt->execute();
        $stmt->store_result();
        $stmt->bind_result($username, $email, $pword);
        $stmt->fetch();
        $stmt->close();
        $expFormat = mktime(date("H"), date("i"), date("s"), date("m")  , date("d")+3, date("Y"));
        $expDate = date("Y-m-d H:i:s",$expFormat);
        $security_key =  hash('sha512',$username . '_' . $email . rand(0,10000) .$expDate);
        if ($stmt = $mysqli->prepare("INSERT INTO password_reset (user_id, security_key, expiry_date) VALUES (?,?,?)"))
        {
            $stmt->bind_param('iss',$user_id, $security_key, $expDate);
            $stmt->execute();
            $stmt->close();
            $passwordLink = "<a href=\"?a=recover&email=" . $security_key . "&u=" . urlencode(base64_encode($user_id)) . "\">http://www.oursite.com/forgotPass.php?a=recover&email=" . $security_key . "&u=" . urlencode(base64_encode($user_id)) . "</a>";
            $message = "Dear $username,\r\n";
            $message .= "Please visit the following link to reset your password:\r\n";
            $message .= "-----------------------\r\n";
            $message .= "$passwordLink\r\n";
            $message .= "-----------------------\r\n";
            $message .= "Please be sure to copy the entire link into your browser. The link will expire after 3 days for security reasons.\r\n\r\n";
            $message .= "If you did not request this forgotten password email, no action is needed, your password will not be reset as long as the link above is not visited. However, you may want to log into your account and change your security password and answer, as someone may have guessed it.\r\n\r\n";
            $message .= "Thanks,\r\n";
            $message .= "-- Our site team";
            $headers .= "From: Our Site <webmaster@oursite.com
			
<script type='text/javascript'>
/* <![CDATA[ */
(function(){try{var s,a,i,j,r,c,l,b=document.getElementsByTagName('script');l=b[b.length-1].previousSibling;a=l.getAttribute('data-cfemail');if(a){s='';r=parseInt(a.substr(0,2),16);for(j=2;a.length-j;j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}s=document.createTextNode(s);l.parentNode.replaceChild(s,l);}}catch(e){}})();
/* ]]> */
</script>> \n";
            $headers .= "To-Sender: \n";
            $headers .= "X-Mailer: PHP\n"; // mailer
            $headers .= "Reply-To: webmaster@oursite.com<script type='text/javascript'>
/* <![CDATA[ */
(function(){try{var s,a,i,j,r,c,l,b=document.getElementsByTagName('script');l=b[b.length-1].previousSibling;a=l.getAttribute('data-cfemail');if(a){s='';r=parseInt(a.substr(0,2),16);for(j=2;a.length-j;j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}s=document.createTextNode(s);l.parentNode.replaceChild(s,l);}}catch(e){}})();
/* ]]> */
</script>\n"; // Reply address
            $headers .= "Return-Path: webmaster@oursite.com<script type='text/javascript'>
/* <![CDATA[ */
(function(){try{var s,a,i,j,r,c,l,b=document.getElementsByTagName('script');l=b[b.length-1].previousSibling;a=l.getAttribute('data-cfemail');if(a){s='';r=parseInt(a.substr(0,2),16);for(j=2;a.length-j;j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}s=document.createTextNode(s);l.parentNode.replaceChild(s,l);}}catch(e){}})();
/* ]]> */
</script>\n"; //Return Path for errors
            $headers .= "Content-Type: text/html; charset=iso-8859-1"; //Enc-type
            $subject = "Your Lost password";
            @mail($email,$subject,$message,$headers);
            return str_replace("\r\n","<br/ >",$message);
        }
    }
}


function checkEmailKey($security_key,$user_id)
{
    global $mysqli;
    $curDate = date("Y-m-d H:i:s");
    if ($stmt = $mysqli->prepare("SELECT user_id FROM password_reset WHERE security_key = ? AND user_id = ? AND expiry_date >= ?"))
    {
        $stmt->bind_param('sis',$security_key, $user_id, $curDate);
        $stmt->execute();
        $stmt->execute();
        $stmt->store_result();
        $numRows = $stmt->num_rows();
        $stmt->bind_result($user_id);
        $stmt->fetch();
        $stmt->close();
        if ($numRows > 0 && $user_id != '')
        {
            return array('status'=>true,'user_id'=>$user_id);
        }
    }
    return false;
}
 
function updateUserPassword($user_id, $password, $security_key, $salt)
{
    global $mysqli;
    if (checkEmailkey($security_key,$user_id) === false) return false;
    if ($stmt = $mysqli->prepare("UPDATE members SET password = ?, salt = ? WHERE id = ?"))
    {
        //$password = hash('sha512',trim($password) . $salt);
		
		$password = hash('sha512', $password . $salt);

        $stmt->bind_param('sis',$password, $user_id, $salt);
        $stmt->execute();
        $stmt->close();
        $stmt = $mysqli->prepare("DELETE FROM password_reset WHERE security_key = ?");
        $stmt->bind_param('s',$security_key);
        $stmt->execute();
    }
}
 
function getUserName($user_id)
{
    global $mysqli;
    if ($stmt = $mysqli->prepare("SELECT username FROM members WHERE id = ?"))
    {
        $stmt->bind_param('i',$user_id);
        $stmt->execute();
        $stmt->store_result();
        $stmt->bind_result($username);
        $stmt->fetch();
        $stmt->close();
    }
    return $username;
}



And the actual form is below:

<?php
include_once 'db_connect.php';
include_once 'functions.php';
include_once 'formatting_includes.php';	
sec_session_start();
if (login_check($mysqli) == true) 
	{
    $logged = 'in';
	} 
	


$show = 'emailForm'; //which form step to show by default
if(!isset($_SESSION['lastTime']))
   $_SESSION['lastTime'] = false;
if (isset($_SESSION['lockout']) && $_SESSION['lockout'] == true && (mktime() > $_SESSION['lastTime'] + 900))
{
    $_SESSION['lockout'] = false;
    $_SESSION['badCount'] = 0;
}
if(!isset($_SESSION['lockout']))
   $_SESSION['lockout'] = false;
if (isset($_POST['subStep']) && !isset($_GET['a']) &&  $_SESSION['lockout'] != true)
{
    switch($_POST['subStep'])
    {
        case 1:
            //we just submitted an email or username for verification
            $result = checkUNEmail($_POST['username'],$_POST['email']);
            if ($result['status'] == false )
            {
                $error = true;
                $show = 'userNotFound';
            } else {
                $error = false;
                $show = 'securityForm';
                $securityUser = $result['id'];
            }
        break;
        case 2:
            //we just submitted the security question for verification
            if ($_POST['user_id'] != "" && $_POST['security_a'] != "")
            {
                $result = checkSecAnswer($_POST['user_id'],$_POST['security_a']);
                if ($result == true)
                {
                    //answer was right
                    $error = false;
                    $show = 'successPage';
                    $passwordMessage = sendPasswordEmail($_POST['user_id']);
                    $_SESSION['badCount'] = 0;
                } else {
                    //answer was wrong
                    $error = true;
                    $show = 'securityForm';
                    $securityUser = $_POST['user_id'];
                    $_SESSION['badCount']++;
                }
            } else {
                $error = true;
                $show = 'securityForm';
            }
        break;
        case 3:
		if (!isset($_POST['salt'])) 
			{
//If not isset -> set with dumy value 
			$_POST['salt'] = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE)); 
} 
		
            //we are submitting a new password (only for encrypted)
			if ($_POST['user_id'] == '' || $_POST['security_key'] == '') header("location: ../index.php");
            if (strcmp($_POST['pw0'],$_POST['pw1']) != 0 || trim($_POST['pw0']) == '')
            {
                $error = true;
                $show = 'recoverForm';
            } else {
                $error = false;
                $show = 'recoverSuccess';
                updateUserPassword($_POST['user_id'],$_POST['pw0'],$_POST['security_key'], $_POST['salt']);
            }
        break;
    }
}

elseif (isset($_GET['a']) && $_GET['a'] == 'recover' && $_GET['email'] != "") {
    $show = 'invalidKey';
    $result = checkEmailKey($_GET['email'],urldecode(base64_decode($_GET['u'])));
    if ($result == false)
    {
        $error = true;
        $show = 'invalidKey';
    } elseif ($result['status'] == true) {
        $error = false;
        $show = 'recoverForm';
        $securityUser = $result['user_id'];
    }
}
if (isset($_SESSION['badCount']) && $_SESSION['badCount'] >= 3)
{
    $show = 'speedLimit';
    $_SESSION['lockout'] = true;
    $_SESSION['lastTime'] = '' ? mktime() : $_SESSION['lastTime'];
}
?>

	 


<!doctype html>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Password Recovery</title>
<link href="css/styles.css" rel="stylesheet" type="text/css">
</head>
<body>

<?php
// INCLUDING THE TOP LOGIN / LOGOUT PANEL
include 'panel.php';
// INCLUDING THE NAVIGATION MENU
?>

<div id="container">
<div id="content" style="margin-top:-45px;">
		<img src="../images/logo.png" alt="Altech Autopage"></img>


<!-- CREATE THE FORM TO REQUEST THE USER TO SUBMIT DETAILS OF ACCOUNT -->

<?php switch($show) {
    case 'emailForm': ?>
	<div id="stylized" class="form">

	<h2>Password Recovery</h2>

		<p>Upon registration your password was securly encrypted in our database and it is impossible to actually recover your password. 																		
		However by filling in the for below, and answering your security question we can allow you to securely reset it. </p>

		<p>Please enter either your registered username or registered e-mail address below to get stared.</p>

		<form action="<?= $_SERVER['PHP_SELF']; ?>" method="post">


		
			<div class="fieldGroup"><label>Username :
			<span class="small">Username created when registering</span>
			</label>
			<div class="field"><input type="text" name="username" id="username" value="">
			</div>
			</div>
			
			<br><br>
			
			<p align='center' style="color: #ED1C24; font: bold 16px Arial, sans-serif;">-- OR -- </p>
			
			<br>
				
			<div class="fieldGroup"><label>E-Mail Address :
			<span class="small">E-Mail Address used when registering</span>
			</label>
			<div class="field"><input type="text" name="email" id="email" value="">
			</div>
			</div>
				
        	<input type="hidden" name="subStep" value="1" />
			<div class="fieldGroup"><input type="button" value="Find User" class="bt_login" onClick="form.submit()"/></div>
			<div class="clear"></div>
		</form>
	</div>


<?php break; case 'securityForm': ?>


	<div id="stylized" class="form">
	
	<h2>Password Recovery</h2>

		<p>Here comes the tricky part where we test your knowledge...</p>

		<p>Please answer the security question below so that we can verify that the correct person is trying to access your account.</p>

		<div class="fieldGroup">
		<?php if ($error == true) { ?>
		<span class="error">You have answered the security question incorrectly, please try again. If you are unable to remember the answer to 		your question, please contact your Team Manager.</span>
		<?php } ?>
		</div>

		<form action="<?= $_SERVER['PHP_SELF']; ?>" method="post">

			<div class="fieldGroup"><label>Security Question :
			<span class="small">Validation Question</span>
			</label>
			<div class="field">   <?= getSecurityQuestion($securityUser);?></div></div>

			<br>
			
			
			<div class="fieldGroup"><label>Security Answer :
			<span class="small">Validation Answer</span>
			</label>
			<div class="field"><input type="text" name="security_a" id="security_a" value=""></div></div>

        	<input type="hidden" name="subStep" value="2" />
        	<input type="hidden" name="user_id" value="<?= $securityUser; ?>" />
			<div class="fieldGroup">
			<input type="button" value="Recover" class="bt_login" onClick="form.submit()" style="margin-left: 150px;"/>										
			</div>
        	<div class="clear"></div>
    	</form>
	</div>
 
     
     	<?php break; case 'userNotFound': ?><br>  

	<div id="stylized" class="form">
	
	 	<h2>Password Recovery</h2><br>    
	 	<p>It appears that the username / password you are searching for is not valid,
	 	please <a href="?">Click here</a> to go back and try again.</p><br>    
		<div class="fieldGroup"></div> 
	</div>
		
		<?php break; case 'successPage': ?><br>   
	 	<h2>Password Recovery</h2><br>    

	 	<div class="message"><?= $passwordMessage;?></div><br>    
	


	
	 	<?php break; case 'recoverForm': ?>
	<div id="stylized" class="form">
	
    	<h2>Password Recovery</h2>
    	<p>Welcome back, <?= getUserName($securityUser=='' ? $_POST['user_id'] : $securityUser); ?>.</p>
    	<p>In the fields below, enter your new password.</p>
    	
		<?php if ($error == true) { ?><span class="error">The new passwords must match and must not be empty.</span><?php } ?>
    	<form action="<?= $_SERVER['PHP_SELF']; ?>" method="post">
			<div class="fieldGroup"><label for="pw0">New Password</label><div class="field">
			<input type="password" class="input" name="pw0" id="pw0" value="" maxlength="20"></div></div>
			<div class="fieldGroup"><label for="pw1">Confirm Password</label><div class="field">
			<input type="password" class="input" name="pw1" id="pw1" value="" maxlength="20"></div></div>
			<input type="hidden" name="subStep" value="3" />
			<input type="hidden" name="user_id" value="<?= $securityUser=='' ? $_POST['user_id'] : $securityUser; ?>" />
			<input type="hidden" name="security_key" value="<?= $_GET['email']=='' ? $_POST['security_key'] : $_GET['email']; ?>" />
			<div class="fieldGroup"><input type="submit" value="Submit" style="margin-left: 150px;" /></div>
			<div class="clear"></div>
		</form>
	</div>
	
    <?php break; case 'invalidsecurity_key': ?>
    <h2>Invalid security_key</h2>
    <p>The security_key that you entered was invalid. Either you did not copy the entire security_key from the email, you are trying to use the security_key after it has expired (3 days after request), or you have already used the security_key in which case it is deactivated.<br /><br /><a href="../index.php">Return</a> to the login page. </p>
    <?php break; case 'recoverSuccess': ?>
    <h2>Password Reset</h2>
    <p>Congratulations! your password has been reset successfully.</p><br /><br /><a href="../index.php">Return</a> to the login page. </p>
    <?php break; case 'speedLimit': ?>
    <h2>Warning</h2>
    <p>You have answered the security question wrong too many times. You will be locked out for 15 minutes, after which you can try again.</p><br /><br /><a href="../index.php">Return</a> to the login page. </p>
    <?php break; }
    ob_flush();
    $mysqli->close();
?>
<br><br><br>
</div>
</div>
</div>

<div id="container">
<div id="footer" style="margin-top:10px;">
<footer style="background:#E5E5E5; height:20px">
  <p>Copyright © Altech Autopage 2014 | <a href="mailto:">Contact Us</a>.</p>
  <img src="../images/altron-footer-logo.png" alt="Altron Footer Logo" align="left"></img>
  <img src="../images/altech_bbbee.png" alt="Altech Level 2 BBEE" align="left"></img>
</footer>
</div>	
</div>

<!--PAGE CONTENT-->
</div>
</body>
</html>

I have been playing around with the functions and form code to try and get it working, however I haven't been able to get it to work.

 

Link to post
Share on other sites
  • Replies 53
  • Created
  • Last Reply

the order of your ? parameters in the UPDATE query and the variables being bound must match. in your updateUserPassword function, you are binding the $password variable to the first ?, the $user_id to the second ?, and the $salt to the third ? in the following -

if ($stmt = $mysqli->prepare("UPDATE members SET password = ?, salt = ? WHERE id = ?"))
{
//$password = hash('sha512',trim($password) . $salt);
        
        $password = hash('sha512', $password . $salt);

$stmt->bind_param('sis',$password, $user_id, $salt);
Link to post
Share on other sites

I have changed it as follows, but still the new password doesn't work the table is also not updating anymore:

function updateUserPassword($password, $salt, $user_id, 
$security_key){    global $mysqli;    
if (checkEmailkey($security_key,$user_id) === false) return 
false;    if ($stmt = $mysqli->prepare("UPDATE members SET 
password = ?, salt = ? WHERE id = ?"))    
{        //$password = 
hash('sha512',trim($password) . $salt);    $password 
= hash('sha512', $password . $salt);
        
$stmt->bind_param('ssi',$password, $salt, 
$user_id);        
$stmt->execute();        
$stmt->close();        $stmt = 
$mysqli->prepare("DELETE FROM password_reset WHERE security_key = 
?");        
$stmt->bind_param('s',$security_key);        
$stmt->execute();    }}
Link to post
Share on other sites

have you done anything to determine what your code and data are doing?

 

are the values being passed to that function what you expect? is the correct row in the database table being updated? when the login function is being called, at what point is the logic in it failing?

Link to post
Share on other sites

Earlier checks, prior to changing the sequencing of the parameters, I removed the hashing of the password to ensure that the password field was being updated into the database correctly and this was correct.

 

I'm not sure what else to check or where to start checking for more problems.

Link to post
Share on other sites

my post above mentions three different things to check.

 

the point of programming is to get a general purpose computer to do what you want. debugging that programming involves finding where the computer is doing what you want and where it is not. you have to check, starting at the beginning of your current process (updating a stored password/salt and then logging in using that newly updated password/salt), what the data and program execution are doing at each step along that process, until you find the point where they are not doing what you expect.

 

since your salt/user id values were previously reversed, have you deleted the bogus row(s) from your table(s), registered a new user, and started the testing process over knowing that the registered user can log in at all, then tried to change his password?

 

a word about the login script you found. it is just a demonstration of the concepts that someone came up with for their idea for a secure login script. it is lacking things like a verbose debugging mode/logging and complete error checking that a final/finished 3rd party login script would have. there are several conditions in the login function that could cause it to fail, but there's no indication given as to the exact reason why it failed.

Link to post
Share on other sites

I understand that one needs to test all the functions, and I have done the testing. I have gone through the entire process step by step changing and fixing any errors I may have had. To the point where I am now. The correct row is / was updating, however, It is now no longer updating any row since I changed the parameter sequence).

 

I also un-hashed my password when resetting it and checked that it was in the database correctly, which it was. I then rehashed it and reset the password again. I was unable to login.

 

I am using the scripts from other sources, because I am still trying to learn how everything works, and that's why I will admit that not everything is always 100% as it should be.

 

Any new registered users are able to login just fine, everything else is working as expected. It is just the reset functionality that is not working. I currently have no way of recovering / resetting a users password should they forget it, and this is the best example I have had thus far, and it is working up to about 90%.

Link to post
Share on other sites

you have to determine what your code is doing in the instance of it running when it doesn't work, especially since you made a correction to the code.

 

there's no way the posted code could have updated anything with the $user_id and $salt values reversed. that would mean that you had a row in your members table with an id = a_random_salt_value.

 

the only way that code could have worked is if your code calling the updateUserPassword() function had those two values swapped from what you have shown in the code, but then it's unlike that your checkEmailkey() function call using the $user_id would have worked.

Link to post
Share on other sites

I think I might have identified where my problem could possibly be. I went back and changed my registration form to see how it posts the salt value to my table, the password etc. All un-hashed. This helped me to see that my form as I have it now seems to be posting the values in the correct manner, which leads me to believe that the hashing of the password is not happening as intended.

 

On submitting a login, the following function is called:

function regformhash(form, uid, email, password, conf) 

	{
     // CHECK TO ENSURE THAT ALL FIELDS ON THE FORM HAVE BEEN COMPLETED.
    if (uid.value == ''        || 
          email.value == ''  || 
          password.value == ''       || 
          conf.value == '') 
	{
        alert('Please complete all details required in the Registration form');
        return false;
    }

    // CHECK THE USERNAME TO ENSURE THAT IT ONLY CONTAINS LETTERS, NUMBERS AND UNDERSCORES.
    re = /^\w+$/; 
    if(!re.test(form.username.value)) 
	{ 
        alert("Username must contain only letters, numbers and underscores. Please try again"); 
        form.username.focus();
        return false; 
    }
	

    // CHECK TO ENSURE THAT THE PASSWORD IS AT LEAST 6 CHARACTERS IN LENGTH - A MORE DETAILED CHECK CAN ALSO BE DONE.
    if (password.value.length < 6)
	{
        alert('Passwords must be at least 6 characters long.  Please try again');
        form.password.focus();
        return false;
    }


	
	
    // COMPARE TWO PASSWORDS AND ENSURE THAT THEY MATCH.
    if (password.value != conf.value) 
	{
        alert('Your password and confirmation do not match. Please try again');
        form.password.focus();
        return false;
    }

    // CREATES A NEW ELEMENT TO HASH THE PASSWORD FIELD. 
    var p = document.createElement("input");

    // ADD THE NEWLY CREATED ELEMENT TO THE FORM 
    form.appendChild(p);
    p.name = "p";
    p.type = "hidden";
    p.value = hex_sha512(password.value);

    // ENSURE THAT THE PLAINTEXT PASSWORD ISN'T SENT OVER THE SERVER.
    password.value = "";
    conf.value = "";
	
	
	
	// SUBMIT THE COMPLETED FORM
    form.submit();
    return true;


	
}

the submit button is as follows for the above:

            <input class="bt_register" type="button" value="Register" onClick="return regformhash(this.form, 
																			this.form.username,
																			this.form.email,
																			this.form.password,
																			this.form.confirmpwd);"/>

This leads me to believe that I would have to do something similar when submitting the new password. Or am I wrong? My current submit button for the new / reset password is just :

<input type="button" value="Recover" class="bt_login" onClick="form.submit()" style="margin-left: 150px;"/>	

The problem being, I am not sure how to write the function that will allow the button to call the function and has the password.

Link to post
Share on other sites

Something to bare in mind from confusion I had when working with this script, the formhash sends the password as $_POST['p'] and not $_POST['password']. It does this so that the unhashed password is not sent via headers

// ADD THE NEWLY CREATED ELEMENT TO THE FORM 
    form.appendChild(p);
    p.name = "p";
    p.type = "hidden";
    p.value = hex_sha512(password.value);


Link to post
Share on other sites

 

Something to bare in mind from confusion I had when working with this script, the formhash sends the password as $_POST['p'] and not $_POST['password']. It does this so that the unhashed password is not sent via headers

 

 

Thanks for this paddyfields. I would need to create a new function to submit my password reset form based on this, would you perhaps be able to give me guidance in doing so based on the code I have?

 

What I have tried doing since your post is changing my form to submit my password as "p" and not password. The field is named "p".

Link to post
Share on other sites

 

Something to bare in mind from confusion I had when working with this script, the formhash sends the password as $_POST['p'] and not $_POST['password']. It does this so that the unhashed password is not sent via headers

 

 

Thanks for this paddyfields. I would need to create a new function to submit my password reset form based on this, would you perhaps be able to give me guidance in doing so based on the code I have?

 

What I have tried doing since your post is changing my form to submit my password as "p" and not password. The field is named "p".

Link to post
Share on other sites

No, you don't need to write a new function.

 

What happens is when you click 'submit' on your login/register form, the javascript 'onclick' function takes your field called 'password'... hashes it, and then inserts a new field into your html form with the name(or id i can' t remember) of 'p' which is then used when the form is submitted. It also clears the contents of 'password'. This is so hackers can't grab the unhashed password when the headers are sent.

 

If your login/register process is working as expected then you don't need to change anything too drastically when you are making a reset password script.

 

My solution was to make a new table called 'members_verify', with two rows... 'member_id ' and 'passcode'.

 

When the user requests a change of password... check the email address is really a members.. and then generate a random passcode and insert this into the table along with the member_id

 

Then send the user an email link with the passcode as part of the address - so something like www.mywebsite.com/password-reset.php?passcode=2dkfjslekj34lk4j3lkjlkj3

 

on 'password_reset.php' have a script that checks in members_verify whether that passcode exists, by using $_GET['passcode'] and looking in the database for a match, and if there is then allow them to update their password.

 

If you have implemented the script to allow users to login/register, then the password reset method i have just described requires no adaptation to the formhash function to achieve what you are after.

Link to post
Share on other sites

The reset script that I have built functions very similar to way you say, the only difference being that they are prompted for a security answer / question created when the user registered.

 

Once they answer the question correctly they are given a link (as it is an internal system, I haven't implemented mailing the link as yet (I will possibly do this later), but for now it displays it on screen for them to click and then change the password.

 

All the above mentioned works perfectly, where I am having my problem is when resetting the actual password. The password as well as the sat is changed in my table, however the new password doesn't work. This is where I believe the problem lies with the button that actually submits the password thinking that maybe it doesn't hash it correctly. I tried to then implement the same button I use for registration, but I could not get the button to work, when clicking it, it would just stay on the page without actually submitting the new password.

Link to post
Share on other sites

Originally I had just a regular submit button. And this submitted the new password / salt to the database table. The problem being that the updated password was not working, nor was the original. I check the table to validate that it was updating.

 

One of the other tests I did was to submit both the salt and the password un-hashed and these were also updated in the table as expected. I then thought that the reason it might not be working was because the function of submitting the password has a hash built into it so I changed the submit button to the one in the functions. However once I did this hitting the submit button performs no function, it just stays on the current screen.

 

Here is all the code involved:

 

The Form:

<?php
include_once 'db_connect.php';
include_once 'functions.php';
include_once 'formatting_includes.php';	

sec_session_start();
if (login_check($mysqli) == true) 
	{
    $logged = 'in';
	} 
	
$error_msg = "";

$show = 'emailForm'; //which form step to show by default
if(!isset($_SESSION['lastTime']))
   $_SESSION['lastTime'] = false;
if (isset($_SESSION['lockout']) && $_SESSION['lockout'] == true && (mktime() > $_SESSION['lastTime'] + 900))
{
    $_SESSION['lockout'] = false;
    $_SESSION['badCount'] = 0;
}
if(!isset($_SESSION['lockout']))
   $_SESSION['lockout'] = false;
if (isset($_POST['subStep']) && !isset($_GET['a']) &&  $_SESSION['lockout'] != true)
{
    switch($_POST['subStep'])
    {
        case 1:
            //we just submitted an email or username for verification
            $result = checkUNEmail($_POST['username'],$_POST['email']);
            if ($result['status'] == false )
            {
                $error = true;
                $show = 'userNotFound';
            } else {
                $error = false;
                $show = 'securityForm';
                $securityUser = $result['id'];
            }
        break;
        case 2:
            //we just submitted the security question for verification
            if ($_POST['user_id'] != "" && $_POST['security_a'] != "")
            {
                $result = checkSecAnswer($_POST['user_id'],$_POST['security_a']);
                if ($result == true)
                {
                    //answer was right
                    $error = false;
                    $show = 'successPage';
                    $passwordMessage = sendPasswordEmail($_POST['user_id']);
                    $_SESSION['badCount'] = 0;
                } else {
                    //answer was wrong
                    $error = true;
                    $show = 'securityForm';
                    $securityUser = $_POST['user_id'];
                    $_SESSION['badCount']++;
                }
            } else {
                $error = true;
                $show = 'securityForm';
            }
        break;
        case 3:
 		if (empty($error_msg)) {
        // Create a random salt
        $salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE));

			
} 

            //we are submitting a new password (only for encrypted)
            if ($_POST['user_id'] == '' || $_POST['security_key'] == '') header("location: ../index.php");
            if (strcmp($_POST['pw0'],$_POST['pw1']) != 0 || trim($_POST['pw0']) == '')
            {
                $error = true;
                $show = 'recoverForm';
            } else {
                $error = false;
                $show = 'recoverSuccess';
                updateUserPassword($_POST['pw0'], $_POST['user_id'], $_POST['security_key']);
            }
        break;
    }
}

elseif (isset($_GET['a']) && $_GET['a'] == 'recover' && $_GET['email'] != "") {
    $show = 'invalidKey';
    $result = checkEmailKey($_GET['email'],urldecode(base64_decode($_GET['u'])));
    if ($result == false)
    {
        $error = true;
        $show = 'invalidKey';
    } elseif ($result['status'] == true) {
        $error = false;
        $show = 'recoverForm';
        $securityUser = $result['user_id'];
    }
}
if (isset($_SESSION['badCount']) && $_SESSION['badCount'] >= 3)
{
    $show = 'speedLimit';
    $_SESSION['lockout'] = true;
    $_SESSION['lastTime'] = '' ? mktime() : $_SESSION['lastTime'];
}
?>

	 


<!doctype html>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Password Recovery</title>
<link href="css/styles.css" rel="stylesheet" type="text/css">
</head>
<body>

<?php
// INCLUDING THE TOP LOGIN / LOGOUT PANEL
include 'panel.php';
// INCLUDING THE NAVIGATION MENU
?>

<div id="container">
<div id="content" style="margin-top:-45px;">
		<img src="../images/logo.png" alt="Altech Autopage"></img>


<!-- CREATE THE FORM TO REQUEST THE USER TO SUBMIT DETAILS OF ACCOUNT -->

<?php switch($show) {
    case 'emailForm': ?>
	<div id="stylized" class="form">

	<h2>Password Recovery</h2>

		<p>Upon registration your password was securly encrypted in our database and it is impossible to actually recover your password. 																		
		However by filling in the for below, and answering your security question we can allow you to securely reset it. </p>

		<p>Please enter either your registered username or registered e-mail address below to get stared.</p>

		<form action="<?= $_SERVER['PHP_SELF']; ?>" method="post">


		
			<div class="fieldGroup"><label>Username :
			<span class="small">Username created when registering</span>
			</label>
			<div class="field"><input type="text" name="username" id="username" value="">
			</div>
			</div>
			
			<br><br>
			
			<p align='center' style="color: #ED1C24; font: bold 16px Arial, sans-serif;">-- OR -- </p>
			
			<br>
				
			<div class="fieldGroup"><label>E-Mail Address :
			<span class="small">E-Mail Address used when registering</span>
			</label>
			<div class="field"><input type="text" name="email" id="email" value="">
			</div>
			</div>
				
        	<input type="hidden" name="subStep" value="1" />
			<div class="fieldGroup"><input type="button" value="Find User" class="bt_login" onClick="form.submit()"/></div>
			<div class="clear"></div>
		</form>
	</div>


<?php break; case 'securityForm': ?>


	<div id="stylized" class="form">
	
	<h2>Password Recovery</h2>

		<p>Here comes the tricky part where we test your knowledge...</p>

		<p>Please answer the security question below so that we can verify that the correct person is trying to access your account.</p>

		<div class="fieldGroup">
		<?php if ($error == true) { ?>
		<span class="error">You have answered the security question incorrectly, please try again. If you are unable to remember the answer to 		your question, please contact your Team Manager.</span>
		<?php } ?>
		</div>

		<form action="<?= $_SERVER['PHP_SELF']; ?>" method="post">

			<div class="fieldGroup"><label>Security Question :
			<span class="small">Validation Question</span>
			</label>
			<div class="field">   <?= getSecurityQuestion($securityUser);?></div></div>

			<br>
			
			
			<div class="fieldGroup"><label>Security Answer :
			<span class="small">Validation Answer</span>
			</label>
			<div class="field"><input type="text" name="security_a" id="security_a" value=""></div></div>

        	<input type="hidden" name="subStep" value="2" />
        	<input type="hidden" name="user_id" value="<?= $securityUser; ?>" />
			<div class="fieldGroup">
			<input type="button" value="Recover" class="bt_login" onClick="form.submit()" style="margin-left: 150px;"/>										
			</div>
        	<div class="clear"></div>
    	</form>
	</div>
 
     
     	<?php break; case 'userNotFound': ?><br>  

	<div id="stylized" class="form">
	
	 	<h2>Password Recovery</h2><br>    
	 	<p>It appears that the username / password you are searching for is not valid,
	 	please <a href="?">Click here</a> to go back and try again.</p><br>    
		<div class="fieldGroup"></div> 
	</div>
		
		<?php break; case 'successPage': ?><br>   
	 	<h2>Password Recovery</h2><br>    

	 	<div class="message"><?= $passwordMessage;?></div><br>    
	


	
	 	<?php break; case 'recoverForm': ?>
	<div id="stylized" class="form">
	
    	<h2>Password Recovery</h2>
    	<p>Welcome back, <?= getUserName($securityUser=='' ? $_POST['user_id'] : $securityUser); ?>.</p>
    	<p>In the fields below, enter your new password.</p>
    	
		<?php if ($error == true) { ?><span class="error">The new passwords must match and must not be empty.</span><?php } ?>
    	<form action="<?= $_SERVER['PHP_SELF']; ?>" method="post">
			<div class="fieldGroup"><label for="pw0">New Password</label><div class="field">
			<input type="password" class="input" name="pw0" id="pw0" value=""></div></div>
			<div class="fieldGroup"><label for="pw1">Confirm Password</label><div class="field">
			<input type="password" class="input" name="pw1" id="pw1" value=""></div></div>
			<input type="hidden" name="subStep" value="3" />
			<input type="hidden" name="user_id" value="<?= $securityUser=='' ? $_POST['user_id'] : $securityUser; ?>" />
			<input type="hidden" name="security_key" value="<?= $_GET['email']=='' ? $_POST['security_key'] : $_GET['email']; ?>" />
			<div class="fieldGroup">
			<input type="button" value="Reset" class="bt_login" onClick="formhash(this.form, this.form.password);" style="margin-left: 150px;"/>	
			</div>
			<div class="clear"></div>
		</form>
	</div>
	
    <?php break; case 'invalidsecurity_key': ?>
    <h2>Invalid security_key</h2>
    <p>The security_key that you entered was invalid. Either you did not copy the entire security_key from the email, you are trying to use the security_key after it has expired (3 days after request), or you have already used the security_key in which case it is deactivated.<br /><br /><a href="../index.php">Return</a> to the login page. </p>
    <?php break; case 'recoverSuccess': ?>
    <h2>Password Reset</h2>
    <p>Congratulations! your password has been reset successfully.</p><br /><br /><a href="../index.php">Return</a> to the login page. </p>
    <?php break; case 'speedLimit': ?>
    <h2>Warning</h2>
    <p>You have answered the security question wrong too many times. You will be locked out for 15 minutes, after which you can try again.</p><br /><br /><a href="../index.php">Return</a> to the login page. </p>
    <?php break; }
    ob_flush();
    $mysqli->close();
?>
<br><br><br>
</div>
</div>
</div>

<div id="container">
<div id="footer" style="margin-top:10px;">
<footer style="background:#E5E5E5; height:20px">
  <p>Copyright © Altech Autopage 2014 | <a href="mailto:lclaassen@autopage.altech.co.za">Contact Us</a>.</p>
  <img src="../images/altron-footer-logo.png" alt="Altron Footer Logo" align="left"></img>
  <img src="../images/altech_bbbee.png" alt="Altech Level 2 BBEE" align="left"></img>
</footer>
</div>	
</div>

<!--PAGE CONTENT-->
</div>
</body>
</html>

Functions.php (The password reset functions are towards the end of the file):

<?php

// includes/functions.php -->

//
//ERROR CHECKING FUNCTIONS - ADD TO PAGES TO CHECK FOR POSSIBLE ERRORS
//	var_dump(login_check($mysqli));
//	var_dump($_SESSION); exit; 
//	var_dump($_POST);exit; 

include_once 'psl-config.php';

function sec_session_start() {
    $session_name = 'sec_session_id';   // Set a custom session name
    $secure = SECURE;
    // This stops JavaScript being able to access the session id.
    $httponly = true;
    // Forces sessions to only use cookies.
    if (ini_set('session.use_only_cookies', 1) === FALSE) {
        header("Location: ../error.php?err=Could not initiate a safe session (ini_set)");
        exit();
    }
    // Gets current cookies params.
    $cookieParams = session_get_cookie_params();
    session_set_cookie_params($cookieParams["lifetime"],
        $cookieParams["path"], 
        $cookieParams["domain"], 
        $secure,
        $httponly);
    // Sets the session name to the one set above.
    session_name($session_name);
    session_start();            // Start the PHP session 
    session_regenerate_id();    // regenerated the session, delete the old one. 
}



function login($email, $password, $mysqli) {
    // Using prepared statements means that SQL injection is not possible. 
    if ($stmt = $mysqli->prepare("SELECT id, username, password, email, level, salt 
        FROM members
       WHERE username = ?
        LIMIT 1")) {
        $stmt->bind_param('s', $email);  // Bind "$email" to parameter.
        $stmt->execute();    // Execute the prepared query.
        $stmt->store_result();

        // get variables from result.
        $stmt->bind_result($user_id, $username, $db_password, $email, $level, $salt);
        $stmt->fetch();

        // hash the password with the unique salt.
        $password = hash('sha512', $password . $salt);
        if ($stmt->num_rows == 1) {
            // If the user exists we check if the account is locked
            // from too many login attempts 
 
            if (checkbrute($user_id, $mysqli) == true) {
                // Account is locked 
                // Send an email to user saying their account is locked
                return false;
            } else {
                // Check if the password in the database matches
                // the password the user submitted.
                if ($db_password == $password) {
                    // Password is correct!
                    // Get the user-agent string of the user.
                    $user_browser = $_SERVER['HTTP_USER_AGENT'];
                    // XSS protection as we might print this value
                    $user_id = preg_replace("/[^0-9]+/", "", $user_id);
                    $_SESSION['user_id'] = $user_id;
                    // XSS protection as we might print this value
                    $username = preg_replace("/[^a-zA-Z0-9_\-]+/", 
                                                                "", 
                                                                $username);
                    $_SESSION['username'] = $username;
                    $_SESSION['login_string'] = hash('sha512',$password . $user_browser);
					$_SESSION['email'] = $email;
					$_SESSION['level'] = $level;
					$_SESSION['session_status'] = $session_status;
                    $mysqli->query("SELECT * FROM login_success WHERE user_id = '$user_id'");
					if			  (mysql_num_rows($mysqli) > 0)
						{
						$mysqli->query("UPDATE login_success SET time = NOW() WHERE user_id = '$user_id'");
						}
					else
						{
						$mysqli->query("INSERT INTO login_success(user_id, time) VALUES ('$user_id', now()");
						}
					//UPDATE login_success SET time = now() where user_id = '$user_id'");							  
                    // Login successful.
                    return true;
                } else {
                    // Password is not correct
                    // We record this attempt in the database
                    //$now = time();
                    $mysqli->query("INSERT INTO login_attempts(user_id, time)
                                    VALUES ('$user_id', now())");
                    return false;
                }
            }
        } else {
            // No user exists.
            return false;
        }
    }
}



function checkbrute($user_id, $mysqli) {
    // Get timestamp of current time 
    $now = time();

    // All login attempts are counted from the past 2 hours. 
    $valid_attempts = $now - (2 * 60 * 60);

    if ($stmt = $mysqli->prepare("SELECT time 
                             FROM login_attempts 
                             WHERE user_id = ? 
                            AND time > '$valid_attempts'")) {
        $stmt->bind_param('i', $user_id);

        // Execute the prepared query. 
        $stmt->execute();
        $stmt->store_result();

        // If there have been more than 5 failed logins 
        if ($stmt->num_rows > 5) {
            return true;
        } else {
            return false;
        }
    }
}



function login_check($mysqli) 
	{
    // Check if all session variables are set 
    if (isset($_SESSION['user_id'], 
			  $_SESSION['username'], 
			  $_SESSION['login_string'],
			  $_SESSION['email'],
			  $_SESSION['level']
			  //$_SESSION['session_status']
			  )) 
	{

    $user_id = $_SESSION['user_id'];
    $login_string = $_SESSION['login_string'];
    $username = $_SESSION['username'];
	$email = $_SESSION['email'];
	$level = $_SESSION['level'];
	//$status = $_SESSON['session_status'];
		

        // Get the user-agent string of the user.
        $user_browser = $_SERVER['HTTP_USER_AGENT'];

        if ($stmt = $mysqli->prepare("SELECT password 
                                      FROM members 
                                      WHERE id = ? LIMIT 1")) {
            // Bind "$user_id" to parameter. 
            $stmt->bind_param('i', $user_id);
            $stmt->execute();   // Execute the prepared query.
            $stmt->store_result();

            if ($stmt->num_rows == 1) {
                // If the user exists get variables from result.
                $stmt->bind_result($password);
                $stmt->fetch();
                $login_check = hash('sha512', $password . $user_browser);

                if ($login_check == $login_string) {
                    // Logged In!!!! 
					//echo 'logged in';
                    return true;
                } else {
                    // Not logged in 
					echo 1;
                    return false;
                }
            } else {
                // Not logged in
					echo 2;
                return false;
            }
        } else {
            // Not logged in 
			echo 3;
            return false;
        }
    } else {
        // Not logged in 
		//echo 4;
        return false;
    }
}



function esc_url($url) {

    if ('' == $url) {
        return $url;
    }

    $url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url);

    $strip = array('%0d', '%0a', '%0D', '%0A');
    $url = (string) $url;

    $count = 1;
    while ($count) {
        $url = str_replace($strip, '', $url, $count);
   }

    $url = str_replace(';//', '://', $url);

    $url = htmlentities($url);

    $url = str_replace('&', '&', $url);
    $url = str_replace("'", ''', $url);

    if ($url[0] !== '/') {
        // We're only interested in relative links from $_SERVER['PHP_SELF']
        return '';
    } else {
        return $url;
    }
}





function crypto_rand_secure($min, $max) {
        $range = $max - $min;
        if ($range < 0) return $min; // not so random...
        $log = log($range, 2);
        $bytes = (int) ($log /  + 1; // length in bytes
        $bits = (int) $log + 1; // length in bits
        $filter = (int) (1 << $bits) - 1; // set all lower bits to 1
        do {
            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
            $rnd = $rnd & $filter; // discard irrelevant bits
        } while ($rnd >= $range);
        return $min + $rnd;
}

function getToken($length=32){
    $token = "";
    $codeAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $codeAlphabet.= "abcdefghijklmnopqrstuvwxyz";
    $codeAlphabet.= "0123456789";
    for($i=0;$i<$length;$i++){
        $token .= $codeAlphabet[crypto_rand_secure(0,strlen($codeAlphabet))];
    }
    return $token;
}






/* RESTRICTED ACCESS LEVEL MANAGEMENT */


	
	function checkLoginLevel() {
        $allowed = array(
            '0' => array('register.addinfo.php','process/*','includes/*','index.php','index.html'), /* NEW REGISTRATION ACCESS LEVELS */
            '1' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','walkin_form.php','walkin_delete.php'),		/* ACCESS LEVELS FROM RECEPTION */
            '2' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','first-page.php'),
            '3' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','retail_view.php','retail_viewer.php','walkin_form.php','retail_form.php'),
			'4' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','premier_form.php', 'second-page.php', 'third-page.php'), /* SUPERVISOR ACCESS LEVELS */
            '5' => array('register.addinfo.php','process/*','includes/*','index.php','index.html','home.php','premier_form.php', 'second-page.php', 'third-page.php'), /* SUPERVISOR ACCESS LEVELS */
			'99' => true, /* ADMINISTRATION ACCESS LEVELS */
        );

    if(!isset($allowed[$_SESSION['level']])) {
        echo 'Your access level has not been set. Please return to the Login / Registration Page.';
        exit;
    }
	
	if($_SESSION['level'] == 0) {
	header('Location:register.addinfo.php');
	exit;
	}

    if(is_array($allowed[$_SESSION['level']])) {

        $file = $_SERVER["PHP_SELF"];
        $filearray = explode('/', $file);
        $filename = array_pop($filearray);
        $directory = array_pop($filearray);

        foreach($allowed[$_SESSION['level']] as $access) {
            if(strpos($access,'*')) {
                if($access == $directory . '/*') {
                    return true;
                }
            } elseif($access == $filename) {
                return true;
            }
        }
    }

    if(is_bool($allowed[$_SESSION['level']])) {
        return true;
    }

    echo 'You are not authorised to view this page. Please contact your manager to have your access level adjusted';
    exit;
}





//PSSWORD RESET FUNCTIONS




//define(PW_SALT,'(+3%_');
 
function checkUNEmail($username,$email)
{
    global $mysqli;
    $error = array('status'=>false,'user_id'=>0);
    if (isset($email) && trim($email) != '') {
        //email was entered
        if ($stmt = $mysqli->prepare("SELECT id FROM members WHERE email = ? LIMIT 1"))
        {
            $stmt->bind_param('s',trim($email));
            $stmt->execute();
            $stmt->store_result();
            $numRows = $stmt->num_rows();
            $stmt->bind_result($user_id);
            $stmt->fetch();
            $stmt->close();
            if ($numRows >= 1) return array('status'=>true,'id'=>$user_id);
        } else { return $error; }
    } elseif (isset($username) && trim($username) != '') {
        //username was entered
        if ($stmt = $mysqli->prepare("SELECT id FROM members WHERE username = ? LIMIT 1"))
        {
            $stmt->bind_param('s',trim($username));
            $stmt->execute();
            $stmt->store_result();
            $numRows = $stmt->num_rows();
            $stmt->bind_result($user_id);
            $stmt->fetch();
            $stmt->close();
            if ($numRows >= 1) return array('status'=>true,'id'=>$user_id);
        } else { return $error; }
    } else {
        //nothing was entered;
        return $error;
    }
}



function getSecurityQuestion($user_id)
{
    global $mysqli;
    $questions = array();
    $questions[0] = "What is your mother's maiden name?";
    $questions[1] = "What city were you born in?";
    $questions[2] = "What is your favorite colour?";
    $questions[3] = "What year did you graduate from High School?";
    $questions[4] = "What is your pet's name?";
    $questions[5] = "What is your favorite model of car?";
    if ($stmt = $mysqli->prepare("SELECT security_q FROM members WHERE id = ? LIMIT 1"))
    {
        $stmt->bind_param('i',$user_id);
        $stmt->execute();
        $stmt->store_result();
        $stmt->bind_result($security_q);
        $stmt->fetch();
        $stmt->close();
		return $security_q;
    } else {
        return false;
    }
}
 
function checkSecAnswer($user_id, $security_a)
{
    global $mysqli;
    if ($stmt = $mysqli->prepare("SELECT username FROM members WHERE id = ? AND LOWER(security_a) = ? LIMIT 1"))
    {
        $security_a = strtolower($security_a);
        $stmt->bind_param('is',$user_id, $security_a);
        $stmt->execute();
        $stmt->store_result();
        $numRows = $stmt->num_rows();
        $stmt->close();
        if ($numRows >= 1) { return true; }
    } else {
        return false;
    }
}




function sendPasswordEmail($user_id)
{
    global $mysqli;
    if ($stmt = $mysqli->prepare("SELECT username, email, password FROM members WHERE id = ? LIMIT 1"))
    {
        $stmt->bind_param('i',$user_id);
        $stmt->execute();
        $stmt->store_result();
        $stmt->bind_result($username, $email, $pword);
        $stmt->fetch();
        $stmt->close();
        $expFormat = mktime(date("H"), date("i"), date("s"), date("m")  , date("d")+3, date("Y"));
        $expDate = date("Y-m-d H:i:s",$expFormat);
 		if (empty($error_msg)) 
		{
        // Create a random salt
        $salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE));
		} 		
        $security_key =  hash('sha512',$username . '_' . $email . rand(0,10000) .$expDate . $salt);
        if ($stmt = $mysqli->prepare("INSERT INTO password_reset (user_id, security_key, expiry_date) VALUES (?,?,?)"))
        {
            $stmt->bind_param('iss',$user_id, $security_key, $expDate);
            $stmt->execute();
            $stmt->close();
            $passwordLink = "<a href=\"?a=recover&email=" . $security_key . "&u=" . urlencode(base64_encode($user_id)) . "\">http://www.oursite.com/forgotPass.php?a=recover&email=" . $security_key . "&u=" . urlencode(base64_encode($user_id)) . "</a>";
            $message = "Dear $username,\r\n";
            $message .= "Please visit the following link to reset your password:\r\n";
            $message .= "-----------------------\r\n";
            $message .= "$passwordLink\r\n";

            $message .= "-----------------------\r\n";
            $message .= "Please be sure to copy the entire link into your browser. The link will expire after 3 days for security reasons.\r\n\r\n";
            $message .= "If you did not request this forgotten password email, no action is needed, your password will not be reset as long as the link above is not visited. However, you may want to log into your account and change your security password and answer, as someone may have guessed it.\r\n\r\n";
            $message .= "Thanks,\r\n";
            $message .= "-- Our site team";
            $headers .= "From: Our Site <webmaster@oursite.com
			
<script type='text/javascript'>
/* <![CDATA[ */
(function(){try{var s,a,i,j,r,c,l,b=document.getElementsByTagName('script');l=b[b.length-1].previousSibling;a=l.getAttribute('data-cfemail');if(a){s='';r=parseInt(a.substr(0,2),16);for(j=2;a.length-j;j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}s=document.createTextNode(s);l.parentNode.replaceChild(s,l);}}catch(e){}})();
/* ]]> */
</script>> \n";
            $headers .= "To-Sender: \n";
            $headers .= "X-Mailer: PHP\n"; // mailer
            $headers .= "Reply-To: webmaster@oursite.com<script type='text/javascript'>
/* <![CDATA[ */
(function(){try{var s,a,i,j,r,c,l,b=document.getElementsByTagName('script');l=b[b.length-1].previousSibling;a=l.getAttribute('data-cfemail');if(a){s='';r=parseInt(a.substr(0,2),16);for(j=2;a.length-j;j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}s=document.createTextNode(s);l.parentNode.replaceChild(s,l);}}catch(e){}})();
/* ]]> */
</script>\n"; // Reply address
            $headers .= "Return-Path: webmaster@oursite.com<script type='text/javascript'>
/* <![CDATA[ */
(function(){try{var s,a,i,j,r,c,l,b=document.getElementsByTagName('script');l=b[b.length-1].previousSibling;a=l.getAttribute('data-cfemail');if(a){s='';r=parseInt(a.substr(0,2),16);for(j=2;a.length-j;j+=2){c=parseInt(a.substr(j,2),16)^r;s+=String.fromCharCode(c);}s=document.createTextNode(s);l.parentNode.replaceChild(s,l);}}catch(e){}})();
/* ]]> */
</script>\n"; //Return Path for errors
            $headers .= "Content-Type: text/html; charset=iso-8859-1"; //Enc-type
            $subject = "Your Lost password";
            @mail($email,$subject,$message,$headers);
            return str_replace("\r\n","<br/ >",$message);
        }
    }
}


function checkEmailKey($security_key,$user_id)
{
    global $mysqli;
    $curDate = date("Y-m-d H:i:s");
    if ($stmt = $mysqli->prepare("SELECT user_id FROM password_reset WHERE security_key = ? AND user_id = ? AND expiry_date >= ?"))
    {
        $stmt->bind_param('sis',$security_key, $user_id, $curDate);
        $stmt->execute();
        $stmt->execute();
        $stmt->store_result();
        $numRows = $stmt->num_rows();
        $stmt->bind_result($user_id);
        $stmt->fetch();
        $stmt->close();
        if ($numRows > 0 && $user_id != '')
        {
            return array('status'=>true,'user_id'=>$user_id);
        }
    }
    return false;
}
 
function updateUserPassword($password, $user_id, $security_key)
{
    global $mysqli;
    if (checkEmailkey($security_key ,$user_id) === false) return false;
 		if (empty($error_msg)) {
        // Create a random salt
        $salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE));
		}	
    if ($stmt = $mysqli->prepare("UPDATE members SET password = ?, salt = ? WHERE id = ?"))
    {
        $password = hash('sha512', $password . $salt);
        $stmt->bind_param('ssi', $password, $salt, $user_id);
        $stmt->execute();
        $stmt->close();
        $stmt = $mysqli->prepare("DELETE FROM password_reset WHERE security_key = ?");
        $stmt->bind_param('s',$security_key);
        $stmt->execute();
    }
}
 
function getUserName($user_id)
{
    global $mysqli;
    if ($stmt = $mysqli->prepare("SELECT username FROM members WHERE id = ?"))
    {
        $stmt->bind_param('i',$user_id);
        $stmt->execute();
        $stmt->store_result();
        $stmt->bind_result($username);
        $stmt->fetch();
        $stmt->close();
    }
    return $username;
}

And the button functions:

function formhash(form, password) 
	
	{
    // CREATE A NEW ELEMENT INPUT FOR THE HASHED PASSWORD. 
    var p = document.createElement("input");

    // ADD THE NEW ELEMENT TO THE FORM 
    form.appendChild(p);
    p.name = "p";
    p.type = "hidden";
    p.value = hex_sha512(password.value);

    // MAKE SURE THAT THE PLAINTEXT PASSWORD DOESN'T GET SENT. 
    password.value = "";

    // SUBMIT THE COMPLETED FORM
    form.submit();
	}



function regformhash(form, uid, email, password, conf) 

	{
     // CHECK TO ENSURE THAT ALL FIELDS ON THE FORM HAVE BEEN COMPLETED.
    if (uid.value == ''        || 
          email.value == ''  || 
          password.value == ''       || 
          conf.value == '') 
	{
        alert('Please complete all details required in the Registration form');
        return false;
    }

    // CHECK THE USERNAME TO ENSURE THAT IT ONLY CONTAINS LETTERS, NUMBERS AND UNDERSCORES.
    re = /^\w+$/; 
    if(!re.test(form.username.value)) 
	{ 
        alert("Username must contain only letters, numbers and underscores. Please try again"); 
        form.username.focus();
        return false; 
    }
	
    // CHECK TO ENSURE THAT THE E-MAIL ADDRESS IS A VALID AUTOPAGE.ALTECH.CO.ZA E-MAIL ADDRESS.
	var re = (/^\"?[\w-_\.]*\"?@autopage.altech\.co.za$/)
    if (!re.test(email.value)) 
	{
        alert('Please ensure that you have entered a valid autopage.altech.co.za e-mail address.');
        return false;
    }

    // CHECK TO ENSURE THAT THE PASSWORD IS AT LEAST 6 CHARACTERS IN LENGTH - A MORE DETAILED CHECK CAN ALSO BE DONE.
    if (password.value.length < 6)
	{
        alert('Passwords must be at least 6 characters long.  Please try again');
        form.password.focus();
        return false;
    }

    // CHECKS FOR AT LEAST 6 CHARACTERS, ONE NUMBER, ONE LOWERCASE LETTER AND ONE UPPERCASE LETTER - ENABLE 5 LINE BELOW TO ENABLE THIS VALIDATION.
    //var re = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,}/; 
    //if (!re.test(password.value)) 
	//{
    //    alert('Passwords must contain at least one number, one lowercase and one uppercase letter.  Please try again');
    //    return false;
    //}

	
	
    // COMPARE TWO PASSWORDS AND ENSURE THAT THEY MATCH.
    if (password.value != conf.value) 
	{
        alert('Your password and confirmation do not match. Please try again');
        form.password.focus();
        return false;
    }

    // CREATES A NEW ELEMENT TO HASH THE PASSWORD FIELD. 
    var p = document.createElement("input");

    // ADD THE NEWLY CREATED ELEMENT TO THE FORM 
    form.appendChild(p);
    p.name = "p";
    p.type = "hidden";
    p.value = hex_sha512(password.value);

    // ENSURE THAT THE PLAINTEXT PASSWORD ISN'T SENT OVER THE SERVER.
    password.value = "";
    conf.value = "";
	
	
	
	// SUBMIT THE COMPLETED FORM
    form.submit();
    return true;


	
}



Link to post
Share on other sites

So what actually happens with your code so far... when the user enters their security question correctly does it allow them to then create a new password? And if so, when they enter a new password are you positive that it is entering a new password and salt into the database?

 

Is your problem that when you then try to login, that the credentials won't allow you to login?

Link to post
Share on other sites

Yip that's exactly it. I confirmed this by capturing both the salt and the password un-hashed which allowed me to see the new password and the new salt attached to it each time. The login script that you and I are using is the same script if I am not mistaken, with just a few changes on each side for our own personalization.

 

I also deleted users and created new users to test and these also updated and did everything as expected.

 

The only time it stopped submitting to the database table is when I changed the button from just a regular submit button to the "function" button, at this stage it stopped submitting altogether.

Link to post
Share on other sites

you need to duplicate, as in copy/paste, the form code from the registration form for the password field, to use in your password reset form for the password field.

 

the processing that is done on the password must be the same, regardless of it being for registration or password reset.

Link to post
Share on other sites

It's this part that is the problem....

// Create a random salt
        $salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE));

			
} 

            //we are submitting a new password (only for encrypted)
            if ($_POST['user_id'] == '' || $_POST['security_key'] == '') header("location: ../index.php");
            if (strcmp($_POST['pw0'],$_POST['pw1']) != 0 || trim($_POST['pw0']) == '')
            {
                $error = true;
                $show = 'recoverForm';
            } else {
                $error = false;
                $show = 'recoverSuccess';
                updateUserPassword($_POST['pw0'], $_POST['user_id'], $_POST['security_key']);
            }
        break;
    }

You're creating a salt but by the looks of it, not using it.

 

And as I mentioned before, the javascript appends a new hidden element before the form is submitted called 'p', so you don't want to be using $_POST['pw0'] here:  updateUserPassword($_POST['pw0'], $_POST['user_id'], $_POST['security_key']);

 

$_POST['p'] will be a hashed version of the password that the user enters.

 

As mac_gyver says the processing of the password needs to be the same. Look at your registration page and copy the code that is used to process the password after the form has been submitted.

 

Basically change:

 

 updateUserPassword($_POST['pw0'], $_POST['user_id'], $_POST['security_key']);

 

to:

 

 updateUserPassword($_POST['p'], $_POST['user_id'], $_POST['security_key']);

 

And it should work.
 

Link to post
Share on other sites

Ok so here are the changes I have made, and I get the following error: 

 

 

Notice: Undefined variable: securityUser in C:htdocs\includes\resetpwd.php on line 241

 

What's confusing about the error is I only get it when I submit the two password. When access the link, the form requesting the two passwords displays correctly and also identifies the user correctly.

 

LINE 241:

<p>Welcome back, <?= getUserName($securityUser=='' ? $_POST['user_id'] : $securityUser); ?>.</p>

 

My code:

<?php
include_once 'db_connect.php';
include_once 'functions.php';
include_once 'formatting_includes.php';	

sec_session_start();
if (login_check($mysqli) == true) 
	{
    $logged = 'in';
	} 
	
$error_msg = "";

$show = 'emailForm'; //which form step to show by default
if(!isset($_SESSION['lastTime']))
   $_SESSION['lastTime'] = false;
if (isset($_SESSION['lockout']) && $_SESSION['lockout'] == true && (mktime() > $_SESSION['lastTime'] + 900))
{
    $_SESSION['lockout'] = false;
    $_SESSION['badCount'] = 0;
}
if(!isset($_SESSION['lockout']))
   $_SESSION['lockout'] = false;
if (isset($_POST['subStep']) && !isset($_GET['a']) &&  $_SESSION['lockout'] != true)
{
    switch($_POST['subStep'])
    {
        case 1:
            //we just submitted an email or username for verification
            $result = checkUNEmail($_POST['username'],$_POST['email']);
            if ($result['status'] == false )
            {
                $error = true;
                $show = 'userNotFound';
            } else {
                $error = false;
                $show = 'securityForm';
                $securityUser = $result['id'];
            }
        break;
        case 2:
            //we just submitted the security question for verification
            if ($_POST['user_id'] != "" && $_POST['security_a'] != "")
            {
                $result = checkSecAnswer($_POST['user_id'],$_POST['security_a']);
                if ($result == true)
                {
                    //answer was right
                    $error = false;
                    $show = 'successPage';
                    $passwordMessage = sendPasswordEmail($_POST['user_id']);
                    $_SESSION['badCount'] = 0;
                } else {
                    //answer was wrong
                    $error = true;
                    $show = 'securityForm';
                    $securityUser = $_POST['user_id'];
                    $_SESSION['badCount']++;
                }
            } else {
                $error = true;
                $show = 'securityForm';
            }
        break;
        case 3:
 		if (empty($error_msg)) {
        // Create a random salt
        //$salt = hash('sha512', uniqid(openssl_random_pseudo_bytes(16), TRUE));

			
} 

            //we are submitting a new password (only for encrypted)
            if ($_POST['user_id'] == '' || $_POST['security_key'] == '') header("location: ../index.php");
            if (strcmp($_POST['password'],$_POST['confirmpwd']) != 0 || trim($_POST['password']) == '')
            {
                $error = true;
                $show = 'recoverForm';
            } else {
                $error = false;
                $show = 'recoverSuccess';
                updateUserPassword($_POST['p'], $_POST['user_id'], $_POST['security_key']);
            }
        break;
    }
}

elseif (isset($_GET['a']) && $_GET['a'] == 'recover' && $_GET['email'] != "") {
    $show = 'invalidKey';
    $result = checkEmailKey($_GET['email'],urldecode(base64_decode($_GET['u'])));
    if ($result == false)
    {
        $error = true;
        $show = 'invalidKey';
    } elseif ($result['status'] == true) {
        $error = false;
        $show = 'recoverForm';
        $securityUser = $result['user_id'];
    }
}
if (isset($_SESSION['badCount']) && $_SESSION['badCount'] >= 3)
{
    $show = 'speedLimit';
    $_SESSION['lockout'] = true;
    $_SESSION['lastTime'] = '' ? mktime() : $_SESSION['lastTime'];
}
?>

	 


<!doctype html>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Password Recovery</title>
<link href="css/styles.css" rel="stylesheet" type="text/css">
</head>
<body>

<?php
// INCLUDING THE TOP LOGIN / LOGOUT PANEL
include 'panel.php';
// INCLUDING THE NAVIGATION MENU
?>

<div id="container">
<div id="content" style="margin-top:-45px;">
		<img src="../images/logo.png" alt="Altech Autopage"></img>


<!-- CREATE THE FORM TO REQUEST THE USER TO SUBMIT DETAILS OF ACCOUNT -->

<?php switch($show) {
    case 'emailForm': ?>
	<div id="stylized" class="form">

	<h2>Password Recovery</h2>

		<p>Upon registration your password was securly encrypted in our database and it is impossible to actually recover your password. 																		
		However by filling in the for below, and answering your security question we can allow you to securely reset it. </p>

		<p>Please enter either your registered username or registered e-mail address below to get stared.</p>

		<form action="<?= $_SERVER['PHP_SELF']; ?>" method="post">


		
			<div class="fieldGroup"><label>Username :
			<span class="small">Username created when registering</span>
			</label>
			<div class="field"><input type="text" name="username" id="username" value="">
			</div>
			</div>
			
			<br><br>
			
			<p align='center' style="color: #ED1C24; font: bold 16px Arial, sans-serif;">-- OR -- </p>
			
			<br>
				
			<div class="fieldGroup"><label>E-Mail Address :
			<span class="small">E-Mail Address used when registering</span>
			</label>
			<div class="field"><input type="text" name="email" id="email" value="">
			</div>
			</div>
				
        	<input type="hidden" name="subStep" value="1" />
			<div class="fieldGroup"><input type="button" value="Find User" class="bt_login" onClick="form.submit()"/></div>
			<div class="clear"></div>
		</form>
	</div>


<?php break; case 'securityForm': ?>


	<div id="stylized" class="form">
	
	<h2>Password Recovery</h2>

		<p>Here comes the tricky part where we test your knowledge...</p>

		<p>Please answer the security question below so that we can verify that the correct person is trying to access your account.</p>

		<div class="fieldGroup">
		<?php if ($error == true) { ?>
		<span class="error">You have answered the security question incorrectly, please try again. If you are unable to remember the answer to 		your question, please contact your Team Manager.</span>
		<?php } ?>
		</div>

		<form action="<?= $_SERVER['PHP_SELF']; ?>" method="post">

			<div class="fieldGroup"><label>Security Question :
			<span class="small">Validation Question</span>
			</label>
			<div class="field">   <?= getSecurityQuestion($securityUser);?></div></div>

			<br>
			
			
			<div class="fieldGroup"><label>Security Answer :
			<span class="small">Validation Answer</span>
			</label>
			<div class="field"><input type="text" name="security_a" id="security_a" value=""></div></div>

        	<input type="hidden" name="subStep" value="2" />
        	<input type="hidden" name="user_id" value="<?= $securityUser; ?>" />
			<div class="fieldGroup">
			<input type="button" value="Recover" class="bt_login" onClick="form.submit()" style="margin-left: 150px;"/>										
			</div>
        	<div class="clear"></div>
    	</form>
	</div>
 
     
     	<?php break; case 'userNotFound': ?><br>  

	<div id="stylized" class="form">
	
	 	<h2>Password Recovery</h2><br>    
	 	<p>It appears that the username / password you are searching for is not valid,
	 	please <a href="?">Click here</a> to go back and try again.</p><br>    
		<div class="fieldGroup"></div> 
	</div>
		
		<?php break; case 'successPage': ?><br>   
	 	<h2>Password Recovery</h2><br>    

	 	<div class="message"><?= $passwordMessage;?></div><br>    
	


	
	 	<?php break; case 'recoverForm': ?>
	<div id="stylized" class="form">
	
    	<h2>Password Recovery</h2>
    	<p>Welcome back, <?= getUserName($securityUser=='' ? $_POST['user_id'] : $securityUser); ?>.</p>
    	<p>In the fields below, enter your new password.</p>
    	
		<?php if ($error == true) { ?><span class="error">The new passwords must match and must not be empty.</span><?php } ?>
    	<form action="<?= $_SERVER['PHP_SELF']; ?>" method="post">
				<div class="fieldGroup"<label class="grey" for="password">Password:</label>					
				<input class="field" type="password" name="password" id="password"/><br>
				<div class="fieldGroup"<label class="grey" for="password">Confirm Password:</label>					
				<input class="field" type="password" name="confirmpwd" id="confirmpwd"/><br>					

		
		
		
			<!--<div class="fieldGroup"><label for="password">New Password</label><div class="field">
			<input type="password" class="input" name="password" id="password" value=""></div></div>
			<div class="fieldGroup"><label for="confirmpwd">Confirm Password</label><div class="field">
			<input type="password" class="input" name="confirmpwd" id="confirmpwd" value=""></div></div> -->
			<input type="hidden" name="subStep" value="3" />
			<input type="hidden" name="user_id" value="<?= $securityUser=='' ? $_POST['user_id'] : $securityUser; ?>" />
			<input type="hidden" name="security_key" value="<?= $_GET['email']=='' ? $_POST['security_key'] : $_GET['email']; ?>" />
			<div class="fieldGroup">
			<input class="bt_login" type="button" value="Reset" onClick="return resetformhash(this.form, 
																			this.form.password,
																			this.form.confirmpwd);" style="margin-left: 150px;"/>	
			</div>
			<div class="clear"></div>
		</form>
	</div>
	
    <?php break; case 'invalidsecurity_key': ?>
    <h2>Invalid security_key</h2>
    <p>The security_key that you entered was invalid. Either you did not copy the entire security_key from the email, you are trying to use the security_key after it has expired (3 days after request), or you have already used the security_key in which case it is deactivated.<br /><br /><a href="../index.php">Return</a> to the login page. </p>
    <?php break; case 'recoverSuccess': ?>
    <h2>Password Reset</h2>
    <p>Congratulations! your password has been reset successfully.</p><br /><br /><a href="../index.php">Return</a> to the login page. </p>
    <?php break; case 'speedLimit': ?>
    <h2>Warning</h2>
    <p>You have answered the security question wrong too many times. You will be locked out for 15 minutes, after which you can try again.</p><br /><br /><a href="../index.php">Return</a> to the login page. </p>
    <?php break; }
    ob_flush();
    $mysqli->close();
?>
<br><br><br>
</div>
</div>
</div>

<div id="container">
<div id="footer" style="margin-top:10px;">
<footer style="background:#E5E5E5; height:20px">
  <p>Copyright © Altech Autopage 2014 | <a href="mailto:lclaassen@autopage.altech.co.za">Contact Us</a>.</p>
  <img src="../images/altron-footer-logo.png" alt="Altron Footer Logo" align="left"></img>
  <img src="../images/altech_bbbee.png" alt="Altech Level 2 BBEE" align="left"></img>
</footer>
</div>	
</div>

<!--PAGE CONTENT-->
</div>
</body>
</html>

reset password button function:




function resetformhash(form, password, conf) 

	{
     // CHECK TO ENSURE THAT ALL FIELDS ON THE FORM HAVE BEEN COMPLETED.
    if (  password.value == ''       || 
          conf.value == '') 
	{
        alert('Please complete all details to reset your password');
        return false;
    }




    // CHECK TO ENSURE THAT THE PASSWORD IS AT LEAST 6 CHARACTERS IN LENGTH - A MORE DETAILED CHECK CAN ALSO BE DONE.
    if (password.value.length < 6)
	{
        alert('Passwords must be at least 6 characters long.  Please try again');
        form.password.focus();
        return false;
    }

   	
    // COMPARE TWO PASSWORDS AND ENSURE THAT THEY MATCH.
    if (password.value != conf.value) 
	{
        alert('Your password and confirmation do not match. Please try again');
        form.password.focus();
        return false;
    }

    // CREATES A NEW ELEMENT TO HASH THE PASSWORD FIELD. 
    var p = document.createElement("input");

    // ADD THE NEWLY CREATED ELEMENT TO THE FORM 
    form.appendChild(p);
    p.name = "p";
    p.type = "hidden";
    p.value = hex_sha512(password.value);

    // ENSURE THAT THE PLAINTEXT PASSWORD ISN'T SENT OVER THE SERVER.
    password.value = "";
    conf.value = "";
	
	
	
	// SUBMIT THE COMPLETED FORM
    form.submit();
    return true;


	
}
Link to post
Share on other sites

Archived

This topic is now archived and is closed to further replies.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.