/** * @param \RainLoop\Plugins\Manager $oPlugins * @param \MailSo\Smtp\SmtpClient|null $oSmtpClient * @param \RainLoop\Application $oConfig * @param bool $bUsePhpMail = false * * @return bool */ public function OutConnectAndLoginHelper($oPlugins, $oSmtpClient, $oConfig, &$bUsePhpMail = false) { $bLogin = false; $aSmtpCredentials = array('UseConnect' => true, 'UseAuth' => $this->DomainOutAuth(), 'UsePhpMail' => $bUsePhpMail, 'Ehlo' => \MailSo\Smtp\SmtpClient::EhloHelper(), 'Host' => $this->DomainOutHost(), 'Port' => $this->DomainOutPort(), 'Secure' => $this->DomainOutSecure(), 'Login' => $this->OutLogin(), 'Password' => $this->Password(), 'ProxyAuthUser' => $this->ProxyAuthUser(), 'ProxyAuthPassword' => $this->ProxyAuthPassword(), 'VerifySsl' => !!$oConfig->Get('ssl', 'verify_certificate', false), 'AllowSelfSigned' => !!$oConfig->Get('ssl', 'allow_self_signed', true)); $oPlugins->RunHook('filter.smtp-credentials', array($this, &$aSmtpCredentials)); $bUsePhpMail = $aSmtpCredentials['UsePhpMail']; $oPlugins->RunHook('event.smtp-pre-connect', array($this, $aSmtpCredentials['UseConnect'], $aSmtpCredentials)); if ($aSmtpCredentials['UseConnect'] && !$aSmtpCredentials['UsePhpMail'] && $oSmtpClient) { $oSmtpClient->Connect($aSmtpCredentials['Host'], $aSmtpCredentials['Port'], $aSmtpCredentials['Ehlo'], $aSmtpCredentials['Secure'], $aSmtpCredentials['VerifySsl'], $aSmtpCredentials['AllowSelfSigned']); } $oPlugins->RunHook('event.smtp-post-connect', array($this, $aSmtpCredentials['UseConnect'], $aSmtpCredentials)); $oPlugins->RunHook('event.smtp-pre-login', array($this, $aSmtpCredentials['UseAuth'], $aSmtpCredentials)); if ($aSmtpCredentials['UseAuth'] && !$aSmtpCredentials['UsePhpMail'] && $oSmtpClient) { $iGatLen = \strlen(APP_GOOGLE_ACCESS_TOKEN_PREFIX); $sPassword = $aSmtpCredentials['Password']; if (APP_GOOGLE_ACCESS_TOKEN_PREFIX === \substr($sPassword, 0, $iGatLen)) { $oSmtpClient->LoginWithXOauth2(\base64_encode('user='******'Login'] . "" . 'auth=Bearer ' . \substr($sPassword, $iGatLen) . "")); } else { $oSmtpClient->Login($aSmtpCredentials['Login'], $aSmtpCredentials['Password']); } $bLogin = true; } $oPlugins->RunHook('event.smtp-post-login', array($this, $aSmtpCredentials['UseAuth'], $bLogin, $aSmtpCredentials)); return $bLogin; }
/** * * @param \RainLoop\Model\Account $oAccount * @param \MailSo\Mime\Message $oMessage * @param resource $rMessageStream * @param bool $bDsn = false * @param bool $bAddHiddenRcpt = true * * @throws \RainLoop\Exceptions\ClientException * @throws \MailSo\Net\Exceptions\ConnectionException */ private function smtpSendMessage($oAccount, $oMessage, &$rMessageStream, &$iMessageStreamSize, $bDsn = false, $bAddHiddenRcpt = true) { $oRcpt = $oMessage->GetRcpt(); if ($oRcpt && 0 < $oRcpt->Count()) { $this->Plugins()->RunHook('filter.smtp-message-stream', array($oAccount, &$rMessageStream, &$iMessageStreamSize)); $this->Plugins()->RunHook('filter.message-rcpt', array($oAccount, &$oRcpt)); try { $oFrom = $oMessage->GetFrom(); $sFrom = $oFrom instanceof \MailSo\Mime\Email ? $oFrom->GetEmail() : ''; $sFrom = empty($sFrom) ? $oAccount->Email() : $sFrom; $this->Plugins()->RunHook('filter.smtp-from', array($oAccount, $oMessage, &$sFrom)); $aHiddenRcpt = array(); if ($bAddHiddenRcpt) { $this->Plugins()->RunHook('filter.smtp-hidden-rcpt', array($oAccount, $oMessage, &$aHiddenRcpt)); } $bUsePhpMail = $oAccount->Domain()->OutUsePhpMail(); $oSmtpClient = \MailSo\Smtp\SmtpClient::NewInstance()->SetLogger($this->Logger()); $oSmtpClient->SetTimeOuts(10, (int) \RainLoop\Api::Config()->Get('labs', 'smtp_timeout', 60)); $bLoggined = $oAccount->OutConnectAndLoginHelper($this->Plugins(), $oSmtpClient, $this->Config(), $bUsePhpMail); if ($bUsePhpMail) { if (\MailSo\Base\Utils::FunctionExistsAndEnabled('mail')) { $aToCollection = $oMessage->GetTo(); if ($aToCollection && $oFrom) { $sRawBody = @\stream_get_contents($rMessageStream); if (!empty($sRawBody)) { $sMailTo = \trim($aToCollection->ToString(true)); $sMailSubject = \trim($oMessage->GetSubject()); $sMailSubject = 0 === \strlen($sMailSubject) ? '' : \MailSo\Base\Utils::EncodeUnencodedValue(\MailSo\Base\Enumerations\Encoding::BASE64_SHORT, $sMailSubject); $sMailHeaders = $sMailBody = ''; list($sMailHeaders, $sMailBody) = \explode("\r\n\r\n", $sRawBody, 2); unset($sRawBody); if ($this->Config()->Get('labs', 'mail_func_clear_headers', true)) { $sMailHeaders = \MailSo\Base\Utils::RemoveHeaderFromHeaders($sMailHeaders, array(\MailSo\Mime\Enumerations\Header::TO_, \MailSo\Mime\Enumerations\Header::SUBJECT)); } if ($this->Config()->Get('debug', 'enable', false)) { $this->Logger()->WriteDump(array($sMailTo, $sMailSubject, $sMailBody, $sMailHeaders)); } $bR = $this->Config()->Get('labs', 'mail_func_additional_parameters', false) ? \mail($sMailTo, $sMailSubject, $sMailBody, $sMailHeaders, '-f' . $oFrom->GetEmail()) : \mail($sMailTo, $sMailSubject, $sMailBody, $sMailHeaders); if (!$bR) { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSendMessage); } } } } else { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CantSendMessage); } } else { if ($oSmtpClient->IsConnected()) { if (!empty($sFrom)) { $oSmtpClient->MailFrom($sFrom, '', $bDsn); } $aRcpt =& $oRcpt->GetAsArray(); foreach ($aRcpt as $oEmail) { $oSmtpClient->Rcpt($oEmail->GetEmail(), $bDsn); } if ($bAddHiddenRcpt && \is_array($aHiddenRcpt) && 0 < \count($aHiddenRcpt)) { foreach ($aHiddenRcpt as $sEmail) { if (\preg_match('/^[^@\\s]+@[^@\\s]+$/', $sEmail)) { $oSmtpClient->Rcpt($sEmail); } } } $oSmtpClient->DataWithStream($rMessageStream); if ($bLoggined) { $oSmtpClient->Logout(); } $oSmtpClient->Disconnect(); } } } catch (\MailSo\Net\Exceptions\ConnectionException $oException) { if ($this->Config()->Get('labs', 'smtp_show_server_errors')) { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ClientViewError, $oException); } else { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ConnectionError, $oException); } } catch (\MailSo\Smtp\Exceptions\LoginException $oException) { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError, $oException); } catch (\Exception $oException) { if ($this->Config()->Get('labs', 'smtp_show_server_errors')) { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ClientViewError, $oException); } else { throw $oException; } } } else { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::InvalidRecipients); } }
private function smtpSendMessage($oAccount, $oMessage, $rMessageStream, $bAddHiddenRcpt = true) { $oRcpt = $oMessage->GetRcpt(); if ($oRcpt && 0 < $oRcpt->Count()) { $this->Plugins()->RunHook('filter.message-rcpt', array($oAccount, &$oRcpt)); try { $oSmtpClient = \MailSo\Smtp\SmtpClient::NewInstance()->SetLogger($this->Logger()); $oFrom = $oMessage->GetFrom(); $sFrom = $oFrom instanceof \MailSo\Mime\Email ? $oFrom->GetEmail() : ''; $aSmtpCredentials = array('Ehlo' => \MailSo\Smtp\SmtpClient::EhloHelper(), 'Host' => $oAccount->Domain()->OutHost(\MailSo\Base\Utils::GetDomainFromEmail($oAccount->Email())), 'Port' => $oAccount->Domain()->OutPort(), 'Secure' => $oAccount->Domain()->OutSecure(), 'UseAuth' => $oAccount->Domain()->OutAuth(), 'From' => empty($sFrom) ? $oAccount->Email() : $sFrom, 'Login' => $oAccount->OutLogin(), 'Password' => $oAccount->Password(), 'HiddenRcpt' => array()); $this->Plugins()->RunHook('filter.smtp-credentials', array($oAccount, &$aSmtpCredentials)); if (!$bAddHiddenRcpt) { $aSmtpCredentials['HiddenRcpt'] = array(); } $bHookConnect = $bHookAuth = $bHookFrom = $bHookFrom = $bHookTo = $bHookData = $bHookLogoutAndDisconnect = false; $this->Plugins()->RunHook('filter.smtp-connect', array($oAccount, $aSmtpCredentials, &$oSmtpClient, $oMessage, &$oRcpt, &$bHookConnect, &$bHookAuth, &$bHookFrom, &$bHookTo, &$bHookData, &$bHookLogoutAndDisconnect)); if (!$bHookConnect) { $oSmtpClient->Connect($aSmtpCredentials['Host'], $aSmtpCredentials['Port'], $aSmtpCredentials['Ehlo'], $aSmtpCredentials['Secure']); } if (!$bHookAuth) { if ($aSmtpCredentials['UseAuth']) { $oSmtpClient->Login($aSmtpCredentials['Login'], $aSmtpCredentials['Password']); } } if (!$bHookFrom) { $oSmtpClient->MailFrom($aSmtpCredentials['From']); } if (!$bHookTo) { $aRcpt =& $oRcpt->GetAsArray(); foreach ($aRcpt as $oEmail) { $oSmtpClient->Rcpt($oEmail->GetEmail()); } if (isset($aSmtpCredentials['HiddenRcpt']) && is_array($aSmtpCredentials['HiddenRcpt'])) { foreach ($aSmtpCredentials['HiddenRcpt'] as $sEmail) { if (\preg_match('/^[^@\\s]+@[^@\\s]+$/', $sEmail)) { $oSmtpClient->Rcpt($sEmail); } } } } if (!$bHookData) { $oSmtpClient->DataWithStream($rMessageStream); } if (!$bHookLogoutAndDisconnect) { $oSmtpClient->LogoutAndDisconnect(); } } catch (\MailSo\Net\Exceptions\ConnectionException $oException) { if ($this->Config()->Get('labs', 'smtp_show_server_errors')) { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ClientViewError, $oException); } else { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ConnectionError, $oException); } } catch (\MailSo\Smtp\Exceptions\LoginException $oException) { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::AuthError, $oException); } catch (\Exception $oException) { if ($this->Config()->Get('labs', 'smtp_show_server_errors')) { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::ClientViewError, $oException); } else { throw $oException; } } } else { throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::InvalidRecipients); } }
/** * Sends message out. * * @param CAccount $oAccount Account object. * @param \MailSo\Mime\Message $oMessage Message to be sent out. * @param CFetcher $oFetcher = null. Fetcher object which may override sending settings. * @param string $sSentFolder = ''. Name of Sent folder. * @param string $sDraftFolder = ''. Name of Sent folder. * @param string $sDraftUid = ''. Last UID value of the message saved in Drafts folder. * * @return array|bool * * @throws CApiInvalidArgumentException */ public function sendMessage($oAccount, $oMessage, $oFetcher = null, $sSentFolder = '', $sDraftFolder = '', $sDraftUid = '') { if (!$oAccount || !$oMessage) { throw new CApiInvalidArgumentException(); } $oImapClient =& $this->_getImapClient($oAccount); $rMessageStream = \MailSo\Base\ResourceRegistry::CreateMemoryResource(); $iMessageStreamSize = \MailSo\Base\Utils::MultipleStreamWriter($oMessage->ToStream(true), array($rMessageStream), 8192, true, true, true); $mResult = false; if (false !== $iMessageStreamSize && is_resource($rMessageStream)) { $oRcpt = $oMessage->GetRcpt(); if ($oRcpt && 0 < $oRcpt->Count()) { $sRcptEmail = ''; try { $iConnectTimeOut = CApi::GetConf('socket.connect-timeout', 5); $iSocketTimeOut = CApi::GetConf('socket.get-timeout', 5); $bVerifySsl = !!CApi::GetConf('socket.verify-ssl', false); CApi::Plugin()->RunHook('webmail-smtp-update-socket-timeouts', array(&$iConnectTimeOut, &$iSocketTimeOut)); $oSmtpClient = \MailSo\Smtp\SmtpClient::NewInstance(); $oSmtpClient->SetTimeOuts($iConnectTimeOut, $iSocketTimeOut); $oLogger = $oImapClient->Logger(); if ($oLogger) { $oSmtpClient->SetLogger($oLogger); } $iSecure = \MailSo\Net\Enumerations\ConnectionSecurityType::AUTO_DETECT; if ($oFetcher) { $iSecure = $oFetcher->OutgoingMailSecurity; } else { if ($oAccount->OutgoingMailUseSSL) { $iSecure = \MailSo\Net\Enumerations\ConnectionSecurityType::SSL; } } $sOutgoingMailLogin = ''; if ($oFetcher) { $sOutgoingMailLogin = $oFetcher->IncomingMailLogin; } if (0 === strlen($sOutgoingMailLogin)) { $sOutgoingMailLogin = $oAccount->OutgoingMailLogin; $sOutgoingMailLogin = 0 < strlen($sOutgoingMailLogin) ? $sOutgoingMailLogin : $oAccount->IncomingMailLogin; } $sOutgoingMailPassword = ''; if ($oFetcher) { $sOutgoingMailPassword = $oFetcher->IncomingMailPassword; } if (0 === strlen($sOutgoingMailPassword)) { $sOutgoingMailPassword = $oAccount->OutgoingMailPassword; $sOutgoingMailPassword = 0 < strlen($sOutgoingMailPassword) ? $sOutgoingMailPassword : $oAccount->IncomingMailPassword; } $sEhlo = \MailSo\Smtp\SmtpClient::EhloHelper(); CApi::Plugin()->RunHook('api-smtp-send-ehlo', array($oAccount, &$sEhlo)); if ($oFetcher) { $oSmtpClient->Connect($oFetcher->OutgoingMailServer, $oFetcher->OutgoingMailPort, $sEhlo, $iSecure, $bVerifySsl); } else { $oSmtpClient->Connect($oAccount->OutgoingMailServer, $oAccount->OutgoingMailPort, $sEhlo, $iSecure, $bVerifySsl); } if ($oFetcher && $oFetcher->OutgoingMailAuth || !$oFetcher && $oAccount->OutgoingMailAuth) { $oSmtpClient->Login($sOutgoingMailLogin, $sOutgoingMailPassword); } $oSmtpClient->MailFrom($oFetcher ? $oFetcher->Email : $oAccount->Email, (string) $iMessageStreamSize); $aRcpt =& $oRcpt->GetAsArray(); CApi::Plugin()->RunHook('api-smtp-send-rcpt', array($oAccount, &$aRcpt)); foreach ($aRcpt as $oEmail) { $sRcptEmail = $oEmail->GetEmail(); $oSmtpClient->Rcpt($sRcptEmail); } $oSmtpClient->DataWithStream($rMessageStream); $oSmtpClient->LogoutAndDisconnect(); } catch (\MailSo\Net\Exceptions\ConnectionException $oException) { throw new \CApiManagerException(Errs::Mail_AccountConnectToMailServerFailed, $oException); } catch (\MailSo\Smtp\Exceptions\LoginException $oException) { throw new \CApiManagerException(Errs::Mail_AccountLoginFailed, $oException); } catch (\MailSo\Smtp\Exceptions\NegativeResponseException $oException) { throw new \CApiManagerException(Errs::Mail_CannotSendMessage, $oException); } catch (\MailSo\Smtp\Exceptions\MailboxUnavailableException $oException) { throw new \CApiManagerException(Errs::Mail_MailboxUnavailable, $oException, array(), array('Mailbox' => $sRcptEmail)); } if (0 < strlen($sSentFolder)) { try { if (!$oMessage->GetBcc()) { if (is_resource($rMessageStream)) { rewind($rMessageStream); } $oImapClient->MessageAppendStream($sSentFolder, $rMessageStream, $iMessageStreamSize, array(\MailSo\Imap\Enumerations\MessageFlag::SEEN)); } else { $rAppendMessageStream = \MailSo\Base\ResourceRegistry::CreateMemoryResource(); $iAppendMessageStreamSize = \MailSo\Base\Utils::MultipleStreamWriter($oMessage->ToStream(), array($rAppendMessageStream), 8192, true, true, true); $oImapClient->MessageAppendStream($sSentFolder, $rAppendMessageStream, $iAppendMessageStreamSize, array(\MailSo\Imap\Enumerations\MessageFlag::SEEN)); if (is_resource($rAppendMessageStream)) { @fclose($rAppendMessageStream); } } } catch (\Exception $oException) { throw new \CApiManagerException(Errs::Mail_CannotSaveMessageInSentItems, $oException); } if (is_resource($rMessageStream)) { @fclose($rMessageStream); } } if (0 < strlen($sDraftFolder) && 0 < strlen($sDraftUid)) { try { $this->deleteMessage($oAccount, $sDraftFolder, array($sDraftUid)); } catch (\Exception $oException) { } } $mResult = true; } else { throw new \CApiManagerException(Errs::Mail_InvalidRecipients); } } return $mResult; }
/** * @param \RainLoop\Plugins\Manager $oPlugins * @param \MailSo\Smtp\SmtpClient|null $oSmtpClient * @param \RainLoop\Application $oConfig * @param bool $bUsePhpMail = false * * @return bool */ public function OutConnectAndLoginHelper($oPlugins, $oSmtpClient, $oConfig, &$bUsePhpMail = false) { $bLogin = false; $aSmtpCredentials = array('UseConnect' => true, 'UseAuth' => $this->DomainOutAuth(), 'UsePhpMail' => $bUsePhpMail, 'Ehlo' => \MailSo\Smtp\SmtpClient::EhloHelper(), 'Host' => $this->DomainOutHost(), 'Port' => $this->DomainOutPort(), 'Secure' => $this->DomainOutSecure(), 'Login' => $this->OutLogin(), 'Password' => $this->Password(), 'ProxyAuthUser' => $this->ProxyAuthUser(), 'ProxyAuthPassword' => $this->ProxyAuthPassword(), 'VerifySsl' => !!$oConfig->Get('ssl', 'verify_certificate', false), 'AllowSelfSigned' => !!$oConfig->Get('ssl', 'allow_self_signed', true)); $oPlugins->RunHook('filter.smtp-credentials', array($this, &$aSmtpCredentials)); $bUsePhpMail = $aSmtpCredentials['UsePhpMail']; $oPlugins->RunHook('event.smtp-pre-connect', array($this, $aSmtpCredentials['UseConnect'], $aSmtpCredentials)); if ($aSmtpCredentials['UseConnect'] && !$aSmtpCredentials['UsePhpMail'] && $oSmtpClient) { $oSmtpClient->Connect($aSmtpCredentials['Host'], $aSmtpCredentials['Port'], $aSmtpCredentials['Ehlo'], $aSmtpCredentials['Secure'], $aSmtpCredentials['VerifySsl'], $aSmtpCredentials['AllowSelfSigned']); } $oPlugins->RunHook('event.smtp-post-connect', array($this, $aSmtpCredentials['UseConnect'], $aSmtpCredentials)); $oPlugins->RunHook('event.smtp-pre-login', array($this, $aSmtpCredentials['UseAuth'], $aSmtpCredentials)); if ($aSmtpCredentials['UseAuth'] && !$aSmtpCredentials['UsePhpMail'] && $oSmtpClient) { $oSmtpClient->Login($aSmtpCredentials['Login'], $aSmtpCredentials['Password']); $bLogin = true; } $oPlugins->RunHook('event.smtp-post-login', array($this, $aSmtpCredentials['UseAuth'], $bLogin, $aSmtpCredentials)); return $bLogin; }