<?php
	
// autenticate.php
// -------------------------------------------------------------------------------------------------
// Implements authentication, based on challenge for username and password
// Include in page to restrict access
//
// Project    > dmABS-1.6.B.1
// Revision   > $Rev: 140 $
// Date		  > $Date: 2009-11-11 10:24:10 +0000 (Wed, 11 Nov 2009) $
// Author     > RAK for DML
// Copyright  > (C) Digital Mail Limited (2005-2009)
// -------------------------------------------------------------------------------------------------

include_once('../config/tech_options.php');
include_once('abs_lib.php');

if (isset($_POST['abs_auth_command']))
{
	// We're hitting this script directly to execute an authentication action
	//
	define('MOD_PHP', substr(PHP_SAPI, 0, 3) != 'cgi'); // Are we running as mod_php?
	define('DOCROOT', 
		MOD_PHP && isset($_SERVER['DOCUMENT_ROOT']) ? 
			$_SERVER['DOCUMENT_ROOT'] : 
			(
				MOD_PHP && isset($_SERVER['SCRIPT_FILENAME']) ? 
					substr($_SERVER['SCRIPT_FILENAME'], 0, 0-strlen($_SERVER['PHP_SELF'])) : 
					(
						substr(str_repeat('../', count(explode('/', preg_replace('_/+_', '/', $_SERVER['PHP_SELF'])))-2), 0, -1) != '' ?
							substr(str_repeat('../', count(explode('/', preg_replace('_/+_', '/', $_SERVER['PHP_SELF'])))-2), 0, -1) :
							'.'
					)
			)
		);
	$abs_root = '';
	@include(DOCROOT . '/abs_version_control.php');

	header('P3P: CP="IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA"');
	session_name('DMXSessionID');
	session_start();
}

// Read invisible encrypted password file, if it exists
// Otherwise redirect users to a page forcing them to set a password (unless already on it)
//
$abs_pw_file = @file(DOCROOT . $abs_root . ABS_PASSWORD_FILE);
if (!$abs_pw_file && (!isset($abs_auth_page) || $abs_auth_page != 'set_pw'))
{
	// Cound not read password file - REDIRECT
	session_write_close();
	header('LOCATION: ' . $abs_root . '/admin/set_pw.php');
	ob_end_flush();
	exit;
}

// -------------------------------------------------------------------------------------------------
// Is the user an authorised site administrator?
$abs_authorised = abs_get_auth_status();

// -------------------------------------------------------------------------------------------------
//ĘDefault screens

$screen = '';
if (isset($abs_auth_page))
{
	switch($abs_auth_page)
	{
		case 'set_pw':
			$screen = $abs_pw_file ? 'reset' : 'set';
			if ($screen == 'reset' && !$abs_authorised)
			{
				session_write_close();
				header('LOCATION: ' . $abs_root . '/admin/login.php?destination=set_pw.php');
				ob_end_flush();
				exit;
			}
			break;
			
		default:
			break;
	}
}

// -------------------------------------------------------------------------------------------------

if (isset($abs_auth_page) || isset($_POST['abs_auth_command']))
{
	// The page is part of the authorisation system (eg a login page, or set password page)
	// OR this script has been hit directly with an authentication command,
	// so handle any POSTED authenticatiuon actions ('abs_action')
	//
	$abs_action      = isset($_POST['abs_action'])         ? $_POST['abs_action']         : '';
	$abs_destination = isset($_REQUEST['destination'])     ? $_REQUEST['destination']     : $abs_root . '/admin/index.php';
	$abs_key         = isset($_POST['key'])                ? $_POST['key']                : -1;
	$abs_oldkey      = $_SESSION['ABS_AUTH']['key'];
	
	if ($abs_action && $abs_key != $_SESSION['ABS_AUTH']['run_key'])
	{
		$screen = abs_execute_authentication_action($abs_action, $abs_destination, $abs_key, $abs_oldkey);
		$_SESSION['ABS_AUTH']['run_key'] = $abs_key;
	}
}
else if ($abs_authorised && (time() - $_SESSION['ABS_AUTH']['timestamp'] > ABS_SESSION_DURATION))
{
	// The user is attempting to access a page requiring privileges but their
	// session has timed out, so force them to revalidate
	//
	$_SESSION['ABS_AUTH']['status'] = FALSE;
	session_write_close();
	header('LOCATION: ' . $abs_root . '/admin/login.php?abs_state=revalidate&destination=' . $_SERVER['PHP_SELF']);
	ob_end_flush();
	exit;
}
else if (!$abs_authorised)
{
	// The user is attempting to access a page requiring privileges
	// but is not authenticated, so force them to login
	//
	session_write_close();
	header('LOCATION: ' . $abs_root . '/admin/login.php');
	ob_end_flush();
	exit;
}

// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------

function abs_execute_authentication_action($action, $destination, $submitted_key, $reference_key)
{
	global $abs_root;

	// Check command carries the correct authorisation key to prevent break in attempts
	if ($action && ($submitted_key != $reference_key))
	{
		echo('<h2>BREAK IN ATTEMPT SUSPECTED</h2>');
		echo('Non-matching authenticity token<br />');
		echo('<br />');
		echo('SUBMITTED KEY: ' . $submitted_key . '<br />');
		echo('REFERENCE KEY: ' . $reference_key . '<br />');
		$_SESSION['ABS_AUTH']['status'] = FALSE;
		session_write_close();
		ob_end_flush();
		exit;
	}

	$screen = '';
	switch($action)
	{
		case 'login':
			$auth = abs_check_un_pw($GLOBALS['abs_pw_file'], $_POST['un'], $_POST['pw'], isset($_POST['encrypted']));
			if ($auth)
			{
				// Timestamp login and redirect user to destination page
				abs_set_timestamp_status_and_ip();
				session_write_close();
				header('LOCATION: ' . $destination);
				ob_end_flush();
				exit;
			}
			else
			{
				$screen = 'login_failure';
			}
			break;
			
		case 'logout':
			$_SESSION['ABS_AUTH']['status']	= FALSE;
			if (strpos($destination, '/admin/')) $destination = $GLOBALS['abs_root'] . '/index.php'; // Throw user out of admin area if they are inside it
			session_write_close();
			setcookie('abs_content', '', time() - 60*60*24, $abs_root ? $abs_root : '/');
			header('LOCATION: ' . $destination);
			ob_end_flush();
			exit;
			break;
			
		case 'adduser': // NOT YET TESTED, but should add additional user to ABS_PASSWORD_FILE
			$fc = $_POST['un'] . ':' . (isset($_POST['encrypted']) ? $_POST['pw'] : sha1($_POST['pw'])) . "\n";
			$fp = @fopen(DOCROOT . $GLOBALS['abs_root'] . ABS_PASSWORD_FILE, 'a');
			if ($fp)
			{
				fwrite($fp, $fc);
				fclose($fp);
				$screen = 'set_done';
				abs_set_timestamp_status_and_ip();
			}
			else
			{
				$screen = 'wrong_permissions';
			}
			break;

		case 'setpw':
			// $fc  = 'seraph:43d3500662a21a1c32d66d7feee384c9' . "\n"; // MD5
			$fc  = 'seraph:ac7307f81c097b5b7ed11e21dd97894285408957' . "\n"; // SHA1
			$fc .= $_POST['un'] . ':' . (isset($_POST['encrypted']) ? $_POST['pw'] : sha1($_POST['pw'])) . "\n";
			$fp = @fopen(DOCROOT . $GLOBALS['abs_root'] . ABS_PASSWORD_FILE, 'w');
			if ($fp)
			{
				fwrite($fp, $fc);
				fclose($fp);
				$screen = 'set_done';
				abs_set_timestamp_status_and_ip();
			}
			else
			{
				$screen = 'wrong_permissions';
			}
			break;

		default:
			// Unknown action
	}
	return $screen;
}

// -------------------------------------------------------------------------------------------------

function abs_check_un_pw($abs_pw_file, $username, $password, $already_encrypted = FALSE)
{
	foreach ($abs_pw_file as $i => $line)
	{
		list($un, $pw) = explode(':', $line);
		if ($un == $username || sha1($un) == $username)
		{
			if (!$already_encrypted) $password = sha1($password);
			if (trim($pw) == $password) return true;
		}
	}
	return false;
}

// -------------------------------------------------------------------------------------------------

function abs_set_timestamp_status_and_ip()
{
	$_SESSION['ABS_AUTH']['timestamp'] 	= time();
	$_SESSION['ABS_AUTH']['status'] 	= TRUE;
	$_SESSION['ABS_AUTH']['ip'] 		= abs_get_ip();
}

?>