From e297b647220b4d80cd8159cf1fa9e6e59b314ac2 Mon Sep 17 00:00:00 2001
From: Laurent Destailleur <eldy@destailleur.fr>
Date: Mon, 26 Dec 2016 12:30:59 +0100
Subject: [PATCH] Several security fix in using mailings.

---
 htdocs/comm/mailing/card.php          | 44 +++++++++++++++------------
 htdocs/conf/conf.php.example          | 25 ++++++---------
 htdocs/core/class/CMailFile.class.php | 21 ++++++++-----
 htdocs/filefunc.inc.php               |  2 +-
 4 files changed, 49 insertions(+), 43 deletions(-)

diff --git a/htdocs/comm/mailing/card.php b/htdocs/comm/mailing/card.php
index 48044928ecc..3660b560f78 100644
--- a/htdocs/comm/mailing/card.php
+++ b/htdocs/comm/mailing/card.php
@@ -753,8 +753,9 @@ else
 				$sendingmode=$conf->global->MAIN_MAIL_SENDMODE;
 				if (empty($sendingmode)) $sendingmode='mail';	// If not defined, we use php mail function
 
-				// MAILING_NO_USING_PHPMAIL may be defined or not
-				// MAILING_LIMIT_SENDBYWEB is always defined to something != 0, MAILING_LIMIT_SENDBYCLI may be defined ot not.
+				// MAILING_NO_USING_PHPMAIL may be defined or not.
+				// MAILING_LIMIT_SENDBYWEB is always defined to something != 0 (-1=forbidden).
+				// MAILING_LIMIT_SENDBYCLI may be defined ot not (-1=forbidden, 0=no limit).
 				if (! empty($conf->global->MAILING_NO_USING_PHPMAIL) && $sendingmode == 'mail')
 				{
 					// EMailing feature may be a spam problem, so when you host several users/instance, having this option may force each user to use their own SMTP agent.
@@ -794,7 +795,7 @@ else
                     }
 				    $text.=$langs->trans('ConfirmSendingEmailing').'<br>';
 					$text.=$langs->trans('LimitSendingEmailing',$conf->global->MAILING_LIMIT_SENDBYWEB);
-					print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('SendMailing'),$text,'sendallconfirmed',$formquestion,'',1,270);
+					print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('SendMailing'),$text,'sendallconfirmed',$formquestion,'',1,300);
 				}
 			}
 
@@ -832,23 +833,28 @@ else
 			print $langs->trans("TotalNbOfDistinctRecipients");
 			print '</td><td colspan="3">';
 			$nbemail = ($object->nbemail?$object->nbemail:img_warning('').' <font class="warning">'.$langs->trans("NoTargetYet").'</font>');
-			if ($object->statut != 3 && !empty($conf->global->MAILING_LIMIT_SENDBYWEB) && is_numeric($nbemail) && $conf->global->MAILING_LIMIT_SENDBYWEB < $nbemail)
+			if ($object->statut != 3 && is_numeric($nbemail))
 			{
-				if ($conf->global->MAILING_LIMIT_SENDBYWEB > 0)
-				{
-					$text=$langs->trans('LimitSendingEmailing',$conf->global->MAILING_LIMIT_SENDBYWEB);
-					print $form->textwithpicto($nbemail,$text,1,'warning');
-				}
-				else
-				{
-					$text=$langs->trans('NotEnoughPermissions');
-					print $form->textwithpicto($nbemail,$text,1,'warning');
-				}
-
-			}
-			else
-			{
-				print $nbemail;
+			    $text='';
+			    if (! empty($conf->global->MAILING_LIMIT_SENDBYWEB) && $conf->global->MAILING_LIMIT_SENDBYWEB < $nbemail)
+			    {
+    				if ($conf->global->MAILING_LIMIT_SENDBYWEB > 0)
+    				{
+    					$text.=$langs->trans('LimitSendingEmailing',$conf->global->MAILING_LIMIT_SENDBYWEB);
+    				}
+    				else
+    				{
+    					$text.=$langs->trans('NotEnoughPermissions');
+    				}
+			    }
+				if ($text)
+    			{
+    			    print $form->textwithpicto($nbemail,$text,1,'warning');
+    			}
+    			else
+    			{
+    				print $nbemail;
+    			}
 			}
 			print '</td></tr>';
 
