<?php
###############################################################################
# custom.login.duo-samplephp
# Duo 2FA for Watch My Domains SED v3
#
# Author: Anil Kumar
# CodePunch Solutions
# https://codepunch.com/
#
# Copy this file to the installation root folder, rename it to custom.login.php
# and specify the two key values plus the duo_host_name to enable Duo 2FO.
###############################################################################

# Create this key yourself (minimum 40 characaters long) and keep it a secret.

$duo_application_key = "CREATEYOUROWNSECRETKEYHEREANDKEEPITSECRET";

# Get these three from the Duo Security admin panel for the Application.

$duo_integration_key = "";
$duo_secret_key      = "";
$duo_host_name       = "";

###############################################################################

define("USE_AUTH_DB","TRUE");

###############################################################################

require_once("lib/php/basic.php");				# Base Functions.
require_once("lib/php/ui/ui.php");				# UI Functions.
require_once("lib/php/pdo/dbinit.php");			# Database
require_once("lib/php/config.check.php");		# Load the configuration.

###############################################################################

$auth = validateSession();
if($auth == 0)
	interfaceRedir();

###############################################################################

require_once("thirdparty/duo/Web.php");

###############################################################################

$login_error = "";

###############################################################################

if (isset($_POST['sig_response'])) 
{
	DuoSignIn($_POST['sig_response']);
}
else if(isset($_POST['ui-user']) && isset($_POST['ui-password'])) 
{
	$username = strip_tags(trim($_REQUEST['ui-user']));
	$password = strip_tags(trim($_REQUEST['ui-password']));
	$login_error = "";
	$login_fail_count = 0;
	$last_login_fail_at = date("Y-m-d H:i:s");
	$returnurl = false;
	
	$user = getConfigData('admin_user_name', "");
	$pass = getConfigData('admin_password', "");
	
	global $db_default_mysql_engine;
	$max_login_attempts = get_config_data('max_login_attempts');
	$login_lockout_minutes = get_config_data('login_lockout_minutes');
	
	$pdo = init_db();
	if(isUserAuthEnabled() && $login_error == "" && $username != "" && $password != "")
	{
		$failcount = $pdo->getSingleEntry($pdo->auth_log_table, "ip", $_SERVER['REMOTE_ADDR'], "login_fail_count");
		if($failcount !== false);
			$login_fail_count = $failcount;
		$failtime = $pdo->getSingleEntry($pdo->auth_log_table, "ip", $_SERVER['REMOTE_ADDR'], "login_last_failed_at");
		if($failtime !== false)
		{
			if(isADate($failtime))
				$last_login_fail_at = $failtime;
		}
		
		$allow_logins = true;
		$maxlogins = 0;
		$lockout = 5;
		if(isset($max_login_attempts))
			$maxlogins = $max_login_attempts;
		if(isset($login_lockout_minutes))
			$lockout = $login_lockout_minutes;
		if($lockout <= 0)
			$lockout = 30*24*60;
		$unblock_minutes = $lockout;
		if($maxlogins > 0 && $login_fail_count >= $maxlogins)
		{
			$allow_logins = false;
			$timegap = intval((time()-strtotime($last_login_fail_at))/60);
			if($timegap >= $lockout && $lockout > 0)
				$allow_logins = true;
			else
				$unblock_minutes = $lockout-$timegap;
		}
		
		if($allow_logins)
		{
			# if salted and hashed
			if(strlen($pass) > 25)
				$admpassword = generateHash($password, $pass);
			else
				$admpassword = $password;

			if($user == $username && $pass == $admpassword && strlen($pass) >= 6)
			{
				$pdo->addAuthLog(true);
				$userinfo['uid'] = 0;
				$userinfo['admin'] = true;
				$userinfo['name'] = $username;
				$userinfo['readwrite'] = 1;
				$userinfo['fullname'] = "System Admin";
				$userinfo['displayname'] = "System Admin [c]";
				$userinfo['lastsignin'] = date("Y-m-d H:i:s");
				$returnurl = $pdo->doLogin($userinfo);
				if($returnurl !== false)
					showDuoAuthentication($username, $returnurl);
			}
			else 
			{
				$returnurl = checkUserLogin($pdo, $username, $password);
				if($returnurl !== false)
					showDuoAuthentication($username, $returnurl);
			}
			if($returnurl === false)
			{
				# Login has failed.
				$login_fail_count++;
				$login_error = "Incorrect Login or Password";
				if($login_fail_count)
				{
					$login_error .= " (";
					$login_error .= $login_fail_count;
					if($maxlogins > 0)
						$login_error .= "/" . $maxlogins;
					$login_error .= ")";
				}
			}
		}
		else
			$login_error = "Temporarily blocked for " . $unblock_minutes . " minutes. Too many failed attempts!";
	}
}

