<?php
define("MAX_HOUR_USAGE", "50");
define("ASCII_TO_STRIP", "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0c\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e");
define("ASCII_REPLACEMENT", "                             ");


require 'include.php';


// Define language to be used
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
	$langue = strtolower(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2));
else $langue="en";

// Use this global in displayed, so it is evaluated as the constant() function and
// allow us to retrieved one of our constant message in displayed text
$GLOBALS['get_string'] = "constant";

if(isset($langue) && $langue=="en") { 
	define("STRING_ERR_QUERY_FAILED" 	, "number_of_access() query failed");
	define("STRING_PAGE_TITLE"			, "VERIFROM: send a test email");
	define("STRING_LEGEND"				, "Send an email to test VERIFROM");
	define("STRING_YOUR_NAME"			, "Your name:");
	define("STRING_YOUR_EMAIL"			, "Your email address:");
	define("STRING_RECIPIENT_EMAIL"		, "Recipient's email address:");
	define("STRING_YOUR_MESSAGE"		, "Your message:");
	define("STRING_MSG_SENT"			, "Your email has been sent. It should arrived in a few minutes.");
	define("STRING_BACK_TO_VERIFROM"	, "Back to verifrom.com.");
	define("STRING_ERR_FILL_THIS_FIELD" , "please fill this field");
	define("STRING_ERR_EMAIL_FORMAT"	, "incorrect email address format");
	define("STRING_ERR_TECHNICAL"		, "Something went wrong, try again later.");
	define("STRING_ERR_QUOTA"			, "Mail quota reached, please try again in 1 hour.");
	define("STRING_MAIL_SUBJECT"		, "Subject: Test email from VERIFROM");
	define("STRING_MAIL_INTRO"			, "sent you this email from WWW.VERIFROM.COM :");
	define("STRING_MAIL_SEND"			, "Send Email");
} else {
	// default
	define("STRING_ERR_QUERY_FAILED" 	, "échec vérification quota");
	define("STRING_PAGE_TITLE"			, "VERIFROM: envoyer un message de test");
	define("STRING_LEGEND"				, "Envoyer un message de test VERIFROM");
	define("STRING_YOUR_NAME"			, "Votre nom:");
	define("STRING_YOUR_EMAIL"			, "Votre adresse email:");
	define("STRING_RECIPIENT_EMAIL"		, "Adresse email du destinataire:");
	define("STRING_YOUR_MESSAGE"		, "Votre message:");
	define("STRING_MSG_SENT"			, "Votre message a été envoyé. Il devrait parvenir à son destinataire dans quelques minutes.");
	define("STRING_BACK_TO_VERIFROM"	, "Retour à verifrom.com.");
	define("STRING_ERR_FILL_THIS_FIELD" , "champ à compléter");
	define("STRING_ERR_EMAIL_FORMAT"	, "format d'adresse incorrect");
	define("STRING_ERR_TECHNICAL"		, "Problème technique, ré-essayez plus tard.");
	define("STRING_ERR_QUOTA"			, "Nombre maximum de mails envoyés atteint. Essayez à nouveau dans 1 heure.");
	define("STRING_MAIL_SUBJECT"		, "Subject: Mail de test VERIFROM");
	define("STRING_MAIL_INTRO"			, "vous a envoyé cet email depuis WWW.VERIFROM.COM :");
	define("STRING_MAIL_SEND"			, "Envoyer");
} 




/**
 * Record IP access in the IPVELOCITY table
 * @param  mysqli $mysqli  Active mysqli class for database connection
 * @param  string $ip_addr IP address to be logged. Must have been sanitized before calling
 *                         this function.
 */
function record_ip_access($mysqli, $ip_addr)
{
	try {
		$query = sprintf("INSERT INTO ipvelocity (ip) VALUES(\"%s\")", $ip_addr);
		if($mysqli->query($query)===FALSE)
			throw new Exception(STRING_ERR_QUERY_FAILED);
	} catch (Exception $e) { 
    	throw $e;
    } 
}


