@@ -55,6 +55,7 @@ class ispcmail {
5555 private $ body = '' ;
5656 private $ _mail_sender = '' ;
5757 private $ _sent_mails = 0 ;
58+ private $ user_agent = 'ISPConfig/3 (Mailer Class) ' ;
5859 /**#@-*/
5960
6061 /**
@@ -100,6 +101,22 @@ class ispcmail {
100101 * How many mails should be sent via one single smtp connection
101102 */
102103 private $ smtp_max_mails = 20 ;
104+ /**
105+ * Should the mail be signed
106+ */
107+ private $ sign_email = false ;
108+ /**
109+ * The cert and key to use for email signing
110+ */
111+ private $ sign_key = '' ;
112+ private $ sign_key_pass = '' ;
113+ private $ sign_cert = '' ;
114+ private $ sign_bundle = '' ;
115+ private $ _is_signed = false ;
116+ /**
117+ * get disposition notification
118+ */
119+ private $ notification = false ;
103120 /**#@-*/
104121
105122 public function __construct ($ options = array ()) {
@@ -110,6 +127,7 @@ public function __construct($options = array()) {
110127 $ this ->attachments = array ();
111128
112129 $ this ->headers ['MIME-Version ' ] = '1.0 ' ;
130+ $ this ->headers ['User-Agent ' ] = $ this ->user_agent ;
113131 if (is_array ($ options ) && count ($ options ) > 0 ) $ this ->setOptions ($ options );
114132 }
115133
@@ -155,9 +173,27 @@ public function setOption($key, $value) {
155173 if ($ value != 'ssl ' && $ value != 'tls ' ) $ value = '' ;
156174 $ this ->smtp_crypt = $ value ;
157175 break ;
176+ case 'sign_email ' :
177+ $ this ->sign_email = ($ value == true ? true : false );
178+ break ;
179+ case 'sign_key ' :
180+ $ this ->sign_key = $ value ;
181+ break ;
182+ case 'sign_key_pass ' :
183+ $ this ->sign_key_pass = $ value ;
184+ break ;
185+ case 'sign_cert ' :
186+ $ this ->sign_cert = $ value ;
187+ break ;
188+ case 'sign_bundle ' :
189+ $ this ->sign_bundle = $ value ;
190+ break ;
158191 case 'mail_charset ' :
159192 $ this ->mail_charset = $ value ;
160193 break ;
194+ case 'notify ' :
195+ $ this ->notification = ($ value == true ? true : false );
196+ break ;
161197 }
162198 }
163199
@@ -394,7 +430,8 @@ private function create() {
394430 $ this ->body .= "-- {$ this ->mime_boundary }\n" .
395431 "Content-Type: " . $ att ['type ' ] . "; \n" .
396432 " name= \"" . $ att ['filename ' ] . "\"\n" .
397- "Content-Transfer-Encoding: base64 \n\n" .
433+ "Content-Transfer-Encoding: base64 \n" .
434+ "Content-Disposition: attachment; \n\n" .
398435 chunk_split (base64_encode ($ att ['content ' ])) . "\n\n" ;
399436 }
400437 }
@@ -415,6 +452,44 @@ private function create() {
415452 }
416453 }
417454
455+ /**
456+ * Function to sign an email body
457+ */
458+ private function sign () {
459+ if ($ this ->sign_email == false || $ this ->sign_key == '' || $ this ->sign_cert == '' ) return false ;
460+ if (function_exists ('openssl_pkcs7_sign ' ) == false ) return false ;
461+
462+ $ tmpin = tempnam (sys_get_temp_dir (), 'sign ' );
463+ $ tmpout = tempnam (sys_get_temp_dir (), 'sign ' );
464+ if (!file_exists ($ tmpin ) || !is_writable ($ tmpin )) return false ;
465+
466+ file_put_contents ($ tmpin , 'Content-Type: ' . $ this ->getHeader ('Content-Type ' ) . "\n\n" . $ this ->body );
467+ $ tmpf_key = tempnam (sys_get_temp_dir (), 'sign ' );
468+ file_put_contents ($ tmpf_key , $ this ->sign_key );
469+ $ tmpf_cert = tempnam (sys_get_temp_dir (), 'sign ' );
470+ file_put_contents ($ tmpf_cert , $ this ->sign_cert );
471+ if ($ this ->sign_bundle != '' ) {
472+ $ tmpf_bundle = tempnam (sys_get_temp_dir (), 'sign ' );
473+ file_put_contents ($ tmpf_bundle , $ this ->sign_bundle );
474+ openssl_pkcs7_sign ($ tmpin , $ tmpout , 'file:// ' . realpath ($ tmpf_cert ), array ('file:// ' . realpath ($ tmpf_key ), $ this ->sign_key_pass ), array (), PKCS7_DETACHED , realpath ($ tmpf_bundle ));
475+ } else {
476+ openssl_pkcs7_sign ($ tmpin , $ tmpout , 'file:// ' . realpath ($ tmpf_cert ), array ('file:// ' . realpath ($ tmpf_key ), $ this ->sign_key_pass ), array ());
477+ }
478+ unlink ($ tmpin );
479+ unlink ($ tmpf_cert );
480+ unlink ($ tmpf_key );
481+ if (file_exists ($ tmpf_bundle )) unlink ($ tmpf_bundle );
482+
483+ if (!file_exists ($ tmpout ) || !is_readable ($ tmpout )) return false ;
484+ $ this ->body = file_get_contents ($ tmpout );
485+ unlink ($ tmpout );
486+
487+ unset($ this ->headers ['Content-Type ' ]);
488+ unset($ this ->headers ['MIME-Version ' ]);
489+
490+ $ this ->_is_signed = true ;
491+ }
492+
418493 /**
419494 * Function to encode a header if necessary
420495 * according to RFC2047
@@ -496,6 +571,7 @@ public function send($recipients) {
496571 else $ this ->_crlf = "\n" ;
497572
498573 $ this ->create ();
574+ if ($ this ->sign_email == true ) $ this ->sign ();
499575
500576 $ subject = '' ;
501577 if (!empty ($ this ->headers ['Subject ' ])) {
@@ -506,6 +582,8 @@ public function send($recipients) {
506582 unset($ this ->headers ['Subject ' ]);
507583 }
508584
585+ if ($ this ->notification == true ) $ this ->setHeader ('Disposition-Notification-To ' , $ this ->getHeader ('From ' ));
586+
509587 unset($ this ->headers ['To ' ]); // always reset the To header to prevent from sending to multiple users at once
510588 $ this ->headers ['Date ' ] = date ('r ' ); //date('D, d M Y H:i:s O');
511589
@@ -554,7 +632,7 @@ public function send($recipients) {
554632 $ mail_content .= 'To: ' . $ this ->getHeader ('To ' ) . $ this ->_crlf ;
555633 if ($ this ->getHeader ('Bcc ' ) != '' ) $ mail_content .= 'Bcc: ' . $ this ->_encodeHeader ($ this ->getHeader ('Bcc ' ), $ this ->mail_charset ) . $ this ->_crlf ;
556634 if ($ this ->getHeader ('Cc ' ) != '' ) $ mail_content .= 'Cc: ' . $ this ->_encodeHeader ($ this ->getHeader ('Cc ' ), $ this ->mail_charset ) . $ this ->_crlf ;
557- $ mail_content .= implode ($ this ->_crlf , $ headers ) . $ this ->_crlf . $ this ->_crlf . $ this ->body ;
635+ $ mail_content .= implode ($ this ->_crlf , $ headers ) . $ this ->_crlf . ( $ this ->_is_signed == false ? $ this -> _crlf : '' ) . $ this ->body ;
558636
559637 fputs ($ this ->_smtp_conn , $ mail_content . $ this ->_crlf . '. ' . $ this ->_crlf );
560638 $ response = fgets ($ this ->_smtp_conn , 515 );
@@ -605,6 +683,7 @@ public function finish() {
605683 $ this ->html_part = '' ;
606684
607685 $ this ->headers ['MIME-Version ' ] = '1.0 ' ;
686+ $ this ->headers ['User-Agent ' ] = $ this ->user_agent ;
608687
609688 $ this ->smtp_helo = '' ;
610689 $ this ->smtp_host = '' ;
@@ -615,6 +694,7 @@ public function finish() {
615694 $ this ->smtp_crypt = false ;
616695 $ this ->mail_charset = 'UTF-8 ' ;
617696 $ this ->_sent_mails = 0 ;
697+
618698 return ;
619699 }
620700}
0 commit comments