/** * Yet another problem: Outlook seems to remove the organizer from * the iCal when forwarding -- we put the original sender back in * as organizer. * * @param string $icaltext The ical message. * @param MIME_Headers $from The message sender. */ function _addOrganizer(&$icaltxt, $from) { global $conf; if (isset($conf['kolab']['filter']['email_domain'])) { $email_domain = $conf['kolab']['filter']['email_domain']; } else { $email_domain = 'localhost'; } $iCal = new Horde_Icalendar(); $iCal->parsevCalendar($icaltxt); $vevent =& $iCal->findComponent('VEVENT'); if ($vevent) { $organizer = $vevent->getAttribute('ORGANIZER', true); if (is_a($organizer, 'PEAR_Error')) { $adrs = imap_rfc822_parse_adrlist($from, $email_domain); if (count($adrs) > 0) { $org_email = 'mailto:' . $adrs[0]->mailbox . '@' . $adrs[0]->host; $org_name = $adrs[0]->personal; if ($org_name) { $vevent->setAttribute('ORGANIZER', $org_email, array('CN' => $org_name), false); } else { $vevent->setAttribute('ORGANIZER', $org_email, array(), false); } Horde::log(sprintf("Adding missing organizer '%s <%s>' to iCal.", $org_name, $org_email), 'DEBUG'); $icaltxt = $iCal->exportvCalendar(); } } } }
/** * @param string $input RFC822 address string * @return Address */ public static function getAddress($input) { $input = str_replace("\t", ' ', $input); $address = imap_rfc822_parse_adrlist($input, ''); $name = isset($address[0]->personal) ? trim($address[0]->personal, '"') : null; $email = $address[0]->mailbox . '@' . $address[0]->host; return new Address($email, $name); }
/** * Enter description here... * * @param string $string * @return array */ static function parseRfcAddressList($input) { $addys = array(); if (!is_array($input)) { $input = array($input); } foreach ($input as $string) { $addys += imap_rfc822_parse_adrlist($string, ''); } return $addys; }
/** * @return AddressCollection */ public static function parse($addressCollection) { $result = imap_rfc822_parse_adrlist($addressCollection, getHostname()); $addressCollection = new static($result); return $addressCollection->map(function ($user) { if (!$user->host) { throw new Exception('Missing or invalid host name'); } if ($user->host == '.SYNTAX-ERROR.') { throw new Exception('Missing or invalid host name'); } $mailAddress = new MailAddress(); if (property_exists($user, 'personal')) { $mailAddress->setUserName($user->personal); } $mailAddress->setMailbox($user->mailbox); $mailAddress->setHostname($user->host); return $mailAddress; }); }
public function getMessages($email) { $messages = []; foreach ($this->query(['to' => $email, 'on' => date('d F Y'), 'unseen' => false]) as $messageId) { $structure = imap_fetchstructure($this->connections[$email], $messageId); $encoding = isset($structure->parts) ? reset($structure->parts) : $structure; $message = imap_fetch_overview($this->connections[$email], $messageId); $message = reset($message); $processFunction = $this->detectProcessFunction($encoding->encoding); $message->subject = $processFunction($message->subject); $message->body = $this->getMessageBody($email, $messageId, $processFunction, reset($structure->parameters)); foreach (['from', 'to'] as $direction) { $address = imap_rfc822_parse_adrlist(imap_utf8($message->{$direction}), ''); $address = reset($address); $message->{$direction} = "{$address->mailbox}@{$address->host}"; } $messages[] = (array) $message; imap_delete($this->connections[$email], $messageId); } return $messages; }
function GetRFC822Addresses($address, &$addresses) { if (function_exists("imap_rfc822_parse_adrlist")) { $parsed_addresses = @imap_rfc822_parse_adrlist($address, $this->localhost); for ($entry = 0; $entry < count($parsed_addresses); $entry++) { if ($parsed_addresses[$entry]->host == ".SYNTAX-ERROR.") { return $parsed_addresses[$entry]->mailbox . " " . $parsed_addresses[$entry]->host; } $parsed_address = $parsed_addresses[$entry]->mailbox . "@" . $parsed_addresses[$entry]->host; if (isset($addresses[$parsed_address])) { $addresses[$parsed_address]++; } else { $addresses[$parsed_address] = 1; } } } else { $length = strlen($address); for ($position = 0; $position < $length;) { $match = split($this->email_address_pattern, strtolower(substr($address, $position)), 2); if (count($match) < 2) { break; } $position += strlen($match[0]); $next_position = $length - strlen($match[1]); $found = substr($address, $position, $next_position - $position); if (!strcmp($found, "")) { break; } if (isset($addresses[$found])) { $addresses[$found]++; } else { $addresses[$found] = 1; } $position = $next_position; } } return ""; }
public static function parseAddressList($string) { $data = []; foreach (imap_rfc822_parse_adrlist(strtr($string, ';', ','), self::INTERNAL_HOST) as $address) { isset($address->mailbox, $address->host) and $data[] = [$address->mailbox, $address->host, isset($address->personal) ? $address->personal : '']; } return $data; }
function saveRequestersPanelAction() { @($ticket_id = DevblocksPlatform::importGPC($_POST['ticket_id'], 'integer')); @($msg_id = DevblocksPlatform::importGPC($_POST['msg_id'], 'integer')); // Dels @($req_deletes = DevblocksPlatform::importGPC($_POST['req_deletes'], 'array', array())); if (!empty($req_deletes)) { foreach ($req_deletes as $del_id) { DAO_Ticket::deleteRequester($ticket_id, $del_id); } } // Adds @($req_adds = DevblocksPlatform::importGPC($_POST['req_adds'], 'string', '')); $req_list = DevblocksPlatform::parseCrlfString($req_adds); $req_addys = array(); if (is_array($req_list) && !empty($req_list)) { foreach ($req_list as $req) { if (empty($req)) { continue; } $rfc_addys = imap_rfc822_parse_adrlist($req, 'localhost'); foreach ($rfc_addys as $rfc_addy) { $addy = $rfc_addy->mailbox . '@' . $rfc_addy->host; if (null != ($req_addy = CerberusApplication::hashLookupAddress($addy, true))) { DAO_Ticket::createRequester($req_addy->id, $ticket_id); } } } } $requesters = DAO_Ticket::getRequestersByTicket($ticket_id); $list = array(); foreach ($requesters as $requester) { $list[] = $requester->email; } echo implode(', ', $list); exit; }
function emailAddressToHTML($_emailAddress) { // create some nice formated HTML for senderaddress if ($_emailAddress == 'undisclosed-recipients: ;') { return $_emailAddress; } $addressData = imap_rfc822_parse_adrlist($this->bofelamimail->decode_header($_emailAddress), ''); if (is_array($addressData)) { $senderAddress = ''; while (list($key, $val) = each($addressData)) { if (!empty($senderAddress)) { $senderAddress .= ", "; } if (!empty($val->personal)) { $tempSenderAddress = $val->mailbox . "@" . $val->host; $newSenderAddress = imap_rfc822_write_address($val->mailbox, $val->host, $val->personal); $linkData = array('menuaction' => 'felamimail.uicompose.compose', 'send_to' => base64_encode($newSenderAddress)); $link = $GLOBALS['phpgw']->link('/index.php', $linkData); $senderAddress .= sprintf('<a href="%s" title="%s">%s</a>', $link, @htmlentities($newSenderAddress, ENT_QUOTES, $this->displayCharset), @htmlentities($val->personal, ENT_QUOTES, $this->displayCharset)); $linkData = array('menuaction' => 'addressbook.uiaddressbook.add_email', 'add_email' => $tempSenderAddress, 'name' => $val->personal, 'referer' => $_SERVER['PHP_SELF'] . '?' . $_SERVER['QUERY_STRING']); $urlAddToAddressbook = $GLOBALS['phpgw']->link('/index.php', $linkData); $image = $GLOBALS['phpgw']->common->image('felamimail', 'sm_envelope'); $senderAddress .= sprintf('<a href="%s"> <img src="%s" width="10" height="8" border="0" align="absmiddle" alt="%s" title="%s"></a>', $urlAddToAddressbook, $image, lang('add to addressbook'), lang('add to addressbook')); } else { $tempSenderAddress = $val->mailbox . "@" . $val->host; $linkData = array('menuaction' => 'felamimail.uicompose.compose', 'send_to' => base64_encode($tempSenderAddress)); $link = $GLOBALS['phpgw']->link('/index.php', $linkData); $senderAddress .= sprintf('<a href="%s">%s</a>', $link, @htmlentities($tempSenderAddress, ENT_QUOTES, $this->displayCharset)); $linkData = array('menuaction' => 'addressbook.uiaddressbook.add_email', 'add_email' => $tempSenderAddress, 'referer' => $_SERVER['PHP_SELF'] . '?' . $_SERVER['QUERY_STRING']); $urlAddToAddressbook = $GLOBALS['phpgw']->link('/index.php', $linkData); $image = $GLOBALS['phpgw']->common->image('felamimail', 'sm_envelope'); $senderAddress .= sprintf('<a href="%s"> <img src="%s" width="10" height="8" border="0" align="absmiddle" alt="%s" title="%s"></a>', $urlAddToAddressbook, $image, lang('add to addressbook'), lang('add to addressbook')); } } return $senderAddress; } // if something goes wrong, just return the original address return $_emailAddress; }
function doContactSendAction() { @($sFrom = DevblocksPlatform::importGPC($_POST['from'], 'string', '')); @($sSubject = DevblocksPlatform::importGPC($_POST['subject'], 'string', '')); @($sContent = DevblocksPlatform::importGPC($_POST['content'], 'string', '')); @($sCaptcha = DevblocksPlatform::importGPC($_POST['captcha'], 'string', '')); @($aFieldIds = DevblocksPlatform::importGPC($_POST['field_ids'], 'array', array())); @($aFollowUpQ = DevblocksPlatform::importGPC($_POST['followup_q'], 'array', array())); // Load the answers to any situational questions $aFollowUpA = array(); if (is_array($aFollowUpQ)) { foreach ($aFollowUpQ as $idx => $q) { @($answer = DevblocksPlatform::importGPC($_POST['followup_a_' . $idx], 'string', '')); $aFollowUpA[$idx] = $answer; } } $umsession = $this->getSession(); $fingerprint = parent::getFingerprint(); $settings = CerberusSettings::getInstance(); $default_from = $settings->get(CerberusSettings::DEFAULT_REPLY_FROM); $umsession->setProperty('support.write.last_from', $sFrom); $umsession->setProperty('support.write.last_subject', $sSubject); $umsession->setProperty('support.write.last_content', $sContent); // $umsession->setProperty('support.write.last_followup_q',$aFollowUpQ); $umsession->setProperty('support.write.last_followup_a', $aFollowUpA); $sNature = $umsession->getProperty('support.write.last_nature', ''); $captcha_enabled = DAO_CommunityToolProperty::get($this->getPortal(), UmScApp::PARAM_CAPTCHA_ENABLED, 1); if (empty($sFrom) || $captcha_enabled && 0 != strcasecmp($sCaptcha, @$umsession->getProperty(UmScApp::SESSION_CAPTCHA, '***'))) { if (empty($sFrom)) { $umsession->setProperty('support.write.last_error', 'Invalid e-mail address.'); } else { $umsession->setProperty('support.write.last_error', 'What you typed did not match the image.'); } // [TODO] Need to report the captcha didn't match and redraw the form DevblocksPlatform::setHttpResponse(new DevblocksHttpResponse(array('portal', $this->getPortal(), 'contact', 'step2'))); return; } // Dispatch $to = $default_from; $subject = 'Contact me: Other'; $sDispatch = DAO_CommunityToolProperty::get($this->getPortal(), UmScApp::PARAM_DISPATCH, ''); $dispatch = !empty($sDispatch) ? unserialize($sDispatch) : array(); foreach ($dispatch as $k => $v) { if (md5($k) == $sNature) { $to = $v['to']; $subject = 'Contact me: ' . strip_tags($k); break; } } if (!empty($sSubject)) { $subject = $sSubject; } $fieldContent = ''; if (!empty($aFollowUpQ)) { $fieldContent = "\r\n\r\n"; $fieldContent .= "--------------------------------------------\r\n"; if (!empty($sNature)) { $fieldContent .= $subject . "\r\n"; $fieldContent .= "--------------------------------------------\r\n"; } foreach ($aFollowUpQ as $idx => $q) { $answer = isset($aFollowUpA[$idx]) ? $aFollowUpA[$idx] : ''; $fieldContent .= "Q) " . $q . "\r\n" . "A) " . $answer . "\r\n"; if ($idx + 1 < count($aFollowUpQ)) { $fieldContent .= "\r\n"; } } $fieldContent .= "--------------------------------------------\r\n"; "\r\n"; } $message = new CerberusParserMessage(); $message->headers['date'] = date('r'); $message->headers['to'] = $to; $message->headers['subject'] = $subject; $message->headers['message-id'] = CerberusApplication::generateMessageId(); $message->headers['x-cerberus-portal'] = 1; // Sender $fromList = imap_rfc822_parse_adrlist($sFrom, ''); if (empty($fromList) || !is_array($fromList)) { return; // abort with message } $from = array_shift($fromList); $message->headers['from'] = $from->mailbox . '@' . $from->host; $message->body = 'IP: ' . $fingerprint['ip'] . "\r\n\r\n" . $sContent . $fieldContent; $ticket_id = CerberusParser::parseMessage($message); $ticket = DAO_Ticket::getTicket($ticket_id); // Auto-save any custom fields $fields = DAO_CustomField::getBySource('cerberusweb.fields.source.ticket'); if (!empty($aFieldIds)) { foreach ($aFieldIds as $iIdx => $iFieldId) { if (!empty($iFieldId)) { $field =& $fields[$iFieldId]; /* @var $field Model_CustomField */ $value = ""; switch ($field->type) { case Model_CustomField::TYPE_SINGLE_LINE: case Model_CustomField::TYPE_MULTI_LINE: @($value = trim($aFollowUpA[$iIdx])); break; case Model_CustomField::TYPE_NUMBER: @($value = intval($aFollowUpA[$iIdx])); break; case Model_CustomField::TYPE_DATE: if (false !== ($time = strtotime($aFollowUpA[$iIdx]))) { @($value = intval($time)); } break; case Model_CustomField::TYPE_DROPDOWN: @($value = $aFollowUpA[$iIdx]); break; case Model_CustomField::TYPE_CHECKBOX: @($value = isset($aFollowUpA[$iIdx]) && !empty($aFollowUpA[$iIdx]) ? 1 : 0); break; } if (!empty($value)) { DAO_CustomFieldValue::setFieldValue('cerberusweb.fields.source.ticket', $ticket_id, $iFieldId, $value); } } } } // Clear any errors $umsession->setProperty('support.write.last_nature', null); $umsession->setProperty('support.write.last_nature_string', null); $umsession->setProperty('support.write.last_content', null); $umsession->setProperty('support.write.last_error', null); $umsession->setProperty('support.write.last_opened', $ticket->mask); DevblocksPlatform::setHttpResponse(new DevblocksHttpResponse(array('portal', $this->getPortal(), 'contact', 'confirm'))); }
function send($_formData) { $bofelamimail =& CreateObject('felamimail.bofelamimail', $this->displayCharset); $mail =& CreateObject('phpgwapi.mailer_smtp'); $messageIsDraft = false; $this->sessionData['identity'] = $_formData['identity']; $this->sessionData['to'] = $_formData['to']; $this->sessionData['cc'] = $_formData['cc']; $this->sessionData['bcc'] = $_formData['bcc']; $this->sessionData['folder'] = $_formData['folder']; $this->sessionData['replyto'] = $_formData['replyto']; $this->sessionData['subject'] = trim($_formData['subject']); $this->sessionData['body'] = $_formData['body']; $this->sessionData['priority'] = $_formData['priority']; $this->sessionData['signatureID'] = $_formData['signatureID']; $this->sessionData['disposition'] = $_formData['disposition']; $this->sessionData['mimeType'] = $_formData['mimeType']; $this->sessionData['to_infolog'] = $_formData['to_infolog']; // if the body is empty, maybe someone pasted something with scripts, into the message body // this should not happen anymore, unless you call send directly, since the check was introduced with the action command if (empty($this->sessionData['body'])) { // this is to be found with the egw_unset_vars array for the _POST['body'] array $name = '_POST'; $key = 'body'; #error_log($GLOBALS['egw_unset_vars'][$name.'['.$key.']']); if (isset($GLOBALS['egw_unset_vars'][$name . '[' . $key . ']'])) { $this->sessionData['body'] = self::_getCleanHTML($GLOBALS['egw_unset_vars'][$name . '[' . $key . ']']); $_formData['body'] = $this->sessionData['body']; } #error_log($this->sessionData['body']); } if (empty($this->sessionData['to']) && empty($this->sessionData['cc']) && empty($this->sessionData['bcc']) && empty($this->sessionData['folder'])) { $messageIsDraft = true; } #error_log(print_r($this->preferences,true)); $identity = $this->preferences->getIdentity((int) $this->sessionData['identity']); $signature = $this->bosignatures->getSignature((int) $this->sessionData['signatureID']); #error_log($this->sessionData['identity']); #error_log(print_r($identity,true)); // create the messages $this->createMessage($mail, $_formData, $identity, $signature); #print "<pre>". $mail->getMessageHeader() ."</pre><hr><br>"; #print "<pre>". $mail->getMessageBody() ."</pre><hr><br>"; #exit; $ogServer = $this->preferences->getOutgoingServer(0); #_debug_array($ogServer); $mail->Host = $ogServer->host; $mail->Port = $ogServer->port; // SMTP Auth?? if ($ogServer->smtpAuth) { $mail->SMTPAuth = true; $mail->Username = $ogServer->username; $mail->Password = $ogServer->password; } // set a higher timeout for big messages @set_time_limit(120); #$mail->SMTPDebug = 10; if (count((array) $this->sessionData['to']) > 0 || count((array) $this->sessionData['cc']) > 0 || count((array) $this->sessionData['bcc']) > 0) { if (!$mail->Send()) { $this->errorInfo = $mail->ErrorInfo; return false; } } #error_log("Mail Sent.!"); $folder = (array) $this->sessionData['folder']; if (isset($GLOBALS['phpgw_info']['user']['preferences']['felamimail']['sentFolder']) && $GLOBALS['phpgw_info']['user']['preferences']['felamimail']['sentFolder'] != 'none' && $messageIsDraft == false) { $folder[] = $GLOBALS['phpgw_info']['user']['preferences']['felamimail']['sentFolder']; } if ($messageIsDraft == true) { if (!empty($GLOBALS['phpgw_info']['user']['preferences']['felamimail']['draftFolder'])) { $this->sessionData['folder'] = array($GLOBALS['phpgw_info']['user']['preferences']['felamimail']['draftFolder']); } } $folder = array_unique($folder); #error_log("Number of Folders to move copy the message to:".count($folder)); if (count($folder) > 0 || isset($this->sessionData['uid']) && isset($this->sessionData['messageFolder']) || isset($this->sessionData['forwardFlag']) && isset($this->sessionData['sourceFolder'])) { $bofelamimail =& CreateObject('felamimail.bofelamimail'); $bofelamimail->openConnection(); //$bofelamimail->reopen($this->sessionData['messageFolder']); #error_log("(re)opened Connection"); } if (count($folder) > 0) { foreach ((array) $this->sessionData['bcc'] as $address) { $address_array = imap_rfc822_parse_adrlist($address, ''); foreach ((array) $address_array as $addressObject) { $emailAddress = $addressObject->mailbox . (!empty($addressObject->host) ? '@' . $addressObject->host : ''); $mailAddr[] = array($emailAddress, $addressObject->personal); } } $BCCmail = ''; if (count($mailAddr) > 0) { $BCCmail = $mail->AddrAppend("Bcc", $mailAddr); } //$bofelamimail =& CreateObject('felamimail.bofelamimail'); //$bofelamimail->openConnection(); foreach ($folder as $folderName) { if ($bofelamimail->isSentFolder($folderName)) { $flags = '\\Seen'; } elseif ($bofelamimail->isDraftFolder($folderName)) { $flags = '\\Draft'; } else { $flags = ''; } #$mailHeader=explode('From:',$mail->getMessageHeader()); #$mailHeader[0].$mail->AddrAppend("Bcc",$mailAddr).'From:'.$mailHeader[1], //FIXME - missing function in phpmailer /* if ($bofelamimail->folderExists($folderName,true)) { $bofelamimail->appendMessage($folderName, $BCCmail.$mail->getMessageHeader(), $mail->getMessageBody(), $flags); } */ } //$bofelamimail->closeConnection(); } #error_log("handling draft messages, flagging and such"); if (isset($this->sessionData['uid']) && isset($this->sessionData['messageFolder']) || isset($this->sessionData['forwardFlag']) && isset($this->sessionData['sourceFolder'])) { // mark message as answered //$bofelamimail =& CreateObject('felamimail.bofelamimail'); $bofelamimail->openConnection(); $bofelamimail->reopen($this->sessionData['messageFolder']); // if the draft folder is a starting part of the messages folder, the draft message will be deleted after the send // unless your templatefolder is a subfolder of your draftfolder, and the message is in there if (!empty($GLOBALS['phpgw_info']['user']['preferences']['felamimail']['draftFolder']) && preg_match('/^' . $GLOBALS['phpgw_info']['user']['preferences']['felamimail']['draftFolder'] . '/', $this->sessionData['messageFolder']) && !(!empty($GLOBALS['phpgw_info']['user']['preferences']['felamimail']['templateFolder']) && preg_match('/^' . $GLOBALS['phpgw_info']['user']['preferences']['felamimail']['templateFolder'] . '/', $this->sessionData['messageFolder']))) { $bofelamimail->deleteMessages(array($this->sessionData['uid'])); } else { $bofelamimail->flagMessages("answered", array($this->sessionData['uid'])); if (array_key_exists('forwardFlag', $this->sessionData) && $this->sessionData['forwardFlag'] == 'forwarded') { $bofelamimail->flagMessages("forwarded", array($this->sessionData['forwardedUID'])); } } //$bofelamimail->closeConnection(); } if ($bofelamimail) { $bofelamimail->closeConnection(); } //error_log("performing Infolog Stuff"); // attension: we dont return from infolog. cleanups will be done there. if ($_formData['to_infolog'] == 'on') { $uiinfolog =& CreateObject('infolog.uiinfolog'); $uiinfolog->import_mail($this->sessionData['to'], $this->sessionData['subject'], $this->convertHTMLToText($this->sessionData['body']), $this->sessionData['attachments']); } if (is_array($this->sessionData['attachments'])) { reset($this->sessionData['attachments']); while (list($key, $value) = @each($this->sessionData['attachments'])) { #print "$key: ".$value['file']."<br>"; if (!empty($value['file'])) { // happens when forwarding mails unlink($value['file']); } } } $this->sessionData = ''; $this->saveSessionData(); return true; }
function probe_url($url, $mode = PROBE_NORMAL) { require_once 'include/email.php'; $result = array(); if (!$url) { return $result; } $network = null; $diaspora = false; $diaspora_base = ''; $diaspora_guid = ''; $diaspora_key = ''; $has_lrdd = false; $email_conversant = false; $twitter = strpos($url, 'twitter.com') !== false ? true : false; $at_addr = strpos($url, '@') !== false ? true : false; if (!$twitter) { if (strpos($url, 'mailto:') !== false && $at_addr) { $url = str_replace('mailto:', '', $url); $links = array(); } else { $links = lrdd($url); } if (count($links)) { $has_lrdd = true; logger('probe_url: found lrdd links: ' . print_r($links, true), LOGGER_DATA); foreach ($links as $link) { if ($link['@attributes']['rel'] === NAMESPACE_ZOT) { $zot = unamp($link['@attributes']['href']); } if ($link['@attributes']['rel'] === NAMESPACE_DFRN) { $dfrn = unamp($link['@attributes']['href']); } if ($link['@attributes']['rel'] === 'salmon') { $notify = unamp($link['@attributes']['href']); } if ($link['@attributes']['rel'] === NAMESPACE_FEED) { $poll = unamp($link['@attributes']['href']); } if ($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard') { $hcard = unamp($link['@attributes']['href']); } if ($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') { $profile = unamp($link['@attributes']['href']); } if ($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0') { $poco = unamp($link['@attributes']['href']); } if ($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') { $diaspora_base = unamp($link['@attributes']['href']); $diaspora = true; } if ($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') { $diaspora_guid = unamp($link['@attributes']['href']); $diaspora = true; } if ($link['@attributes']['rel'] === 'diaspora-public-key') { $diaspora_key = base64_decode(unamp($link['@attributes']['href'])); $pubkey = rsatopem($diaspora_key); $diaspora = true; } } // Status.Net can have more than one profile URL. We need to match the profile URL // to a contact on incoming messages to prevent spam, and we won't know which one // to match. So in case of two, one of them is stored as an alias. Only store URL's // and not webfinger user@host aliases. If they've got more than two non-email style // aliases, let's hope we're lucky and get one that matches the feed author-uri because // otherwise we're screwed. foreach ($links as $link) { if ($link['@attributes']['rel'] === 'alias') { if (strpos($link['@attributes']['href'], '@') === false) { if (isset($profile)) { if ($link['@attributes']['href'] !== $profile) { $alias = unamp($link['@attributes']['href']); } } else { $profile = unamp($link['@attributes']['href']); } } } } } elseif ($mode == PROBE_NORMAL) { // Check email $orig_url = $url; if (strpos($orig_url, '@') && validate_email($orig_url)) { $x = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1", intval(local_user())); $r = q("SELECT * FROM `mailacct` WHERE `uid` = %d AND `server` != '' LIMIT 1", intval(local_user())); if (count($x) && count($r)) { $mailbox = construct_mailbox_name($r[0]); $password = ''; openssl_private_decrypt(hex2bin($r[0]['pass']), $password, $x[0]['prvkey']); $mbox = email_connect($mailbox, $r[0]['user'], $password); if (!$mbox) { logger('probe_url: email_connect failed.'); } unset($password); } if ($mbox) { $msgs = email_poll($mbox, $orig_url); logger('probe_url: searching ' . $orig_url . ', ' . count($msgs) . ' messages found.', LOGGER_DEBUG); if (count($msgs)) { $addr = $orig_url; $network = NETWORK_MAIL; $name = substr($url, 0, strpos($url, '@')); $phost = substr($url, strpos($url, '@') + 1); $profile = 'http://' . $phost; // fix nick character range $vcard = array('fn' => $name, 'nick' => $name, 'photo' => avatar_img($url)); $notify = 'smtp ' . random_string(); $poll = 'email ' . random_string(); $priority = 0; $x = email_msg_meta($mbox, $msgs[0]); if (stristr($x->from, $orig_url)) { $adr = imap_rfc822_parse_adrlist($x->from, ''); } elseif (stristr($x->to, $orig_url)) { $adr = imap_rfc822_parse_adrlist($x->to, ''); } if (isset($adr)) { foreach ($adr as $feadr) { if (strcasecmp($feadr->mailbox, $name) == 0 && strcasecmp($feadr->host, $phost) == 0 && strlen($feadr->personal)) { $personal = imap_mime_header_decode($feadr->personal); $vcard['fn'] = ""; foreach ($personal as $perspart) { if ($perspart->charset != "default") { $vcard['fn'] .= iconv($perspart->charset, 'UTF-8//IGNORE', $perspart->text); } else { $vcard['fn'] .= $perspart->text; } } $vcard['fn'] = notags($vcard['fn']); } } } } imap_close($mbox); } } } } if ($mode == PROBE_NORMAL) { if (strlen($zot)) { $s = fetch_url($zot); if ($s) { $j = json_decode($s); if ($j) { $network = NETWORK_ZOT; $vcard = array('fn' => $j->fullname, 'nick' => $j->nickname, 'photo' => $j->photo); $profile = $j->url; $notify = $j->post; $pubkey = $j->pubkey; $poll = 'N/A'; } } } if (strlen($dfrn)) { $ret = scrape_dfrn($hcard ? $hcard : $dfrn); if (is_array($ret) && x($ret, 'dfrn-request')) { $network = NETWORK_DFRN; $request = $ret['dfrn-request']; $confirm = $ret['dfrn-confirm']; $notify = $ret['dfrn-notify']; $poll = $ret['dfrn-poll']; $vcard = array(); $vcard['fn'] = $ret['fn']; $vcard['nick'] = $ret['nick']; $vcard['photo'] = $ret['photo']; } } } if ($diaspora && $diaspora_base && $diaspora_guid) { if ($mode == PROBE_DIASPORA || !$notify) { $notify = $diaspora_base . 'receive/users/' . $diaspora_guid; $batch = $diaspora_base . 'receive/public'; } if (strpos($url, '@')) { $addr = str_replace('acct:', '', $url); } } if ($network !== NETWORK_ZOT && $network !== NETWORK_DFRN && $network !== NETWORK_MAIL) { if ($diaspora) { $network = NETWORK_DIASPORA; } elseif ($has_lrdd) { $network = NETWORK_OSTATUS; } $priority = 0; if ($hcard && !$vcard) { $vcard = scrape_vcard($hcard); // Google doesn't use absolute url in profile photos if (x($vcard, 'photo') && substr($vcard['photo'], 0, 1) == '/') { $h = @parse_url($hcard); if ($h) { $vcard['photo'] = $h['scheme'] . '://' . $h['host'] . $vcard['photo']; } } logger('probe_url: scrape_vcard: ' . print_r($vcard, true), LOGGER_DATA); } if ($twitter) { logger('twitter: setup'); $tid = basename($url); $tapi = 'https://api.twitter.com/1/statuses/user_timeline.rss'; if (intval($tid)) { $poll = $tapi . '?user_id=' . $tid; } else { $poll = $tapi . '?screen_name=' . $tid; } $profile = 'http://twitter.com/#!/' . $tid; $vcard['photo'] = 'https://api.twitter.com/1/users/profile_image/' . $tid; $vcard['nick'] = $tid; $vcard['fn'] = $tid . '@twitter'; } if (!x($vcard, 'fn')) { if (x($vcard, 'nick')) { $vcard['fn'] = $vcard['nick']; } } $check_feed = false; if ($twitter || !$poll) { $check_feed = true; } if (!isset($vcard) || !x($vcard, 'fn') || !$profile) { $check_feed = true; } if ($at_addr && !count($links)) { $check_feed = false; } if ($check_feed) { $feedret = scrape_feed($poll ? $poll : $url); logger('probe_url: scrape_feed ' . ($poll ? $poll : $url) . ' returns: ' . print_r($feedret, true), LOGGER_DATA); if (count($feedret) && ($feedret['feed_atom'] || $feedret['feed_rss'])) { $poll = x($feedret, 'feed_atom') ? unamp($feedret['feed_atom']) : unamp($feedret['feed_rss']); if (!x($vcard)) { $vcard = array(); } } if (x($feedret, 'photo') && !x($vcard, 'photo')) { $vcard['photo'] = $feedret['photo']; } require_once 'library/simplepie/simplepie.inc'; $feed = new SimplePie(); $xml = fetch_url($poll); logger('probe_url: fetch feed: ' . $poll . ' returns: ' . $xml, LOGGER_DATA); $a = get_app(); logger('probe_url: scrape_feed: headers: ' . $a->get_curl_headers(), LOGGER_DATA); $feed->set_raw_data($xml); $feed->init(); if ($feed->error()) { logger('probe_url: scrape_feed: Error parsing XML: ' . $feed->error()); } if (!x($vcard, 'photo')) { $vcard['photo'] = $feed->get_image_url(); } $author = $feed->get_author(); if ($author) { $vcard['fn'] = unxmlify(trim($author->get_name())); if (!$vcard['fn']) { $vcard['fn'] = trim(unxmlify($author->get_email())); } if (strpos($vcard['fn'], '@') !== false) { $vcard['fn'] = substr($vcard['fn'], 0, strpos($vcard['fn'], '@')); } $email = unxmlify($author->get_email()); if (!$profile && $author->get_link()) { $profile = trim(unxmlify($author->get_link())); } if (!$vcard['photo']) { $rawtags = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); if ($rawtags) { $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]; if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo') { $vcard['photo'] = $elems['link'][0]['attribs']['']['href']; } } } } else { $item = $feed->get_item(0); if ($item) { $author = $item->get_author(); if ($author) { $vcard['fn'] = trim(unxmlify($author->get_name())); if (!$vcard['fn']) { $vcard['fn'] = trim(unxmlify($author->get_email())); } if (strpos($vcard['fn'], '@') !== false) { $vcard['fn'] = substr($vcard['fn'], 0, strpos($vcard['fn'], '@')); } $email = unxmlify($author->get_email()); if (!$profile && $author->get_link()) { $profile = trim(unxmlify($author->get_link())); } } if (!$vcard['photo']) { $rawmedia = $item->get_item_tags('http://search.yahoo.com/mrss/', 'thumbnail'); if ($rawmedia && $rawmedia[0]['attribs']['']['url']) { $vcard['photo'] = unxmlify($rawmedia[0]['attribs']['']['url']); } } if (!$vcard['photo']) { $rawtags = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); if ($rawtags) { $elems = $rawtags[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]; if (x($elems, 'link') && $elems['link'][0]['attribs']['']['rel'] === 'photo') { $vcard['photo'] = $elems['link'][0]['attribs']['']['href']; } } } } } if (!$vcard['photo'] && strlen($email)) { $vcard['photo'] = avatar_img($email); } if ($poll === $profile) { $lnk = $feed->get_permalink(); } if (isset($lnk) && strlen($lnk)) { $profile = $lnk; } if (!x($vcard, 'fn')) { $vcard['fn'] = notags($feed->get_title()); } if (!x($vcard, 'fn')) { $vcard['fn'] = notags($feed->get_description()); } if (strpos($vcard['fn'], 'Twitter / ') !== false) { $vcard['fn'] = substr($vcard['fn'], strpos($vcard['fn'], '/') + 1); $vcard['fn'] = trim($vcard['fn']); } if (!x($vcard, 'nick')) { $vcard['nick'] = strtolower(notags(unxmlify($vcard['fn']))); if (strpos($vcard['nick'], ' ')) { $vcard['nick'] = trim(substr($vcard['nick'], 0, strpos($vcard['nick'], ' '))); } } if (!$network) { $network = NETWORK_FEED; } if (!$priority) { $priority = 2; } } } if (!x($vcard, 'photo')) { $a = get_app(); $vcard['photo'] = $a->get_baseurl() . '/images/person-175.jpg'; } if (!$profile) { $profile = $url; } // No human could be associated with this link, use the URL as the contact name if ($network === NETWORK_FEED && $poll && !x($vcard, 'fn')) { $vcard['fn'] = $url; } $vcard['fn'] = notags($vcard['fn']); $vcard['nick'] = str_replace(' ', '', notags($vcard['nick'])); $result['name'] = $vcard['fn']; $result['nick'] = $vcard['nick']; $result['url'] = $profile; $result['addr'] = $addr; $result['batch'] = $batch; $result['notify'] = $notify; $result['poll'] = $poll; $result['request'] = $request; $result['confirm'] = $confirm; $result['poco'] = $poco; $result['photo'] = $vcard['photo']; $result['priority'] = $priority; $result['network'] = $network; $result['alias'] = $alias; $result['pubkey'] = $pubkey; logger('probe_url: ' . print_r($result, true), LOGGER_DEBUG); return $result; }
/** * Takes in a string of Email Addresses and returns an Array of * addresses. * * Example: * "craigslist.org" <*****@*****.**> * * will return: * Array * ( * [0] => stdClass Object * ( * [mailbox] => noreply * [host] => craigslist.org * [personal] => craigslist.org * ) * *) * * Note: More then one Email Address can be entered as a parameter. An * array containing N array entries (where N is the number of emails entered) * will be returned. * */ public function parseAddresses($adr) { $adrArray = imap_rfc822_parse_adrlist($adr, "#"); return $adrArray; }
$tpl->assign('step', STEP_UPGRADE); $tpl->display('steps/redirect.tpl'); exit; } break; // Personalize system information (title, timezone, language) // Personalize system information (title, timezone, language) case STEP_CONTACT: $settings = DevblocksPlatform::getPluginSettingsService(); @($default_reply_from = DevblocksPlatform::importGPC($_POST['default_reply_from'], 'string', $settings->get('feg.core', FegSettings::DEFAULT_REPLY_FROM))); @($default_reply_personal = DevblocksPlatform::importGPC($_POST['default_reply_personal'], 'string', $settings->get('feg.core', FegSettings::DEFAULT_REPLY_PERSONAL))); @($app_title = DevblocksPlatform::importGPC($_POST['app_title'], 'string', $settings->get('feg.core', FegSettings::APP_TITLE, 'Feg - Fax Email Gateway'))); @($form_submit = DevblocksPlatform::importGPC($_POST['form_submit'], 'integer')); if (!empty($form_submit)) { // && !empty($default_reply_from) $validate = imap_rfc822_parse_adrlist(sprintf("<%s>", $default_reply_from), "localhost"); if (!empty($default_reply_from) && is_array($validate) && 1 == count($validate)) { $settings->set('feg.core', FegSettings::DEFAULT_REPLY_FROM, $default_reply_from); } if (!empty($default_reply_personal)) { $settings->set('feg.core', FegSettings::DEFAULT_REPLY_PERSONAL, $default_reply_personal); } if (!empty($app_title)) { $settings->set('feg.core', FegSettings::APP_TITLE, $app_title); } $tpl->assign('step', STEP_OUTGOING_MAIL); $tpl->display('steps/redirect.tpl'); exit; } if (!empty($form_submit) && empty($default_reply_from)) { $tpl->assign('failed', true);
/** * Parse and validate a string containing one or more RFC822-style comma-separated email addresses * of the form "display name <address>" into an array of name/address pairs. * Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available. * Note that quotes in the name part are removed. * @param string $addrstr The address list string * @param bool $useimap Whether to use the IMAP extension to parse the list * @return array * @link http://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation */ public function parseAddresses($addrstr, $useimap = true) { $addresses = array(); if ($useimap and function_exists('imap_rfc822_parse_adrlist')) { //Use this built-in parser if it's available $list = imap_rfc822_parse_adrlist($addrstr, ''); foreach ($list as $address) { if ($address->host != '.SYNTAX-ERROR.') { if ($this->validateAddress($address->mailbox . '@' . $address->host)) { $addresses[] = array('name' => property_exists($address, 'personal') ? $address->personal : '', 'address' => $address->mailbox . '@' . $address->host); } } } } else { //Use this simpler parser $list = explode(',', $addrstr); foreach ($list as $address) { $address = trim($address); //Is there a separate name part? if (strpos($address, '<') === false) { //No separate name, just use the whole thing if ($this->validateAddress($address)) { $addresses[] = array('name' => '', 'address' => $address); } } else { list($name, $email) = explode('<', $address); $email = trim(str_replace('>', '', $email)); if ($this->validateAddress($email)) { $addresses[] = array('name' => trim(str_replace(array('"', "'"), '', $name)), 'address' => $email); } } } } return $addresses; }
protected function processDsn($messageId) { $result = array('email' => null, 'bounceType' => self::BOUNCE_HARD, 'action' => null, 'statusCode' => null, 'diagnosticCode' => null); $action = $statusCode = $diagnosticCode = null; // first part of DSN (Delivery Status Notification), human-readable explanation $dsnMessage = imap_fetchbody($this->_connection, $messageId, "1"); $dsnMessageStructure = imap_bodystruct($this->_connection, $messageId, "1"); if ($dsnMessageStructure->encoding == 4) { $dsnMessage = quoted_printable_decode($dsnMessage); } elseif ($dsnMessageStructure->encoding == 3) { $dsnMessage = base64_decode($dsnMessage); } // second part of DSN (Delivery Status Notification), delivery-status $dsnReport = imap_fetchbody($this->_connection, $messageId, "2"); if (preg_match("/Original-Recipient: rfc822;(.*)/i", $dsnReport, $matches)) { $emailArr = imap_rfc822_parse_adrlist($matches[1], 'default.domain.name'); if (isset($emailArr[0]->host) && $emailArr[0]->host != '.SYNTAX-ERROR.' && $emailArr[0]->host != 'default.domain.name') { $result['email'] = $emailArr[0]->mailbox . '@' . $emailArr[0]->host; } } else { if (preg_match("/Final-Recipient: rfc822;(.*)/i", $dsnReport, $matches)) { $emailArr = imap_rfc822_parse_adrlist($matches[1], 'default.domain.name'); if (isset($emailArr[0]->host) && $emailArr[0]->host != '.SYNTAX-ERROR.' && $emailArr[0]->host != 'default.domain.name') { $result['email'] = $emailArr[0]->mailbox . '@' . $emailArr[0]->host; } } } if (preg_match("/Action: (.+)/i", $dsnReport, $matches)) { $action = strtolower(trim($matches[1])); } if (preg_match("/Status: ([0-9\\.]+)/i", $dsnReport, $matches)) { $statusCode = $matches[1]; } // Could be multi-line , if the new line is beginning with SPACE or HTAB if (preg_match("/Diagnostic-Code:((?:[^\n]|\n[\t ])+)(?:\n[^\t ]|\$)/is", $dsnReport, $matches)) { $diagnosticCode = $matches[1]; } if (empty($result['email'])) { if (preg_match("/quota exceed.*<(\\S+@\\S+\\w)>/is", $dsnMessage, $matches)) { $result['email'] = $matches[1]; $result['bounceType'] = self::BOUNCE_SOFT; } } else { // "failed" / "delayed" / "delivered" / "relayed" / "expanded" if ($action == 'failed') { $rules = $this->getRules(); $foundMatch = false; foreach ($rules[self::DIAGNOSTIC_CODE_RULES] as $rule) { if (preg_match($rule['regex'], $diagnosticCode, $matches)) { $foundMatch = true; $result['bounceType'] = $rule['bounceType']; break; } } if (!$foundMatch) { foreach ($rules[self::DSN_MESSAGE_RULES] as $rule) { if (preg_match($rule['regex'], $dsnMessage, $matches)) { $foundMatch = true; $result['bounceType'] = $rule['bounceType']; break; } } } if (!$foundMatch) { foreach ($rules[self::COMMON_RULES] as $rule) { if (preg_match($rule['regex'], $dsnMessage, $matches)) { $foundMatch = true; $result['bounceType'] = $rule['bounceType']; break; } } } if (!$foundMatch) { $result['bounceType'] = self::BOUNCE_HARD; } } else { $result['bounceType'] = self::BOUNCE_SOFT; } } $result['action'] = $action; $result['statusCode'] = $statusCode; $result['diagnosticCode'] = $diagnosticCode; return $result; }
/** * Returns headers. * * @param string $pid Part Id * @return array * @throws \Jyxo\Mail\Parser\EmailNotExistException If no such email exists */ public function getHeaders($pid = null) { // Parses headers $rawHeaders = $this->getRawHeaders($pid); if (null === $pid) { $msgno = imap_msgno($this->connection, $this->uid); if (0 === $msgno) { throw new Parser\EmailNotExistException('Email does not exist'); } $headerInfo = imap_headerinfo($this->connection, $msgno); } else { $headerInfo = imap_rfc822_parse_headers($rawHeaders); } // Adds a header that the IMAP extension does not support if (preg_match("~Disposition-Notification-To:(.+?)(?=\r?\n(?:\\S|\r?\n))~is", $rawHeaders, $matches)) { $addressList = imap_rfc822_parse_adrlist($matches[1], ''); // {''} is used because of CS rules $headerInfo->{'disposition_notification_toaddress'} = substr(trim($matches[1]), 0, 1024); $headerInfo->{'disposition_notification_to'} = array($addressList[0]); } $headers = array(); static $mimeHeaders = array('toaddress', 'ccaddress', 'bccaddress', 'fromaddress', 'reply_toaddress', 'senderaddress', 'return_pathaddress', 'subject', 'fetchfrom', 'fetchsubject', 'disposition_notification_toaddress'); foreach ($headerInfo as $key => $value) { if (!is_object($value) && !is_array($value)) { if (in_array($key, $mimeHeaders)) { $headers[$key] = $this->decodeMimeHeader($value); } else { $headers[$key] = $this->convertToUtf8($value); } } } // Adds "udate" if missing if (!empty($headerInfo->udate)) { $headers['udate'] = $headerInfo->udate; } elseif (!empty($headerInfo->date)) { $headers['udate'] = strtotime($headerInfo->date); } else { $headers['udate'] = time(); } // Parses references $headers['references'] = isset($headers['references']) ? explode('> <', trim($headers['references'], '<>')) : array(); static $types = array('to', 'cc', 'bcc', 'from', 'reply_to', 'sender', 'return_path', 'disposition_notification_to'); for ($i = 0; $i < count($types); $i++) { $type = $types[$i]; $headers[$type] = array(); if (isset($headerInfo->{$type})) { foreach ($headerInfo->{$type} as $object) { $newHeader = array(); foreach ($object as $attributeName => $attributeValue) { if (!empty($attributeValue)) { $newHeader[$attributeName] = 'personal' === $attributeName ? $this->decodeMimeHeader($attributeValue) : $this->convertToUtf8($attributeValue); } } if (!empty($newHeader)) { if (isset($newHeader['mailbox'], $newHeader['host'])) { $newHeader['email'] = $newHeader['mailbox'] . '@' . $newHeader['host']; } elseif (isset($newHeader['mailbox'])) { $newHeader['email'] = $newHeader['mailbox']; } else { $newHeader['email'] = 'undisclosed-recipients'; } $headers[$type][] = $newHeader; } } } } // Adds X-headers if (preg_match_all("~(X(?:[\\-]\\w+)+):(.+?)(?=\r?\n(?:\\S|\r?\n))~is", $rawHeaders, $matches) > 0) { for ($i = 0; $i < count($matches[0]); $i++) { // Converts to the format used by imap_headerinfo() $key = str_replace('-', '_', strtolower($matches[1][$i])); // Removes line endings $value = strtr(trim($matches[2][$i]), array("\r" => '', "\n" => '', "\t" => ' ')); $headers[$key] = $value; } } return $headers; }
/** * Creates a new e-mail address record. * * @param array $fields An array of fields=>values * @return integer The new address ID * * DAO_Address::create(array( * DAO_Address::EMAIL => 'user@domain' * )); * */ static function create($fields) { $db = DevblocksPlatform::getDatabaseService(); $id = $db->GenID('address_seq'); if (null == ($email = @$fields[self::EMAIL])) { return NULL; } // [TODO] Validate @($addresses = imap_rfc822_parse_adrlist('<' . $email . '>', 'host')); if (!is_array($addresses) || empty($addresses)) { return NULL; } $address = array_shift($addresses); if (empty($address->host) || $address->host == 'host') { return NULL; } $full_address = trim(strtolower($address->mailbox . '@' . $address->host)); // Make sure the address doesn't exist already if (null == ($check = self::getByEmail($full_address))) { $sql = sprintf("INSERT INTO address (id,email,first_name,last_name,contact_org_id,num_spam,num_nonspam,is_banned,last_autoreply) " . "VALUES (%d,%s,'','',0,0,0,0,0)", $id, $db->qstr($full_address)); $db->Execute($sql) or die(__CLASS__ . '(' . __LINE__ . ')' . ':' . $db->ErrorMsg()); /* @var $rs ADORecordSet */ } else { // update $id = $check->id; unset($fields[self::ID]); unset($fields[self::EMAIL]); } self::update($id, $fields); return $id; }
function onepoll_run(&$argv, &$argc) { global $a, $db; if (is_null($a)) { $a = new App(); } if (is_null($db)) { @(include ".htconfig.php"); require_once "include/dba.php"; $db = new dba($db_host, $db_user, $db_pass, $db_data); unset($db_host, $db_user, $db_pass, $db_data); } require_once 'include/session.php'; require_once 'include/datetime.php'; require_once 'library/simplepie/simplepie.inc'; require_once 'include/items.php'; require_once 'include/Contact.php'; require_once 'include/email.php'; require_once 'include/socgraph.php'; require_once 'include/pidfile.php'; require_once 'include/queue_fn.php'; load_config('config'); load_config('system'); $a->set_baseurl(get_config('system', 'url')); load_hooks(); logger('onepoll: start'); $manual_id = 0; $generation = 0; $hub_update = false; $force = false; $restart = false; if ($argc > 1 && intval($argv[1])) { $contact_id = intval($argv[1]); } if (!$contact_id) { logger('onepoll: no contact'); return; } $lockpath = get_lockpath(); if ($lockpath != '') { $pidfile = new pidfile($lockpath, 'onepoll' . $contact_id); if ($pidfile->is_already_running()) { logger("onepoll: Already running for contact " . $contact_id); if ($pidfile->running_time() > 9 * 60) { $pidfile->kill(); logger("killed stale process"); } exit; } } $d = datetime_convert(); // Only poll from those with suitable relationships, // and which have a polling address and ignore Diaspora since // we are unable to match those posts with a Diaspora GUID and prevent duplicates. $contacts = q("SELECT `contact`.* FROM `contact`\n\t\tWHERE ( `rel` = %d OR `rel` = %d ) AND `poll` != ''\n\t\tAND NOT `network` IN ( '%s', '%s', '%s' )\n\t\tAND `contact`.`id` = %d\n\t\tAND `self` = 0 AND `contact`.`blocked` = 0 AND `contact`.`readonly` = 0\n\t\tAND `contact`.`archive` = 0 LIMIT 1", intval(CONTACT_IS_SHARING), intval(CONTACT_IS_FRIEND), dbesc(NETWORK_DIASPORA), dbesc(NETWORK_FACEBOOK), dbesc(NETWORK_PUMPIO), intval($contact_id)); if (!count($contacts)) { return; } $contact = $contacts[0]; $xml = false; $t = $contact['last-update']; if ($contact['subhub']) { $poll_interval = get_config('system', 'pushpoll_frequency'); $contact['priority'] = $poll_interval !== false ? intval($poll_interval) : 3; $hub_update = false; if (datetime_convert('UTC', 'UTC', 'now') > datetime_convert('UTC', 'UTC', $t . " + 1 day")) { $hub_update = true; } } else { $hub_update = false; } $importer_uid = $contact['uid']; $r = q("SELECT `contact`.*, `user`.`page-flags` FROM `contact` INNER JOIN `user` on `contact`.`uid` = `user`.`uid` WHERE `user`.`uid` = %d AND `contact`.`self` = 1 LIMIT 1", intval($importer_uid)); if (!count($r)) { return; } $importer = $r[0]; logger("onepoll: poll: ({$contact['id']}) IMPORTER: {$importer['name']}, CONTACT: {$contact['name']}"); $last_update = $contact['last-update'] === '0000-00-00 00:00:00' ? datetime_convert('UTC', 'UTC', 'now - 7 days', ATOM_TIME) : datetime_convert('UTC', 'UTC', $contact['last-update'], ATOM_TIME); if ($contact['network'] === NETWORK_DFRN) { $idtosend = $orig_id = $contact['dfrn-id'] ? $contact['dfrn-id'] : $contact['issued-id']; if (intval($contact['duplex']) && $contact['dfrn-id']) { $idtosend = '0:' . $orig_id; } if (intval($contact['duplex']) && $contact['issued-id']) { $idtosend = '1:' . $orig_id; } // they have permission to write to us. We already filtered this in the contact query. $perm = 'rw'; // But this may be our first communication, so set the writable flag if it isn't set already. if (!intval($contact['writable'])) { q("update contact set writable = 1 where id = %d", intval($contact['id'])); } $url = $contact['poll'] . '?dfrn_id=' . $idtosend . '&dfrn_version=' . DFRN_PROTOCOL_VERSION . '&type=data&last_update=' . $last_update . '&perm=' . $perm; $handshake_xml = fetch_url($url); $html_code = $a->get_curl_code(); logger('onepoll: handshake with url ' . $url . ' returns xml: ' . $handshake_xml, LOGGER_DATA); if (!strlen($handshake_xml) || $html_code >= 400 || !$html_code) { logger("poller: {$url} appears to be dead - marking for death "); // dead connection - might be a transient event, or this might // mean the software was uninstalled or the domain expired. // Will keep trying for one month. mark_for_death($contact); // set the last-update so we don't keep polling $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d", dbesc(datetime_convert()), intval($contact['id'])); return; } if (!strstr($handshake_xml, '<')) { logger('poller: response from ' . $url . ' did not contain XML.'); mark_for_death($contact); $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d", dbesc(datetime_convert()), intval($contact['id'])); return; } $res = parse_xml_string($handshake_xml); if (intval($res->status) == 1) { logger("poller: {$url} replied status 1 - marking for death "); // we may not be friends anymore. Will keep trying for one month. // set the last-update so we don't keep polling $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d", dbesc(datetime_convert()), intval($contact['id'])); mark_for_death($contact); } else { if ($contact['term-date'] != '0000-00-00 00:00:00') { logger("poller: {$url} back from the dead - removing mark for death"); unmark_for_death($contact); } } if (intval($res->status) != 0 || !strlen($res->challenge) || !strlen($res->dfrn_id)) { return; } if ((double) $res->dfrn_version > 2.21 && $contact['poco'] == '') { q("update contact set poco = '%s' where id = %d", dbesc(str_replace('/profile/', '/poco/', $contact['url'])), intval($contact['id'])); } $postvars = array(); $sent_dfrn_id = hex2bin((string) $res->dfrn_id); $challenge = hex2bin((string) $res->challenge); $final_dfrn_id = ''; if ($contact['duplex'] && strlen($contact['prvkey'])) { openssl_private_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['prvkey']); openssl_private_decrypt($challenge, $postvars['challenge'], $contact['prvkey']); } else { openssl_public_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['pubkey']); openssl_public_decrypt($challenge, $postvars['challenge'], $contact['pubkey']); } $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.')); if (strpos($final_dfrn_id, ':') == 1) { $final_dfrn_id = substr($final_dfrn_id, 2); } if ($final_dfrn_id != $orig_id) { logger('poller: ID did not decode: ' . $contact['id'] . ' orig: ' . $orig_id . ' final: ' . $final_dfrn_id); // did not decode properly - cannot trust this site return; } $postvars['dfrn_id'] = $idtosend; $postvars['dfrn_version'] = DFRN_PROTOCOL_VERSION; $postvars['perm'] = 'rw'; $xml = post_url($contact['poll'], $postvars); } elseif ($contact['network'] === NETWORK_OSTATUS || $contact['network'] === NETWORK_DIASPORA || $contact['network'] === NETWORK_FEED) { // Upgrading DB fields from an older Friendica version // Will only do this once per notify-enabled OStatus contact // or if relationship changes $stat_writeable = $contact['notify'] && ($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['rel'] == CONTACT_IS_FRIEND) ? 1 : 0; if ($contact['network'] === NETWORK_OSTATUS && get_pconfig($importer_uid, 'system', 'ostatus_autofriend')) { $stat_writeable = 1; } if ($stat_writeable != $contact['writable']) { q("UPDATE `contact` SET `writable` = %d WHERE `id` = %d", intval($stat_writeable), intval($contact['id'])); } // Are we allowed to import from this person? if ($contact['rel'] == CONTACT_IS_FOLLOWER || $contact['blocked'] || $contact['readonly']) { return; } $xml = fetch_url($contact['poll']); } elseif ($contact['network'] === NETWORK_MAIL || $contact['network'] === NETWORK_MAIL2) { logger("Mail: Fetching", LOGGER_DEBUG); $mail_disabled = function_exists('imap_open') && !get_config('system', 'imap_disabled') ? 0 : 1; if ($mail_disabled) { return; } logger("Mail: Enabled", LOGGER_DEBUG); $mbox = null; $x = q("SELECT `prvkey` FROM `user` WHERE `uid` = %d LIMIT 1", intval($importer_uid)); $mailconf = q("SELECT * FROM `mailacct` WHERE `server` != '' AND `uid` = %d LIMIT 1", intval($importer_uid)); if (count($x) && count($mailconf)) { $mailbox = construct_mailbox_name($mailconf[0]); $password = ''; openssl_private_decrypt(hex2bin($mailconf[0]['pass']), $password, $x[0]['prvkey']); $mbox = email_connect($mailbox, $mailconf[0]['user'], $password); unset($password); logger("Mail: Connect to " . $mailconf[0]['user']); if ($mbox) { q("UPDATE `mailacct` SET `last_check` = '%s' WHERE `id` = %d AND `uid` = %d", dbesc(datetime_convert()), intval($mailconf[0]['id']), intval($importer_uid)); logger("Mail: Connected to " . $mailconf[0]['user']); } else { logger("Mail: Connection error " . $mailconf[0]['user'] . " " . print_r(imap_errors())); } } if ($mbox) { $msgs = email_poll($mbox, $contact['addr']); if (count($msgs)) { logger("Mail: Parsing " . count($msgs) . " mails for " . $mailconf[0]['user'], LOGGER_DEBUG); $metas = email_msg_meta($mbox, implode(',', $msgs)); if (count($metas) != count($msgs)) { logger("onepoll: for " . $mailconf[0]['user'] . " there are " . count($msgs) . " messages but received " . count($metas) . " metas", LOGGER_DEBUG); } else { $msgs = array_combine($msgs, $metas); foreach ($msgs as $msg_uid => $meta) { logger("Mail: Parsing mail " . $msg_uid, LOGGER_DATA); $datarray = array(); $datarray['verb'] = ACTIVITY_POST; $datarray['object-type'] = ACTIVITY_OBJ_NOTE; // $meta = email_msg_meta($mbox,$msg_uid); // $headers = email_msg_headers($mbox,$msg_uid); $datarray['uri'] = msgid2iri(trim($meta->message_id, '<>')); // Have we seen it before? $r = q("SELECT * FROM `item` WHERE `uid` = %d AND `uri` = '%s' LIMIT 1", intval($importer_uid), dbesc($datarray['uri'])); if (count($r)) { logger("Mail: Seen before " . $msg_uid . " for " . $mailconf[0]['user'] . " UID: " . $importer_uid . " URI: " . $datarray['uri'], LOGGER_DEBUG); // Only delete when mails aren't automatically moved or deleted if ($mailconf[0]['action'] != 1 and $mailconf[0]['action'] != 3) { if ($meta->deleted && !$r[0]['deleted']) { q("UPDATE `item` SET `deleted` = 1, `changed` = '%s' WHERE `id` = %d", dbesc(datetime_convert()), intval($r[0]['id'])); } } switch ($mailconf[0]['action']) { case 0: logger("Mail: Seen before " . $msg_uid . " for " . $mailconf[0]['user'] . ". Doing nothing.", LOGGER_DEBUG); break; case 1: logger("Mail: Deleting " . $msg_uid . " for " . $mailconf[0]['user']); imap_delete($mbox, $msg_uid, FT_UID); break; case 2: logger("Mail: Mark as seen " . $msg_uid . " for " . $mailconf[0]['user']); imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID); break; case 3: logger("Mail: Moving " . $msg_uid . " to " . $mailconf[0]['movetofolder'] . " for " . $mailconf[0]['user']); imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID); if ($mailconf[0]['movetofolder'] != "") { imap_mail_move($mbox, $msg_uid, $mailconf[0]['movetofolder'], FT_UID); } break; } continue; } // look for a 'references' or an 'in-reply-to' header and try to match with a parent item we have locally. // $raw_refs = ((x($headers,'references')) ? str_replace("\t",'',$headers['references']) : ''); $raw_refs = property_exists($meta, 'references') ? str_replace("\t", '', $meta->references) : ''; if (!trim($raw_refs)) { $raw_refs = property_exists($meta, 'in_reply_to') ? str_replace("\t", '', $meta->in_reply_to) : ''; } $raw_refs = trim($raw_refs); // Don't allow a blank reference in $refs_arr if ($raw_refs) { $refs_arr = explode(' ', $raw_refs); if (count($refs_arr)) { for ($x = 0; $x < count($refs_arr); $x++) { $refs_arr[$x] = "'" . msgid2iri(str_replace(array('<', '>', ' '), array('', '', ''), dbesc($refs_arr[$x]))) . "'"; } } $qstr = implode(',', $refs_arr); $r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `uri` IN ( {$qstr} ) AND `uid` = %d LIMIT 1", intval($importer_uid)); if (count($r)) { $datarray['parent-uri'] = $r[0]['parent-uri']; } // Set the parent as the top-level item // $datarray['parent-uri'] = $r[0]['uri']; } // Decoding the header $subject = imap_mime_header_decode($meta->subject); $datarray['title'] = ""; foreach ($subject as $subpart) { if ($subpart->charset != "default") { $datarray['title'] .= iconv($subpart->charset, 'UTF-8//IGNORE', $subpart->text); } else { $datarray['title'] .= $subpart->text; } } $datarray['title'] = notags(trim($datarray['title'])); //$datarray['title'] = notags(trim($meta->subject)); $datarray['created'] = datetime_convert('UTC', 'UTC', $meta->date); // Is it a reply? $reply = (substr(strtolower($datarray['title']), 0, 3) == "re:" or substr(strtolower($datarray['title']), 0, 3) == "re-" or $raw_refs != ""); // Remove Reply-signs in the subject $datarray['title'] = RemoveReply($datarray['title']); // If it seems to be a reply but a header couldn't be found take the last message with matching subject if (!x($datarray, 'parent-uri') and $reply) { $r = q("SELECT `uri` , `parent-uri` FROM `item` WHERE `title` = \"%s\" AND `uid` = %d ORDER BY `created` DESC LIMIT 1", dbesc(protect_sprintf($datarray['title'])), intval($importer_uid)); if (count($r)) { $datarray['parent-uri'] = $r[0]['parent-uri']; } } if (!x($datarray, 'parent-uri')) { $datarray['parent-uri'] = $datarray['uri']; } $r = email_get_msg($mbox, $msg_uid, $reply); if (!$r) { logger("Mail: can't fetch msg " . $msg_uid . " for " . $mailconf[0]['user']); continue; } $datarray['body'] = escape_tags($r['body']); $datarray['body'] = limit_body_size($datarray['body']); logger("Mail: Importing " . $msg_uid . " for " . $mailconf[0]['user']); // some mailing lists have the original author as 'from' - add this sender info to msg body. // todo: adding a gravatar for the original author would be cool if (!stristr($meta->from, $contact['addr'])) { $from = imap_mime_header_decode($meta->from); $fromdecoded = ""; foreach ($from as $frompart) { if ($frompart->charset != "default") { $fromdecoded .= iconv($frompart->charset, 'UTF-8//IGNORE', $frompart->text); } else { $fromdecoded .= $frompart->text; } } $fromarr = imap_rfc822_parse_adrlist($fromdecoded, $a->get_hostname()); $frommail = $fromarr[0]->mailbox . "@" . $fromarr[0]->host; if (isset($fromarr[0]->personal)) { $fromname = $fromarr[0]->personal; } else { $fromname = $frommail; } //$datarray['body'] = "[b]".t('From: ') . escape_tags($fromdecoded) . "[/b]\n\n" . $datarray['body']; $datarray['author-name'] = $fromname; $datarray['author-link'] = "mailto:" . $frommail; $datarray['author-avatar'] = $contact['photo']; $datarray['owner-name'] = $contact['name']; $datarray['owner-link'] = "mailto:" . $contact['addr']; $datarray['owner-avatar'] = $contact['photo']; } else { $datarray['author-name'] = $contact['name']; $datarray['author-link'] = 'mailbox'; $datarray['author-avatar'] = $contact['photo']; } $datarray['uid'] = $importer_uid; $datarray['contact-id'] = $contact['id']; if ($datarray['parent-uri'] === $datarray['uri']) { $datarray['private'] = 1; } if ($contact['network'] === NETWORK_MAIL && !get_pconfig($importer_uid, 'system', 'allow_public_email_replies')) { $datarray['private'] = 1; $datarray['allow_cid'] = '<' . $contact['id'] . '>'; } $stored_item = item_store($datarray); q("UPDATE `item` SET `last-child` = 0 WHERE `parent-uri` = '%s' AND `uid` = %d", dbesc($datarray['parent-uri']), intval($importer_uid)); q("UPDATE `item` SET `last-child` = 1 WHERE `id` = %d", intval($stored_item)); switch ($mailconf[0]['action']) { case 0: logger("Mail: Seen before " . $msg_uid . " for " . $mailconf[0]['user'] . ". Doing nothing.", LOGGER_DEBUG); break; case 1: logger("Mail: Deleting " . $msg_uid . " for " . $mailconf[0]['user']); imap_delete($mbox, $msg_uid, FT_UID); break; case 2: logger("Mail: Mark as seen " . $msg_uid . " for " . $mailconf[0]['user']); imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID); break; case 3: logger("Mail: Moving " . $msg_uid . " to " . $mailconf[0]['movetofolder'] . " for " . $mailconf[0]['user']); imap_setflag_full($mbox, $msg_uid, "\\Seen", ST_UID); if ($mailconf[0]['movetofolder'] != "") { imap_mail_move($mbox, $msg_uid, $mailconf[0]['movetofolder'], FT_UID); } break; } } } } else { logger("Mail: no mails for " . $mailconf[0]['user']); } logger("Mail: closing connection for " . $mailconf[0]['user']); imap_close($mbox); } } elseif ($contact['network'] === NETWORK_FACEBOOK) { // This is picked up by the Facebook plugin on a cron hook. // Ignored here. } elseif ($contact['network'] === NETWORK_PUMPIO) { // This is picked up by the pump.io plugin on a cron hook. // Ignored here. } if ($xml) { logger('poller: received xml : ' . $xml, LOGGER_DATA); if (!strstr($xml, '<')) { logger('poller: post_handshake: response from ' . $url . ' did not contain XML.'); $r = q("UPDATE `contact` SET `last-update` = '%s' WHERE `id` = %d", dbesc(datetime_convert()), intval($contact['id'])); return; } consume_feed($xml, $importer, $contact, $hub, 1, 1); // do it twice. Ensures that children of parents which may be later in the stream aren't tossed consume_feed($xml, $importer, $contact, $hub, 1, 2); $hubmode = 'subscribe'; if ($contact['network'] === NETWORK_DFRN || $contact['blocked'] || $contact['readonly']) { $hubmode = 'unsubscribe'; } if (($contact['network'] === NETWORK_OSTATUS || $contact['network'] == NETWORK_FEED) && !$contact['hub-verify']) { $hub_update = true; } if (strlen($hub) && $hub_update && ($contact['rel'] != CONTACT_IS_FOLLOWER || $contact['network'] == NETWORK_FEED)) { logger('poller: hub ' . $hubmode . ' : ' . $hub . ' contact name : ' . $contact['name'] . ' local user : '******'name']); $hubs = explode(',', $hub); if (count($hubs)) { foreach ($hubs as $h) { $h = trim($h); if (!strlen($h)) { continue; } subscribe_to_hub($h, $importer, $contact, $hubmode); } } } } $updated = datetime_convert(); $r = q("UPDATE `contact` SET `last-update` = '%s', `success_update` = '%s' WHERE `id` = %d", dbesc($updated), dbesc($updated), intval($contact['id'])); // load current friends if possible. if ($contact['poco']) { $r = q("SELECT count(*) as total from glink\n\t\t\twhere `cid` = %d and updated > UTC_TIMESTAMP() - INTERVAL 1 DAY", intval($contact['id'])); } if (count($r)) { if (!$r[0]['total']) { poco_load($contact['id'], $importer_uid, 0, $contact['poco']); } } return; }
function logTicketAction() { $active_worker = CerberusApplication::getActiveWorker(); if (!$active_worker->hasPriv('core.mail.log_ticket')) { return; } @($to = DevblocksPlatform::importGPC($_POST['to'], 'string')); @($reqs = DevblocksPlatform::importGPC($_POST['reqs'], 'string')); @($subject = DevblocksPlatform::importGPC($_POST['subject'], 'string')); @($content = DevblocksPlatform::importGPC($_POST['content'], 'string')); @($send_to_requesters = DevblocksPlatform::importGPC($_POST['send_to_requesters'], 'integer', 0)); @($closed = DevblocksPlatform::importGPC($_POST['closed'], 'integer', 0)); @($move_bucket = DevblocksPlatform::importGPC($_POST['bucket_id'], 'string', '')); @($next_worker_id = DevblocksPlatform::importGPC($_POST['next_worker_id'], 'integer', 0)); @($ticket_reopen = DevblocksPlatform::importGPC($_POST['ticket_reopen'], 'string', '')); @($unlock_date = DevblocksPlatform::importGPC($_POST['unlock_date'], 'string', '')); if (DEMO_MODE) { DevblocksPlatform::redirect(new DevblocksHttpResponse(array('tickets', 'create'))); return; } // ******** $message = new CerberusParserMessage(); $message->headers['date'] = date('r'); $message->headers['to'] = $to; $message->headers['subject'] = $subject; $message->headers['message-id'] = CerberusApplication::generateMessageId(); //$message->headers['x-cerberus-portal'] = 1; // Sender $fromList = imap_rfc822_parse_adrlist(rtrim($reqs, ', '), ''); if (empty($fromList) || !is_array($fromList)) { return; // abort with message } $from = array_shift($fromList); $from_address = $from->mailbox . '@' . $from->host; $message->headers['from'] = $from_address; $message->body = sprintf("(... This message was manually created by %s on behalf of the requesters ...)\r\n", $active_worker->getName()); // // Custom Fields // // if(!empty($aFieldIds)) // foreach($aFieldIds as $iIdx => $iFieldId) { // if(!empty($iFieldId)) { // $field =& $fields[$iFieldId]; /* @var $field Model_CustomField */ // $value = ""; // // switch($field->type) { // case Model_CustomField::TYPE_SINGLE_LINE: // case Model_CustomField::TYPE_MULTI_LINE: // case Model_CustomField::TYPE_URL: // @$value = trim($aFollowUpA[$iIdx]); // break; // // case Model_CustomField::TYPE_NUMBER: // @$value = $aFollowUpA[$iIdx]; // if(!is_numeric($value) || 0 == strlen($value)) // $value = null; // break; // // case Model_CustomField::TYPE_DATE: // if(false !== ($time = strtotime($aFollowUpA[$iIdx]))) // @$value = intval($time); // break; // // case Model_CustomField::TYPE_DROPDOWN: // @$value = $aFollowUpA[$iIdx]; // break; // // case Model_CustomField::TYPE_MULTI_PICKLIST: // @$value = DevblocksPlatform::importGPC($_POST['followup_a_'.$iIdx],'array',array()); // break; // // case Model_CustomField::TYPE_CHECKBOX: // @$value = (isset($aFollowUpA[$iIdx]) && !empty($aFollowUpA[$iIdx])) ? 1 : 0; // break; // // case Model_CustomField::TYPE_MULTI_CHECKBOX: // @$value = DevblocksPlatform::importGPC($_POST['followup_a_'.$iIdx],'array',array()); // break; // // case Model_CustomField::TYPE_WORKER: // @$value = DevblocksPlatform::importGPC($_POST['followup_a_'.$iIdx],'integer',0); // break; // } // // if((is_array($value) && !empty($value)) // || (!is_array($value) && 0 != strlen($value))) // $message->custom_fields[$iFieldId] = $value; // } // } // Parse $ticket_id = CerberusParser::parseMessage($message); $ticket = DAO_Ticket::getTicket($ticket_id); // Add additional requesters to ticket if (is_array($fromList) && !empty($fromList)) { foreach ($fromList as $requester) { if (empty($requester)) { continue; } $host = empty($requester->host) ? 'localhost' : $requester->host; $requester_addy = DAO_Address::lookupAddress($requester->mailbox . '@' . $host, true); DAO_Ticket::createRequester($requester_addy->id, $ticket_id); } } // Worker reply $properties = array('message_id' => $ticket->first_message_id, 'ticket_id' => $ticket_id, 'subject' => $subject, 'content' => $content, 'files' => @$_FILES['attachment'], 'next_worker_id' => $next_worker_id, 'closed' => $closed, 'bucket_id' => $move_bucket, 'ticket_reopen' => $ticket_reopen, 'unlock_date' => $unlock_date, 'agent_id' => $active_worker->id, 'dont_send' => false == $send_to_requesters); CerberusMail::sendTicketMessage($properties); // ******** // if(empty($to) || empty($team_id)) { // DevblocksPlatform::redirect(new DevblocksHttpResponse(array('tickets','create'))); // return; // } $visit = CerberusApplication::getVisit(); /* @var CerberusVisit $visit */ $visit->set('compose.last_ticket', $ticket->mask); DevblocksPlatform::redirect(new DevblocksHttpResponse(array('tickets', 'create'))); }
public static function getDestinations($headers) { $sources = array(); if (isset($headers['to'])) { $sources = array_merge($sources, is_array($headers['to']) ? $headers['to'] : array($headers['to'])); } if (isset($headers['cc'])) { $sources = array_merge($sources, is_array($headers['cc']) ? $headers['cc'] : array($headers['cc'])); } if (isset($headers['envelope-to'])) { $sources = array_merge($sources, is_array($headers['envelope-to']) ? $headers['envelope-to'] : array($headers['envelope-to'])); } if (isset($headers['x-envelope-to'])) { $sources = array_merge($sources, is_array($headers['x-envelope-to']) ? $headers['x-envelope-to'] : array($headers['x-envelope-to'])); } if (isset($headers['delivered-to'])) { $sources = array_merge($sources, is_array($headers['delivered-to']) ? $headers['delivered-to'] : array($headers['delivered-to'])); } $destinations = array(); foreach ($sources as $source) { @($parsed = imap_rfc822_parse_adrlist($source, 'localhost')); $destinations = array_merge($destinations, is_array($parsed) ? $parsed : array($parsed)); } $addresses = array(); foreach ($destinations as $destination) { if (empty($destination->mailbox) || empty($destination->host)) { continue; } $addresses[] = $destination->mailbox . '@' . $destination->host; } @imap_errors(); // Prevent errors from spilling out into STDOUT return $addresses; }
/** * Check that the From header is not trying to impersonate a valid * user that is not $sasluser. * * @param string $sasluser The current, authenticated user. * @param string $sender Sender address * @param string $fromhdr From header * @param string $client_addr Client IP * * @return mixed A PEAR_Error in case of an error, true if From * can be accepted, false if From must be rejected, * or a string with a corrected From header that * makes From acceptable */ function _verify_sender($sasluser, $sender, $fromhdr, $client_addr) { global $conf; if (isset($conf['kolab']['filter']['email_domain'])) { $domains = $conf['kolab']['filter']['email_domain']; } else { $domains = 'localhost'; } if (!is_array($domains)) { $domains = array($domains); } if (isset($conf['kolab']['filter']['local_addr'])) { $local_addr = $conf['kolab']['filter']['local_addr']; } else { $local_addr = '127.0.0.1'; } if (empty($client_addr)) { $client_addr = $local_addr; } if (isset($conf['kolab']['filter']['verify_subdomains'])) { $verify_subdomains = $conf['kolab']['filter']['verify_subdomains']; } else { $verify_subdomains = true; } if (isset($conf['kolab']['filter']['reject_forged_from_header'])) { $reject_forged_from_header = $conf['kolab']['filter']['reject_forged_from_header']; } else { $reject_forged_from_header = false; } if (isset($conf['kolab']['filter']['kolabhosts'])) { $kolabhosts = $conf['kolab']['filter']['kolabhosts']; } else { $kolabhosts = 'localhost'; } if (isset($conf['kolab']['filter']['privileged_networks'])) { $privnetworks = $conf['kolab']['filter']['privileged_networks']; } else { $privnetworks = '127.0.0.0/8'; } /* Allow anything from localhost and * fellow Kolab-hosts */ if ($client_addr == $local_addr) { return true; } $kolabhosts = explode(',', $kolabhosts); $kolabhosts = array_map('gethostbyname', $kolabhosts); $privnetworks = explode(',', $privnetworks); if (array_search($client_addr, $kolabhosts) !== false) { return true; } foreach ($privnetworks as $network) { $iplong = ip2long($client_addr); $cidr = explode("/", $network); $netiplong = ip2long($cidr[0]); if (count($cidr) == 2) { $iplong = $iplong & 0xffffffff << 32 - $cidr[1]; $netiplong = $netiplong & 0xffffffff << 32 - $cidr[1]; } if ($iplong == $netiplong) { return true; } } if ($sasluser) { /* Load the Server library */ require_once 'Horde/Kolab/Server.php'; $server =& Horde_Kolab_Server::singleton(); if (is_a($server, 'PEAR_Error')) { $server->code = OUT_LOG | EX_TEMPFAIL; return $server; } $allowed_addrs = $server->addrsForIdOrMail($sasluser); if (is_a($allowed_addrs, 'PEAR_Error')) { $allowed_addrs->code = OUT_LOG | EX_NOUSER; return $allowed_addrs; } } else { $allowed_addrs = false; } if (isset($conf['kolab']['filter']['unauthenticated_from_insert'])) { $fmt = $conf['kolab']['filter']['unauthenticated_from_insert']; } else { $fmt = '(UNTRUSTED, sender <%s> is not authenticated)'; } $adrs = imap_rfc822_parse_adrlist($fromhdr, $domains[0]); foreach ($adrs as $adr) { $from = $adr->mailbox . '@' . $adr->host; $fromdom = $adr->host; if ($sasluser) { if (!in_array(strtolower($from), $allowed_addrs)) { Horde::log(sprintf("%s is not an allowed From address for %s", $from, $sasluser), 'DEBUG'); return false; } } else { foreach ($domains as $domain) { if (strtolower($fromdom) == $domain || $verify_subdomains && substr($fromdom, -strlen($domain) - 1) == ".{$domain}") { if ($reject_forged_from_header) { Horde::log(sprintf("%s is not an allowed From address for unauthenticated users.", $from), 'DEBUG'); return false; } else { require_once 'Horde/String.php'; require_once 'Horde/MIME.php'; /* Rewrite */ Horde::log(sprintf("%s is not an allowed From address for unauthenticated users, rewriting.", $from), 'DEBUG'); if (property_exists($adr, 'personal')) { $name = str_replace(array("\\", '"'), array("\\\\", '\\"'), MIME::decode($adr->personal, 'utf-8')); } else { $name = ''; } $untrusted = sprintf($fmt, $sender, $from, $name); // Is this test really correct? Is $fromhdr a _decoded_ string? // If not comparing with the unencoded $untrusted is wrong. // sw - 20091125 if (strpos($fromhdr, $untrusted) === false) { $new_from = '"' . MIME::encode($untrusted) . '"'; return $new_from . ' <' . $from . '>'; } else { return true; } } } } } } /* All seems OK */ return true; }
function GetRFC822Addresses($address, &$addresses) { if (function_exists("imap_rfc822_parse_adrlist")) { if (GetType($parsed_addresses = @imap_rfc822_parse_adrlist($address, $this->localhost)) != "array") { return "it was not specified a valid address list"; } for ($entry = 0; $entry < count($parsed_addresses); ++$entry) { if (!isset($parsed_addresses[$entry]->host) || $parsed_addresses[$entry]->host == ".SYNTAX-ERROR.") { return $parsed_addresses[$entry]->mailbox . " .SYNTAX-ERROR."; } $parsed_address = $parsed_addresses[$entry]->mailbox . "@" . $parsed_addresses[$entry]->host; if (isset($addresses[$parsed_address])) { ++$addresses[$parsed_address]; } else { $addresses[$parsed_address] = 1; } } } else { $length = strlen($address); for ($position = 0; $position < $length;) { $match = preg_split($this->EscapePattern($this->email_address_pattern), strtolower(substr($address, $position)), 2); if (count($match) < 2) { break; } $position += strlen($match[0]); $next_position = $length - strlen($match[1]); $found = substr($address, $position, $next_position - $position); if (!strcmp($found, "")) { break; } if (isset($addresses[$found])) { ++$addresses[$found]; } else { $addresses[$found] = 1; } $position = $next_position; } } return ""; }
/** * This function takes in an array of the address objects generated by the message headers and turns them into an * associative array. * * @param string $addresses * * @return Address[] */ protected function processAddressObject($addresses) { $output_addresses = array(); $decoded_addresses = imap_rfc822_parse_adrlist($addresses, null); if (is_array($decoded_addresses)) { foreach ($decoded_addresses as $address) { $current_address = new Address($address->mailbox . '@' . $address->host); if (isset($address->personal)) { $current_address->setName($address->personal); } array_push($output_addresses, $current_address); } } return $output_addresses; }
private function _parseRfcAddressList($addressStr, $only_one) { // Need to parse the 'From' header as RFC-2822: "name" <*****@*****.**> @($rfcAddressList = imap_rfc822_parse_adrlist($addressStr, 'host')); if (!is_array($rfcAddressList) || empty($rfcAddressList)) { return NULL; } $addresses = array(); foreach ($rfcAddressList as $rfcAddress) { if (empty($rfcAddress->host) || $rfcAddress->host == 'host') { continue; } $addresses[] = trim(strtolower($rfcAddress->mailbox . '@' . $rfcAddress->host)); } if (empty($addresses)) { return NULL; } $result = $only_one ? $addresses[0] : $addresses; return $result; }
private function extractMailFromHeader($mail_header) { $mail_addresses = imap_rfc822_parse_adrlist($mail_header, ''); if (!is_array($mail_addresses) || count($mail_addresses) !== 1) { throw new Tracker_Artifact_MailGateway_InvalidMailHeadersException(); } return $mail_addresses[0]->mailbox . '@' . $mail_addresses[0]->host; }
static function getMatches(Model_Address $fromAddress, CerberusParserMessage $message) { // print_r($fromAddress); // print_r($message); $matches = array(); $rules = DAO_MailToGroupRule::getWhere(); $message_headers = $message->headers; $custom_fields = DAO_CustomField::getAll(); // Lazy load when needed on criteria basis $address_field_values = null; $org_field_values = null; // Check filters if (is_array($rules)) { foreach ($rules as $rule) { /* @var $rule Model_MailToGroupRule */ $passed = 0; // check criteria foreach ($rule->criteria as $crit_key => $crit) { @($value = $crit['value']); switch ($crit_key) { case 'dayofweek': $current_day = strftime('%w'); // $current_day = 1; // Forced to English abbrevs as indexes $days = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'); // Is the current day enabled? if (isset($crit[$days[$current_day]])) { $passed++; } break; case 'timeofday': $current_hour = strftime('%H'); $current_min = strftime('%M'); // $current_hour = 17; // $current_min = 5; if (null != ($from_time = @$crit['from'])) { list($from_hour, $from_min) = explode(':', $from_time); } if (null != ($to_time = @$crit['to'])) { if (list($to_hour, $to_min) = explode(':', $to_time)) { } } // Do we need to wrap around to the next day's hours? if ($from_hour > $to_hour) { // yes $to_hour += 24; // add 24 hrs to the destination (1am = 25th hour) } // Are we in the right 24 hourly range? if ((int) $current_hour >= $from_hour && (int) $current_hour <= $to_hour) { // If we're in the first hour, are we minutes early? if ($current_hour == $from_hour && (int) $current_min < $from_min) { break; } // If we're in the last hour, are we minutes late? if ($current_hour == $to_hour && (int) $current_min > $to_min) { break; } $passed++; } break; case 'tocc': $tocc = array(); $destinations = DevblocksPlatform::parseCsvString($value); // Build a list of To/Cc addresses on this message @($to_list = imap_rfc822_parse_adrlist($message_headers['to'], 'localhost')); @($cc_list = imap_rfc822_parse_adrlist($message_headers['cc'], 'localhost')); if (is_array($to_list)) { foreach ($to_list as $addy) { $tocc[] = $addy->mailbox . '@' . $addy->host; } } if (is_array($cc_list)) { foreach ($cc_list as $addy) { $tocc[] = $addy->mailbox . '@' . $addy->host; } } $dest_flag = false; // bail out when true if (is_array($destinations) && is_array($tocc)) { foreach ($destinations as $dest) { if ($dest_flag) { break; } $regexp_dest = DevblocksPlatform::strToRegExp($dest); foreach ($tocc as $addy) { if (@preg_match($regexp_dest, $addy)) { $passed++; $dest_flag = false; break; } } } } break; case 'from': $regexp_from = DevblocksPlatform::strToRegExp($value); if (@preg_match($regexp_from, $fromAddress->email)) { $passed++; } break; case 'subject': // [TODO] Decode if necessary @($subject = $message_headers['subject']); $regexp_subject = DevblocksPlatform::strToRegExp($value); if (@preg_match($regexp_subject, $subject)) { $passed++; } break; case 'body': // Line-by-line body scanning (sed-like) $lines = preg_split("/[\r\n]/", $message->body); if (is_array($lines)) { foreach ($lines as $line) { if (@preg_match($value, $line)) { $passed++; break; } } } break; case 'header1': case 'header2': case 'header3': case 'header4': case 'header5': @($header = strtolower($crit['header'])); if (empty($header)) { $passed++; break; } if (empty($value)) { // we're checking for null/blanks if (!isset($message_headers[$header]) || empty($message_headers[$header])) { $passed++; } } elseif (isset($message_headers[$header]) && !empty($message_headers[$header])) { $regexp_header = DevblocksPlatform::strToRegExp($value); // Flatten CRLF if (@preg_match($regexp_header, str_replace(array("\r", "\n"), ' ', $message_headers[$header]))) { $passed++; } } break; default: // ignore invalids // Custom Fields if (0 == strcasecmp('cf_', substr($crit_key, 0, 3))) { $field_id = substr($crit_key, 3); // Make sure it exists if (null == @($field = $custom_fields[$field_id])) { continue; } // Lazy values loader $field_values = array(); switch ($field->source_extension) { case ChCustomFieldSource_Address::ID: if (null == $address_field_values) { $address_field_values = array_shift(DAO_CustomFieldValue::getValuesBySourceIds(ChCustomFieldSource_Address::ID, $fromAddress->id)); } $field_values =& $address_field_values; break; case ChCustomFieldSource_Org::ID: if (null == $org_field_values) { $org_field_values = array_shift(DAO_CustomFieldValue::getValuesBySourceIds(ChCustomFieldSource_Org::ID, $fromAddress->contact_org_id)); } $field_values =& $org_field_values; break; } // No values, default. if (!isset($field_values[$field_id])) { continue; } // Type sensitive value comparisons switch ($field->type) { case 'S': // string // string case 'T': // clob // clob case 'U': // URL $field_val = isset($field_values[$field_id]) ? $field_values[$field_id] : ''; $oper = isset($crit['oper']) ? $crit['oper'] : "="; if ($oper == "=" && @preg_match(DevblocksPlatform::strToRegExp($value, true), $field_val)) { $passed++; } elseif ($oper == "!=" && @(!preg_match(DevblocksPlatform::strToRegExp($value, true), $field_val))) { $passed++; } break; case 'N': // number if (!isset($field_values[$field_id])) { break; } $field_val = isset($field_values[$field_id]) ? $field_values[$field_id] : 0; $oper = isset($crit['oper']) ? $crit['oper'] : "="; if ($oper == "=" && intval($field_val) == intval($value)) { $passed++; } elseif ($oper == "!=" && intval($field_val) != intval($value)) { $passed++; } elseif ($oper == ">" && intval($field_val) > intval($value)) { $passed++; } elseif ($oper == "<" && intval($field_val) < intval($value)) { $passed++; } break; case 'E': // date $field_val = isset($field_values[$field_id]) ? intval($field_values[$field_id]) : 0; $from = isset($crit['from']) ? $crit['from'] : "0"; $to = isset($crit['to']) ? $crit['to'] : "now"; if (intval(@strtotime($from)) <= $field_val && intval(@strtotime($to)) >= $field_val) { $passed++; } break; case 'C': // checkbox $field_val = isset($field_values[$field_id]) ? $field_values[$field_id] : 0; if (intval($value) == intval($field_val)) { $passed++; } break; case 'D': // dropdown // dropdown case 'X': // multi-checkbox // multi-checkbox case 'M': // multi-picklist // multi-picklist case 'W': // worker $field_val = isset($field_values[$field_id]) ? $field_values[$field_id] : array(); if (!is_array($value)) { $value = array($value); } if (is_array($field_val)) { // if multiple things set foreach ($field_val as $v) { // loop through possible if (isset($value[$v])) { // is any possible set? $passed++; break; } } } else { // single if (isset($value[$field_val])) { // is our set field in possibles? $passed++; break; } } break; } } break; } } // If our rule matched every criteria, stop and return the filter if ($passed == count($rule->criteria)) { DAO_MailToGroupRule::increment($rule->id); // ++ the times we've matched $matches[$rule->id] = $rule; // Bail out if this rule had a move action if (isset($rule->actions['move'])) { return $matches; } } } } // If we're at the end of rules and didn't bail out yet if (!empty($matches)) { return $matches; } // No matches return NULL; }
protected function parseAddrList($value) { $value = $this->decode($value); //as alternative we can use mailparse_rfc822_parse_addresses $items = imap_rfc822_parse_adrlist($value, 'nodomain'); return $items; }
/** * Defined bounce parsing rules for standard DSN (Delivery Status Notification) * * @param string $dsn_msg human-readable explanation * @param string $dsn_report delivery-status report * @param boolean $debug_mode show debug info. or not * @return array $result an array include the following fields: 'email', 'bounce_type','remove','rule_no','rule_cat' * if we could NOT detect the type of bounce, return rule_no = '0000' */ function bmhDSNRules($dsn_msg, $dsn_report, $debug_mode = false) { echo $dsn_msg . "<br><br>"; // initialize the result array $result = array('email' => '', 'bounce_type' => false, 'remove' => 0, 'rule_cat' => 'unrecognized', 'rule_no' => '0000'); $action = false; $status_code = false; $diag_code = false; // ======= parse $dsn_report ====== // get the recipient email if (preg_match("/Original-Recipient: rfc822;(.*)/i", $dsn_report, $match)) { $email_arr = imap_rfc822_parse_adrlist($match[1], 'default.domain.name'); if (isset($email_arr[0]->host) && $email_arr[0]->host != '.SYNTAX-ERROR.' && $email_arr[0]->host != 'default.domain.name') { $result['email'] = $email_arr[0]->mailbox . '@' . $email_arr[0]->host; } } else { if (preg_match("/Final-Recipient: rfc822;(.*)/i", $dsn_report, $match)) { $email_arr = imap_rfc822_parse_adrlist($match[1], 'default.domain.name'); if (isset($email_arr[0]->host) && $email_arr[0]->host != '.SYNTAX-ERROR.' && $email_arr[0]->host != 'default.domain.name') { $result['email'] = $email_arr[0]->mailbox . '@' . $email_arr[0]->host; } } } if (preg_match("/Action: (.+)/i", $dsn_report, $match)) { $action = strtolower(trim($match[1])); } if (preg_match("/Status: ([0-9\\.]+)/i", $dsn_report, $match)) { $status_code = $match[1]; } // Could be multi-line , if the new line is beginning with SPACE or HTAB if (preg_match("/Diagnostic-Code:((?:[^\n]|\n[\t ])+)(?:\n[^\t ]|\$)/is", $dsn_report, $match)) { $diag_code = $match[1]; } // ======= rules ====== if (empty($result['email'])) { /* email address is empty * rule: full * sample: DSN Message only * User quota exceeded: SMTP <*****@*****.**> */ if (preg_match("/quota exceed.*<(\\S+@\\S+\\w)>/is", $dsn_msg, $match)) { $result['rule_cat'] = 'full'; $result['rule_no'] = '0161'; $result['email'] = $match[1]; } } else { /* action could be one of them as RFC:1894 * "failed" / "delayed" / "delivered" / "relayed" / "expanded" */ switch ($action) { case 'failed': /* rule: full * sample: * Diagnostic-Code: X-Postfix; me.domain.com platform: said: 552 5.2.2 Over * quota (in reply to RCPT TO command) */ if (preg_match("/over.*quota/is", $diag_code)) { $result['rule_cat'] = 'full'; $result['rule_no'] = '0105'; } elseif (preg_match("/exceed.*quota/is", $diag_code)) { $result['rule_cat'] = 'full'; $result['rule_no'] = '0129'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*full/is", $diag_code)) { $result['rule_cat'] = 'full'; $result['rule_no'] = '0145'; } elseif (preg_match("/Insufficient system storage/is", $diag_code)) { $result['rule_cat'] = 'full'; $result['rule_no'] = '0134'; } elseif (preg_match("/File too large/is", $diag_code)) { $result['rule_cat'] = 'full'; $result['rule_no'] = '0192'; } elseif (preg_match("/larger than.*limit/is", $diag_code)) { $result['rule_cat'] = 'oversize'; $result['rule_no'] = '0146'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user)(.*)not(.*)list/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0103'; } elseif (preg_match("/user path no exist/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0106'; } elseif (preg_match("/Relay.*(?:denied|prohibited)/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0108'; } elseif (preg_match("/no.*valid.*(?:alias|account|recipient|address|email|mailbox|user)/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0185'; } elseif (preg_match("/Invalid.*(?:alias|account|recipient|address|email|mailbox|user)/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0111'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*(?:disabled|discontinued)/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0114'; } elseif (preg_match("/user doesn't have.*account/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0127'; } elseif (preg_match("/(?:unknown|illegal).*(?:alias|account|recipient|address|email|mailbox|user)/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0128'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*(?:un|not\\s+)available/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0122'; } elseif (preg_match("/no (?:alias|account|recipient|address|email|mailbox|user)/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0123'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*unknown/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0125'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*disabled/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0133'; } elseif (preg_match("/No such (?:alias|account|recipient|address|email|mailbox|user)/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0143'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*NOT FOUND/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0136'; } elseif (preg_match("/deactivated (?:alias|account|recipient|address|email|mailbox|user)/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0138'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*reject/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0148'; } elseif (preg_match("/bounce.*administrator/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0151'; } elseif (preg_match("/<.*>.*disabled/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0152'; } elseif (preg_match("/not our customer/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0154'; } elseif (preg_match("/Wrong (?:alias|account|recipient|address|email|mailbox|user)/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0159'; } elseif (preg_match("/(?:unknown|bad).*(?:alias|account|recipient|address|email|mailbox|user)/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0160'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*not OK/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0186'; } elseif (preg_match("/Access.*Denied/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0189'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*lookup.*fail/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0195'; } elseif (preg_match("/(?:recipient|address|email|mailbox|user).*not.*member of domain/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0198'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*cannot be verified/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0202'; } elseif (preg_match("/Unable to relay/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0203'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*(?:n't|not) exist/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0205'; } elseif (preg_match("/not have an account/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0207'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*is not allowed/is", $diag_code)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0220'; } elseif (preg_match("/inactive.*(?:alias|account|recipient|address|email|mailbox|user)/is", $diag_code)) { $result['rule_cat'] = 'inactive'; $result['rule_no'] = '0135'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*Inactive/is", $diag_code)) { $result['rule_cat'] = 'inactive'; $result['rule_no'] = '0155'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user) closed due to inactivity/is", $diag_code)) { $result['rule_cat'] = 'inactive'; $result['rule_no'] = '0170'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user) not activated/is", $diag_code)) { $result['rule_cat'] = 'inactive'; $result['rule_no'] = '0177'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*(?:suspend|expire)/is", $diag_code)) { $result['rule_cat'] = 'inactive'; $result['rule_no'] = '0183'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*no longer exist/is", $diag_code)) { $result['rule_cat'] = 'inactive'; $result['rule_no'] = '0184'; } elseif (preg_match("/(?:forgery|abuse)/is", $diag_code)) { $result['rule_cat'] = 'inactive'; $result['rule_no'] = '0196'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*restrict/is", $diag_code)) { $result['rule_cat'] = 'inactive'; $result['rule_no'] = '0209'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*locked/is", $diag_code)) { $result['rule_cat'] = 'inactive'; $result['rule_no'] = '0228'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user) refused/is", $diag_code)) { $result['rule_cat'] = 'user_reject'; $result['rule_no'] = '0156'; } elseif (preg_match("/sender.*not/is", $diag_code)) { $result['rule_cat'] = 'user_reject'; $result['rule_no'] = '0206'; } elseif (preg_match("/Message refused/is", $diag_code)) { $result['rule_cat'] = 'command_reject'; $result['rule_no'] = '0175'; } elseif (preg_match("/No permit/is", $diag_code)) { $result['rule_cat'] = 'command_reject'; $result['rule_no'] = '0190'; } elseif (preg_match("/domain isn't in.*allowed rcpthost/is", $diag_code)) { $result['rule_cat'] = 'command_reject'; $result['rule_no'] = '0191'; } elseif (preg_match("/AUTH FAILED/is", $diag_code)) { $result['rule_cat'] = 'command_reject'; $result['rule_no'] = '0197'; } elseif (preg_match("/relay.*not.*(?:permit|allow)/is", $diag_code)) { $result['rule_cat'] = 'command_reject'; $result['rule_no'] = '0201'; } elseif (preg_match("/not local host/is", $diag_code)) { $result['rule_cat'] = 'command_reject'; $result['rule_no'] = '0204'; } elseif (preg_match("/Unauthorized relay/is", $diag_code)) { $result['rule_cat'] = 'command_reject'; $result['rule_no'] = '0215'; } elseif (preg_match("/Transaction.*fail/is", $diag_code)) { $result['rule_cat'] = 'command_reject'; $result['rule_no'] = '0221'; } elseif (preg_match("/Invalid data/is", $diag_code)) { $result['rule_cat'] = 'command_reject'; $result['rule_no'] = '0223'; } elseif (preg_match("/Local user only/is", $diag_code)) { $result['rule_cat'] = 'command_reject'; $result['rule_no'] = '0224'; } elseif (preg_match("/not.*permit.*to/is", $diag_code)) { $result['rule_cat'] = 'command_reject'; $result['rule_no'] = '0225'; } elseif (preg_match("/Content reject/is", $diag_code)) { $result['rule_cat'] = 'content_reject'; $result['rule_no'] = '0165'; } elseif (preg_match("/MIME\\/REJECT/is", $diag_code)) { $result['rule_cat'] = 'content_reject'; $result['rule_no'] = '0212'; } elseif (preg_match("/MIME error/is", $diag_code)) { $result['rule_cat'] = 'content_reject'; $result['rule_no'] = '0217'; } elseif (preg_match("/Mail data refused.*AISP/is", $diag_code)) { $result['rule_cat'] = 'content_reject'; $result['rule_no'] = '0218'; } elseif (preg_match("/Host unknown/is", $diag_code)) { $result['rule_cat'] = 'dns_unknown'; $result['rule_no'] = '0130'; } elseif (preg_match("/Specified domain.*not.*allow/is", $diag_code)) { $result['rule_cat'] = 'dns_unknown'; $result['rule_no'] = '0180'; } elseif (preg_match("/No route to host/is", $diag_code)) { $result['rule_cat'] = 'dns_unknown'; $result['rule_no'] = '0188'; } elseif (preg_match("/unrouteable address/is", $diag_code)) { $result['rule_cat'] = 'dns_unknown'; $result['rule_no'] = '0208'; } elseif (preg_match("/System.*busy/is", $diag_code)) { $result['rule_cat'] = 'defer'; $result['rule_no'] = '0112'; } elseif (preg_match("/Resources temporarily unavailable/is", $diag_code)) { $result['rule_cat'] = 'defer'; $result['rule_no'] = '0116'; } elseif (preg_match("/sender is rejected/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0101'; } elseif (preg_match("/Client host rejected/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0102'; } elseif (preg_match("/MAIL FROM(.*)mismatches client IP/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0104'; } elseif (preg_match("/denyip/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0144'; } elseif (preg_match("/client host.*blocked/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0201'; } elseif (preg_match("/mail.*reject/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0147'; } elseif (preg_match("/spam.*detect/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0162'; } elseif (preg_match("/reject.*spam/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0216'; } elseif (preg_match("/SpamTrap/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0200'; } elseif (preg_match("/Verify mailfrom failed/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0210'; } elseif (preg_match("/MAIL.*FROM.*mismatch/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0226'; } elseif (preg_match("/spam scale/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0211'; } elseif (preg_match("/junk mail/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0230'; } elseif (preg_match("/message filtered/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0227'; } elseif (preg_match("/subject.*consider.*spam/is", $diag_code)) { $result['rule_cat'] = 'antispam'; $result['rule_no'] = '0222'; } elseif (preg_match("/Temporary local problem/is", $diag_code)) { $result['rule_cat'] = 'internal_error'; $result['rule_no'] = '0142'; } elseif (preg_match("/system config error/is", $diag_code)) { $result['rule_cat'] = 'internal_error'; $result['rule_no'] = '0153'; } elseif (preg_match("/delivery.*suspend/is", $diag_code)) { $result['rule_cat'] = 'delayed'; $result['rule_no'] = '0213'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user)(.*)invalid/i", $dsn_msg)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0107'; } elseif (preg_match("/Deferred.*No such.*(?:file|directory)/i", $dsn_msg)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0141'; } elseif (preg_match("/mail receiving disabled/i", $dsn_msg)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0194'; } elseif (preg_match("/bad.*(?:alias|account|recipient|address|email|mailbox|user)/i", $dsn_msg)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '227'; } elseif (preg_match("/over.*quota/i", $dsn_msg)) { $result['rule_cat'] = 'full'; $result['rule_no'] = '0131'; } elseif (preg_match("/quota.*exceeded/i", $dsn_msg)) { $result['rule_cat'] = 'full'; $result['rule_no'] = '0150'; } elseif (preg_match("/exceed.*\n?.*quota/i", $dsn_msg)) { $result['rule_cat'] = 'full'; $result['rule_no'] = '0187'; } elseif (preg_match("/(?:alias|account|recipient|address|email|mailbox|user).*full/i", $dsn_msg)) { $result['rule_cat'] = 'full'; $result['rule_no'] = '0132'; } elseif (preg_match("/space.*not.*enough/i", $dsn_msg)) { $result['rule_cat'] = 'full'; $result['rule_no'] = '0219'; } elseif (preg_match("/Deferred.*Connection (?:refused|reset)/i", $dsn_msg)) { $result['rule_cat'] = 'defer'; $result['rule_no'] = '0115'; } elseif (preg_match("/Invalid host name/i", $dsn_msg)) { $result['rule_cat'] = 'dns_unknown'; $result['rule_no'] = '0109'; } elseif (preg_match("/Deferred.*No route to host/i", $dsn_msg)) { $result['rule_cat'] = 'dns_unknown'; $result['rule_no'] = '0109'; } elseif (preg_match("/Host unknown/i", $dsn_msg)) { $result['rule_cat'] = 'dns_unknown'; $result['rule_no'] = '0140'; } elseif (preg_match("/Name server timeout/i", $dsn_msg)) { $result['rule_cat'] = 'dns_unknown'; $result['rule_no'] = '0118'; } elseif (preg_match("/Deferred.*Connection.*tim(?:e|ed).*out/i", $dsn_msg)) { $result['rule_cat'] = 'dns_unknown'; $result['rule_no'] = '0119'; } elseif (preg_match("/Deferred.*host name lookup failure/i", $dsn_msg)) { $result['rule_cat'] = 'dns_unknown'; $result['rule_no'] = '0121'; } elseif (preg_match("/MX list.*point.*back/i", $dsn_msg)) { $result['rule_cat'] = 'dns_loop'; $result['rule_no'] = '0199'; } elseif (preg_match("/I\\/O error/i", $dsn_msg)) { $result['rule_cat'] = 'internal_error'; $result['rule_no'] = '0120'; } elseif (preg_match("/connection.*broken/i", $dsn_msg)) { $result['rule_cat'] = 'internal_error'; $result['rule_no'] = '0231'; } elseif (preg_match("/User unknown/i", $dsn_msg)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0193'; } elseif (preg_match("/Service unavailable/i", $dsn_msg)) { $result['rule_cat'] = 'unknown'; $result['rule_no'] = '0214'; } else { global $bmh_rule_result; mysql_data_seek($bmh_rule_result, 0); $temp_bmh_res = $bmh_rule_result; while ($bmh_rule_row = mysql_fetch_row($temp_bmh_res)) { if ($bmh_rule_row[3] == 1 && preg_match("{$bmh_rule_row['2']}", $dsn_msg)) { $result['rule_cat'] = 'other'; $result['rule_no'] = '0176'; break; } } } break; case 'delayed': $result['rule_cat'] = 'delayed'; $result['rule_no'] = '0110'; break; case 'delivered': case 'relayed': case 'expanded': // unhandled cases break; default: break; } } global $rule_categories, $bmh_newline; if ($result['rule_no'] == '0000') { if ($debug_mode) { echo 'email: ' . $result['email'] . $bmh_newline; echo 'Action: ' . $action . $bmh_newline; echo 'Status: ' . $status_code . $bmh_newline; echo 'Diagnostic-Code: ' . $diag_code . $bmh_newline; echo "DSN Message:<br />\n" . $dsn_msg . $bmh_newline; echo $bmh_newline; } } else { if ($result['bounce_type'] === false) { $result['bounce_type'] = $rule_categories[$result['rule_cat']]['bounce_type']; $result['remove'] = $rule_categories[$result['rule_cat']]['remove']; } } return $result; }
protected function isValid($idx_name, $value) { switch ($idx_name) { case 'contact_org_id': return is_numeric($value) ? true : false; case 'is_banned': return '1' == $value || '0' == $value ? true : false; case 'email': $addr_array = imap_rfc822_parse_adrlist($value, "webgroupmedia.com"); return is_array($addr_array) && count($addr_array) > 0 ? true : false; case 'first_name': case 'last_name': return !empty($value) ? true : false; default: return false; } }