/**
 * Return the number of access attempts for a given IP address in the last $seconds
 * @param  mysql $mysqli  Active mysql class for database connection.
 * @param  string $ip_addr IP address for which we are looking for the number of acess
 * @param  string $seconds delay in seconds
 * @return string          number of access recorded for $ip_addr in the last $seconds
 */
function number_of_access($mysqli, $ip_addr, $seconds)
{
	try {
		// Query the IPVELOCITY table
		$query = sprintf("SELECT COUNT(*) FROM ipvelocity WHERE ip=\"%s\" AND TIMESTAMPDIFF(second, time, now())<%s", 
			$ip_addr, $seconds);
		$result_query = $mysqli->query($query);
		if($result_query===FALSE)
			throw new Exception();

		// Read data from database
		$row = $result_query->fetch_row();

		$result_query->close();

		return($row==NULL ? 0 : $row[0]);

	} catch (Exception $e) { 
    	throw $e;
    } 
}



function reset_global_variables()
{
	global $sender_name_value, $sender_name_error, $sender_addr_value, $sender_addr_error,
	$dest_addr_value, $dest_addr_error, $msg_text_value, $msg_text_error, $error;

	$sender_name_value = "";
	$sender_name_error = "&nbsp;";
	$sender_addr_value = "";
	$sender_addr_error = "&nbsp;";
	$dest_addr_value   = "";
	$dest_addr_error   = "&nbsp;";
	$msg_text_value    = "";
	$msg_text_error    = "&nbsp;";
	$error             = FALSE;
}







function display_header()
{
echo <<<__END
<head>
	<meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <link rel="icon" href="favicon.ico" type="image/x-icon" />
    <link href="apple-touch-icon-76x76.png" rel="apple-touch-icon" sizes="76x76" />
    <link href="apple-touch-icon-120x120.png" rel="apple-touch-icon" sizes="120x120" />
    <link href="apple-touch-icon-152x152.png" rel="apple-touch-icon" sizes="152x152" />
    <link href="apple-touch-icon-192x192.png" rel="apple-touch-icon" sizes="192x192" />
    <meta id="viewport" name="viewport" content="width=600" />
    <meta name="format-detection" content="telephone=no">

    <!-- Bootstrap Core CSS -->
    <link href="css/bootstrap.min.css" rel="stylesheet" type="text/css">
    <!-- Fonts -->
    <link href="font-awesome/css/font-awesome.min.css" rel="stylesheet" type="text/css"/>
	<link href="css/animate.css" rel="stylesheet" type="text/css"/>
    <!-- Squad theme CSS -->
    <link href="css/style.css" rel="stylesheet" type="text/css"/>
	<link href="color/default.css" rel="stylesheet" type="text/css"/>

	<script type='text/javascript' src='https://code.jquery.com/jquery-1.11.2.min.js'></script>
    <!-- Core JavaScript Files -->
    <script src="js/jquery.min.js"></script>
    <script src="js/bootstrap.min.js"></script>
    <script src="js/jquery.easing.min.js"></script>	
	<script src="js/jquery.scrollTo.js"></script>
	<script src="js/wow.min.js"></script>
    <!-- Custom Theme JavaScript -->
    <script src="js/custom.js"></script>

    <title>{$GLOBALS['get_string']('STRING_PAGE_TITLE')}</title>
	<style>
		body {
			background-color: #15B7FF;
			/*text-align: center;*/
			font-family: Verdana, Geneva, sans-serif;
			color: white;
		}
		table { 
			margin: auto; 
			table-layout: fixed;
		}
		a:link {
    		/*text-decoration: none;*/
    		color: white;
		}
		a:visited {
    		/*text-decoration: none;*/
    		color: white;
		}	
		form {
			max-width: 600px;
			display:block; 
			margin-left:auto; 
			margin-right:auto;
		}
		legend {
			font-size: 120%;
			font-weight: bold;
		}
		label {
			 margin-top:5px;
			 margin-left:3%;
			 display:block;
		}
		input, textarea {
		 	width: 95%;
		 	font-family: Verdana, Geneva, sans-serif;	
		 	font-size: 100%;
		}
		input[type=submit], input[type=reset] {
			-webkit-appearance: none;
		 	width: auto;
		 	display: inline;
		 	margin-left: auto;
		 	margin-right: auto;
		 	font-family: Verdana, Geneva, sans-serif;	
		 	font-size: 100%;
			-moz-box-shadow: 2px 2px 0px 1px #045190;
			-webkit-box-shadow: 2px 2px 0px 1px #045190;
			box-shadow: 2px 2px 0px 1px #045190;
			background-color:#08619c;
			-moz-border-radius:6px;
			-webkit-border-radius:6px;
			border-radius:6px;
			border:1px solid #29668f;
			cursor:pointer;
			color:#ffffff;
			font-weight:bold;
			padding:10px 20px;
			text-decoration:none;
			text-shadow:0px 1px 0px #3d768a;
		}
		input[type=submit]:hover, input[type=reset]:hover {
			background-color:#08619c;
		}
		input[type=submit]:active, input[type=reset]:active {
			position:relative;
			top:1px;
		}
		p {
		 	text-align: center;
		}
		.error {
			color: red;
			font-family: "Times New Roman", Georgia, Serif;
			font-style: italic;
			font-weight: normal;
			font-size: 90%;
			margin-left: 5%;
		}
	</style>
</head>
__END;

}


