From 0deff130c6d7404da71e9ab9d8ee738112bd4f74 Mon Sep 17 00:00:00 2001
From: Florian Schaal <florian@schaal-24.de>
Date: Fri, 05 Jun 2015 10:47:18 -0400
Subject: [PATCH] add mailfilter to resync

---
 interface/lib/classes/tform_base.inc.php |   76 +++++++++++++++++++++++++++++++++++--
 1 files changed, 71 insertions(+), 5 deletions(-)

diff --git a/interface/lib/classes/tform_base.inc.php b/interface/lib/classes/tform_base.inc.php
index 9fbd530..104217d 100644
--- a/interface/lib/classes/tform_base.inc.php
+++ b/interface/lib/classes/tform_base.inc.php
@@ -414,6 +414,30 @@
 		if(!is_array($this->formDef)) $app->error("No form definition found.");
 		if(!is_array($this->formDef['tabs'][$tab])) $app->error("The tab is empty or does not exist (TAB: $tab).");
 
+		/* CSRF PROTECTION */
+		// generate csrf protection id and key
+		$_csrf_id = uniqid($this->formDef['name'] . '_');
+		$_csrf_value = sha1(uniqid(microtime(true), true));
+		if(!isset($_SESSION['_csrf'])) $_SESSION['_csrf'] = array();
+		if(!isset($_SESSION['_csrf_timeout'])) $_SESSION['_csrf_timeout'] = array();
+		$_SESSION['_csrf'][$_csrf_id] = $_csrf_value;
+		$_SESSION['_csrf_timeout'][$_csrf_id] = time() + 3600; // timeout hash in 1 hour
+		$this->formDef['tabs'][$tab]['fields']['_csrf_id'] = array(
+			'datatype' => 'VARCHAR',
+			'formtype' => 'TEXT',
+			'default' => $_csrf_id,
+			'value' => $_csrf_id
+		);
+		$this->formDef['tabs'][$tab]['fields']['_csrf_key'] = array(
+			'datatype' => 'VARCHAR',
+			'formtype' => 'TEXT',
+			'default' => $_csrf_value,
+			'value' => $_csrf_value
+		);
+		$record['_csrf_id'] = $_csrf_id;
+		$record['_csrf_key'] = $_csrf_value;
+		/* CSRF PROTECTION */
+		
 		$new_record = array();
 		if($action == 'EDIT') {
 			$record = $this->decode($record, $tab);
@@ -447,7 +471,7 @@
 						if(is_array($field['value'])) {
 							foreach($field['value'] as $k => $v) {
 								$selected = ($k == $val)?' SELECTED':'';
-								if(!empty($this->wordbook[$v]))
+								if(isset($this->wordbook[$v]))
 									$v = $this->wordbook[$v];
 								$out .= "<option value='$k'$selected>".$this->lng($v)."</option>\r\n";
 							}
@@ -669,8 +693,50 @@
 	 */
 	protected function _encode($record, $tab, $dbencode = true, $api = false) {
 		global $app;
-		if($api == true) $fields = &$this->formDef['fields'];
-		else $fields = &$this->formDef['tabs'][$tab]['fields'];
+		if($api == true) {
+			$fields = &$this->formDef['fields'];
+		} else {
+			$fields = &$this->formDef['tabs'][$tab]['fields'];
+			/* CSRF PROTECTION */
+			if(isset($_POST) && is_array($_POST)) {
+				$_csrf_valid = false;
+				if(isset($_POST['_csrf_id']) && isset($_POST['_csrf_key'])) {
+					$_csrf_id = trim($_POST['_csrf_id']);
+					$_csrf_key = trim($_POST['_csrf_key']);
+					if(isset($_SESSION['_csrf']) && isset($_SESSION['_csrf'][$_csrf_id]) && isset($_SESSION['_csrf_timeout']) && isset($_SESSION['_csrf_timeout'][$_csrf_id])) {
+						if($_SESSION['_csrf'][$_csrf_id] === $_csrf_key && $_SESSION['_csrf_timeout'] >= time()) $_csrf_valid = true;
+					}
+				}
+				if($_csrf_valid !== true) {
+					$app->log('CSRF attempt blocked. Referer: ' . (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : 'unknown'), LOGLEVEL_WARN);
+					$errmsg = 'err_csrf_attempt_blocked';
+					$this->errorMessage .= ($api == true ? $errmsg : $this->wordbook[$errmsg]."<br />") . "\r\n";
+					unset($_POST);
+					unset($record);
+				}
+				$_SESSION['_csrf'][$_csrf_id] = null;
+				$_SESSION['_csrf_timeout'][$_csrf_id] = null;
+				unset($_SESSION['_csrf'][$_csrf_id]);
+				unset($_SESSION['_csrf_timeout'][$_csrf_id]);
+				
+				if(isset($_SESSION['_csrf_timeout']) && is_array($_SESSION['_csrf_timeout'])) {
+					$to_unset = array();
+					foreach($_SESSION['_csrf_timeout'] as $_csrf_id => $timeout) {
+						if($timeout < time()) $to_unset[] = $_csrf_id;
+					}
+					foreach($to_unset as $_csrf_id) {
+						$_SESSION['_csrf'][$_csrf_id] = null;
+						$_SESSION['_csrf_timeout'][$_csrf_id] = null;
+						unset($_SESSION['_csrf'][$_csrf_id]);
+						unset($_SESSION['_csrf_timeout'][$_csrf_id]);
+					}
+					unset($to_unset);
+				}
+			}
+			/* CSRF PROTECTION */
+		}
+		
+		$new_record = array();
 		if(is_array($record)) {
 			foreach($fields as $key => $field) {
 
@@ -710,7 +776,7 @@
 					if($record[$key] != '' && $record[$key] != '0000-00-00') {
 						if(function_exists('date_parse_from_format')) {
 							$date_parts = date_parse_from_format($this->dateformat, $record[$key]);
-							$new_record[$key] = $date_parts['year'].'-'.$date_parts['month'].'-'.$date_parts['day'];
+							$new_record[$key] = $date_parts['year'].'-'.str_pad($date_parts['month'], 2, "0", STR_PAD_LEFT).'-'.str_pad($date_parts['day'], 2, "0", STR_PAD_LEFT);
 						} else {
 							$tmp = strtotime($record[$key]);
 							$new_record[$key] = date('Y-m-d', $tmp);
@@ -881,7 +947,7 @@
 				}
 				break;
 			case 'NOTEMPTY':
-				if(empty($field_value)) {
+				if(!isset($field_value) || $field_value === '') {
 					$errmsg = $validator['errmsg'];
 					if(isset($this->wordbook[$errmsg])) {
 						$this->errorMessage .= $this->wordbook[$errmsg]."<br />\r\n";

--
Gitblit v1.9.1