True, 'get_info_msg' => True, 'get_info_msgs' => True, 'get_folders_list' => True, 'import_msgs' => True, 'msgs_to_archive' => True ); var $ldap; var $mbox; var $imap_port; var $has_cid; var $imap_options = ''; var $functions; var $prefs; var $foldersLimit; var $imap_sentfolder; function imap_functions (){ $this->foldersLimit = $_SESSION['phpgw_info']['user']['preferences']['expressoMail']['imap_max_folders'] ? $_SESSION['phpgw_info']['user']['preferences']['expressoMail']['imap_max_folders'] : 20000; //Limit of folders (mailboxes) user can see $this->username = $_SESSION['phpgw_info']['expressomail']['user']['userid']; $this->password = $_SESSION['phpgw_info']['expressomail']['user']['passwd']; $this->imap_server = $_SESSION['phpgw_info']['expressomail']['email_server']['imapServer']; $this->imap_port = $_SESSION['phpgw_info']['expressomail']['email_server']['imapPort']; $this->imap_delimiter = $_SESSION['phpgw_info']['expressomail']['email_server']['imapDelimiter']; $this->functions = new functions(); $this->imap_sentfolder = $_SESSION['phpgw_info']['expressomail']['email_server']['imapDefaultSentFolder'] ? $_SESSION['phpgw_info']['expressomail']['email_server']['imapDefaultSentFolder'] : str_replace("*","", $this->functions->getLang("Sent")); $this->has_cid = false; $this->prefs = $_SESSION['phpgw_info']['user']['preferences']['expressoMail']; if ($_SESSION['phpgw_info']['expressomail']['email_server']['imapTLSEncryption'] == 'yes') { $this->imap_options = '/tls/novalidate-cert'; } else { $this->imap_options = '/notls/novalidate-cert'; } } // BEGIN of functions. function open_mbox($folder = False) { if (is_resource($this->mbox)) return $this->mbox; $folder = mb_convert_encoding($folder, "UTF7-IMAP","ISO_8859-1"); $this->mbox = @imap_open("{".$this->imap_server.":".$this->imap_port.$this->imap_options."}".$folder, $this->username, $this->password) or die(serialize(array('imap_error' => $this->parse_error(imap_last_error())))); return $this->mbox; } function parse_error($error){ // This error is returned from Imap. if(strstr($error,'Connection refused')) { return str_replace("%1", $this->functions->getLang("Mail"), $this->functions->getLang("Connection failed with %1 Server. Try later.")); } // This error is returned from Postfix. elseif(strstr($error,'message file too big')) { return str_replace("%1",$_SESSION['phpgw_info']['user']['preferences']['expressoMail']['max_attachment_size'],$this->functions->getLang('The size of this message has exceeded the limit (%1B).')); } elseif(strstr($error,'virus')) { return str_replace("%1", $this->functions->getLang("Mail"), $this->functions->getLang("Your message was rejected by antivirus. Perhaps your attachment has been infected.")); } // This condition verifies if SESSION is expired. elseif(!count($_SESSION)) return "nosession"; return $error; } function get_range_msgs2($params) { // Free others requests session_write_close(); $folder = $params['folder']; $msg_range_begin = $params['msg_range_begin']; $msg_range_end = $params['msg_range_end']; $sort_box_type = $params['sort_box_type']; $sort_box_reverse = $params['sort_box_reverse']; $search_box_type = $params['search_box_type'] != "ALL" && $params['search_box_type'] != "" ? $params['search_box_type'] : false; $sort_array_msg = $this-> get_msgs($folder, $sort_box_type, $search_box_type, $sort_box_reverse,$msg_range_begin,$msg_range_end); $return = array(); $i = 0; $num_msgs = imap_num_msg($this->mbox); if(is_array($sort_array_msg)){ foreach($sort_array_msg as $msg_number => $value) { $temp = $this->get_info_head_msg($msg_number); $temp['msg_sample'] = $this->get_msg_sample($msg_number); if(!$temp) { return false; } $return[$i] = $temp; $i++; } } $return['num_msgs'] = $num_msgs; return $return; } function get_info_head_msg($msg_number) { $head_array = array(); include_once("class.imap_attachment.inc.php"); $imap_attachment = new imap_attachment(); //if ($this->prefs['use_important_flag'] ) //{ /*Como eu preciso do atributo Importance para saber se o email é * importante ou não, uso abaixo a função imap_fetchheader e busco * o atributo importance nela. Isso faz com que eu acesse o cabeçalho * duas vezes e de duas formas diferentes, mas em contrapartida, eu * não preciso reimplementar o método utilizando o fetchheader. * Como as mensagens são renderizadas em um número pequeno por vez, * não parece ter perda considerável de performance. */ $tempHeader = imap_fetchheader($this->mbox, imap_msgno($this->mbox, $msg_number)); $flag = preg_match('/importance *: *(.*)\r/i', $tempHeader, $importance); //} // Reimplementado código para identificação dos e-mails assinados e cifrados // no método getMessageType(). Mário César Kolling $head_array['ContentType'] = $this->getMessageType($msg_number, $tempHeader); $head_array['Importance'] = $flag==0?"Normal":$importance[1]; $header = $this->get_header($msg_number); if (!is_object($header)) return false; $head_array['Recent'] = $header->Recent; $head_array['Unseen'] = $header->Unseen; if($header->Answered =='A' && $header->Draft == 'X'){ $head_array['Forwarded'] = 'F'; } else { $head_array['Answered'] = $header->Answered; $head_array['Draft'] = $header->Draft; } $head_array['Deleted'] = $header->Deleted; $head_array['Flagged'] = $header->Flagged; $head_array['msg_number'] = $msg_number; $head_array['udate'] = $header->udate; $from = $header->from; $head_array['from'] = array(); $head_array['from']['name'] = ( isset( $from[0]->personal ) ) ? $this->decode_string($from[0]->personal) : NULL; $head_array['from']['email'] = $this->decode_string($from[0]->mailbox) . "@" . $from[0]->host; if(!$head_array['from']['name']) $head_array['from']['name'] = $head_array['from']['email']; $to = $header->to; $head_array['to'] = array(); $tmp = ( isset( $to[0]->personal ) ) ? imap_mime_header_decode($to[0]->personal) : NULL; $head_array['to']['name'] = ( isset( $tmp[0]->text ) ) ? $this->decode_string($this->decode_string($tmp[0]->text)) : NULL; $head_array['to']['email'] = ( isset( $to[0]->mailbox ) ) ? ( $this->decode_string($to[0]->mailbox) . "@" . ( ( isset( $to[0]->host ) ) ? $to[0]->host : '' ) ) : NULL; if(!$head_array['to']['name']) $head_array['to']['name'] = $head_array['to']['email']; $head_array['subject'] = ( isset( $header->fetchsubject ) ) ? $this->decode_string($header->fetchsubject) : ''; $head_array['Size'] = $header->Size; $head_array['attachment'] = array(); $head_array['attachment'] = $imap_attachment->get_attachment_headerinfo($this->mbox, $msg_number); return $head_array; } function decode_string($string) { if ((strpos(strtolower($string), '=?iso-8859-1') !== false) || (strpos(strtolower($string), '=?windows-1252') !== false)) { $return = ''; $tmp = imap_mime_header_decode($string); foreach ($tmp as $tmp1) $return .= $this->htmlspecialchars_encode($tmp1->text); return $return; } else if (strpos(strtolower($string), '=?utf-8') !== false) { $elements = imap_mime_header_decode($string); for($i = 0;$i < count($elements);$i++) { $charset = strtolower($elements[$i]->charset); $text = $elements[$i]->text; if(!strcasecmp($charset, "utf-8") || !strcasecmp($charset, "utf-7")) { $decoded .= $this->functions->utf8_to_ncr($text); } else { if( strcasecmp($charset,"default") ) $decoded .= $this->htmlspecialchars_encode(iconv($charset, "iso-8859-1", $text)); else $decoded .= $this->htmlspecialchars_encode($text); } } return $decoded; } else return $this->htmlspecialchars_encode($string); } /** * Função que importa arquivos .eml exportados pelo expresso para a caixa do usuário. Testado apenas * com .emls gerados pelo expresso, e o arquivo pode ser um zip contendo vários emls ou um .eml. */ function import_msgs($params) { if(!$this->mbox) $this->mbox = $this->open_mbox(); if( preg_match('/local_/',$params["folder"]) ) { // PLEASE, BE CAREFULL!!! YOU SHOULD USE EMAIL CONFIGURATION VALUES (EMAILADMIN MODULE) $tmp_box = mb_convert_encoding('INBOX'.$this->imap_delimiter.$_SESSION['phpgw_info']['expressomail']['email_server']['imapDefaultTrashFolder'].$this->imap_delimiter.'tmpMoveToLocal', "UTF7-IMAP", "UTF-8"); if ( ! imap_createmailbox( $this -> mbox,"{".$this -> imap_server."}$tmp_box" ) ) return $this->functions->getLang( 'Import to Local : fail...' ); imap_reopen($this->mbox, "{".$this->imap_server.":".$this->imap_port.$this->imap_options."}".$tmp_box); $params["folder"] = $tmp_box; } $errors = array(); $invalid_format = false; $filename = $params['FILES'][0]['name']; $params["folder"] = mb_convert_encoding($params["folder"], "UTF7-IMAP","ISO_8859-1"); $quota = imap_get_quotaroot($this->mbox, $params["folder"]); if((($quota['limit'] - $quota['usage'])*1024) <= $params['FILES'][0]['size']){ return array( 'error' => $this->functions->getLang("fail in import:"). " ".$this->functions->getLang("Over quota")); } if(substr($filename,strlen($filename)-4)==".zip") { $zip = zip_open($params['FILES'][0]['tmp_name']); if ($zip) { while ($zip_entry = zip_read($zip)) { if (zip_entry_open($zip, $zip_entry, "r")) { $email = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)); $status = @imap_append($this->mbox, "{".$this->imap_server.":".$this->imap_port.$this->imap_options."}".$params["folder"], $email ); if(!$status) array_push($errors,zip_entry_name($zip_entry)); zip_entry_close($zip_entry); } } zip_close($zip); } if ( isset( $tmp_box ) && ! sizeof( $errors ) ) { $mc = imap_check($this->mbox); $result = imap_fetch_overview( $this -> mbox, "1:{$mc -> Nmsgs}", 0 ); $ids = array( ); foreach ($result as $overview) $ids[ ] = $overview -> uid; return implode( ',', $ids ); } } else if(substr($filename,strlen($filename)-4)==".eml") { $email = implode("",file($params['FILES'][0]['tmp_name'])); $status = @imap_append($this->mbox, "{".$this->imap_server.":".$this->imap_port.$this->imap_options."}".$params["folder"], $email ); if(!$status){ array_push($errors,zip_entry_name($zip_entry)); zip_entry_close($zip_entry); } } else { if ( isset( $tmp_box ) ) imap_deletemailbox( $this->mbox,"{".$this -> imap_server."}$tmp_box" ); return array("error" => $this->functions->getLang("wrong file format")); $invalid_format = true; } if(!$invalid_format) { if(count($errors)>0) { $message = $this->functions->getLang("fail in import:")."\n"; foreach($errors as $arquivo) { $message.=$arquivo."\n"; } return array("error" => $message); } else return ("The import was executed successfully."); } } /* Remove os anexos de uma mensagem. A estratégia para isso é criar uma mensagem nova sem os anexos, mantendo apenas a primeira parte do e-mail, que é o texto, sem anexos. O método considera que o email é multpart. */ function remove_attachments($params) { include_once("class.message_components.inc.php"); if(!$this->mbox || !is_resource($this->mbox)) $this->mbox = $this->open_mbox($params["folder"]); $return["status"] = true; $header = ""; $headertemp = explode("\n",imap_fetchheader($this->mbox, imap_msgno($this->mbox, $params["msg_num"]))); foreach($headertemp as $head) {//Se eu colocar todo o header do email dá pau no append, então procuro apenas o que interessa. $head1 = explode(":",$head); if ( (strtoupper($head1[0]) == "TO") || (strtoupper($head1[0]) == "FROM") || (strtoupper($head1[0]) == "SUBJECT") || (strtoupper($head1[0]) == "DATE") || (strtoupper($head1[0]) == "CONTENT-TYPE")) { if(strtoupper($head1[0]) == "CONTENT-TYPE"){ $head = str_replace("multipart/mixed","text/html",$head); } $header .= $head."\n"; } } $msg = &new message_components($this->mbox); $msg->fetch_structure($params["msg_num"]);/* O fetchbody tava trazendo o email com problemas na acentuação. Então uso essa classe para verificar a codificação e o charset, para que o método decodeBody do expresso possa trazer tudo certinho*/ $status = imap_append($this->mbox, "{".$this->imap_server.":".$this->imap_port.$this->imap_options."}".$params["folder"], $header. "\r\n". str_replace("\n","\r\n",$this->decodeBody( imap_fetchbody($this->mbox,imap_msgno($this->mbox, $params["msg_num"]),"1"), $msg->encoding[$params["msg_num"]][0], $msg->charset[$params["msg_num"]][0] ) ), "\\Seen"); //Append do novo email, só com header e conteúdo sem anexos. if(!$status) { $return["status"] = false; $return["msg"] = lang("error appending mail on delete attachments"); } else { $status = imap_status($this->mbox, "{".$this->imap_server.":".$this->imap_port."}".$params['folder'], SA_UIDNEXT); $return['msg_no'] = $status->uidnext - 1; imap_delete($this->mbox, imap_msgno($this->mbox, $params["msg_num"])); imap_expunge($this->mbox); } return $return; } function msgs_to_archive($params) { $folder = $params['folder']; $all_ids = $this-> get_msgs($folder, 'SORTARRIVAL', false, 0,-1,-1); $messages_not_to_copy = explode(",",$params['mails']); $ids = array(); $cont = 0; foreach($all_ids as $each_id=>$value) { if(!in_array($each_id,$messages_not_to_copy)) { array_push($ids,$each_id); $cont++; } if($cont>=100) break; } if (empty($ids)) return array(); $params = array("folder"=>$folder,"msgs_number"=>implode(",",$ids)); return $this->get_info_msgs($params); } /** * * @return * @param $params Object */ function get_info_msgs($params) { include_once("class.exporteml.inc.php"); $return = array(); $new_params = array(); $attach_params = array(); $new_params["msg_folder"]=$params["folder"]; $attach_params["folder"] = $params["folder"]; $msgs = explode(",",$params["msgs_number"]); $exporteml = new ExportEml(); $unseen_msgs = array(); foreach($msgs as $msg_number) { $new_params["msg_number"] = $msg_number; //ini_set("display_errors","1"); $msg_info = $this->get_info_msg($new_params); $this->mbox = $this->open_mbox($params['folder']); //Não sei porque, mas se não abrir de novo a caixa dá erro. $msg_info['header'] = $this->get_info_head_msg($msg_number); $attach_params["num_msg"] = $msg_number; $msg_info['array_attach'] = $exporteml->get_attachments_in_array($attach_params); $msg_info['url_export_file'] = $exporteml->export_to_archive($msg_number,$params["folder"]); imap_close($this->mbox); $this->mbox=false; array_push($return,serialize($msg_info)); if($msg_info['Unseen'] == "U" || $msg_info['Recent'] == "N"){ array_push($unseen_msgs,$msg_number); } } if($unseen_msgs){ $msgs_list = implode(",",$unseen_msgs); $array_msgs = array('folder' => $new_params["msg_folder"], "msgs_to_set" => $msgs_list, "flag" => "unseen"); $this->set_messages_flag($array_msgs); } return $return; } function get_info_msg($params) { $return = array(); $msg_number = $params['msg_number']; if(preg_match('(.+)(_[a-zA-Z0-9]+)',$msg_number,$matches)) { //Verifies if it comes from a tab diferent of the main one. $msg_number = $matches[1]; $plus_id = $matches[2]; } else { $plus_id = ''; } $msg_folder = urldecode($params['msg_folder']); if(!$this->mbox || !is_resource($this->mbox)) $this->mbox = $this->open_mbox($msg_folder); $header = $this->get_header($msg_number); if (!$header) { $return['status_get_msg_info'] = "false"; return $return; } $header_ = imap_fetchheader($this->mbox, $msg_number, FT_UID); $return_get_body = $this->get_body_msg($msg_number, $msg_folder); $body = $return_get_body['body']; if($return_get_body['body']=='isCripted'){ $exporteml = new ExportEml(); $return['source']=$exporteml->export_msg_data($msg_number,$msg_folder); $return['body'] = ""; $return['attachments'] = ""; $return['thumbs'] = ""; $return['signature'] = ""; //return $return; }else{ $return['body'] = $body; $return['attachments'] = $return_get_body['attachments']; $return['thumbs'] = $return_get_body['thumbs']; $return['signature'] = $return_get_body['signature']; } $pattern = '/^[ \t]*Disposition-Notification-To:[ ]*?/sm'; if (preg_match($pattern, $header_, $fields)) { if(preg_match('/[[:alnum:]\._\-]+@[[:alnum:]_\-\.]+/',$fields[0], $matches)){ $return['DispositionNotificationTo'] = "<".$matches[0].">"; } } $return['Recent'] = $header->Recent; $return['Unseen'] = $header->Unseen; $return['Deleted'] = $header->Deleted; $return['Flagged'] = $header->Flagged; if($header->Answered =='A' && $header->Draft == 'X'){ $return['Forwarded'] = 'F'; } else { $return['Answered'] = $header->Answered; $return['Draft'] = $header->Draft; } $return['msg_number'] = $msg_number.$plus_id; $return['msg_folder'] = $msg_folder; $date_msg = gmdate("d/m/Y",$header->udate); if (date("d/m/Y") == $date_msg) $return['udate'] = gmdate("H:i",$header->udate); else $return['udate'] = $date_msg; $return['msg_day'] = $date_msg; $return['msg_hour'] = gmdate("H:i",$header->udate); if (date("d/m/Y") == $date_msg) //no dia { $return['fulldate'] = gmdate("d/m/Y H:i",$header->udate); $return['smalldate'] = gmdate("H:i",$header->udate); $timestamp_now = strtotime("now"); $timestamp_msg_time = $header->udate; // $timestamp_now is GMT and $timestamp_msg_time is MailDate TZ. // The variable $timestamp_diff is calculated without MailDate TZ. $pdate = date_parse($header->MailDate); $timestamp_diff = $timestamp_now - $timestamp_msg_time + ($pdate['zone']*(-60)); if (gmdate("H",$timestamp_diff) > 0) { $return['fulldate'] .= " (" . gmdate("H:i", $timestamp_diff) . ' ' . $this->functions->getLang('hours ago') . ')'; } else { if (gmdate("i",$timestamp_diff) == 0){ $return['fulldate'] .= ' ('. $this->functions->getLang('now').')'; } elseif (gmdate("i",$timestamp_diff) == 1){ $return['fulldate'] .= ' (1 '. $this->functions->getLang('minute ago').')'; } else{ $return['fulldate'] .= " (" . gmdate("i",$timestamp_diff) .' '. $this->functions->getLang('minutes ago') . ')'; } } } else{ $return['fulldate'] = gmdate("d/m/Y H:i",$header->udate); $return['smalldate'] = gmdate("d/m/Y",$header->udate); } $from = $header->from; $return['from'] = array(); $return['from']['name'] = $this->decode_string($from[0]->personal); $return['from']['email'] = $this->decode_string($from[0]->mailbox . "@" . $from[0]->host); if ($return['from']['name']) { if (substr($return['from']['name'], 0, 1) == '"') $return['from']['full'] = $return['from']['name'] . ' ' . '<' . $return['from']['email'] . '>'; else $return['from']['full'] = '"' . $return['from']['name'] . '" ' . '<' . $return['from']['email'] . '>'; } else $return['from']['full'] = $return['from']['email']; // Sender attribute $sender = $header->sender; $return['sender'] = array(); $return['sender']['name'] = $this->decode_string($sender[0]->personal); $return['sender']['email'] = $this->decode_string($sender[0]->mailbox . "@" . $sender[0]->host); if ($return['sender']['name']) { if (substr($return['sender']['name'], 0, 1) == '"') $return['sender']['full'] = $return['sender']['name'] . ' ' . '<' . $return['sender']['email'] . '>'; else $return['sender']['full'] = '"' . $return['sender']['name'] . '" ' . '<' . $return['sender']['email'] . '>'; } else $return['sender']['full'] = $return['sender']['email']; if($return['from']['full'] == $return['sender']['full']) $return['sender'] = null; $to = $header->to; $return['toaddress2'] = ""; if (!empty($to)) { foreach ($to as $tmp) { if (!empty($tmp->personal)) { $personal_tmp = imap_mime_header_decode($tmp->personal); $return['toaddress2'] .= '"' . $personal_tmp[0]->text . '"'; $return['toaddress2'] .= " "; $return['toaddress2'] .= "<"; if ($tmp->host != 'unspecified-domain') $return['toaddress2'] .= $tmp->mailbox . "@" . $tmp->host; else $return['toaddress2'] .= $tmp->mailbox; $return['toaddress2'] .= ">"; $return['toaddress2'] .= ", "; } else { if ($tmp->host != 'unspecified-domain') $return['toaddress2'] .= $tmp->mailbox . "@" . $tmp->host; else $return['toaddress2'] .= $tmp->mailbox; $return['toaddress2'] .= ", "; } } $return['toaddress2'] = $this->del_last_two_caracters($return['toaddress2']); } else { $return['toaddress2'] = "<Empty>"; } $cc = $header->cc; $return['cc'] = ""; if (!empty($cc)) { foreach ($cc as $tmp_cc) { if (!empty($tmp_cc->personal)) { $personal_tmp_cc = imap_mime_header_decode($tmp_cc->personal); $return['cc'] .= '"' . $personal_tmp_cc[0]->text . '"'; $return['cc'] .= " "; $return['cc'] .= "<"; $return['cc'] .= $tmp_cc->mailbox . "@" . $tmp_cc->host; $return['cc'] .= ">"; $return['cc'] .= ", "; } else { $return['cc'] .= $tmp_cc->mailbox . "@" . $tmp_cc->host; $return['cc'] .= ", "; } } $return['cc'] = $this->del_last_two_caracters($return['cc']); } else { $return['cc'] = ""; } ## # @AUTHOR Rodrigo Souza dos Santos # @DATE 2008/09/12 # @BRIEF Adding the BCC field. ## $bcc = $header->bcc; $return['bcc'] = ""; if (!empty($bcc)) { foreach ($bcc as $tmp_bcc) { if (!empty($tmp_bcc->personal)) { $personal_tmp_bcc = imap_mime_header_decode($tmp_bcc->personal); $return['bcc'] .= '"' . $personal_tmp_bcc[0]->text . '"'; $return['bcc'] .= " "; $return['bcc'] .= "<"; $return['bcc'] .= $tmp_bcc->mailbox . "@" . $tmp_bcc->host; $return['bcc'] .= ">"; $return['bcc'] .= ", "; } else { $return['bcc'] .= $tmp_bcc->mailbox . "@" . $tmp_bcc->host; $return['bcc'] .= ", "; } } $return['bcc'] = $this->del_last_two_caracters($return['bcc']); } else { $return['bcc'] = ""; } $reply_to = $header->reply_to; $return['reply_to'] = ""; if (is_object($reply_to[0])) { if ($return['from']['email'] != ($reply_to[0]->mailbox."@".$reply_to[0]->host)) { if (!empty($reply_to[0]->personal)) { $personal_reply_to = imap_mime_header_decode($tmp_reply_to->personal); if(!empty($personal_reply_to[0]->text)) { $return['reply_to'] .= '"' . $personal_reply_to[0]->text . '"'; $return['reply_to'] .= " "; $return['reply_to'] .= "<"; $return['reply_to'] .= $reply_to[0]->mailbox . "@" . $reply_to[0]->host; $return['reply_to'] .= ">"; } else { $return['reply_to'] .= $reply_to[0]->mailbox . "@" . $reply_to[0]->host; } } else { $return['reply_to'] .= $reply_to[0]->mailbox . "@" . $reply_to[0]->host; } } } $return['reply_to'] = $this->decode_string($return['reply_to']); $return['subject'] = $this->decode_string($header->fetchsubject); $return['Size'] = $header->Size; $return['reply_toaddress'] = $header->reply_toaddress; //All this is to help in local messages $return['timestamp'] = $header->udate; $return['login'] = $_SESSION['phpgw_info']['expressomail']['user']['account_id'];//$GLOBALS['phpgw_info']['user']['account_id']; $return['reply_toaddress'] = $header->reply_toaddress; return $return; } function get_msg_sample($msg_number) { $return = ""; if( (!isset($this->prefs['preview_msg_subject']) || ($this->prefs['preview_msg_subject'] != "1")) && (!isset($this->prefs['preview_msg_tip'] ) || ($this->prefs['preview_msg_tip'] != "1")) ) { $return['body'] = ""; return $return; } include_once("class.message_components.inc.php"); $msg = &new message_components($this->mbox); $msg->fetch_structure($msg_number); if(!$msg->structure[$msg_number]->parts) { $content = ''; if (strtolower($msg->structure[$msg_number]->subtype) == "plain" || strtolower($msg->structure[$msg_number]->subtype) == "html") { $content = $this->decodeBody(imap_body($this->mbox, $msg_number, FT_UID|FT_PEEK), $msg->encoding[$msg_number][0], $msg->charset[$msg_number][0]); } } else { foreach($msg->pid[$msg_number] as $values => $msg_part) { $file_type = strtolower($msg->file_type[$msg_number][$values]); if($file_type == "text/plain" || $file_type == "text/html") { $content = $this->decodeBody(imap_fetchbody($this->mbox, $msg_number, $msg_part, FT_UID|FT_PEEK), $msg->encoding[$msg_number][$values], $msg->charset[$msg_number][$values]); break; } } } $content = $this->replace_special_characters($content); $tags_replace = array("
","
","
"); $content = str_replace($tags_replace," ", $content); $content = strip_tags($content); $content = str_replace(array("{","}"," "), " ", $content); $content = trim($content); $content = html_entity_decode(substr($content,0,300)); $content != "" ? $return['body'] = " - " . $content: $return['body'] = ""; return $return; } function get_body_msg($msg_number, $msg_folder) { include_once("class.message_components.inc.php"); $msg = &new message_components($this->mbox); $msg->fetch_structure($msg_number); $return = array(); $return['attachments'] = $this-> download_attachment($msg,$msg_number); if(!$this->has_cid) { $return['thumbs'] = $this->get_thumbs($msg,$msg_number,urlencode($msg_folder)); $return['signature'] = $this->get_signature($msg,$msg_number,$msg_folder); } if(!$msg->structure[$msg_number]->parts) //Simple message, only 1 piece { if(strtolower($msg->structure[$msg_number]->subtype) == 'x-pkcs7-mime'){ $return['body']='isCripted'; return $return; } $attachment = array(); //No attachments if(strtolower($msg->structure[$msg_number]->subtype) == 'x-pkcs7-mime'){ $return['body']='isCripted'; return $return; } $content = ''; // If simple message is subtype 'html' or 'plain', then get content body. if(strtolower($msg->structure[$msg_number]->subtype) == "html" || strtolower( $msg -> structure[ $msg_number ] -> subtype ) == 'plain'){ $content = $this->decodeBody( imap_body( $this -> mbox, $msg_number, FT_UID ), $msg -> encoding[ $msg_number ][ 0 ], $msg -> charset[ $msg_number ][ 0 ] ); if ( strtolower( $msg -> structure[ $msg_number ] -> subtype ) == 'plain' ) { $content = str_replace( array( '<', '>' ), array( ' #$<$# ', ' #$>$# ' ), $content ); $content = htmlentities( $content ); $content = $this -> replace_links( $content ); $content = str_replace( array( ' #$<$# ', ' #$>$# ' ), array( '<', '>' ), $content ); $content = '
' . $content . '
'; $return[ 'body' ] = $content; return $return; } } } else { //Complicated message, multiple parts $html_body = ''; $content = ''; $has_multipart = true; $this->has_cid = false; if (strtolower($msg->structure[$msg_number]->subtype) == "related") $this->has_cid = true; if (strtolower($msg->structure[$msg_number]->subtype) == "alternative") { $show_only_html = false; foreach($msg->pid[$msg_number] as $values => $msg_part) { $file_type = strtolower($msg->file_type[$msg_number][$values]); if($file_type == "text/html") $show_only_html = true; } } else $show_only_html = false; foreach($msg->pid[$msg_number] as $values => $msg_part) { $file_type = strtolower($msg->file_type[$msg_number][$values]); if($file_type == "message/rfc822" || $file_type == "multipart/alternative") { // Show only 'text/html' part, when message/rfc822 format contains 'text/plain' alternative part. if(array_key_exists($values+1, $msg->file_type[$msg_number]) && strtolower($msg->file_type[$msg_number][$values+1]) == 'text/plain' && array_key_exists($values+2, $msg->file_type[$msg_number]) && strtolower($msg->file_type[$msg_number][$values+2]) == 'text/html') { $has_multipart = false; } } if(($file_type == "text/plain" || $file_type == "text/html") && $file_type != 'attachment') { if($file_type == "text/plain" && !$show_only_html && $has_multipart) { // if TXT file size > 100kb, then it will not expand. if(!($file_type == "text/plain" && $msg->fsize[$msg_number][$values] > 102400)) { $content .= htmlentities($this->decodeBody(imap_fetchbody($this->mbox, $msg_number, $msg_part, FT_UID), $msg->encoding[$msg_number][$values], $msg->charset[$msg_number][$values])); $content = '
' . $content . '
'; } } // if HTML attachment file size > 300kb, then it will not expand. else if($file_type == "text/html" && $msg->fsize[$msg_number][$values] < 307200) { $content .= $this->decodeBody(imap_fetchbody($this->mbox, $msg_number, $msg_part, FT_UID), $msg->encoding[$msg_number][$values], $msg->charset[$msg_number][$values]); $show_only_html = true; } } else if($file_type == "message/delivery-status" || $file_type == "message/feedback-report"){ $content .= "
"; $content .= $this->decodeBody(imap_fetchbody($this->mbox, $msg_number, $msg_part, FT_UID), $msg->encoding[$msg_number][$values], $msg->charset[$msg_number][$values]); $content = '
' . $content . '
'; } else if($file_type == "message/rfc822" || $file_type == "text/rfc822-headers"){ include_once("class.imap_attachment.inc.php"); $att = new imap_attachment(); $attachments = $att -> get_attachment_info($this->mbox,$msg_number); if($attachments['number_attachments'] > 0) { foreach($attachments ['attachment'] as $index => $attachment) { if ( in_array( strtolower( $attachment[ 'type' ] ), array( 'delivery-status', 'rfc822', 'rfc822-headers', 'plain' ) ) ) { $obj = imap_rfc822_parse_headers( imap_fetchbody( $this -> mbox, $msg_number, $msg_part, FT_UID ), $msg -> encoding[ $msg_number ][ $values ] ); $content .= '
'; $content .= '
'; $content .= ''; $content .= ''; $content .= ''; $content .= ''; if ( $obj->cc ) $content .= ''; $content .= '
' . $this->functions->getLang("Subject") . ':' .$this->decode_string($obj->subject) . '
' . $this -> functions -> getLang( 'From' ) . ':' . $this -> replace_links( $this -> decode_string( $obj -> from[ 0 ] -> mailbox . '@' . $obj -> from[ 0 ] -> host) ) . '
' . $this->functions->getLang("Date") . ':' . $obj->date . '
' . $this -> functions -> getLang( 'TO' ) . ':' . $this -> replace_links( $this -> decode_string( $obj -> to[ 0 ] -> mailbox . '@' . $obj -> to[ 0 ] -> host ) ) . '
' . $this -> functions -> getLang( 'CC' ) . ':' . $this -> replace_links( $this -> decode_string( $obj -> cc[ 0 ] -> mailbox . '@' . $obj -> cc[ 0 ] -> host ) ) . '

'; $id = ( ( strtolower( $attachment[ 'type' ] ) == 'delivery-status' ) ? false : true ); if ( strtolower( $msg->structure[$msg_number]->parts[1]->parts[0]->subtype ) == 'plain' ) { $id = !$id; if ( $msg->structure[$msg_number]->parts[1]->parts[0]->encoding == 4 ) $msg->encoding[ $msg_number ][ $values ] = 'quoted-printable'; } $body = $this->decodeBody( imap_fetchbody( $this->mbox, $msg_number, ( $attachment['part_in_msg'] + ( ( int ) $id ) ) . ".1", FT_UID ), $msg->encoding[ $msg_number ][ $values ], $msg->charset[ $msg_number ][ $values ] ); if ( strtolower( $msg->structure[$msg_number]->parts[1]->parts[0]->subtype ) == 'plain' ) { $body = str_replace( array( '<', '>' ), array( ' #$<$# ', ' #$>$# ' ), $body ); $body = htmlentities( $body ); $body = $this -> replace_links( $body ); $body = str_replace( array( ' #$<$# ', ' #$>$# ' ), array( '<', '>' ), $body ); $body = '
' . $body . '
'; } $content .= $body; break; } } } } } if($file_type == "text/plain" && ($show_only_html && $msg_part == 1) || (!$show_only_html && $msg_part == 3)){ if(strtolower($msg->structure[$msg_number]->subtype) == "mixed" && $msg_part == 1) $content .= nl2br(imap_base64(imap_fetchbody($this->mbox, $msg_number, $msg_part, FT_UID))); else if(!strtolower($msg->structure[$msg_number]->subtype) == "mixed") $content .= nl2br(imap_fetchbody($this->mbox, $msg_number, $msg_part, FT_UID)); } } // Force message with flag Seen (imap_fetchbody not works correctly) $params = array('folder' => $msg_folder, "msgs_to_set" => $msg_number, "flag" => "seen"); $this->set_messages_flag($params); $content = $this->process_embedded_images($msg,$msg_number,$content, $msg_folder); $content = $this->replace_special_characters($content); $return['body'] = $content; return $return; } function htmlfilter($body) { require_once('htmlfilter.inc'); $tag_list = Array( false, 'blink', 'object', 'meta', 'html', 'link', 'frame', 'iframe', 'layer', 'ilayer', 'plaintext' ); /** * A very exclusive set: */ // $tag_list = Array(true, "b", "a", "i", "img", "strong", "em", "p"); $rm_tags_with_content = Array( 'script', 'style', 'applet', 'embed', 'head', 'frameset', 'xml', 'xmp' ); $self_closing_tags = Array( 'img', 'br', 'hr', 'input' ); $force_tag_closing = true; $rm_attnames = Array( '/.*/' => Array( '/target/i', //'/^on.*/i', -> onClick, dos compromissos da agenda. '/^dynsrc/i', '/^datasrc/i', '/^data.*/i', '/^lowsrc/i' ) ); /** * Yeah-yeah, so this looks horrible. Check out htmlfilter.inc for * some idea of what's going on here. :) */ $bad_attvals = Array( '/.*/' => Array( '/.*/' => Array( Array( '/^([\'\"])\s*\S+\s*script\s*:*(.*)([\'\"])/si', //'/^([\'\"])\s*https*\s*:(.*)([\'\"])/si', -> doclinks notes '/^([\'\"])\s*mocha\s*:*(.*)([\'\"])/si', '/^([\'\"])\s*about\s*:(.*)([\'\"])/si' ), Array( '\\1oddjob:\\2\\1', //'\\1uucp:\\2\\1', -> doclinks notes '\\1amaretto:\\2\\1', '\\1round:\\2\\1' ) ), '/^style/i' => Array( Array( '/expression/i', '/behaviou*r/i', '/binding/i', '/include-source/i', '/url\s*\(\s*([\'\"]*)\s*https*:.*([\'\"]*)\s*\)/si', '/url\s*\(\s*([\'\"]*)\s*\S+\s*script:.*([\'\"]*)\s*\)/si' ), Array( 'idiocy', 'idiocy', 'idiocy', 'idiocy', 'url(\\1http://securityfocus.com/\\1)', 'url(\\1http://securityfocus.com/\\1)' ) ) ) ); $add_attr_to_tag = Array( '/^a$/i' => Array('target' => '"_new"') ); $trusted_body = sanitize($body, $tag_list, $rm_tags_with_content, $self_closing_tags, $force_tag_closing, $rm_attnames, $bad_attvals, $add_attr_to_tag ); return $trusted_body; } function decodeBody($body, $encoding, $charset=null) { /** * replace e-mail by anchor. */ // HTML Filter //$body = preg_replace("#(^|[\n ])([a-z0-9&\-_.]+?)@([\w\-]+\.([\w\-\.]+\.)*[\w]+)#i", "\\1\\2@\\3", $body); //$body = str_replace("\r\n", "\n", $body); if ($encoding == 'quoted-printable') { /* for($i=0;$i<256;$i++) { $c1=dechex($i); if(strlen($c1)==1){$c1="0".$c1;} $c1="=".$c1; $myqprinta[]=$c1; $myqprintb[]=chr($i); } */ $body = str_replace($myqprinta,$myqprintb,($body)); $body = quoted_printable_decode($body); while (ereg("=\n", $body)) { $body = ereg_replace ("=\n", '', $body); } } else if ($encoding == 'base64') { $body = base64_decode($body); } // All other encodings are returned raw. if (strtolower($charset) == "utf-8") return utf8_decode($body); else return $body; } function process_embedded_images($msg, $msgno, $body, $msg_folder) { if (count($msg->inline_id[$msgno]) > 0) { foreach ($msg->inline_id[$msgno] as $index => $cid) { $cid = eregi_replace("<", "", $cid); $cid = eregi_replace(">", "", $cid); $msg_part = $msg->pid[$msgno][$index]; //$body = eregi_replace("alt=\"\"", "", $body); $body = eregi_replace("
", "", $body); $body = str_replace("src=\"cid:".$cid."\"", " src=\"./inc/show_embedded_attach.php?msg_folder=$msg_folder&msg_num=$msgno&msg_part=$msg_part\" ", $body); $body = str_replace("src='cid:".$cid."'", " src=\"./inc/show_embedded_attach.php?msg_folder=$msg_folder&msg_num=$msgno&msg_part=$msg_part\" ", $body); $body = str_replace("src=cid:".$cid, " src=\"./inc/show_embedded_attach.php?msg_folder=$msg_folder&msg_num=$msgno&msg_part=$msg_part\" ", $body); } } return $body; } function replace_special_characters($body) { // Suspected TAGS! /*$tag_list = Array( 'blink','object','meta', 'html','link','frame', 'iframe','layer','ilayer', 'plaintext','script','style','img', 'applet','embed','head', 'frameset','xml','xmp'); */ // Layout problem: Change html elements // with absolute position to relate position, CASE INSENSITIVE. $body = @mb_eregi_replace("POSITION: ABSOLUTE;","",$body); $tag_list = Array('head','blink','object','frame', 'iframe','layer','ilayer','plaintext','script', 'applet','embed','frameset','xml','xmp','style'); $blocked_tags = array(); foreach($tag_list as $index => $tag) { $new_body = @mb_eregi_replace("<$tag", "", $new_body); } // Malicious Code Remove $dirtyCodePattern = "/(<([\w]+[\w0-9]*)(.*)on(mouse(move|over|down|up)|load|blur|change|error|click|dblclick|focus|key(down|up|press)|select)([\n\ ]*)=([\n\ ]*)[\"'][^>\"']*[\"']([^>]*)>)(.*)(<\/\\2>)?/misU"; preg_match_all($dirtyCodePattern,$body,$rest,PREG_PATTERN_ORDER); foreach($rest[0] as $i => $val) if (!(preg_match("/javascript:window\.open\(\"([^'\"]*)\/index\.php\?menuaction=calendar\.uicalendar\.set_action\&cal_id=([^;'\"]+);?['\"]/i",$rest[1][$i]) && strtoupper($rest[4][$i]) == "CLICK" )) //Calendar events $body = str_replace($rest[1][$i],"<".$rest[2][$i].$rest[3][$i].$rest[7][$i].">",$body); $body = $this-> replace_links($body); //Remoção de tags para correção de erro no firefox $body = mb_eregi_replace("","",$body); $body = mb_eregi_replace("","",$body); //Correção para compatibilização com Outlook, ao visualizar a mensagem $body = mb_ereg_replace('', $body); $body = str_replace("\x00", '', $body); return "".$body; } function replace_links( $body ) { // Domains and IPs addresses found in the text and which is not a link yet should be replaced by one. // See more informations in www.iana.org $octets = array( 'first' => '(2[0-3][0-9]|1[0-9]{2}|[1-9][0-9]?)', 'middle' => '(25[0-5]|2[0-4][0-9]|1?[0-9]{1,2})', 'last' => '(25[0-4]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)' ); $ip = "\b{$octets[ 'first' ]}\.({$octets[ 'middle' ]}\.){2}{$octets[ 'last' ]}\b"; $top_level_domains = '(\.(ac|ad|ae|aero|af|ag|ai|al|am|an|ao|aq|ar|as|asia|at|au|aw|ax|az|' . 'ba|bb|bd|be|bf|bg|bh|bi|biz|bj|bl|bm|bn|bo|br|bs|bt|bv|bw|by|bz|' . 'ca|cat|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|com|coop|cr|cu|cv|cx|cy|cz|' . 'de|dj|dk|dm|do|dz|ec|edu|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|' . 'ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gov|gp|gq|gr|gs|gt|gu|gw|gy|' . 'hk|hm|hn|hr|ht|hu|id|ie|il|im|in|info|int|io|iq|ir|is|it|je|jm|jo|jobs|jp|' . 'ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|' . 'ma|mc|md|me|mf|mg|mh|mil|mk|ml|mm|mn|mo|mobi|mp|mq|mr|ms|mt|mu|museum|' . 'mv|mw|mx|my|mz|na|name|nc|ne|net|nf|ng|ni|nl|no|np|nr|nu|nz|om|org|' . 'pa|pe|pf|pg|ph|pk|pl|pm|pn|pro|ps|pt|pw|py|qa|re|ro|rs|ru|rw|' . 'sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|' . 'tc|td|tel|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|travel|tt|tv|tw|tz|' . 'ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zw))+\b'; $path = '(?>\/[\w\d\/\.\'\(\)\-\+~?!&#@$%|:;,*=_]+)?'; $port = '(?>:\d{2,5})?'; $domain = '(?>[\w\d_\-]+)'; $subdomain = "(?>{$domain}\.)*"; $protocol = '(?>(http|ftp)(s)?:\/\/)?'; $url = "(?>{$protocol}((?>{$subdomain}{$domain}{$top_level_domains}|{$ip}){$port}{$path}))"; $pattern = "/(<\w[^>]+|[\/\"'@=])?{$url}/"; ini_set( 'pcre.backtrack_limit', 300000 ); /* // PHP 5.3 $replace = function( $matches ) { if ( $matches[ 1 ] ) return $matches[ 0 ]; $url = ( $matches[ 2 ] ) ? $matches[ 2 ] : 'http'; $url .= "{$matches[ 3 ]}://{$matches[ 4 ]}"; return "{$matches[ 4 ]}"; }; $body = preg_replace_callback( $pattern, $replace, $body ); */ // PHP 5.2.x - Remover assim que possível $body = preg_replace_callback( $pattern, create_function( '$matches', 'if ( $matches[ 1 ] ) return $matches[ 0 ];' . '$url = ( $matches[ 2 ] ) ? $matches[ 2 ] : "http";' . '$url .= "{$matches[ 3 ]}://{$matches[ 4 ]}";' . 'return "{$matches[ 4 ]}";' ), $body ); ini_set( 'pcre.backtrack_limit', 100000 ); // E-mail address in the text should create a new e-mail on ExpressoMail $pattern = '/( |<|<|>)([A-Za-z0-9\.~?\/_=#\-]*@[A-Za-z0-9\.~?\/_=#\-]*)( |>|>|<)/im'; $replacement = '$1$2$3'; $body = preg_replace( $pattern, $replacement, $body ); return $body; } function get_signature($msg, $msg_number, $msg_folder) { include_once(dirname( __FILE__ ) ."/../../security/classes/CertificadoB.php"); include_once("class.db_functions.inc.php"); foreach ($msg->file_type[$msg_number] as $index => $file_type) { $sign = array(); $temp = $this->get_info_head_msg($msg_number); if($temp['ContentType'] =='normal') return $sign; $file_type = strtolower($file_type); if(strtolower($msg->encoding[$msg_number][$index]) == 'base64') { if ($file_type == 'application/x-pkcs7-signature' || $file_type == 'application/pkcs7-signature') { if(!$this->mbox || !is_resource($this->mbox)) $this->mbox = $this->open_mbox($msg_folder); $header = @imap_headerinfo($this->mbox, imap_msgno($this->mbox, $msg_number), 80, 255); $imap_msg = @imap_fetchheader($this->mbox, $msg_number, FT_UID); $imap_msg .= @imap_body($this->mbox, $msg_number, FT_UID); $certificado = new certificadoB(); $validade = $certificado->verificar($imap_msg); if ($certificado->apresentado) { $from = $header->from; foreach ($from as $id => $object) { $fromname = $object->personal; $fromaddress = $object->mailbox . "@" . $object->host; } $sign_alert = ''; foreach ($certificado->erros_ssl as $item) { $check_error_msg = $this->functions->getLang($item); /* * Desabilite o teste abaixo para mostrar todas as mensagem * de erro. */ //if (!strpos($check_error_msg,'*',strlen($check_error_msg-1))) //{ $sign[] = "" . $check_error_msg . " "; //} } if (count($certificado->erros_ssl) < 1) { $check_msg = $this->functions->getLang('Message untouched') . " "; if(strtoupper($fromaddress) != strtoupper($certificado->dados['EMAIL'])) { $check_msg .= $this->functions->getLang('and') . " "; $check_msg .= $this->functions->getLang('authentic'); } $sign[] = "".$check_msg.""; } if(strtoupper($fromaddress) != strtoupper($certificado->dados['EMAIL'])) { $sign[] = "" . $this->functions->getLang('message') . " " . $this->functions->getLang('with signer different from sender') . " "; } $sign[] = "" . $this->functions->getLang('Message signed by: ') . "" . $certificado->dados['NOME']; $sign[] = "" . $this->functions->getLang('Certificate email: ') . "" . $certificado->dados['EMAIL']; $sign[] = "" . $this->functions->getLang('Mail from: ') . "" . $fromaddress; $sign[] = "" . $this->functions->getLang('Certificate Authority: ') . "" . $certificado->dados['EMISSOR']; $sign[] = "" . $this->functions->getLang('Validity of certificate: ') . "" . gmdate('r',openssl_to_timestamp($certificado->dados['FIM_VALIDADE'])); $sign[] = "" . $this->functions->getLang('Message date: ') . "" . $header->Date; $cert = openssl_x509_parse($certificado->cert_assinante); /* $sign[] = ''; $sign[] = ''; $sign[] = ''; $X = substr($certificado->dados['NASCIMENTO'] ,0,2) . '-' . substr($certificado->dados['NASCIMENTO'] ,2,2) . '-' . substr($certificado->dados['NASCIMENTO'] ,4,4); $sign[] = ''; $sign[] = ''; $sign[] = ''; $sign[] = ''; $sign[] = ''; //$sign[] = ''; $sign[] = ''; $sign[] = ''; $sign[] = ''; $sign[] = ''; $sign[] = ''; $sign[] = ''; $sign[] = ''; $H = data_hora($cert[validFrom]); $X = substr($H,6,2) . '-' . substr($H,4,2) . '-' . substr($H,0,4); $sign[] = ''; $H = data_hora($cert[validTo]); $X = substr($H,6,2) . '-' . substr($H,4,2) . '-' . substr($H,0,4); $sign[] = ''; $sign[] = ''; $sign[] = '
Expedido para:
Nome Comum (CN) ' . $cert[subject]['CN'] . '
Data de nascimento ' . $certificado->dados['NASCIMENTO'] . '
CPF ' . $certificado->dados['CPF'] . '
Documento identidade ' . $certificado->dados['RG'] . '
Empresa (O) ' . $cert[subject]['O'] . '
Unidade Organizacional (OU) ' . $cert[subject]['OU'][0] . '
Numero de serie ' . $cert['serialNumber'] . '
Expedido por:
Nome Comum (CN) ' . $cert[issuer]['CN'] . '
Empresa (O) ' . $cert[issuer]['O'] . '
Unidade Organizacional (OU) ' . $cert[issuer]['OU'][0] . '
Validade:
Expedido em ' . $X . '
Valido ate ' . $X . '
'; */ $sign_alert .= 'Expedido para:\n'; $sign_alert .= 'Nome Comum (CN) ' . $cert[subject]['CN'] . '\n'; $X = substr($certificado->dados['NASCIMENTO'] ,0,2) . '-' . substr($certificado->dados['NASCIMENTO'] ,2,2) . '-' . substr($certificado->dados['NASCIMENTO'] ,4,4); $sign_alert .= 'Data de nascimento ' . $X . '\n'; $sign_alert .= 'CPF ' . $certificado->dados['CPF'] . '\n'; $sign_alert .= 'Documento identidade ' . $certificado->dados['RG'] . '\n'; $sign_alert .= 'Empresa (O) ' . $cert[subject]['O'] . '\n'; $sign_alert .= 'Unidade Organizacional (OU) ' . $cert[subject]['OU'][0] . '\n'; //$sign_alert[] = 'Numero de serie ' . $cert['serialNumber'] . ''; $sign_alert .= '\n'; $sign_alert .= 'Expedido por:\n'; $sign_alert .= 'Nome Comum (CN) ' . $cert[issuer]['CN'] . '\n'; $sign_alert .= 'Empresa (O) ' . $cert[issuer]['O'] . '\n'; $sign_alert .= 'Unidade Organizacional (OU) ' . $cert[issuer]['OU'][0] . '\n'; $sign_alert .= '\n'; $sign_alert .= 'Validade:\n'; $H = data_hora($cert[validFrom]); $X = substr($H,6,2) . '-' . substr($H,4,2) . '-' . substr($H,0,4); $sign_alert .= 'Expedido em ' . $X . '\n'; $H = data_hora($cert[validTo]); $X = substr($H,6,2) . '-' . substr($H,4,2) . '-' . substr($H,0,4); $sign_alert .= 'Valido ate ' . $X . '\n'; $sign[] = "".$this->functions->getLang("More")."..."; $this->db = new db_functions(); // TODO: testar se existe um certificado no banco e verificar qual � o mais atual. if(!$certificado->dados['EXPIRADO'] && !$certificado->dados['REVOGADO'] && count($certificado->erros_ssl) < 1) $this->db->insert_certificate(strtolower($certificado->dados['EMAIL']), $certificado->cert_assinante, $certificado->dados['SERIALNUMBER'], $certificado->dados['AUTHORITYKEYIDENTIFIER']); } else { $sign[] = "" . $this->functions->getLang('Invalid signature') . ""; foreach($certificado->erros_ssl as $item) $sign[] = "" . $this->functions->getLang($item) . ""; } } } } return $sign; } function get_thumbs($msg, $msg_number, $msg_folder) { $thumbs_array = array(); $i = 0; foreach ($msg->file_type[$msg_number] as $index => $file_type) { $file_type = strtolower($file_type); if(strtolower($msg->encoding[$msg_number][$index]) == 'base64') { if (($file_type == 'image/jpeg') || ($file_type == 'image/pjpeg') || ($file_type == 'image/gif') || ($file_type == 'image/png')) { $img = "pid[$msg_number][$index].">"; $href = "pid[$msg_number][$index]."','mywindow','width=700,height=600,scrollbars=yes');\">". $img .""; $thumbs_array[] = $href; } $i++; } } return $thumbs_array; } /*function delete_msg($params) { $folder = $params['folder']; $msgs_to_delete = explode(",",$params['msgs_to_delete']); $mbox_stream = $this->open_mbox($folder); foreach ($msgs_to_delete as $msg_number){ imap_delete($mbox_stream, $msg_number, FT_UID); } imap_close($mbox_stream, CL_EXPUNGE); return $params['msgs_to_delete']; }*/ // Novo function delete_msgs($params) { $folder = $params['folder']; $folder = mb_convert_encoding($folder, "UTF7-IMAP","ISO-8859-1"); $msgs_number = explode(",",$params['msgs_number']); $border_ID = $params['border_ID']; $return = array(); if ($params['get_previous_msg']){ $return['previous_msg'] = $this->get_info_previous_msg($params); // Fix problem in unserialize function JS. $return['previous_msg']['body'] = str_replace(array('{','}'), array('{','}'), $return['previous_msg']['body']); } //$mbox_stream = $this->open_mbox($folder); $mbox_stream = @imap_open("{".$this->imap_server.":".$this->imap_port.$this->imap_options."}".$folder, $this->username, $this->password) or die(serialize(array('imap_error' => $this->parse_error(imap_last_error())))); foreach ($msgs_number as $msg_number) { if (imap_delete($mbox_stream, $msg_number, FT_UID)); $return['msgs_number'][] = $msg_number; } $return['folder'] = $folder; $return['border_ID'] = $border_ID; if($mbox_stream) imap_close($mbox_stream, CL_EXPUNGE); return $return; } function refresh($params) { $folder = $params['folder']; $msg_range_begin = $params['msg_range_begin']; $msg_range_end = $params['msg_range_end']; $msgs_existent = $params['msgs_existent']; $sort_box_type = $params['sort_box_type']; $sort_box_reverse = $params['sort_box_reverse']; $msgs_in_the_server = array(); $search_box_type = $params['search_box_type'] != "ALL" && $params['search_box_type'] != "" ? $params['search_box_type'] : false; $msgs_in_the_server = $this->get_msgs($folder, $sort_box_type, $search_box_type, $sort_box_reverse,$msg_range_begin,$msg_range_end); $msgs_in_the_server = array_keys($msgs_in_the_server); if(!count($msgs_in_the_server)) return array(); $num_msgs = (count($msgs_in_the_server) - imap_num_recent($this->mbox)); $msgs_in_the_client = explode(",", $msgs_existent); $msg_to_insert = array_diff($msgs_in_the_server, $msgs_in_the_client); $msg_to_delete = array_diff($msgs_in_the_client, $msgs_in_the_server); $msgs_to_exec = array(); foreach($msg_to_insert as $msg_number) $msgs_to_exec[] = $msg_number; sort($msgs_to_exec); $return = array(); $i = 0; foreach($msgs_to_exec as $msg_number) { /*A função imap_headerinfo não traz o cabeçalho completo, e sim alguns * atributos do cabeçalho. Como eu preciso do atributo Importance * para saber se o email é importante ou não, uso abaixo a função * imap_fetchheader e busco o atributo importance nela para passar * para as funções ajax. Isso faz com que eu acesse o cabeçalho * duas vezes e de duas formas diferentes, mas em contrapartida, eu * não preciso reimplementar o método utilizando o fetchheader. */ $tempHeader = @imap_fetchheader($this->mbox, imap_msgno($this->mbox, $msg_number)); $flag = preg_match('/importance *: *(.*)\r/i', $tempHeader, $importance); $return[$i]['Importance'] = $flag==0?"Normal":$importance[1]; $msg_sample = $this->get_msg_sample($msg_number); $return[$i]['msg_sample'] = $msg_sample; $header = $this->get_header($msg_number); if (!is_object($header)) continue; $return[$i]['msg_number'] = $msg_number; $return[$i]['msg_folder'] = $folder; // Atribui o tipo (normal, signature ou cipher) ao campo Content-Type $return[$i]['ContentType'] = $this->getMessageType($msg_number, $tempHeader); $return[$i]['Recent'] = $header->Recent; $return[$i]['Unseen'] = $header->Unseen; $return[$i]['Answered'] = $header->Answered; $return[$i]['Deleted'] = $header->Deleted; $return[$i]['Draft'] = $header->Draft; $return[$i]['Flagged'] = $header->Flagged; $return[$i]['udate'] = $header->udate; $from = $header->from; $return[$i]['from'] = array(); $tmp = imap_mime_header_decode($from[0]->personal); $return[$i]['from']['name'] = $tmp[0]->text; $return[$i]['from']['email'] = $from[0]->mailbox . "@" . $from[0]->host; //$return[$i]['from']['full'] ='"' . $return[$i]['from']['name'] . '" ' . '<' . $return[$i]['from']['email'] . '>'; if(!$return[$i]['from']['name']) $return[$i]['from']['name'] = $return[$i]['from']['email']; /*$toaddress = imap_mime_header_decode($header->toaddress); $return[$i]['toaddress'] = ''; foreach ($toaddress as $tmp) $return[$i]['toaddress'] .= $tmp->text;*/ $to = $header->to; $return[$i]['to'] = array(); $tmp = imap_mime_header_decode($to[0]->personal); $return[$i]['to']['name'] = $tmp[0]->text; $return[$i]['to']['email'] = $to[0]->mailbox . "@" . $to[0]->host; $return[$i]['to']['full'] ='"' . $return[$i]['to']['name'] . '" ' . '<' . $return[$i]['to']['email'] . '>'; $return[$i]['subject'] = $this->decode_string($header->fetchsubject); $return[$i]['Size'] = $header->Size; $return[$i]['reply_toaddress'] = $header->reply_toaddress; $return[$i]['attachment'] = array(); if (!isset($imap_attachment)) { include_once("class.imap_attachment.inc.php"); $imap_attachment = new imap_attachment(); } $return[$i]['attachment'] = $imap_attachment->get_attachment_headerinfo($this->mbox, $msg_number); $i++; } $return['quota'] = $this->get_quota(array('folder_id' => $folder)); $return['sort_box_type'] = $params['sort_box_type']; $return['new_msgs'] = imap_num_recent($this->mbox); $return['msgs_to_delete'] = $msg_to_delete; if($this->mbox && is_resource($this->mbox)) imap_close($this->mbox); return $return; } /** * Método que faz a verificação do Content-Type do e-mail e verifica se é um e-mail normal, * assinado ou cifrado. * @author Mário César Kolling * @param $headers Uma String contendo os Headers do e-mail retornados pela função imap_imap_fetchheader * @param $msg_number O número da mesagem * @return Retorna o tipo da mensagem (normal, signature, cipher). */ function getMessageType($msg_number, $headers = false){ $contentType = "normal"; if (!$headers){ $headers = imap_fetchheader($this->mbox, imap_msgno($this->mbox, $msg_number)); } //$header2 = imap_fetchheader($this->mbox, imap_msgno($this->mbox, $msg_number)); if (preg_match("/Content-Type:.*pkcs7-signature/i", $headers) == 1){ $contentType = "signature"; } else if (preg_match("/Content-Type:.*x-pkcs7-mime/i", $headers) == 1){ $contentType = "cipher"; } return $contentType; } /** * Metodo que retorna todas as pastas do usuario logado. * @param $params array opcional para repassar os argumentos ao metodo. * Se usar $params['noSharedFolders'] = true, ira retornar todas as pastas do usuário logado, * excluindo as compartilhadas para ele. * @return Retorna um array contendo as seguintes informacoes de cada pasta: folder_unseen, * folder_id, folder_name, folder_parent e folder_hasChildren. */ function get_folders_list($params = null) { $mbox_stream = $this->open_mbox(); if($params && $params['onload'] && $_SESSION['phpgw_info']['expressomail']['server']['certificado']){ $this->delete_mailbox(array("del_past" => "INBOX/decifradas")); } $inbox = 'INBOX'; $trash = $inbox . $this->imap_delimiter . $_SESSION['phpgw_info']['expressomail']['email_server']['imapDefaultTrashFolder']; $drafts = $inbox . $this->imap_delimiter . $_SESSION['phpgw_info']['expressomail']['email_server']['imapDefaultDraftsFolder']; $spam = $inbox . $this->imap_delimiter . $_SESSION['phpgw_info']['expressomail']['email_server']['imapDefaultSpamFolder']; $sent = $inbox . $this->imap_delimiter . $_SESSION['phpgw_info']['expressomail']['email_server']['imapDefaultSentFolder']; $uid2cn = $_SESSION['phpgw_info']['user']['preferences']['expressoMail']['uid2cn']; // Free others requests session_write_close(); $serverString = "{".$this->imap_server.":".$this->imap_port.$this->imap_options."}"; $folders_list = imap_getmailboxes($mbox_stream, $serverString, ($params && $params['noSharedFolders']) ? "INBOX/*" : "*"); if ( $params && $params['noSharedFolders'] ) $folders_list = imap_getmailboxes($mbox_stream, $serverString, 'INBOX' ) + $folders_list; $folders_list = array_slice($folders_list,0,$this->foldersLimit); $tmp = array(); $resultMine = array(); $resultDefault = array(); if (is_array($folders_list)) { reset($folders_list); $this->ldap = new ldap_functions(); $i = 0; while (list($key, $val) = each($folders_list)) { $status = imap_status($mbox_stream, $val->name, SA_UNSEEN); //$tmp_folder_id = explode("}", imap_utf7_decode($val->name)); $tmp_folder_id = explode("}", mb_convert_encoding($val->name, "ISO_8859-1", "UTF7-IMAP" )); if($tmp_folder_id[1]=='INBOX'.$this->imap_delimiter.'decifradas') { //error_log('passou', 3,'/tmp/imap_get_list.log'); //imap_deletemailbox($mbox_stream,imap_utf7_encode("{".$this->imap_server."}".'INBOX/decifradas')); continue; } $result[$i]['folder_unseen'] = $status->unseen; $folder_id = $tmp_folder_id[1]; $result[$i]['folder_id'] = $folder_id; $tmp_folder_parent = explode($this->imap_delimiter, $folder_id); $result[$i]['folder_name'] = array_pop($tmp_folder_parent); $result[$i]['folder_name'] = $result[$i]['folder_name'] == 'INBOX' ? 'Inbox' : $result[$i]['folder_name']; if ($uid2cn && substr($folder_id,0,4) == 'user') { //$this->ldap = new ldap_functions(); if ($cn = $this->ldap->uid2cn($result[$i]['folder_name'])) { $result[$i]['folder_name'] = $cn; } } $tmp_folder_parent = implode($this->imap_delimiter, $tmp_folder_parent); $result[$i]['folder_parent'] = $tmp_folder_parent == 'INBOX' ? '' : $tmp_folder_parent; if (($val->attributes == 32) && ($result[$i]['folder_name'] != 'Inbox')) $result[$i]['folder_hasChildren'] = 1; else $result[$i]['folder_hasChildren'] = 0; switch ($tmp_folder_id[1]) { case $inbox: case $sent: case $drafts: case $spam: case $trash: $resultDefault[]=$result[$i]; default: $resultMine[]=$result[$i]; } $i++; } } // Sorting resultMine foreach ($resultMine as $folder_info) { $array_tmp[] = $folder_info['folder_id']; } natcasesort($array_tmp); foreach ($array_tmp as $key => $folder_id) { $result2[] = $resultMine[$key]; } $resultDefault2=$resultDefault; // Sorting resultDefault foreach ($resultDefault as $key => $folder_id) { switch ($resultDefault[$key]['folder_id']) { case $inbox: $resultDefault2[0] = $resultDefault[$key]; break; case $sent: $resultDefault2[1] = $resultDefault[$key]; break; case $drafts: $resultDefault2[2] = $resultDefault[$key]; break; case $spam: $resultDefault2[3] = $resultDefault[$key]; break; case $trash: $resultDefault2[4] = $resultDefault[$key]; break; } } // Merge default folders and mines $result2 = array_merge($resultDefault2, $result2); $current_folder = "INBOX"; if($params && $params['folder']) $current_folder = $params['folder']; return array_merge($result2, $this->get_quota(array('folder_id' => $current_folder))); } function create_mailbox($arr) { $namebox = $arr['newp']; $mbox_stream = $this->open_mbox(); $imap_server = $_SESSION['phpgw_info']['expressomail']['email_server']['imapServer']; $namebox = mb_convert_encoding($namebox, "UTF7-IMAP", "UTF-8"); $result = "Ok"; if(!imap_createmailbox($mbox_stream,"{".$imap_server."}$namebox")) { $result = implode("
\n", imap_errors()); } if($mbox_stream) imap_close($mbox_stream); return $result; } function create_extra_mailbox($arr) { $nameboxs = explode(";",$arr['nw_folders']); $result = ""; $mbox_stream = $this->open_mbox(); $imap_server = $_SESSION['phpgw_info']['expressomail']['email_server']['imapServer']; foreach($nameboxs as $key=>$tmp){ if($tmp != ""){ if(!imap_createmailbox($mbox_stream,imap_utf7_encode("{".$imap_server."}$tmp"))){ $result = implode("
\n", imap_errors()); if($mbox_stream) imap_close($mbox_stream); return $result; } } } if($mbox_stream) imap_close($mbox_stream); return true; } function delete_mailbox($arr) { $namebox = $arr['del_past']; $imap_server = $_SESSION['phpgw_info']['expressomail']['email_server']['imapServer']; $mbox_stream = $this->mbox ? $this->mbox : $this->open_mbox(); //$del_folder = imap_deletemailbox($mbox_stream,"{".$imap_server."}INBOX.$namebox"); $result = "Ok"; $namebox = mb_convert_encoding($namebox, "UTF7-IMAP","UTF-8"); if(!imap_deletemailbox($mbox_stream,"{".$imap_server."}$namebox")) { $result = implode("
\n", imap_errors()); } /* if($mbox_stream) imap_close($mbox_stream); */ return $result; } function ren_mailbox($arr) { $namebox = $arr['current']; $new_box = $arr['rename']; $imap_server = $_SESSION['phpgw_info']['expressomail']['email_server']['imapServer']; $mbox_stream = $this->open_mbox(); //$ren_folder = imap_renamemailbox($mbox_stream,"{".$imap_server."}INBOX.$namebox","{".$imap_server."}INBOX.$new_box"); $result = "Ok"; $namebox = mb_convert_encoding($namebox, "UTF7-IMAP","UTF-8"); $new_box = mb_convert_encoding($new_box, "UTF7-IMAP","UTF-8"); if(!imap_renamemailbox($mbox_stream,"{".$imap_server."}$namebox","{".$imap_server."}$new_box")) { $result = imap_errors(); } if($mbox_stream) imap_close($mbox_stream); return $result; } function get_num_msgs($params) { $folder = $params['folder']; if(!$this->mbox || !is_resource($this->mbox)) { $this->mbox = $this->open_mbox($folder); if(!$this->mbox || !is_resource($this->mbox)) return imap_last_error(); } $num_msgs = imap_num_msg($this->mbox); if($this->mbox && is_resource($this->mbox)) imap_close($this->mbox); return $num_msgs; } function folder_exists($folder){ $mbox = $this->open_mbox(); $serverString = "{".$this->imap_server.":".$this->imap_port.$this->imap_options."}"; $list = imap_getmailboxes($mbox,$serverString, $folder); $return = is_array($list); imap_close($mbox); return $return; } function send_mail($params) { include_once("class.phpmailer.php"); $mail = new PHPMailer(); include_once("class.db_functions.inc.php"); $db = new db_functions(); $fromaddress = $params['input_from'] ? explode(';',$params['input_from']) : ""; ## # @AUTHOR Rodrigo Souza dos Santos # @DATE 2008/09/17 # @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."; } $toaddress = implode(',',$db->getAddrs(explode(',',$params['input_to']))); $ccaddress = implode(',',$db->getAddrs(explode(',',$params['input_cc']))); $ccoaddress = implode(',',$db->getAddrs(explode(',',$params['input_cco']))); $subject = $params['input_subject']; $msg_uid = $params['msg_id']; $return_receipt = $params['input_return_receipt']; $is_important = $params['input_important_message']; $encrypt = $params['input_return_cripto']; $signed = $params['input_return_digital']; if($params['smime']) { $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.'; if($certificado->dados['CPF'] != $this->username) $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 { $body = $params['body']; //Compatibilização com Outlook, ao encaminhar a mensagem $body = mb_ereg_replace('