function display_form() 
{
	global $sender_name_value, $sender_name_error, $sender_addr_value, $sender_addr_error,
		$dest_addr_value, $dest_addr_error, $msg_text_value, $msg_text_error;

	$value = bin2hex(openssl_random_pseudo_bytes(32));
	$_SESSION['form_testemail_token'] = $value;
	$_SESSION['form_testemail_time'] = time();

echo "<!DOCTYPE html><html>";

display_header();

echo <<<__END
<body>
<div class="container">
	        <div class="row">
	            <div class="col-sm-12 col-md-12">
	                <div class="service-box">
						<div class="service-desc text-center">
						<p class="bg-primary"><H4>Formulaire à remplir pour recevoir un email de test de VERIFROM :</H4></p>
						</div>
					</div>
				</div>
	        </div>

      <div class="row">
      <div class="col-sm-12 col-md-12" role="main">
	<form method="post" action="testemail2.php" class="form-horizontal">
			<div class="form-group">
		    <label for="sender_name" class="col-sm-4 control-label">{$GLOBALS['get_string']('STRING_YOUR_NAME')}</label>
    		<div class="col-sm-7"><input type="text" class="form-control" name="sender_name" required id="sender_name" placeholder="$sender_name_value"></div>
			</div>
			<div class="form-group">
		    <label for="sender_addr" class="col-sm-4 control-label">{$GLOBALS['get_string']('STRING_YOUR_EMAIL')}</label>
    		<div class="col-sm-7"><input type="email" class="form-control" name="sender_addr" required id="sender_addr" placeholder="$sender_addr_value"></div>
			</div>
			<div class="form-group">
		    <label for="dest_addr" class="col-sm-4 control-label">{$GLOBALS['get_string']('STRING_RECIPIENT_EMAIL')}</label>
    		<div class="col-sm-7"><input type="email" class="form-control" name="dest_addr" required id="dest_addr" placeholder="$dest_addr_value"></div>
			</div>
			<div class="form-group">
		    <label for="msg_text" class="col-sm-4 control-label">{$GLOBALS['get_string']('STRING_YOUR_MESSAGE')}</label>
			<div class="col-sm-7"><textarea name="msg_text" id ="msg_text" required rows="6" maxlength="1000" class="form-control">$msg_text_value</textarea></div>
			</div>
			<div class="form-group">
			    <div class="col-sm-offset-6 col-sm-6">
			      <button type="submit" class="btn btn-default" value="Envoyer">{$GLOBALS['get_string']('STRING_MAIL_SEND')}</button>
			    </div>
			</div>
			<input type="hidden" name="value" value="$value">
	</form>

	</div></div></div>
__END;

/*			<!--<label>{$GLOBALS['get_string']('STRING_YOUR_NAME')}<br><input type="text" name="sender_name" required value="$sender_name_value" /></label>
			<div class="error">$sender_name_error</div>
			<label>{$GLOBALS['get_string']('STRING_YOUR_EMAIL')}<br><input type="email" name="sender_addr" required value="$sender_addr_value" /></label>
			<div class="error">$sender_addr_error</div>
			<label>{$GLOBALS['get_string']('STRING_RECIPIENT_EMAIL')}<br><input type="email" name="dest_addr" required value="$dest_addr_value" /></label>
			<div class="error">$dest_addr_error</div>
			<label>{$GLOBALS['get_string']('STRING_YOUR_MESSAGE')}<br><textarea name="msg_text" required rows="6" maxlength="1000">$msg_text_value</textarea></label>
			<div class="error">$msg_text_error</div>
					 <p>
			 <input type="submit" value="Envoyer" />
		</p>-->*/

display_google_analytics();

echo "</body>";

exit;
}


