예제 #1
0
 /**
  * Sends mail via SMTP using PhpSMTP (Author:
  * Chris Ryan).  Returns bool.  Returns false if there is a
  * bad MAIL FROM, RCPT, or DATA input.
  * @access private
  * @return bool
  */
 function SmtpSend($header, $body)
 {
     include_once $this->PluginDir . "class.smtp.php";
     $error = "";
     $bad_rcpt = array();
     $errorx = '';
     if (!$this->SmtpConnect()) {
         return false;
     }
     if ($this->SMIME) {
         $header = '';
         $body = $this->Body;
     }
     $smtp_from = $this->Sender == "" ? $this->From : $this->Sender;
     if (!$this->smtp->Mail($smtp_from)) {
         $error = $this->Lang("from_failed") . $smtp_from;
         $this->SetError($error);
         $this->smtp->Reset();
         return false;
     }
     // Attempt to send attach all recipients
     $to_count = count($this->to);
     for ($i = 0; $i < $to_count; ++$i) {
         if (!$this->smtp->Recipient($this->to[$i][0])) {
             $bad_rcpt[] = $this->to[$i][0];
         }
     }
     $cc_count = count($this->cc);
     for ($i = 0; $i < $cc_count; ++$i) {
         if (!$this->smtp->Recipient($this->cc[$i][0])) {
             $bad_rcpt[] = $this->cc[$i][0];
         }
     }
     $bcc_count = count($this->bcc);
     for ($i = 0; $i < $bcc_count; ++$i) {
         if (!$this->smtp->Recipient($this->bcc[$i][0])) {
             $bad_rcpt[] = $this->bcc[$i][0];
         }
     }
     if ($errorx != '') {
         $error = $errorx;
         $error = $this->Lang("recipients_failed") . '  ' . $errorx;
         $this->SetError($error);
         $this->smtp->Reset();
         return false;
     }
     if (count($bad_rcpt) > 0) {
         //Postfix version 2.3.8-2
         $smtp_code_error = substr($this->smtp->error['smtp_msg'], 0, 5);
         //Postfix version 2.1.5-9
         $array_error = explode(":", $this->smtp->error['smtp_msg']);
         $bad_rcpt_count = count($bad_rcpt);
         for ($i = 0; $i < $bad_rcpt_count; ++$i) {
             if ($i != 0) {
                 $error .= ", ";
             }
             $error .= $bad_rcpt[$i];
         }
         if ($smtp_code_error == '5.7.1' || trim($array_error[2]) == 'Access denied') {
             $error = $this->Lang("not_allowed") . $error;
         } else {
             $error = $this->Lang("recipients_failed") . $error;
         }
         $this->SetError($error);
         $this->smtp->Reset();
         return false;
     }
     // Vai verificar se deve cifrar a msg ......
     if (count($this->Certs_crypt) > 0) {
         // Vai cifrar a msg antes de enviar ......
         include_once "../security/classes/CertificadoB.php";
         $teste1 = array();
         $aux_cifra1 = $header . $body;
         // Início relocação dos headers
         // Esta relocação dos headers podem causar problemas.
         $match = 0;
         $pattern = '/^Disposition\\-Notification\\-To:.*\\n/m';
         $match = preg_match($pattern, $aux_cifra1, $teste1);
         if (!empty($match)) {
             $aux_cifra1 = preg_replace($pattern, '', $aux_cifra1, 1);
             // retira o Disposition-Notification-To
             $match = 0;
             $teste2 = array();
             $pattern = '/^MIME\\-Version:.*\\n/m';
             $match = preg_match($pattern, $aux_cifra1, $teste2);
             $aux_cifra1 = preg_replace($pattern, $teste1[0] . $teste2[0], $aux_cifra1, 1);
             // Adiciona Disposition-Notification-To logo acima de MIME-Version
         }
         // Fim relocação dos headers
         // Vai partir em duas partes a msg.  A primeira parte he a dos headers, e a segunda vai ser criptografada ...
         $pos_content_type = strpos($aux_cifra1, 'Content-Type:');
         $pos_MIME_Version = strpos($aux_cifra1, 'MIME-Version: 1.0' . chr(0xd) . chr(0xa));
         $valx_len = 19;
         if ($pos_MIME_Version === False) {
             $pos_MIME_Version = strpos($aux_cifra1, 'MIME-Version: 1.0' . chr(0xa));
             $valx_len = 18;
         }
         if ($pos_MIME_Version >= $pos_content_type) {
             // nao deve enviar a msg..... O header MIME-Version com posicao invalida ......
             $this->SetError('Formato dos headers da msg estao invalidos.(CD-17) - A');
             $this->smtp->Reset();
             return false;
         }
         $aux_cifra2 = array();
         $aux_cifra2[] = substr($aux_cifra1, 0, $pos_MIME_Version - 1);
         $aux_cifra2[] = substr($aux_cifra1, $pos_MIME_Version + $valx_len);
         /*
         			// este explode pode ser fonte de problemas .......
         			$aux_cifra2 = explode('MIME-Version: 1.0' . chr(0x0A), $aux_cifra1);
         			// Pode ocorrer um erro se nao tiver o header MIME-Version .....
         			if(count($aux_cifra2)  != 2 )
         				{
         					$aux_cifra2 = explode('MIME-Version: 1.0' . chr(0x0D) . chr(0x0A), $aux_cifra1);
         					if(count($aux_cifra2)  != 2 )
         						{
         							// nao deve enviar a msg..... nao tem o header MIME-Version ......
         							$this->SetError('Formato dos headers da msg estao invalidos.(CD-17) - ' . count($aux_cifra2));
         							$this->smtp->Reset();
         							return false;
         						}
         				}
         */
         $certificado = new certificadoB();
         $h = array();
         $aux_body = $certificado->encriptar($aux_cifra2[1], $this->Certs_crypt, $h);
         if (!$aux_body) {
             $this->SetError('Ocorreu um erro. A msg nao foi enviada. (CD-18)');
             $this->smtp->Reset();
             return false;
         }
         // salvar sem cifra......
         //$smtpSent = $this->smtp->Data($aux_cifra2[0] . $aux_body);
         // salva a msg sifrada. neste caso deve ter sido adicionado o certificado do autor da msg......
         $header = $aux_cifra2[0];
         $body = $aux_body;
         $smtpSent = $this->smtp->Data($header . $body);
     } else {
         $smtpSent = $this->smtp->Data($header . $body);
     }
     if (!$smtpSent) {
         $this->SetError($this->Lang("data_not_accepted") . ' ' . $this->smtp->error['error'] . ',' . $this->smtp->error['smtp_code'] . ',' . $this->smtp->error['smtp_msg']);
         $this->smtp->Reset();
         return false;
     }
     if ($this->SMTPKeepAlive == true) {
         $this->smtp->Reset();
     } else {
         $this->SmtpClose();
     }
     if ($this->SaveMessageInFolder) {
         $username = $_SESSION['phpgw_info']['expressomail']['user']['userid'];
         $password = $_SESSION['phpgw_info']['expressomail']['user']['passwd'];
         $imap_server = $_SESSION['phpgw_info']['expressomail']['email_server']['imapServer'];
         $imap_port = $_SESSION['phpgw_info']['expressomail']['email_server']['imapPort'];
         if ($_SESSION['phpgw_info']['expressomail']['email_server']['imapTLSEncryption'] == 'yes') {
             $imap_options = '/tls/novalidate-cert';
         } else {
             $imap_options = '/notls/novalidate-cert';
         }
         $mbox_stream = imap_open("{" . $imap_server . ":" . $imap_port . $imap_options . "}" . $this->SaveMessageInFolder, $username, $password);
         ##
         # @AUTHOR Rodrigo Souza dos Santos
         # @DATE 2008/09/11
         # @BRIEF Adding arbitrarily the BCC field. You may need to
         #        check if this field already exists in the header.
         ##
         if (count($this->bcc) > 0) {
             $target = stripos($header, 'subject');
             $header = substr($header, 0, $target) . $this->AddrAppend("Bcc", $this->bcc) . substr($header, $target);
         }
         $new_headerx = str_replace(chr(0xa), chr(0xd) . chr(0xa), $header);
         $new_bodyx = str_replace(chr(0xa), chr(0xd) . chr(0xa), $body);
         $new_header = str_replace(chr(0xd) . chr(0xd) . chr(0xa), chr(0xd) . chr(0xa), $new_headerx);
         $new_body = str_replace(chr(0xd) . chr(0xd) . chr(0xa), chr(0xd) . chr(0xa), $new_bodyx);
         if ($this->SaveMessageAsDraft) {
             imap_append($mbox_stream, "{" . $imap_server . ":" . $imap_port . "}" . $this->SaveMessageInFolder, $new_header . $new_body, "\\Seen \\Draft");
             return true;
         } else {
             imap_append($mbox_stream, "{" . $imap_server . ":" . $imap_port . "}" . $this->SaveMessageInFolder, $new_header . $new_body, "\\Seen");
         }
     }
     return $smtpSent;
 }
 function send_mail($params)
 {
     require_once dirname(__FILE__) . '/../../services/class.servicelocator.php';
     require_once dirname(__FILE__) . '/../../prototype/api/controller.php';
     $mailService = ServiceLocator::getService('mail');
     include_once "class.db_functions.inc.php";
     $db = new db_functions();
     $fromaddress = $params['input_from'] ? explode(';', $params['input_from']) : "";
     $message_attachments_contents = isset($params['message_attachments_content']) ? $params['message_attachments_content'] : false;
     ##
     # @AUTHOR Rodrigo Souza dos Santos
     # @DATE 2008/09/17$fileName
     # @BRIEF Checks if the user has permission to send an email with the email address used.
     ##
     if (is_array($fromaddress) && $fromaddress[1] != $_SESSION['phpgw_info']['expressomail']['user']['email']) {
         $deny = true;
         foreach ($_SESSION['phpgw_info']['expressomail']['user']['shared_mailboxes'] as $key => $val) {
             if (array_key_exists('mail', $val) && $val['mail'][0] == $fromaddress[1]) {
                 $deny = false and end($_SESSION['phpgw_info']['expressomail']['user']['shared_mailboxes']);
             }
         }
         if ($deny) {
             return "The server denied your request to send a mail, you cannot use this mail address.";
         }
     }
     $params['input_to'] = mb_convert_encoding($params['input_to'], "ISO-8859-1", "UTF-8, ISO-8859-1");
     $params['input_cc'] = mb_convert_encoding($params['input_cc'], "ISO-8859-1", "UTF-8, ISO-8859-1");
     $params['input_cco'] = mb_convert_encoding($params['input_cco'], "ISO-8859-1", "UTF-8, ISO-8859-1");
     if (substr($params['input_to'], -1) == ',') {
         $params['input_to'] = substr($params['input_to'], 0, -1);
     }
     if (substr($params['input_cc'], -1) == ',') {
         $params['input_cc'] = substr($params['input_cc'], 0, -1);
     }
     if (substr($params['input_cco'], -1) == ',') {
         $params['input_cco'] = substr($params['input_cco'], 0, -1);
     }
     /*Wraps the text dividing the emails as from ">,"*/
     $toaddress = $db->getAddrs(preg_split('/>,/', preg_replace('/>,/', '>>,', $params['input_to'])));
     $ccaddress = $db->getAddrs(preg_split('/>,/', preg_replace('/>,/', '>>,', $params['input_cc'])));
     $ccoaddress = $db->getAddrs(preg_split('/>,/', preg_replace('/>,/', '>>,', $params['input_cco'])));
     if ($toaddress["False"] || $ccaddress["False"] || $ccoaddress["False"]) {
         return $this->parse_error("Invalid Mail:", $toaddress["False"] ? $toaddress["False"] : ($ccaddress["False"] ? $ccaddress["False"] : $ccoaddress["False"]));
     }
     $toaddress = implode(',', $toaddress);
     $ccaddress = implode(',', $ccaddress);
     $ccoaddress = implode(',', $ccoaddress);
     if ($toaddress == "" && $ccaddress == "" && $ccoaddress == "") {
         return $this->parse_error("Invalid Mail:", $params['input_to'] ? $params['input_to'] : ($params['input_cc'] ? $params['input_cc'] : $params['input_cco']));
     }
     $toaddress = preg_replace('/<\\s+/', '<', $toaddress);
     $toaddress = preg_replace('/\\s+>/', '>', $toaddress);
     $ccaddress = preg_replace('/<\\s+/', '<', $ccaddress);
     $ccaddress = preg_replace('/\\s+>/', '>', $ccaddress);
     $ccoaddress = preg_replace('/<\\s+/', '<', $ccoaddress);
     $ccoaddress = preg_replace('/\\s+>/', '>', $ccoaddress);
     $replytoaddress = $params['input_reply_to'];
     $subject = mb_convert_encoding($params['input_subject'], "ISO-8859-1", "UTF-8, ISO-8859-1");
     $return_receipt = $params['input_return_receipt'];
     $is_important = $params['input_important_message'];
     $encrypt = $params['input_return_cripto'];
     $signed = $params['input_return_digital'];
     $params['attachments'] = mb_convert_encoding($params['attachments'], "UTF7-IMAP", "UTF-8, ISO-8859-1, UTF7-IMAP");
     $message_attachments = $params['message_attachments'];
     $user_info = $_SESSION['phpgw_info']['expressomail']['user'];
     $sent_from = '"' . $user_info['fullname'] . '" <' . $user_info['email'] . '>';
     if ($fromaddress) {
         $sent_from = $fromaddress;
         if (is_array($sent_from)) {
             $sent_from = '"' . $sent_from[0] . '" <' . $sent_from[1] . '>';
         }
     }
     $loginfo = "|# Subject: {$subject} #|# FROM: {$sent_from} #|# TO: {$toaddress} #|# CC: {$ccaddress} #|# BCC: {$ccoaddress} #|# REPLY_TO: {$replytoaddress}";
     // Valida numero Maximo de Destinatarios
     if ($_SESSION['phpgw_info']['expresso']['expressoMail']['expressoAdmin_maximum_recipients'] > 0) {
         $sendersNumber = count(explode(',', $params['input_to']));
         if ($params['input_cc']) {
             $sendersNumber += count(explode(',', $params['input_cc']));
         }
         if ($params['input_cco']) {
             $sendersNumber += count(explode(',', $params['input_cco']));
         }
         $userMaxmimumSenders = $db->getMaximumRecipientsUser($this->username);
         if ($userMaxmimumSenders) {
             if ($sendersNumber > $userMaxmimumSenders) {
                 return $this->functions->getLang('Number of recipients greater than allowed');
             }
         } else {
             $ldap = new ldap_functions();
             $groupsToUser = $ldap->get_user_groups($this->username);
             $groupMaxmimumSenders = $db->getMaximumRecipientsGroup($groupsToUser);
             if ($groupMaxmimumSenders > 0) {
                 if ($sendersNumber > $groupMaxmimumSenders) {
                     return $this->functions->getLang('Number of recipients greater than allowed');
                 }
             } else {
                 if ($sendersNumber > $_SESSION['phpgw_info']['expresso']['expressoMail']['expressoAdmin_maximum_recipients']) {
                     return $this->functions->getLang('Number of recipients greater than allowed');
                 }
             }
         }
     }
     //Fim Valida numero maximo de destinatarios
     //Valida envio de email para shared accounts
     if ($_SESSION['phpgw_info']['expresso']['expressoMail']['expressoMail_block_institutional_comunication'] == 'true') {
         $ldap = new ldap_functions();
         $arrayF = explode(';', $params['input_from']);
         /*
          * Verifica se o remetente n?o ? uma conta compartilhada
          */
         if (!$ldap->isSharedAccountByMail($arrayF[1])) {
             $groupsToUser = $ldap->get_user_groups($this->username);
             $sharedAccounts = $ldap->returnSharedsAccounts($toaddress, $ccaddress, $ccoaddress);
             /*
              * Pega o UID do remetente
              */
             $uidFrom = $ldap->mail2uid($arrayF[1]);
             /*
              * Remove a conta compartilhada caso o uid do remetente exista na conta compartilhada
              */
             foreach ($sharedAccounts as $key => $value) {
                 if ($value) {
                     $acl = $this->getaclfrombox($value);
                 }
                 if (array_key_exists($uidFrom, $acl)) {
                     unset($sharedAccounts[$key]);
                 }
             }
             /*
              * Caso ainda exista contas compartilhadas, verifica se existe alguma exce??o para estas contas
              */
             if (count($sharedAccounts) > 0) {
                 $accountsBlockeds = $db->validadeSharedAccounts($this->username, $groupsToUser, $sharedAccounts);
             }
             /*
              * Retorna as contas compartilhadas bloqueadas
              */
             if (count($accountsBlockeds) > 0) {
                 $return = '';
                 foreach ($accountsBlockeds as $accountBlocked) {
                     $return .= $accountBlocked . ', ';
                 }
                 $return = substr($return, 0, -2);
                 return $this->functions->getLang('you are blocked from sending mail to the following addresses') . ': ' . $return;
             }
         }
     }
     // Fim Valida envio de email para shared accounts
     //	    TODO - implementar tratamento SMIME no novo serviço de envio de emails e retirar o AND false abaixo
     if ($params['smime'] and false) {
         $body = $params['smime'];
         $mail->SMIME = true;
         // A MSG assinada deve ser testada neste ponto.
         // Testar o certificado e a integridade da msg....
         include_once dirname(__FILE__) . "/../../security/classes/CertificadoB.php";
         $erros_acumulados = '';
         $certificado = new certificadoB();
         $validade = $certificado->verificar($body);
         if (!$validade) {
             foreach ($certificado->erros_ssl as $linha_erro) {
                 $erros_acumulados .= $linha_erro;
             }
         } else {
             // Testa o CERTIFICADO: se o CPF  he o do usuario logado, se  pode assinar msgs e se  nao esta expirado...
             if ($certificado->apresentado) {
                 if ($certificado->dados['EXPIRADO']) {
                     $erros_acumulados .= 'Certificado expirado.';
                 }
                 $this->cpf = isset($GLOBALS['phpgw_info']['server']['certificado_atributo_cpf']) && $GLOBALS['phpgw_info']['server']['certificado_atributo_cpf'] != '' ? $_SESSION['phpgw_info']['expressomail']['user'][$GLOBALS['phpgw_info']['server']['certificado_atributo_cpf']] : $this->username;
                 if ($certificado->dados['CPF'] != $this->cpf) {
                     $erros_acumulados .= ' CPF no certificado diferente do logado no expresso.';
                 }
                 if (!($certificado->dados['KEYUSAGE']['digitalSignature'] && $certificado->dados['EXTKEYUSAGE']['emailProtection'])) {
                     $erros_acumulados .= ' Certificado nao permite assinar mensagens.';
                 }
             } else {
                 ${$erros_acumulados} .= 'Nao foi possivel usar o certificado para assinar a msg';
             }
         }
         if (!$erros_acumulados == '') {
             return $erros_acumulados;
         }
     } else {
         //Compatibilização com Outlook, ao encaminhar a mensagem
         $body = mb_ereg_replace('<!--\\[', '<!-- [', base64_decode($params['body']));
         $body = str_replace("&lt;", "&yzwkx;", $body);
         //Alterar as Entities padrão das tags < > para compatibilizar com o Expresso
         $body = str_replace("&gt;", "&xzwky;", $body);
         $body = str_replace("%nbsp;", "&nbsp;", $body);
         //$body = preg_replace("/\n/"," ",$body);
         //$body = preg_replace("/\r/","" ,$body);
         $body = html_entity_decode($body, ENT_QUOTES, 'ISO-8859-1');
         $body = str_replace("&yzwkx;", "&lt;", $body);
         $body = str_replace("&xzwky;", "&gt;", $body);
     }
     $attachments = $_FILES;
     $forwarding_attachments = $params['forwarding_attachments'];
     $local_attachments = $params['local_attachments'];
     //Test if must be saved in shared folder and change if necessary
     if ($fromaddress[2] == 'y') {
         //build shared folder path
         $newfolder = "user" . $this->imap_delimiter . $fromaddress[3] . $this->imap_delimiter . $this->imap_sentfolder;
         if ($this->folder_exists($newfolder)) {
             $has_new_folder = false;
             $folder = $newfolder;
         } else {
             $name_folder = $this->imap_sentfolder;
             $base_path = "user" . $this->imap_delimiter . $fromaddress[3];
             $arr_new_folder['newp'] = $name_folder;
             $arr_new_folder['base_path'] = $base_path;
             $this->create_mailbox($arr_new_folder);
             $has_new_folder = true;
             $folder = $newfolder;
         }
     } else {
         $has_new_folder = false;
         $folder = $params['folder'];
     }
     $folder = mb_convert_encoding($folder, 'UTF7-IMAP', 'ISO-8859-1');
     $folder = preg_replace('/INBOX[\\/.]/i', 'INBOX' . $this->imap_delimiter, $folder);
     $folder_name = $params['folder_name'];
     //		TODO - tratar assinatura e remover o AND false
     if ($signed && !$params['smime'] and false) {
         $mail->Mailer = "smime";
         $mail->SignedBody = true;
     }
     $from = $fromaddress ? '"' . $fromaddress[0] . '" <' . $fromaddress[1] . '>' : '"' . $_SESSION['phpgw_info']['expressomail']['user']['fullname'] . '" <' . $_SESSION['phpgw_info']['expressomail']['user']['email'] . '>';
     $mailService->setFrom(mb_convert_encoding($from, "ISO-8859-1", "UTF-8, ISO-8859-1"));
     $mailService->addHeaderField('Reply-To', !!$replytoaddress ? $replytoaddress : $from);
     $bol = $this->add_recipients('to', $toaddress, $mailService);
     if (!$bol) {
         return $this->parse_error("Invalid Mail:", $toaddress);
     }
     $bol = $this->add_recipients('cc', $ccaddress, $mailService);
     if (!$bol) {
         return $this->parse_error("Invalid Mail:", $ccaddress);
     }
     $allow = $_SESSION['phpgw_info']['server']['expressomail']['allow_hidden_copy'];
     if ($allow) {
         //$mailService->addBcc($ccoaddress);
         $bol = $this->add_recipients('cco', $ccoaddress, $mailService);
         if (!$bol) {
             return $this->parse_error("Invalid Mail:", $ccoaddress);
         }
     }
     //Implementação para o In-Reply-To e References
     $msg_numb = $params['messageNum'];
     $msg_folder = $params['messageFolder'];
     $this->mbox = $this->open_mbox($msg_folder);
     $header = $this->get_header($msg_numb);
     $header_ = imap_fetchheader($this->mbox, $msg_numb, FT_UID);
     $pattern = '/^[ \\t]*Disposition-Notification-To:.*/mi';
     if (preg_match($pattern, $header_, $fields)) {
         $return['DispositionNotificationTo'] = base64_encode(trim(str_ireplace('Disposition-Notification-To:', '', $fields[0])));
     }
     $message_id = $header->message_id;
     $references = array();
     if ($message_id != "") {
         $mailService->addHeaderField('In-Reply-To', $message_id);
         if (isset($header->references)) {
             array_push($references, $header->references);
         }
         array_push($references, $message_id);
         $mailService->addHeaderField('References', $references);
     }
     $mailService->setSubject($subject);
     $isHTML = isset($params['type']) && $params['type'] == 'html' ? true : false;
     //	TODO - tratar mensagem criptografada e remover o AND false abaixo
     if ($encrypt && $signed && $params['smime'] || $encrypt && !$signed and false) {
         // a msg deve ser enviada cifrada...
         $email = $this->add_recipients_cert($toaddress . ',' . $ccaddress . ',' . $ccoaddress);
         $email = explode(",", $email);
         // Deve ser testado se foram obtidos os certificados de todos os destinatarios.
         // Deve ser verificado um numero limite de destinatarios.
         // Deve ser verificado se os certificados sao validos.
         // Se uma das verificacoes falhar, nao enviar o e-mail e avisar o usuario.
         // O array $mail->Certs_crypt soh deve ser preenchido se os certificados passarem nas verificacoes.
         $numero_maximo = $_SESSION['phpgw_info']['user']['preferences']['expressoMail']['num_max_certs_to_cipher'];
         // Este valor dever ser configurado pelo administrador do site ....
         $erros_acumulados = "";
         $aux_mails = array();
         $mail_list = array();
         if (count($email) > $numero_maximo) {
             $erros_acumulados .= "Excedido o numero maximo (" . $numero_maximo . ") de destinatarios para uma msg cifrada...." . chr(0xa);
             return $erros_acumulados;
         }
         // adiciona o email do remetente. eh para cifrar a msg para ele tambem. Assim vai poder visualizar a msg na pasta enviados..
         $email[] = $_SESSION['phpgw_info']['expressomail']['user']['email'];
         foreach ($email as $item) {
             $certificate = $db->get_certificate(strtolower($item));
             if (!$certificate) {
                 $erros_acumulados .= "Chamada com parametro invalido.  e-Mail nao pode ser vazio." . chr(0xa);
                 return $erros_acumulados;
             }
             if (array_key_exists("dberr1", $certificate)) {
                 $erros_acumulados .= "Ocorreu um erro quando pesquisava certificados dos destinatarios para cifrar a msg." . chr(0xa);
                 return $erros_acumulados;
             }
             if (array_key_exists("dberr2", $certificate)) {
                 $erros_acumulados .= $item . ' : Nao  pode cifrar a msg. Certificado nao localizado.' . chr(0xa);
                 //continue;
             }
             /*  Retirado este teste para evitar mensagem de erro duplicada.
                  if (!array_key_exists("certs", $certificate))
                  {
                  $erros_acumulados .=  $item . ' : Nao  pode cifrar a msg. Certificado nao localizado.' . chr(0x0A);
                  continue;
                  }
                 */
             include_once dirname(__FILE__) . "/../../security/classes/CertificadoB.php";
             foreach ($certificate['certs'] as $registro) {
                 $c1 = new certificadoB();
                 $c1->certificado($registro['chave_publica']);
                 if ($c1->apresentado) {
                     $c2 = new Verifica_Certificado($c1->dados, $registro['chave_publica']);
                     if (!$c1->dados['EXPIRADO'] && !$c2->revogado && $c2->status) {
                         $aux_mails[] = $registro['chave_publica'];
                         $mail_list[] = strtolower($item);
                     } else {
                         if ($c1->dados['EXPIRADO'] || $c2->revogado) {
                             $db->update_certificate($c1->dados['SERIALNUMBER'], $c1->dados['EMAIL'], $c1->dados['AUTHORITYKEYIDENTIFIER'], $c1->dados['EXPIRADO'], $c2->revogado);
                         }
                         $erros_acumulados .= $item . ':  ' . $c2->msgerro . chr(0xa);
                         foreach ($c2->erros_ssl as $linha) {
                             $erros_acumulados .= $linha . chr(0xa);
                         }
                         $erros_acumulados .= 'Emissor: ' . $c1->dados['EMISSOR'] . chr(0xa);
                         $erros_acumulados .= $c1->dados['CRLDISTRIBUTIONPOINTS'] . chr(0xa);
                     }
                 } else {
                     $erros_acumulados .= $item . ' : Nao  pode cifrar a msg. Certificado invalido.' . chr(0xa);
                 }
             }
             if (!in_array(strtolower($item), $mail_list) && !empty($erros_acumulados)) {
                 return $erros_acumulados;
             }
         }
         $mail->Certs_crypt = $aux_mails;
     }
     $attachment = json_decode($params['attachments'], TRUE);
     $message_size_total = 0;
     // se possui anexos, inserir informação no log
     if (count($attachment) > 0) {
         $loginfo .= "#|# ATTACH: ";
     }
     foreach ($attachment as &$value) {
         if ((int) $value > 0) {
             $att = Controller::read(array('id' => $value, 'concept' => 'mailAttachment'));
             if ($att['disposition'] == 'embedded' && $isHTML) {
                 $body = str_replace('"../prototype/getArchive.php?mailAttachment=' . $att['id'] . '"', '"' . mb_convert_encoding($att['name'], 'ISO-8859-1', 'UTF-8,ISO-8859-1') . '"', $body);
                 $mailService->addStringImage(base64_decode($att['source']), $att['type'], mb_convert_encoding($att['name'], 'ISO-8859-1', 'UTF-8,ISO-8859-1'));
                 $loginfo .= "[" . $att['name'] . ":" . $att['size'] . "]";
             } else {
                 $mailService->addStringAttachment(base64_decode($att['source']), mb_convert_encoding($att['name'], 'ISO-8859-1', 'UTF-8,ISO-8859-1'), $att['type'], 'base64', isset($att['disposition']) ? $att['disposition'] : 'attachment');
                 $loginfo .= "[" . $att['name'] . ":" . $att['size'] . "]";
             }
             $message_size_total += $att['size'];
             unset($att);
         } else {
             $value = json_decode($value, true);
             if ($value["folder"] == "archiver") {
                 $value['folder'] = "INBOX/Trash";
             }
             switch ($value['type']) {
                 case 'imapPart':
                     $att = $this->getForwardingAttachment(mb_convert_encoding($value['folder'], 'ISO-8859-1', 'UTF7-IMAP'), $value['uid'], $value['part']);
                     if (strstr($body, 'src="./inc/get_archive.php?msgFolder=' . $value['folder'] . '&msgNumber=' . $value['uid'] . '&indexPart=' . $value['part'] . '"') !== false) {
                         $body = str_ireplace('src="./inc/get_archive.php?msgFolder=' . $value['folder'] . '&msgNumber=' . $value['uid'] . '&indexPart=' . $value['part'] . '"', 'src="' . $att['name'] . '"', $body);
                         $mailService->addStringImage($att['source'], $att['type'], mb_convert_encoding($att['name'], 'ISO-8859-1', 'UTF-8,ISO-8859-1'));
                     } else {
                         $mailService->addStringAttachment($att['source'], mb_convert_encoding($att['name'], 'ISO-8859-1', 'UTF-8,ISO-8859-1'), $att['type'], 'base64', isset($att['disposition']) ? $att['disposition'] : 'attachment');
                         $loginfo .= "[" . $att['name'] . ":" . $att['fsize'] . "]";
                     }
                     $message_size_total += $att['fsize'];
                     //Adiciona o tamanho do anexo a variavel que controlao tamanho da msg.
                     unset($att);
                     break;
                 case 'imapMSG':
                     $mbox_stream = $this->open_mbox(mb_convert_encoding($value['folder'], 'ISO-8859-1', 'UTF7-IMAP'));
                     $rawmsg = $this->getRawHeader($value['uid']) . "\r\n\r\n" . $this->getRawBody($value['uid']);
                     $mailService->addStringAttachment($rawmsg, mb_convert_encoding(base64_decode($value['name']), 'ISO-8859-1', 'UTF-8,ISO-8859-1'), 'message/rfc822', '7bit', 'attachment');
                     /*envia o anexo para o email*/
                     $message_size_total += mb_strlen($rawmsg);
                     //Adiciona o tamanho do anexo a variavel que controlao tamanho da msg.
                     unset($rawmsg);
                     //TODO: tem como fazer log deste tipo de anexo?
                     break;
                 default:
                     break;
             }
         }
     }
     $message_size_total += strlen($params['body']);
     /* Tamanho do corpo da mensagem. */
     ////////////////////////////////////////////////////////////////////////////////////////////////////
     /**
      * Faz a validação pelo tamanho máximo de mensagem permitido para o usuário. Se o usuário não estiver em nenhuma regra, usa o tamanho padrão.
      */
     $default_max_size_rule = $db->get_default_max_size_rule();
     if (!$default_max_size_rule) {
         $default_max_size_rule = str_replace("M", "", ini_get('upload_max_filesize')) * 1024 * 1024;
         /* hack para não bloquear o envio de email quando não for configurado um tamanho padrão */
     } else {
         foreach ($default_max_size_rule as $i => $value) {
             $default_max_size_rule = $value['config_value'];
         }
     }
     $default_max_size_rule = $default_max_size_rule * 1024 * 1024;
     /* Tamanho da regra padrão, em bytes */
     $id_user = $_SESSION['phpgw_info']['expressomail']['user']['userid'];
     $ldap = new ldap_functions();
     $groups_user = $ldap->get_user_groups($id_user);
     $size_rule_by_group = array();
     foreach ($groups_user as $k => $value_) {
         $rule_in_group = $db->get_rule_by_user_in_groups($k);
         if ($rule_in_group != "") {
             array_push($size_rule_by_group, $rule_in_group);
         }
     }
     $n_rule_groups = 0;
     $maior_valor_regra_grupo = 0;
     foreach ($size_rule_by_group as $i => $value) {
         if (is_array($value[0])) {
             ++$n_rule_groups;
             if ($value[0]['email_max_recipient'] > $maior_valor_regra_grupo) {
                 $maior_valor_regra_grupo = $value[0]['email_max_recipient'];
             }
         }
     }
     if ($default_max_size_rule) {
         $size_rule = $db->get_rule_by_user($_SESSION['phpgw_info']['expressomail']['user']['userid']);
         if (!$size_rule && $n_rule_groups == 0) {
             if ($message_size_total > $default_max_size_rule) {
                 return $this->functions->getLang("Message size greateruler than allowed (Default rule)") . " (" . $default_max_size_rule / 1024 / 1024 . " Mb)";
             }
         } else {
             if (count($size_rule) > 0) {
                 $regra_mais_permissiva = 0;
                 foreach ($size_rule as $i => $value) {
                     if ($regra_mais_permissiva < $value['email_max_recipient']) {
                         $regra_mais_permissiva = $value['email_max_recipient'];
                     }
                 }
                 $regra_mais_permissiva = $regra_mais_permissiva * 1024 * 1024;
                 if ($message_size_total > $regra_mais_permissiva) {
                     return $this->functions->getLang("Message size greater than allowed (Rule By User)");
                 }
             } else {
                 $maior_valor_regra_grupo = $maior_valor_regra_grupo * 1024 * 1024;
                 if ($message_size_total > $maior_valor_regra_grupo) {
                     return $this->functions->getLang("Message size greater than allowed (Rule By Group)");
                 }
             }
         }
     }
     /**
      * Fim da validação do tamanho da regra do tamanho de mensagem.
      */
     ////////////////////////////////////////////////////////////////////////////////////////////////////
     if ($isHTML) {
         $this->rfc2397ToEmbeddedAttachment($mailService, $body);
         $defaultStyle = '';
         if (isset($_SESSION['phpgw_info']['user']['preferences']['expressoMail']['font_family_editor']) && $_SESSION['phpgw_info']['user']['preferences']['expressoMail']['font_family_editor']) {
             $defaultStyle .= ' font-family:' . $_SESSION['phpgw_info']['user']['preferences']['expressoMail']['font_family_editor'] . ';';
         }
         if (isset($_SESSION['phpgw_info']['user']['preferences']['expressoMail']['font_size_editor']) && $_SESSION['phpgw_info']['user']['preferences']['expressoMail']['font_size_editor']) {
             $defaultStyle .= ' font-size:' . $_SESSION['phpgw_info']['user']['preferences']['expressoMail']['font_size_editor'] . ';';
         }
         $body = '<span class="' . $defaultStyle . '">' . $body . '</span>';
         $mailService->setBodyHtml($body);
     } else {
         $mailService->setBodyText(mb_convert_encoding($body, 'ISO-8859-1', 'UTF-8,ISO-8859-1'));
     }
     $mailService->addHeaderField('Message-ID', "<" . md5(uniqid(time())) . "@" . $_SERVER['SERVER_NAME'] . ">\n");
     if ($is_important) {
         $mailService->addHeaderField('Importance', 'High');
     }
     if ($return_receipt) {
         $mailService->addHeaderField('Disposition-Notification-To', $_SESSION['phpgw_info']['expressomail']['user']['email']);
     }
     $mailService->addHeaderField('Date', date("r"));
     if ($folder != 'null') {
         $mbox_stream = $this->open_mbox($folder);
         @imap_append($mbox_stream, "{" . $this->imap_server . ":" . $this->imap_port . "}" . $folder, $mailService->getMessage(), "\\Seen");
     }
     $sent = $mailService->send();
     if ($sent !== true) {
         return $this->parse_error($sent);
     } else {
         if ($signed && !$params['smime']) {
             return $sent;
         }
         if ($_SESSION['phpgw_info']['server']['expressomail']['expressoMail_enable_log_messages'] == "True") {
             $userid = $_SESSION['phpgw_info']['expressomail']['user']['userid'];
             $userip = $_SESSION['phpgw_info']['expressomail']['user']['session_ip'];
             $now = date("d/m/y H:i:s");
             $addrs = $toaddress . $ccaddress . $ccoaddress;
             $sent = trim($sent);
             error_log("{$now} - {$userip} - {$sent} [{$subject}] - {$userid} => {$addrs}\r\n", 3, "/home/expressolivre/mail_senders.log");
         }
         if ($params['uids_save']) {
             $this->delete_msgs(array('folder' => $params['save_folder'], 'msgs_number' => $params['uids_save']));
         }
         //return array("success" => true, "folder" => $folder_list);
         Logger::info('expressomail', 'sendmsg', $loginfo);
         return array("success" => true, "load" => $has_new_folder);
     }
 }