Browse Source

Use Redis for forwarded_hosts, some fixes

andryyy 8 years ago
parent
commit
74359f6df4

+ 17 - 22
data/web/admin.php

@@ -292,24 +292,25 @@ $tfa_data = get_tfa();
             </thead>
             </thead>
             <tbody>
             <tbody>
               <?php
               <?php
-              $forwarding_hosts = get_forwarding_hosts();
-              if ($forwarding_hosts) {
-                foreach ($forwarding_hosts as $host) {
+              $fwd_hosts = get_forwarding_hosts();
+              if (!empty($fwd_hosts)) {
+                foreach ($fwd_hosts as $host => $attr) {
                 ?>
                 ?>
                 <tr id="data">
                 <tr id="data">
-                  <td><?=htmlspecialchars(strtolower($host->host));?></td>
-                  <td><?=htmlspecialchars(strtolower($host->source));?></td>
+                  <td><?=htmlspecialchars($host);?></td>
+                  <td><?=htmlspecialchars($attr['source']);?></td>
+                  <td><?=($attr['keep_spam'] == "no") ? $lang['admin']['yes'] : $lang['admin']['no'];?></td>
                   <td style="text-align: right;">
                   <td style="text-align: right;">
                     <div class="btn-group">
                     <div class="btn-group">
-                      <a href="delete.php?forwardinghost=<?=$host->host;?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['admin']['remove'];?></a>
+                      <a href="delete.php?forwardinghost=<?=htmlspecialchars($host);?>" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> <?=$lang['admin']['remove'];?></a>
                     </div>
                     </div>
                   </td>
                   </td>
                   </td>
                   </td>
                 </tr>
                 </tr>
-
                 <?php
                 <?php
                 }
                 }
-              } else {
+              }
+              else {
               ?>
               ?>
                 <tr id="no-data"><td colspan="4" style="text-align: center; font-style: italic;"><?=$lang['admin']['no_record'];?></td></tr>
                 <tr id="no-data"><td colspan="4" style="text-align: center; font-style: italic;"><?=$lang['admin']['no_record'];?></td></tr>
               <?php
               <?php
@@ -321,24 +322,18 @@ $tfa_data = get_tfa();
         </form>
         </form>
         <legend><?=$lang['admin']['add_forwarding_host'];?></legend>
         <legend><?=$lang['admin']['add_forwarding_host'];?></legend>
         <p class="help-block"><?=$lang['admin']['forwarding_hosts_add_hint'];?></p>
         <p class="help-block"><?=$lang['admin']['forwarding_hosts_add_hint'];?></p>
-        <form class="form-horizontal" role="form" method="post">
-          <div class="form-group">
-            <label class="control-label col-sm-2" for="hostname"><?=$lang['edit']['host'];?>:</label>
-            <div class="col-sm-10">
-              <input type="text" class="form-control" name="hostname" id="hostname" required>
-            </div>
-          </div>
+        <form class="form-inline" role="form" method="post">
           <div class="form-group">
           <div class="form-group">
-            <label class="control-label col-sm-2" for="filter_spam"><?=$lang['user']['spamfilter'];?>:</label>
-            <div class="col-sm-10">
-              <input type="checkbox" class="form-control" name="filter_spam" id="filter_spam">
-            </div>
+            <label for="hostname"><?=$lang['edit']['host'];?></label>
+            <input class="form-control" id="hostname" name="hostname" placeholder="example.org" required>
           </div>
           </div>
           <div class="form-group">
           <div class="form-group">
-            <div class="col-sm-offset-2 col-sm-10">
-              <button type="submit" name="add_forwarding_host" class="btn btn-default"><?=$lang['admin']['add'];?></button>
-            </div>
+            <select data-width="200px" class="form-control" id="filter_spam" name="filter_spam" title="<?=$lang['user']['spamfilter'];?>" required>
+              <option value="1"><?=$lang['admin']['active'];?></option>
+              <option value="0"><?=$lang['admin']['inactive'];?></option>
+            </select>
           </div>
           </div>
+          <button type="submit" name="add_forwarding_host" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> <?=$lang['admin']['add'];?></button>
         </form>
         </form>
       </div>
       </div>
     </div>
     </div>

+ 68 - 47
data/web/inc/functions.inc.php

@@ -5100,14 +5100,29 @@ function get_u2f_registrations($username) {
   return $sel->fetchAll(PDO::FETCH_OBJ);
   return $sel->fetchAll(PDO::FETCH_OBJ);
 }
 }
 function get_forwarding_hosts() {
 function get_forwarding_hosts() {
-	global $pdo;
-  $sel = $pdo->prepare("SELECT * FROM `forwarding_hosts`");
-  $sel->execute();
-  return $sel->fetchAll(PDO::FETCH_OBJ);
+	global $redis;
+  $data = array();
+  try {
+    $wl_hosts = $redis->hGetAll('WHITELISTED_FWD_HOST');
+    if (!empty($wl_hosts)) {
+      foreach ($wl_hosts as $host => $source) {
+        $data[$host]['keep_spam'] = ($redis->hGet('KEEP_SPAM', $host)) ? "yes" : "no";
+        $data[$host]['source'] = $source;
+      }
+    }
+  }
+  catch (RedisException $e) {
+		$_SESSION['return'] = array(
+			'type' => 'danger',
+			'msg' => 'Redis: '.$e
+		);
+		return false;
+  }
+  return $data;
 }
 }
 function add_forwarding_host($postarray) {
 function add_forwarding_host($postarray) {
 	require_once 'spf.inc.php';
 	require_once 'spf.inc.php';
-	global $pdo;
+	global $redis;
 	global $lang;
 	global $lang;
 	if ($_SESSION['mailcow_cc_role'] != "admin") {
 	if ($_SESSION['mailcow_cc_role'] != "admin") {
 		$_SESSION['return'] = array(
 		$_SESSION['return'] = array(
@@ -5117,20 +5132,21 @@ function add_forwarding_host($postarray) {
 		return false;
 		return false;
 	}
 	}
 	$source = $postarray['hostname'];
 	$source = $postarray['hostname'];
-	$host = $postarray['hostname'];
-	$filter_spam = !empty($postarray['filter_spam']);
-	$hosts = array();
-	if (preg_match('/^[0-9a-fA-F:\/]+$/', $host)) { // IPv6 address
-		$hosts = array($host);
-	}
-	elseif (preg_match('/^[0-9\.\/]+$/', $host)) { // IPv4 address
+	$host   = trim($postarray['hostname']);
+  $filter_spam = $postarray['filter_spam'];
+  if (isset($postarray['filter_spam']) && $postarray['filter_spam'] == 1) {
+    $filter_spam = 1;
+  }
+  else {
+    $filter_spam = 0;
+  }
+  if (filter_var($host, FILTER_VALIDATE_IP)) {
 		$hosts = array($host);
 		$hosts = array($host);
-	}
+  }
 	else {
 	else {
 		$hosts = get_outgoing_hosts_best_guess($host);
 		$hosts = get_outgoing_hosts_best_guess($host);
 	}
 	}
-	if (!$hosts)
-	{
+	if (!$hosts) {
 		$_SESSION['return'] = array(
 		$_SESSION['return'] = array(
 			'type' => 'danger',
 			'type' => 'danger',
 			'msg' => 'Invalid host specified: '. htmlspecialchars($host)
 			'msg' => 'Invalid host specified: '. htmlspecialchars($host)
@@ -5138,23 +5154,22 @@ function add_forwarding_host($postarray) {
 		return false;
 		return false;
 	}
 	}
 	foreach ($hosts as $host) {
 	foreach ($hosts as $host) {
-		if ($source == $host)
-			$source = '';
-		try {
-			$stmt = $pdo->prepare("REPLACE INTO `forwarding_hosts` (`host`, `source`, `filter_spam`) VALUES (:host, :source, :filter_spam)");
-			$stmt->execute(array(
-				':host' => $host,
-				':source' => $source,
-				':filter_spam' => $filter_spam ? 1 : 0,
-			));
-		}
-		catch (PDOException $e) {
-			$_SESSION['return'] = array(
-				'type' => 'danger',
-				'msg' => 'MySQL: '.$e
-			);
-			return false;
-		}
+    try {
+      $redis->hSet('WHITELISTED_FWD_HOST', $host, $source);
+      if ($filter_spam == 0) {
+        $redis->hSet('KEEP_SPAM', $host, 1);
+      }
+      elseif ($redis->hGet('KEEP_SPAM', $host)) {
+        $redis->hDel('KEEP_SPAM', $host);
+      }
+    }
+    catch (RedisException $e) {
+      $_SESSION['return'] = array(
+        'type' => 'danger',
+        'msg' => 'Redis: '.$e
+      );
+      return false;
+    }
 	}
 	}
 	$_SESSION['return'] = array(
 	$_SESSION['return'] = array(
 		'type' => 'success',
 		'type' => 'success',
@@ -5162,7 +5177,7 @@ function add_forwarding_host($postarray) {
 	);
 	);
 }
 }
 function delete_forwarding_host($postarray) {
 function delete_forwarding_host($postarray) {
-	global $pdo;
+	global $redis;
 	global $lang;
 	global $lang;
 	if ($_SESSION['mailcow_cc_role'] != "admin") {
 	if ($_SESSION['mailcow_cc_role'] != "admin") {
 		$_SESSION['return'] = array(
 		$_SESSION['return'] = array(
@@ -5171,20 +5186,26 @@ function delete_forwarding_host($postarray) {
 		);
 		);
 		return false;
 		return false;
 	}
 	}
-	$host = $postarray['forwardinghost'];
-	try {
-		$stmt = $pdo->prepare("DELETE FROM `forwarding_hosts` WHERE `host` = :host");
-		$stmt->execute(array(
-			':host' => $host,
-		));
-	}
-	catch (PDOException $e) {
-		$_SESSION['return'] = array(
-			'type' => 'danger',
-			'msg' => 'MySQL: '.$e
-		);
-		return false;
-	}
+  if (!is_array($postarray['forwardinghost'])) {
+    $hosts = array();
+    $hosts[] = $postarray['forwardinghost'];
+  }
+  else {
+    $hosts = $postarray['forwardinghost'];
+  }
+  foreach ($hosts as $host) {
+    try {
+      return $redis->hDel('WHITELISTED_FWD_HOST', $host);
+      return $redis->hDel('KEEP_SPAM', $host);
+    }
+    catch (RedisException $e) {
+      $_SESSION['return'] = array(
+        'type' => 'danger',
+        'msg' => 'Redis: '.$e
+      );
+      return false;
+    }
+  }
 	$_SESSION['return'] = array(
 	$_SESSION['return'] = array(
 		'type' => 'success',
 		'type' => 'success',
 		'msg' => sprintf($lang['success']['forwarding_host_removed'], htmlspecialchars($host))
 		'msg' => sprintf($lang['success']['forwarding_host_removed'], htmlspecialchars($host))

+ 7 - 4
data/web/inc/spf.inc.php

@@ -1,4 +1,6 @@
 <?php
 <?php
+error_reporting(0);
+
 function get_spf_allowed_hosts($domain)
 function get_spf_allowed_hosts($domain)
 {
 {
 	$hosts = array();
 	$hosts = array();
@@ -85,10 +87,11 @@ function get_mx_hosts($domain)
 	$hosts = array();
 	$hosts = array();
   try {
   try {
     $mx_records = dns_get_record($domain, DNS_MX);
     $mx_records = dns_get_record($domain, DNS_MX);
-    foreach ($mx_records as $mx_record)
-    {
-      $new_hosts = get_a_hosts($mx_record['target']);
-      $hosts = array_unique(array_merge($hosts,$new_hosts), SORT_REGULAR);
+    if ($mx_records) {
+      foreach ($mx_records as $mx_record) {
+        $new_hosts = get_a_hosts($mx_record['target']);
+        $hosts = array_unique(array_merge($hosts,$new_hosts), SORT_REGULAR);
+      }
     }
     }
   }
   }
   catch (Exception $e) {
   catch (Exception $e) {

+ 1 - 1
data/web/inc/vars.inc.php

@@ -1,5 +1,5 @@
 <?php
 <?php
-error_reporting(E_ERROR | E_WARNING);
+error_reporting(E_ERROR);
 //error_reporting(E_ALL);
 //error_reporting(E_ALL);
 
 
 /*
 /*

+ 1 - 0
data/web/lang/lang.de.php

@@ -450,6 +450,7 @@ $lang['admin']['configuration'] = 'Konfiguration';
 $lang['admin']['password'] = 'Passwort';
 $lang['admin']['password'] = 'Passwort';
 $lang['admin']['password_repeat'] = 'Passwort (Wiederholung)';
 $lang['admin']['password_repeat'] = 'Passwort (Wiederholung)';
 $lang['admin']['active'] = 'Aktiv';
 $lang['admin']['active'] = 'Aktiv';
+$lang['admin']['inactive'] = 'Inaktiv';
 $lang['admin']['action'] = 'Aktion';
 $lang['admin']['action'] = 'Aktion';
 $lang['admin']['add_domain_admin'] = 'Domain-Administrator hinzufügen';
 $lang['admin']['add_domain_admin'] = 'Domain-Administrator hinzufügen';
 $lang['admin']['admin_domains'] = 'Domain-Zuweisungen';
 $lang['admin']['admin_domains'] = 'Domain-Zuweisungen';

+ 1 - 0
data/web/lang/lang.en.php

@@ -462,6 +462,7 @@ $lang['admin']['configuration'] = 'Configuration';
 $lang['admin']['password'] = 'Password';
 $lang['admin']['password'] = 'Password';
 $lang['admin']['password_repeat'] = 'Confirmation password (repeat)';
 $lang['admin']['password_repeat'] = 'Confirmation password (repeat)';
 $lang['admin']['active'] = 'Active';
 $lang['admin']['active'] = 'Active';
+$lang['admin']['inactive'] = 'Inactive';
 $lang['admin']['action'] = 'Action';
 $lang['admin']['action'] = 'Action';
 $lang['admin']['add_domain_admin'] = 'Add Domain administrator';
 $lang['admin']['add_domain_admin'] = 'Add Domain administrator';
 $lang['admin']['admin_domains'] = 'Domain assignments';
 $lang['admin']['admin_domains'] = 'Domain assignments';