function display_ok()
{
	echo "<!DOCTYPE html><html>";

display_header();


echo <<<__END
<body>

	<img src="VERIFROM-logo-400x400.png" alt="logo VERIFROM" width="20%" style="display:block; margin-left:auto; margin-right:auto; max-width:200px; min-width:100px">

	<br>

	<p>
		{$GLOBALS['get_string']('STRING_MSG_SENT')}
	</p>

__END;
display_google_analytics();

echo "</body>";

	$_POST = array();
}


function display_ko($msg)
{
	echo "<!DOCTYPE html><html>";

display_header();

echo <<<__END
<body>

	<img src="VERIFROM-logo-400x400.png" alt="logo VERIFROM" width="20%" style="display:block; margin-left:auto; margin-right:auto; max-width:200px; min-width:100px">

	<br>

	<p style="color:red;">
		$msg
	</p>

__END;
display_google_analytics();

echo "</body>";
}



/*
	MAIN
 */


// Use ssession to store an access token and form age (in seconds)
session_start();

// Initialize global variables used to store form values and error messages
reset_global_variables();

// If no values returned or some error conditions, display an empty form 
// to be filled by the user
if(    !isset($_SERVER['REMOTE_ADDR'])
	|| !filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP) 
	|| empty($_POST)
	|| !isset($_POST['value'])
	|| !isset($_SESSION['form_testemail_token']))
	display_form();

// Check the accesse token hidden in form matches the last token we stored for 
// this session
if($_POST['value']!==$_SESSION['form_testemail_token']) {
	error_log("testemail.php: token in form does not match token in session");
	display_form();
}

// Debug
// if(isset($_POST['sender_name'])) error_log("sender_name=".$_POST['sender_name']);
// if(isset($_POST['msg_text']))    error_log("msg_text=".$_POST['msg_text']);
// if(isset($_POST['sender_addr'])) error_log("sender_addr=".$_POST['sender_addr']);
// if(isset($_POST['dest_addr']))   error_log("dest_addr=".$_POST['dest_addr']);

// Copy form values so we can reused them if the form has to be displayed again
if(isset($_POST['sender_name'])) $sender_name_value = $_POST['sender_name'];
if(isset($_POST['msg_text']))    $msg_text_value = $_POST['msg_text'];
if(isset($_POST['sender_addr'])) $sender_addr_value = $_POST['sender_addr'];
if(isset($_POST['dest_addr']))   $dest_addr_value = $_POST['dest_addr'];

// Check the form has been well filled
if(!isset($_POST['sender_name']) || $_POST['sender_name']=="") {
	$error = TRUE;
	// $sender_name_error = "à compléter";	
	$sender_name_error = STRING_ERR_FILL_THIS_FIELD;	
}
if(!isset($_POST['msg_text']) || $_POST['msg_text']=="") {
	$error = TRUE;
	// $msg_text_error = "à compléter";	
	$msg_text_error = STRING_ERR_FILL_THIS_FIELD;;	
}
if(!isset($_POST['sender_addr']) || $_POST['sender_addr']=="") {
	$error = TRUE;
	// $sender_addr_error = "à compléter";	
	$sender_addr_error = STRING_ERR_FILL_THIS_FIELD;;	
}
if(!isset($_POST['dest_addr']) || $_POST['dest_addr']=="") {
	$error = TRUE;
	// $dest_addr_error = "à compléter";	
	$dest_addr_error = STRING_ERR_FILL_THIS_FIELD;;	
}
if(isset($_POST['sender_addr']) && $_POST['sender_addr']!="" && !filter_var(trim($_POST['sender_addr']), FILTER_VALIDATE_EMAIL)) {
	$error = TRUE;
	// $sender_addr_error = "format incorrect";	
	$sender_addr_error = STRING_ERR_EMAIL_FORMAT;	
}
if(isset($_POST['dest_addr']) && $_POST['dest_addr']!="" && !filter_var(trim($_POST['dest_addr']), FILTER_VALIDATE_EMAIL)) {
	$error = TRUE;
	// $dest_addr_error = "format incorrect";	
	$dest_addr_error = STRING_ERR_EMAIL_FORMAT;	
}

