<?php
////////////////////////////////////////////////////////////////////////
// Breeze Website Builder
// Copyright Silver Dolphin Solutions, LLC, Edward Lemmers, P.E.
// For licensing, see license.txt.
// Revised: 4/26/2010	ELL
// Added dictionary attack protection.
// Revised: 10/15/2011	ELL
// Added ability to lockout file manager for restricted users.
// Revised: 2/8/2012	ELL
// Added table prefix handling.
// Revised: 11/16/2012	ELL
// Added handling of passwords sent SHA-256 hashed and added handling of salt.
// Revised: 3/25/2013	ELL
// Security enhancements for PDO.
//
	$userid = $_REQUEST['userid'];
	$password = $_REQUEST['password'];

	include ("../connect/db_connect.php");
	include ("../connect/config.php");
	
	// Check referers to make sure SPAM bot is not trying to brake in.
	$server_name = $_SERVER['SERVER_NAME'];
	$server_name_www = "www." . $server_name;
	$referers = array($server_name_www, $server_name);
	if (!check_referer($referers))
	{
		echo <<<END
		<br>
		<div align="center">
		<h2>You do not appear to be valid. Make sure you have JavaScript turned on, cookies turned on, referers turned on and IP tracking blocks turned off. If this is in error, go back and try again.</h2>
		<h2><a href="javascript:history.go(-1);">Click here</a> to return to the login page, or use your 'Back' button.</h2>
		</div>
		<br>
END;
	
		exit;
	}
	
	// If dictionary attack detected, just dump 'em. 
	$attempt_limit = CheckAttempts($userid, $bwb_dbh);
	if ($attempt_limit > 10)
	{
		LogAttempt($userid, $bwb_dbh);
		echo "You have exceeded the maximum number of login attempts.  Please contact your system administrator.";
		exit;
	}

	$query = "SELECT * FROM " . BWB_TABLE_PREFIX . "users WHERE `UserID` = :userid";
	$stmt = $bwb_dbh->prepare($query);
	$stmt->execute(array(':userid' => $userid));
	$num_results = $stmt->rowCount();
	$row = $stmt->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT);
	
	if ($num_results < 1)
	{
		LogAttempt($userid, $bwb_dbh);
		echo "There is no user by that name.   Click <a href='index.php'> here </a> to re-enter your user ID and password.";
		exit;
	}
		
	$access_level = $row["AccessLevel"];
	
	/////////////////////////////////////////////
	//Decrypt password for comparison:
	$enc_text = stripslashes($row["password"]);
	$key = stripslashes($row["UserID"]);
	
	//Convert key to codes and pad as necessary.
	for( $i = 0; $i < (strlen($enc_text))/2; $i++)
	{
		if ($i < strlen($key))
		{
			$c = $key{$i};
			$k[$i] = ord($c);
		}
		else
			$k[$i] = 65 + $i;
	}
	
	//Convert encrypted string to array of HEX uni-character codes.
	$j = 0;
	$q = 0;
	for( $i = 0; $i < strlen($enc_text); $i++)
	{
		if ($j == 0) {
			$c = $enc_text{$i};
			$j++;
		}
		else {
			$c = $c.$enc_text{$i};
			$e[$q] = hexdec($c);
			$q++;
			$j = 0;
		}
		
	}
	
	//Decrypt encrypted string with key to get original data.
	$decrypt_text = "";
	for( $i = 0; $i < (strlen($enc_text))/2; $i++)
   	{
   		$a[$i] = $e[$i] ^ $k[$i];
		$decrypt_text = $decrypt_text. chr($a[$i]);
   	}
	////////////////////////////////////////////////////
	
	$decrypt_text = str_replace(BWB_SALT, '', $decrypt_text);
	$password_lookup = hash('sha256', $decrypt_text);
	if ($password_lookup == $password)
	{
		session_start();
		$_SESSION['userid'] = $userid;
		$session = md5(session_id());
		$ip = $_SERVER['REMOTE_ADDR'];
		$query = "UPDATE `" . BWB_TABLE_PREFIX . "users` SET `Session`='$session', `IP`='$ip' WHERE `UserID` = :userid";
		$stmt = $bwb_dbh->prepare($query);
		$stmt->execute(array(':userid' => $userid));
		CleanAttemptLog($bwb_dbh);
		LogAttempt($userid, $bwb_dbh, 1);
		
		if ($access_level == "restricted")
		{
			$query = "SELECT `option_value` FROM `" . BWB_TABLE_PREFIX . "options_selected` WHERE `option_name`='EnableFileManager'";
			$result = $bwb_dbh->query($query);
			$row = $result->fetch(PDO::FETCH_ASSOC);
			$enable_file_manager = $row["option_value"];
		}
		
		if (($access_level != "restricted") || ($enable_file_manager == 1))
			$_SESSION['enable_file_manager'] = "100";
		else
			$_SESSION['enable_file_manager'] = "0";
			
		header("Location: main.php");
	}
	else
	{
		LogAttempt($userid, $bwb_dbh);
		echo "Your password has not been confirmed.   Click <a href='index.php'> here </a> to re-enter your password.";
	}
	exit;
	
	//////////////////////////////////////////////////
	function CheckAttempts($userid, $dbh)
	{
		$ip = $_SERVER['REMOTE_ADDR'];
		$current_ts = date('Y-m-d H:i:s', time());
		$query = "SELECT * FROM " . BWB_TABLE_PREFIX . "login_attempts WHERE (`IP` = '$ip') AND (TIMESTAMPDIFF(MINUTE, `AttemptTimeStamp`, '$current_ts') < 60)";
		$result = $dbh->query($query);
		$row = $dbh->query($query)->fetch();
		return($result->rowCount());
	}
	
	function LogAttempt($userid, $dbh, $success = 0)
	{
		$ip = $_SERVER['REMOTE_ADDR'];
		$query = "INSERT INTO " . BWB_TABLE_PREFIX . "login_attempts (`UserID`, `IP`, `Success`) VALUES (:userid, '$ip', $success)";
		$stmt = $dbh->prepare($query);
		$stmt->execute(array(':userid' => $userid));
	}
	
	function CleanAttemptLog($dbh)
	{
		$current_ts = date('Y-m-d H:i:s', time());
		$query = "DELETE FROM " . BWB_TABLE_PREFIX . "login_attempts WHERE (TIMESTAMPDIFF(DAY, `AttemptTimeStamp`, '$current_ts') > 7)";
		$cnt = $dbh->exec($query);
		
	}
	
 /****************************************************************
 * check_referer() breaks up the enviromental variable		*
 * HTTP_REFERER by "/" and then checks to see if the second	*
 * member of the array (from the explode) matches any of the	*
 * domains listed in the $referers array (declaired at top)	*
 ****************************************************************/