diff --git a/htdocs/conf/conf.php.example b/htdocs/conf/conf.php.example
index 9545332d93b..faf6f28c955 100644
--- a/htdocs/conf/conf.php.example
+++ b/htdocs/conf/conf.php.example
@@ -251,11 +251,16 @@ $dolibarr_main_restrict_os_commands='mysqldump, mysql, pg_dump, pgrestore';
 $dolibarr_nocsrfcheck='0';
 
 // dolibarr_mailing_limit_sendbyweb
-// Can set a limit for mailing send by web. Can be used for a restricted mode.
-// Default value: 0 (use database value if exist)
-// Examples:
-// $dolibarr_mailing_limit_sendbyweb='0';
+// Can set a limit for mailing send by web. This overwrite database value. Can be used to restrict on OS level.
+// Default value: '25'
+// Examples: '-1' (sending by web is forbidden)
+// $dolibarr_mailing_limit_sendbyweb='25';
 
+// dolibarr_mailing_limit_sendbycli
+// Can set a limit for mailing send by cli. This overwrite database value. Can be used to restrict on OS level.
+// Default value: '0' (no hard limit, use soft database value if exists)
+// Examples: '-1' (sending by cli is forbidden)
+// $dolibarr_mailing_limit_sendbycli='0';
 
 
 //##################
@@ -274,18 +279,6 @@ $dolibarr_nocsrfcheck='0';
 // Examples:
 // $dolibarr_main_limit_users='0';
 
-// dolibarr_mailing_limit_sendbyweb
-// Can set a limit for mailing send by web. This overwrite database value. Can be used to restrict on OS level.
-// Default value: '0' (no overwrite, use database value if exists)
-// Examples: '-1' (sending by web is forbidden)
-// $dolibarr_mailing_limit_sendbyweb='0';
-
-// dolibarr_mailing_limit_sendbycli
-// Can set a limit for mailing send by cli. This overwrite database value. Can be used to restrict on OS level.
-// Default value: '0' (no overwrite, use database value if exists)
-// Examples: '-1' (sending by cli is forbidden)
-// $dolibarr_mailing_limit_sendbycli='0';
-
 // dolibarr_strict_mode
 // Set this to 1 to enable the PHP strict mode. For dev environment only.
 // Default value: 0 (use database value if exist)
diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php
index e74ba8fc03b..52cce35f0d2 100644
--- a/htdocs/core/class/CMailFile.class.php
+++ b/htdocs/core/class/CMailFile.class.php
@@ -483,28 +483,35 @@ class CMailFile
 
             // Check number of recipient is lower or equal than MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL
             if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL=10;
-            $tmparray = explode(',', $this->addr_to);
-            if (count($tmparray) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL)
+            $tmparray1 = explode(',', $this->addr_to);
+            if (count($tmparray1) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL)
             {
                 $this->error = 'Too much recipients in to:';
                 dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
                 return false;
             }
-            $tmparray = explode(',', $this->addr_cc);
-            if (count($tmparray) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL)
+            $tmparray2 = explode(',', $this->addr_cc);
+            if (count($tmparray2) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_CC_IN_SAME_EMAIL)
             {
                 $this->error = 'Too much recipients in cc:';
                 dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
                 return false;
             }
-            $tmparray = explode(',', $this->addr_bcc);
-            if (count($tmparray) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL)
+            $tmparray3 = explode(',', $this->addr_bcc);
+            if (count($tmparray3) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_BCC_IN_SAME_EMAIL)
             {
                 $this->error = 'Too much recipients in bcc:';
                 dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
                 return false;
             }
-
+            if ((count($tmparray1)+count($tmparray2)+count($tmparray3)) > $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL)
+            {
+                $this->error = 'Too much recipients in to:, cc:, bcc:';
+                dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_WARNING);
+                return false;
+            }
+            
+                
 			// Action according to choosed sending method
 			if ($conf->global->MAIN_MAIL_SENDMODE == 'mail')
 			{
diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php
index ccbc8aa9b92..eddcf1ebbdf 100644
--- a/htdocs/filefunc.inc.php
+++ b/htdocs/filefunc.inc.php
@@ -31,7 +31,7 @@
  */
 
 if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr');
-if (! defined('DOL_VERSION')) define('DOL_VERSION','4.0.3');
+if (! defined('DOL_VERSION')) define('DOL_VERSION','4.0.4');
 
 if (! defined('EURO')) define('EURO',chr(128));
 
-- 
GitLab