// If there is an error in the values posted, display the form again with 
// original values and error messages
if($error)
	display_form();

// Form is OK, now check for IP velocity
try {
	$mysqli = database_Connect();
	if($mysqli==NULL)
		// throw new Exception("Erreur technique, réessayez plus tard.");
		throw new Exception(STRING_ERR_TECHNICAL);
	if(number_of_access($mysqli, $_SERVER['REMOTE_ADDR'], 3600) >= MAX_HOUR_USAGE)
		// throw new Exception("Quota d'envoi atteint, réessayez dans 1 heure.");	
		throw new Exception(STRING_ERR_QUOTA);	
	record_ip_access($mysqli, $_SERVER['REMOTE_ADDR']);
	$mysqli->close();
	$mysqli = NULL;
} catch (Exception $e) {
	error_log("testemail.php: ".$e->getMessage());
	display_ko($e->getMessage());
	if(isset($mysqli) && $mysqli)
		$mysqli->close();	
	exit;
}

// Check the form is several seconds old. If not, it means it has probably 
// been activated by a robot
if(isset($_SESSION['form_testemail_time'])) {
	$age = time() - $_SESSION['form_testemail_time'];
	if($age<5) {
		error_log("testemail.php: form fill too quick");
		reset_global_variables();	// make sure form is empty
		display_form();
	}
}

// Sanitize received contents against injection threats
$sender_name = filter_var(trim($_POST['sender_name']), FILTER_DEFAULT, FILTER_FLAG_STRIP_LOW);
$msg_text    = filter_var(trim($_POST['msg_text']), FILTER_DEFAULT); 
$dest_addr   = filter_var(trim($_POST['dest_addr']), FILTER_SANITIZE_EMAIL);
$sender_addr = filter_var(trim($_POST['sender_addr']), FILTER_SANITIZE_EMAIL);
$msg_text    = strtr($msg_text, ASCII_TO_STRIP, ASCII_REPLACEMENT);
$sender_name = strtr($sender_name, ASCII_TO_STRIP, ASCII_REPLACEMENT);
$msg_text    = strip_tags($msg_text);
$sender_name = strip_tags($sender_name);

// Send email using ssmtp, and limit email content to 1000 characters
$handler = popen("/usr/sbin/ssmtp ".$dest_addr, "w");
if($handler==FALSE)
	throw new Exception("cannot popen() to ssmtp");
fwrite($handler, STRING_MAIL_SUBJECT."\n");
fwrite($handler, "From: ".$sender_name." <test@".DOMAIN.">\n");
fwrite($handler, "To: ".$dest_addr."\n");
fwrite($handler, "Reply-To: ".$sender_addr."\n");
fwrite($handler, "Return-Path: ".$sender_addr."\n");
fwrite($handler, "Sender: ".$sender_addr."\n\n");
// fwrite($handler, $sender_name." (".$sender_addr.") vous a envoyé ce message depuis WWW.VERIFROM.COM :\n\n");
fwrite($handler, $sender_name." (".$sender_addr.") ".STRING_MAIL_INTRO."\n\n");
fwrite($handler, $msg_text, 1000);
pclose($handler);

// Log email sent
error_log("testemail.php: "."From: ".$sender_name." <".$sender_addr.">; "
	."To: ".$dest_addr."; ".$msg_text);

// Make the send longer than needed to limit massive sendings attacks
sleep(2);

// Confirm sending is OK and quit. 
display_ok();
exit;


?>