function check_referer($referers)
{
	global $errors;
	if (count($referers)) {
		if (getenv('HTTP_REFERER')) {
			$temp = explode('/', getenv('HTTP_REFERER'));
			$found = false;
			while (list(,$stored_referer) = each($referers)) {
				if (eregi('^' . $stored_referer . '$', $temp[2]))
					$found = true;
			}
			if (!$found) {
				$errors[] = '1|You are coming from an unauthorized domain.  Please read the manual section titled &quot;<a href="' . MANUAL . '#setting_up" target="_blank">Setting Up the PHPFormMail Script</a>&quot;.';
				error_log('[PHPFormMail] Illegal Referer. (' . getenv('HTTP_REFERER') . ')', 0);
			}
			return $found;
		} else {
			$errors[] = '0|Sorry, but I cannot figure out who sent you here.  Your browser is not sending an HTTP_REFERER.  This could be caused by a firewall or browser that removes the HTTP_REFERER from each HTTP request you submit.';
			error_log('[PHPFormMail] HTTP_REFERER not defined. Browser: ' . getenv('HTTP_USER_AGENT') . '; Client IP: ' . getenv('REMOTE_ADDR') . '; Request Method: ' . getenv('REQUEST_METHOD') . ';', 0);
			return false;
		}
	} else {
		$errors[] = '1|There are no referers defined.  All submissions will be denied.  Please read the manual section titled &quot;<a href="' . MANUAL . '#setting_up" target="_blank">Setting Up the PHPFormMail Script</a>&quot;.';
		error_log('[PHPFormMail] You have no referers defined.  All submissions will be denied.', 0);
		return false;
	}
}
	
?>