###############################################################################

function showDuoAuthentication($username, $returnurl)
{
	$_SESSION['logged'] = false;
	$_SESSION['duser'] = $username;
	$_SESSION['url'] = $returnurl;
	$logoimage = getConfigData('main_logo_image', '');
	if($logoimage == "")
		$logoimage = "lib/css/images/logo-small-dark.png";
	global $duo_host_name, $duo_integration_key, $duo_secret_key, $duo_application_key;
	$sig_request = Duo\Web::signRequest($duo_integration_key, $duo_secret_key, $duo_application_key, $username);
?>
<html>
<head></head>
<body>
<script type="text/javascript" src="<?php echo get_root_url(); ?>thirdparty/duo/Duo-Web-v2.min.js"></script>
<link rel="stylesheet" type="text/css" href="<?php echo get_root_url(); ?>thirdparty/duo/Duo-Frame.css">
<p><img id="loginlogo" src="<?php echo $logoimage; ?>" class="logo" alt="Watch My Domains SED v3"></p>
<iframe id="duo_iframe"
	data-host="<?php echo $duo_host_name; ?>"
	data-sig-request="<?php echo $sig_request; ?>">
</iframe>
	<p class="footer">Watch My Domains Server Edition
<?php
	$phppath = get_php_folder_path();		
	require_once($phppath . "version.php");
	if(function_exists('get_version'))
	{
		echo '&nbsp;' . get_version() . '.&nbsp;';
		echo '<br>Build: ' . get_build_date();
	}
?>
	</p>
</body>
</html>
<?php
	exit;
}

###############################################################################

function DuoSignIn($sigresponse)
{
	global $duo_integration_key, $duo_secret_key, $duo_application_key;
	$resp = Duo\Web::verifyResponse($duo_integration_key, $duo_secret_key, $duo_application_key, $sigresponse);
    if($resp === $_SESSION['duser']) 
	{
		$_SESSION['logged'] = true;
		header('Location:' . $_SESSION['url']) ;
		exit;
    }
	show_message("Unknown Error");
	exit;
}

###############################################################################

$loginmsg = $login_error;
$extracss = "";
if(isset($_REQUEST['r']))
{
	$loginmsg = filter_var($_REQUEST['r'], FILTER_SANITIZE_STRING);
	if($loginmsg == "timeout")
	{
		$loginmsg = "session timed out";
		doAuditLog(AUDIT_SESSION_TIMEOUT, "Session timedout for " . getUserName());
	}
	else if($loginmsg == "badsession")
		$loginmsg = "invalid session or session timed out";
	$extracss = "";
}
if(isset($_REQUEST['redir']))
{
	$redir = $_REQUEST['redir'];
	if(isValidApp($redir))
		$_SESSION['redir'] = $redir;
}

$phppath = get_php_folder_path();		
require_once($phppath . "version.php");
$layoutpath = get_layout_folder_path();
require_once($layoutpath . "head.inc.php");
echo "<body>\n";

###############################################################################

?>
<div id="header"></div>
<div id="content">
	<div class="container-fluid">
		<div class="row">
			<div class="col-xs-12 main">
				<div id="content">
					<div class="container-fluid">
						<div class="row">
							<div class="col-xs-12">
								<p class="text-center"><a href="menu.php"><img id="loginlogo" src="lib/css/images/logo-small.png" class="img-responsive logo" alt="Watch My Domains SED v3"></a></p>
							</div>
						</div>
						<div class="row lgbox">
							<div class="col-sm-1"></div>
							<div class="col-sm-10 loginbg text-center">
								<div class="loginbox">
									<form action='<?php echo get_root_url(); ?>custom.login.php' method='post'>
										<input type="text" name="ui-user" class="form-control" placeholder="Username" required autofocus>
										<input type="password" name="ui-password" class="form-control" placeholder="Password" required>
										<hr>
										<input type='submit' class="btn btn-primary btn-block" value='Submit'>
										<div class="loginmsg"<?php echo $extracss; ?>>
											<br>
											<p class="text-danger bg-danger" id="login-message" style="margin-bottom:0;">
											<?php echo $loginmsg; ?>
											</p>
										</div>
									</form>
								</div>
							</div>
							<div class="col-sm-1"></div>
						</div>
						<br>
						<div class="row">
							<div class="col-xs-12">
								<p class="text-center">
								Watch My Domains Server Edition
								<?php
									if(function_exists('get_version'))
									{
										echo '&nbsp;' . get_version() . '.&nbsp;(Duo)';
										echo '<br>Build: ' . get_build_date();
									}
								?>
								</p>
							</div>
						</div>
					</div>
				</div>

			</div>
		</div>
	</div>
</div>
<?php
	require_once($layoutpath . "bodytail.inc.php");
	echo "</body>\n</html>\n";
?>
