This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | 1 | if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point'); |
|
3 | /********************************************************************************* |
||
4 | * SugarCRM Community Edition is a customer relationship management program developed by |
||
5 | * SugarCRM, Inc. Copyright (C) 2004-2013 SugarCRM Inc. |
||
6 | |||
7 | * SuiteCRM is an extension to SugarCRM Community Edition developed by Salesagility Ltd. |
||
8 | * Copyright (C) 2011 - 2014 Salesagility Ltd. |
||
9 | * |
||
10 | * This program is free software; you can redistribute it and/or modify it under |
||
11 | * the terms of the GNU Affero General Public License version 3 as published by the |
||
12 | * Free Software Foundation with the addition of the following permission added |
||
13 | * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK |
||
14 | * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY |
||
15 | * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. |
||
16 | * |
||
17 | * This program is distributed in the hope that it will be useful, but WITHOUT |
||
18 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
||
19 | * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more |
||
20 | * details. |
||
21 | * |
||
22 | * You should have received a copy of the GNU Affero General Public License along with |
||
23 | * this program; if not, see http://www.gnu.org/licenses or write to the Free |
||
24 | * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
||
25 | * 02110-1301 USA. |
||
26 | * |
||
27 | * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road, |
||
28 | * SW2-130, Cupertino, CA 95014, USA. or at email address [email protected]. |
||
29 | * |
||
30 | * The interactive user interfaces in modified source and object code versions |
||
31 | * of this program must display Appropriate Legal Notices, as required under |
||
32 | * Section 5 of the GNU Affero General Public License version 3. |
||
33 | * |
||
34 | * In accordance with Section 7(b) of the GNU Affero General Public License version 3, |
||
35 | * these Appropriate Legal Notices must retain the display of the "Powered by |
||
36 | * SugarCRM" logo and "Supercharged by SuiteCRM" logo. If the display of the logos is not |
||
37 | * reasonably feasible for technical reasons, the Appropriate Legal Notices must |
||
38 | * display the words "Powered by SugarCRM" and "Supercharged by SuiteCRM". |
||
39 | ********************************************************************************/ |
||
40 | |||
41 | 1 | require_once('include/phpmailer/class.phpmailer.php'); |
|
42 | 1 | require_once('include/phpmailer/class.smtp.php'); |
|
43 | 1 | require_once('include/OutboundEmail/OutboundEmail.php'); |
|
44 | |||
45 | /** |
||
46 | * Sugar mailer |
||
47 | * @api |
||
48 | */ |
||
49 | class SugarPHPMailer extends PHPMailer |
||
50 | { |
||
51 | var $oe; // OutboundEmail |
||
52 | var $protocol = "tcp://"; |
||
53 | var $preppedForOutbound = false; |
||
54 | var $disclosureEnabled; |
||
55 | var $disclosureText; |
||
56 | var $isHostEmpty = false; |
||
57 | var $opensslOpened = true; |
||
58 | |||
59 | /** |
||
60 | * Sole constructor |
||
61 | */ |
||
62 | 6 | public function __construct() { |
|
63 | 6 | parent::__construct(); |
|
64 | 6 | global $locale; |
|
65 | 6 | global $current_user; |
|
66 | 6 | global $sugar_config; |
|
67 | |||
68 | 6 | $admin = new Administration(); |
|
69 | 6 | $admin->retrieveSettings(); |
|
70 | |||
71 | 6 | if(isset($admin->settings['disclosure_enable']) && !empty($admin->settings['disclosure_enable'])) { |
|
72 | $this->disclosureEnabled = true; |
||
73 | $this->disclosureText = $admin->settings['disclosure_text']; |
||
74 | } |
||
75 | |||
76 | 6 | $this->oe = new OutboundEmail(); |
|
77 | 6 | $this->oe->getUserMailerSettings($current_user); |
|
78 | |||
79 | 6 | $this->SetLanguage('en', 'include/phpmailer/language/'); |
|
80 | 6 | $this->PluginDir = 'include/phpmailer/'; |
|
0 ignored issues
–
show
|
|||
81 | 6 | $this->Mailer = 'smtp'; |
|
82 | // cn: i18n |
||
83 | 6 | $this->CharSet = $locale->getPrecedentPreference('default_email_charset'); |
|
84 | 6 | $this->Encoding = 'quoted-printable'; |
|
85 | 6 | $this->IsHTML(false); // default to plain-text email |
|
86 | 6 | $this->Hostname = $sugar_config['host_name']; |
|
87 | 6 | $this->WordWrap = 996; |
|
88 | // cn: gmail fix |
||
89 | 6 | $this->protocol = ($this->oe->mail_smtpssl == 1) ? "ssl://" : $this->protocol; |
|
90 | |||
91 | 6 | } |
|
92 | |||
93 | /** |
||
94 | * @deprecated deprecated since version 7.6, PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code, use __construct instead |
||
95 | */ |
||
96 | public function SugarPHPMailer(){ |
||
97 | $deprecatedMessage = 'PHP4 Style Constructors are deprecated and will be remove in 7.8, please update your code'; |
||
98 | if(isset($GLOBALS['log'])) { |
||
99 | $GLOBALS['log']->deprecated($deprecatedMessage); |
||
100 | } |
||
101 | else { |
||
102 | trigger_error($deprecatedMessage, E_USER_DEPRECATED); |
||
103 | } |
||
104 | self::__construct(); |
||
105 | } |
||
106 | |||
107 | /** |
||
108 | * Prefills outbound details |
||
109 | */ |
||
110 | function setMailer() { |
||
111 | global $current_user; |
||
112 | |||
113 | require_once("include/OutboundEmail/OutboundEmail.php"); |
||
114 | $oe = new OutboundEmail(); |
||
115 | $oe = $oe->getUserMailerSettings($current_user); |
||
116 | |||
117 | // ssl or tcp - keeping outside isSMTP b/c a default may inadvertently set ssl:// |
||
118 | $this->protocol = ($oe->mail_smtpssl) ? "ssl://" : "tcp://"; |
||
119 | |||
120 | if($oe->mail_sendtype == "SMTP") |
||
121 | { |
||
122 | //Set mail send type information |
||
123 | $this->Mailer = "smtp"; |
||
124 | $this->Host = $oe->mail_smtpserver; |
||
125 | $this->Port = $oe->mail_smtpport; |
||
126 | if ($oe->mail_smtpssl == 1) { |
||
127 | $this->SMTPSecure = 'ssl'; |
||
128 | } // if |
||
129 | if ($oe->mail_smtpssl == 2) { |
||
130 | $this->SMTPSecure = 'tls'; |
||
131 | } // if |
||
132 | |||
133 | if($oe->mail_smtpauth_req) { |
||
134 | $this->SMTPAuth = TRUE; |
||
135 | $this->Username = $oe->mail_smtpuser; |
||
136 | $this->Password = $oe->mail_smtppass; |
||
137 | } |
||
138 | } |
||
139 | else |
||
140 | $this->Mailer = "sendmail"; |
||
141 | } |
||
142 | |||
143 | /** |
||
144 | * Prefills mailer for system |
||
145 | */ |
||
146 | 1 | function setMailerForSystem() { |
|
147 | 1 | require_once("include/OutboundEmail/OutboundEmail.php"); |
|
148 | 1 | $oe = new OutboundEmail(); |
|
149 | 1 | $oe = $oe->getSystemMailerSettings(); |
|
150 | |||
151 | // ssl or tcp - keeping outside isSMTP b/c a default may inadvertantly set ssl:// |
||
152 | 1 | $this->protocol = ($oe->mail_smtpssl) ? "ssl://" : "tcp://"; |
|
153 | |||
154 | 1 | if($oe->mail_sendtype == "SMTP") |
|
155 | { |
||
156 | //Set mail send type information |
||
157 | 1 | $this->Mailer = "smtp"; |
|
158 | 1 | $this->Host = $oe->mail_smtpserver; |
|
159 | 1 | $this->Port = $oe->mail_smtpport; |
|
160 | 1 | if ($oe->mail_smtpssl == 1) { |
|
161 | $this->SMTPSecure = 'ssl'; |
||
162 | } // if |
||
163 | 1 | if ($oe->mail_smtpssl == 2) { |
|
164 | $this->SMTPSecure = 'tls'; |
||
165 | } // if |
||
166 | 1 | if($oe->mail_smtpauth_req) { |
|
167 | 1 | $this->SMTPAuth = TRUE; |
|
168 | 1 | $this->Username = $oe->mail_smtpuser; |
|
169 | 1 | $this->Password = $oe->mail_smtppass; |
|
170 | } |
||
171 | } |
||
172 | else |
||
173 | $this->Mailer = "sendmail"; |
||
174 | 1 | } |
|
175 | |||
176 | /** |
||
177 | * Attaches all fs, string, and binary attachments to the message. |
||
178 | * Returns an empty string on failure. |
||
179 | * @access private |
||
180 | * @return string |
||
181 | */ |
||
182 | /*function AttachAll() { |
||
183 | // Return text of body |
||
184 | $mime = array(); |
||
185 | |||
186 | // Add all attachments |
||
187 | for($i = 0; $i < count($this->attachment); $i++) { |
||
188 | // Check for string attachment |
||
189 | $bString = $this->attachment[$i][5]; |
||
190 | if ($bString) { |
||
191 | $string = $this->attachment[$i][0]; |
||
192 | } else { |
||
193 | $path = $this->attachment[$i][0]; |
||
194 | } |
||
195 | |||
196 | // cn: overriding parent class' method to perform encode on the following |
||
197 | $filename = $this->EncodeHeader(trim($this->attachment[$i][1])); |
||
198 | $name = $this->EncodeHeader(trim($this->attachment[$i][2])); |
||
199 | $encoding = $this->attachment[$i][3]; |
||
200 | $type = $this->attachment[$i][4]; |
||
201 | $disposition = $this->attachment[$i][6]; |
||
202 | $cid = $this->attachment[$i][7]; |
||
203 | |||
204 | $mime[] = sprintf("--%s%s", $this->boundary[1], $this->LE); |
||
205 | $mime[] = sprintf("Content-Type: %s; name=\"%s\"%s", $type, $name, $this->LE); |
||
206 | $mime[] = sprintf("Content-Transfer-Encoding: %s%s", $encoding, $this->LE); |
||
207 | |||
208 | if($disposition == "inline") { |
||
209 | $mime[] = sprintf("Content-ID: <%s>%s", $cid, $this->LE); |
||
210 | } |
||
211 | |||
212 | $mime[] = sprintf("Content-Disposition: %s; filename=\"%s\"%s", $disposition, $name, $this->LE.$this->LE); |
||
213 | |||
214 | // Encode as string attachment |
||
215 | if($bString) { |
||
216 | $mime[] = $this->EncodeString($string, $encoding); |
||
217 | if($this->IsError()) { return ""; } |
||
218 | $mime[] = $this->LE.$this->LE; |
||
219 | } else { |
||
220 | $mime[] = $this->EncodeFile($path, $encoding); |
||
221 | |||
222 | if($this->IsError()) { |
||
223 | return ""; |
||
224 | } |
||
225 | $mime[] = $this->LE.$this->LE; |
||
226 | } |
||
227 | } |
||
228 | $mime[] = sprintf("--%s--%s", $this->boundary[1], $this->LE); |
||
229 | |||
230 | return join("", $mime); |
||
231 | }*/ |
||
232 | |||
233 | /** |
||
234 | * handles Charset translation for all visual parts of the email. |
||
235 | * @param string charset Default = '' |
||
236 | */ |
||
237 | 3 | function prepForOutbound() { |
|
238 | 3 | global $locale; |
|
239 | |||
240 | 3 | if($this->preppedForOutbound == false) { |
|
0 ignored issues
–
show
|
|||
241 | //bug 28534. We should not set it to true to circumvent the following conversion as each email is independent. |
||
242 | //$this->preppedForOutbound = true; // flag so we don't redo this |
||
243 | 3 | $OBCharset = $locale->getPrecedentPreference('default_email_charset'); |
|
244 | |||
245 | // handle disclosure |
||
246 | 3 | if($this->disclosureEnabled) { |
|
247 | $this->Body .= "<br /> <br />{$this->disclosureText}"; |
||
248 | $this->AltBody .= "\r\r{$this->disclosureText}"; |
||
249 | } |
||
250 | |||
251 | // body text |
||
252 | 3 | $this->Body = from_html($locale->translateCharset(trim($this->Body), 'UTF-8', $OBCharset)); |
|
253 | 3 | $this->AltBody = from_html($locale->translateCharset(trim($this->AltBody), 'UTF-8', $OBCharset)); |
|
254 | 3 | $subjectUTF8 = from_html(trim($this->Subject)); |
|
255 | 3 | $subject = $locale->translateCharset($subjectUTF8, 'UTF-8', $OBCharset); |
|
256 | 3 | $this->Subject = $locale->translateCharset($subjectUTF8, 'UTF-8', $OBCharset); |
|
257 | |||
258 | // HTML email RFC compliance |
||
259 | 3 | if($this->ContentType == "text/html") { |
|
260 | if(strpos($this->Body, '<html') === false) { |
||
261 | |||
262 | $langHeader = get_language_header(); |
||
263 | |||
264 | $head=<<<eoq |
||
265 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
||
266 | <html xmlns="http://www.w3.org/1999/xhtml" {$langHeader}> |
||
267 | <head> |
||
268 | <meta http-equiv="Content-Type" content="text/html; charset={$OBCharset}" /> |
||
269 | <title>{$subject}</title> |
||
270 | </head> |
||
271 | <body> |
||
272 | eoq; |
||
273 | $this->Body = $head.$this->Body."</body></html>"; |
||
274 | } |
||
275 | } |
||
276 | |||
277 | // Headers ///////////////////////////////// |
||
278 | // the below is done in PHPMailer::CreateHeader(); |
||
279 | //$this->Subject = $locale->translateCharsetMIME(trim($this->Subject), 'UTF-8', $locale->getPrecedentPreference('default_email_charset')); |
||
280 | 3 | $this->FromName = $locale->translateCharset(trim($this->FromName), 'UTF-8', $OBCharset); |
|
281 | /* |
||
282 | foreach($this->ReplyTo as $k => $v) { |
||
283 | $this->ReplyTo[$k][1] = $locale->translateCharset(trim($v[1]), 'UTF-8', $OBCharset); |
||
284 | } |
||
285 | // TO: fields |
||
286 | foreach($this->to as $k => $toArr) { |
||
287 | $this->to[$k][1] = $locale->translateCharset(trim($toArr[1]), 'UTF-8', $OBCharset); |
||
288 | } |
||
289 | // CC: fields |
||
290 | foreach($this->cc as $k => $ccAddr) { |
||
291 | $this->cc[$k][1] = $locale->translateCharset(trim($ccAddr[1]), 'UTF-8', $OBCharset); |
||
292 | } |
||
293 | // BCC: fields |
||
294 | foreach($this->bcc as $k => $bccAddr) { |
||
295 | $this->bcc[$k][1] = $locale->translateCharset(trim($bccAddr[1]), 'UTF-8', $OBCharset); |
||
296 | } |
||
297 | */ |
||
298 | |||
299 | } |
||
300 | 3 | } |
|
301 | |||
302 | /** |
||
303 | * Replace images with locations specified by regex with cid: images |
||
304 | * and attach needed files |
||
305 | * @param string $regex Regular expression |
||
306 | * @param string $local_prefix Prefix where local files are stored |
||
307 | * @param bool $object Use attachment object |
||
308 | */ |
||
309 | 2 | public function replaceImageByRegex($regex, $local_prefix, $object = false) |
|
310 | { |
||
311 | 2 | preg_match_all("#<img[^>]*[\s]+src[^=]*=[\s]*[\"']($regex)(.+?)[\"']#si", $this->Body, $matches); |
|
312 | 2 | $i = 0; |
|
313 | 2 | foreach($matches[2] as $match) { |
|
314 | $filename = urldecode($match); |
||
315 | $cid = $filename; |
||
316 | $file_location = $local_prefix.$filename; |
||
317 | if(!file_exists($file_location)) continue; |
||
318 | if($object) { |
||
319 | if(preg_match('#&(?:amp;)?type=([\w]+)#i', $matches[0][$i], $typematch)) { |
||
320 | switch(strtolower($typematch[1])) { |
||
321 | case 'documents': |
||
322 | $beanname = 'DocumentRevisions'; |
||
323 | break; |
||
324 | case 'notes': |
||
325 | $beanname = 'Notes'; |
||
326 | break; |
||
327 | } |
||
328 | } |
||
329 | $mime_type = "application/octet-stream"; |
||
330 | if(isset($beanname)) { |
||
331 | $bean = SugarModule::get($beanname)->loadBean(); |
||
332 | $bean->retrieve($filename); |
||
333 | if(!empty($bean->id)) { |
||
334 | $mime_type = $bean->file_mime_type; |
||
335 | $filename = $bean->filename; |
||
336 | } |
||
337 | } |
||
338 | } else { |
||
339 | $mime_type = "image/".strtolower(pathinfo($filename, PATHINFO_EXTENSION)); |
||
340 | } |
||
341 | if (!$this->embeddedAttachmentExists($cid)) { |
||
342 | $this->AddEmbeddedImage($file_location, $cid, $filename, 'base64', $mime_type); |
||
343 | } |
||
344 | $i++; |
||
345 | } |
||
346 | //replace references to cache with cid tag |
||
347 | 2 | $this->Body = preg_replace("|\"$regex|i",'"cid:',$this->Body); |
|
348 | // remove bad img line from outbound email |
||
349 | 2 | $this->Body = preg_replace('#<img[^>]+src[^=]*=\"\/([^>]*?[^>]*)>#sim', '', $this->Body); |
|
350 | 2 | } |
|
351 | |||
352 | /** |
||
353 | * @param notes array of note beans |
||
354 | */ |
||
355 | function handleAttachments($notes) { |
||
356 | global $sugar_config; |
||
357 | |||
358 | // cn: bug 4864 - reusing same SugarPHPMailer class, need to clear attachments |
||
359 | $this->ClearAttachments(); |
||
360 | |||
361 | //replace references to cache/images with cid tag |
||
362 | $this->Body = preg_replace(';=\s*"'.preg_quote(sugar_cached('images/'), ';').';','="cid:',$this->Body); |
||
363 | |||
364 | $this->replaceImageByRegex("(?:{$sugar_config['site_url']})?/?cache/images/", sugar_cached("images/")); |
||
365 | |||
366 | //Replace any embeded images using the secure entryPoint for src url. |
||
367 | $this->replaceImageByRegex("(?:{$sugar_config['site_url']})?index.php[?]entryPoint=download&(?:amp;)?[^\"]+?id=", "upload://", true); |
||
368 | |||
369 | if (empty($notes)) { |
||
370 | return; |
||
371 | } |
||
372 | //Handle regular attachments. |
||
373 | foreach($notes as $note) { |
||
374 | $mime_type = 'text/plain'; |
||
375 | $file_location = ''; |
||
376 | $filename = ''; |
||
377 | |||
378 | if($note->object_name == 'Note') { |
||
379 | if (! empty($note->file->temp_file_location) && is_file($note->file->temp_file_location)) { |
||
380 | $file_location = $note->file->temp_file_location; |
||
381 | $filename = $note->file->original_file_name; |
||
382 | $mime_type = $note->file->mime_type; |
||
383 | } else { |
||
384 | $file_location = "upload://{$note->id}"; |
||
385 | $filename = $note->id.$note->filename; |
||
386 | $mime_type = $note->file_mime_type; |
||
387 | } |
||
388 | } elseif($note->object_name == 'DocumentRevision') { // from Documents |
||
389 | $filename = $note->id.$note->filename; |
||
390 | $file_location = "upload://$filename"; |
||
391 | $mime_type = $note->file_mime_type; |
||
392 | } |
||
393 | |||
394 | $filename = substr($filename, 36, strlen($filename)); // strip GUID for PHPMailer class to name outbound file |
||
395 | if (!$note->embed_flag) { |
||
396 | $this->AddAttachment($file_location, $filename, 'base64', $mime_type); |
||
397 | } // else |
||
398 | } |
||
399 | } |
||
400 | |||
401 | /** |
||
402 | * overloads class.phpmailer's SetError() method so that we can log errors in sugarcrm.log |
||
403 | * |
||
404 | */ |
||
405 | 3 | function SetError($msg) { |
|
406 | 3 | $GLOBALS['log']->fatal("SugarPHPMailer encountered an error: {$msg}"); |
|
407 | 3 | parent::SetError($msg); |
|
408 | 3 | } |
|
409 | |||
410 | function SmtpConnect($options = array()) { |
||
411 | $connection = parent::SmtpConnect(); |
||
412 | if (!$connection) { |
||
413 | global $app_strings; |
||
414 | if(isset($this->oe) && $this->oe->type == "system") { |
||
415 | $this->SetError($app_strings['LBL_EMAIL_INVALID_SYSTEM_OUTBOUND']); |
||
416 | } else { |
||
417 | $this->SetError($app_strings['LBL_EMAIL_INVALID_PERSONAL_OUTBOUND']); |
||
418 | } // else |
||
419 | } |
||
420 | return $connection; |
||
421 | } // fn |
||
422 | |||
423 | /* |
||
424 | * overloads PHPMailer::PreSend() to allow for empty messages to go out. |
||
425 | */ |
||
426 | 1 | public function PreSend() { |
|
427 | //check to see if message body is empty |
||
428 | 1 | if(empty($this->Body)){ |
|
429 | //PHPMailer will throw an error if the body is empty, so insert a blank space if body is empty |
||
430 | 1 | $this->Body = " "; |
|
431 | } |
||
432 | 1 | return parent::PreSend(); |
|
433 | } |
||
434 | |||
435 | /** |
||
436 | * Checks if the embedded file is already attached. |
||
437 | * @access protected |
||
438 | * @param string $filename Name of the file to check. |
||
439 | * @return boolean |
||
440 | */ |
||
441 | protected function embeddedAttachmentExists($filename) |
||
442 | { |
||
443 | $result = false; |
||
444 | for ($i = 0; $i < count($this->attachment); $i++) |
||
0 ignored issues
–
show
It seems like you are calling the size function
count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.
If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration: for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}
// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
![]() |
|||
445 | { |
||
446 | if ($this->attachment[$i][1] == $filename) |
||
447 | { |
||
448 | $result = true; |
||
449 | break; |
||
450 | } |
||
451 | } |
||
452 | |||
453 | return $result; |
||
454 | } |
||
455 | |||
456 | } // end class definition |
||
457 |
This property has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the property will be removed from the class and what other property to use instead.