/** * @param \RainLoop\Model\Account $oAccount * @param array $aSmtpCredentials */ public function FilterSmtpCredentials($oAccount, &$aSmtpCredentials) { if ($oAccount instanceof \RainLoop\Model\Account && \is_array($aSmtpCredentials)) { $sEmail = $oAccount->Email(); $sHost = \trim($this->Config()->Get('plugin', 'smtp_host', '')); $sWhiteList = \trim($this->Config()->Get('plugin', 'override_users', '')); if (0 < strlen($sWhiteList) && 0 < \strlen($sHost) && \RainLoop\Plugins\Helper::ValidateWildcardValues($sEmail, $sWhiteList)) { $aSmtpCredentials['Host'] = $sHost; $aSmtpCredentials['Port'] = (int) $this->Config()->Get('plugin', 'smtp_port', 25); $sSecure = \trim($this->Config()->Get('plugin', 'smtp_secure', 'None')); switch ($sSecure) { case 'SSL': $aSmtpCredentials['Secure'] = MailSo\Net\Enumerations\ConnectionSecurityType::SSL; break; case 'TLS': $aSmtpCredentials['Secure'] = MailSo\Net\Enumerations\ConnectionSecurityType::STARTTLS; break; default: $aSmtpCredentials['Secure'] = MailSo\Net\Enumerations\ConnectionSecurityType::NONE; break; } $aSmtpCredentials['UseAuth'] = (bool) $this->Config()->Get('plugin', 'smtp_auth', true); $aSmtpCredentials['Login'] = \trim($this->Config()->Get('plugin', 'smtp_user', '')); $aSmtpCredentials['Password'] = (string) $this->Config()->Get('plugin', 'smtp_password', ''); } } }
/** * This function detects the SMTP Host, and if it is set to "auto", replaces it with the email domain. * * @param \RainLoop\Model\Account $oAccount * @param array $aSmtpCredentials */ public function FilterSmtpCredentials($oAccount, &$aSmtpCredentials) { if ($oAccount instanceof \RainLoop\Model\Account && \is_array($aSmtpCredentials)) { // Check for mail.$DOMAIN as entered value in RL settings if (!empty($aSmtpCredentials['Host']) && 'auto' === $aSmtpCredentials['Host']) { $aSmtpCredentials['Host'] = \MailSo\Base\Utils::GetDomainFromEmail($oAccount->Email()); } } }
/** * This function detects the SMTP Host, and if it is set to "auto", replaces it with the email domain. * @param \RainLoop\Model\Account $oAccount * @param array $aSmtpCredentials */ public function FilterSmtpCredentials($oAccount, &$aSmtpCredentials) { if ($oAccount instanceof \RainLoop\Model\Account && \is_array($aSmtpCredentials)) { $sEmail = $oAccount->Email(); // Check for mail.$DOMAIN as entered value in RL settings if ($aSmtpCredentials['Host'] == "auto") { $aSmtpCredentials['Host'] = $this->getDomainFromEmail($sEmail); } } }
/** * @param \RainLoop\Model\Account $oAccount * * @return bool */ public function PasswordChangePossibility($oAccount) { return $oAccount && $oAccount->Email() && \RainLoop\Plugins\Helper::ValidateWildcardValues($oAccount->Email(), $this->sAllowedEmails); }
/** * * @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); } }
/** * @param \RainLoop\Model\Account $oAccount * * @return bool */ public function isDemoAccount($oAccount) { return $oAccount && $oAccount->Email() === $this->Config()->Get('plugin', 'email'); }
/** * @param \RainLoop\Model\Account $oAccount * @param string $sQuery * @param int $iLimit = 20 * * @return array */ public function Process($oAccount, $sQuery, $iLimit = 20) { return array(array($oAccount->Email(), ''), array('*****@*****.**', 'name')); }
/** * @param \RainLoop\Model\Account|string|null $mAccount * @param int $iStorageType * @param string $sKey * @param bool $bMkDir = false * @param bool $bForDeleteAction = false * * @return string */ public function generateFileName($mAccount, $iStorageType, $sKey, $bMkDir = false, $bForDeleteAction = false) { if (null === $mAccount) { $iStorageType = \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY; } $sEmail = $sSubEmail = ''; if ($mAccount instanceof \RainLoop\Model\Account) { $sEmail = $mAccount->ParentEmailHelper(); if ($this->bLocal && $mAccount->IsAdditionalAccount() && !$bForDeleteAction) { $sSubEmail = $mAccount->Email(); } } if (\is_string($mAccount) && empty($sEmail)) { $sEmail = $mAccount; } $sEmail = \preg_replace('/[^a-z0-9\\-\\.@]+/', '_', $sEmail); $sSubEmail = \preg_replace('/[^a-z0-9\\-\\.@]+/', '_', $sSubEmail); $sTypePath = $sKeyPath = ''; switch ($iStorageType) { default: case \RainLoop\Providers\Storage\Enumerations\StorageType::USER: case \RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY: $sTypePath = 'data'; $sKeyPath = \md5($sKey); $sKeyPath = \substr($sKeyPath, 0, 2) . '/' . $sKeyPath; break; case \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG: $sTypePath = 'cfg'; $sKeyPath = \preg_replace('/[_]+/', '_', \preg_replace('/[^a-zA-Z0-9\\/]/', '_', $sKey)); break; } $sFilePath = ''; if (\RainLoop\Providers\Storage\Enumerations\StorageType::NOBODY === $iStorageType) { $sFilePath = $this->sDataPath . '/' . $sTypePath . '/__nobody__/' . $sKeyPath; } else { if (!empty($sEmail)) { $sFilePath = $this->sDataPath . '/' . $sTypePath . '/' . \str_pad(\rtrim(\substr($sEmail, 0, 2), '@'), 2, '_') . '/' . $sEmail . '/' . (0 < \strlen($sSubEmail) ? $sSubEmail . '/' : '') . ($bForDeleteAction ? '' : $sKeyPath); } } if ($bMkDir && !$bForDeleteAction && !empty($sFilePath) && !@\is_dir(\dirname($sFilePath))) { if (!@\mkdir(\dirname($sFilePath), 0755, true)) { throw new \RainLoop\Exceptions\Exception('Can\'t make storage directory "' . $sFilePath . '"'); } } return $sFilePath; }
/** * @param \RainLoop\Model\Account $oAccount * * @return \RainLoop\Model\Identity */ public static function NewInstanceFromAccount(\RainLoop\Model\Account $oAccount) { return new self('', $oAccount->Email()); }
/** * @param \RainLoop\Model\Account $oAccount * @param string $sKey * @param bool $bMkDir = false * * @return string */ private function generateFileName($oAccount, $sKey, $bMkDir = false) { $sEmail = $sSubEmail = ''; if ($oAccount instanceof \RainLoop\Model\Account) { $sEmail = \preg_replace('/[^a-z0-9\\-\\.@]+/', '_', $oAccount->ParentEmailHelper()); if ($oAccount->IsAdditionalAccount()) { $sSubEmail = \preg_replace('/[^a-z0-9\\-\\.@]+/', '_', $oAccount->Email()); } } if (empty($sEmail)) { $sEmail = '__unknown__'; } $sKeyPath = \sha1($sKey); $sKeyPath = \substr($sKeyPath, 0, 2) . '/' . \substr($sKeyPath, 2, 2) . '/' . $sKeyPath; $sFilePath = $this->sDataPath . '/' . \str_pad(\rtrim(\substr($sEmail, 0, 2), '@'), 2, '_') . '/' . $sEmail . '/' . (0 < \strlen($sSubEmail) ? $sSubEmail . '/' : '') . $sKeyPath; if ($bMkDir && !empty($sFilePath) && !@\is_dir(\dirname($sFilePath))) { if (!@\mkdir(\dirname($sFilePath), 0755, true)) { throw new \RainLoop\Exceptions\Exception('Can\'t make storage directory "' . $sFilePath . '"'); } } return $sFilePath; }
/** * @param \RainLoop\Model\Account $oAccount * @param string $sQuery * @param int $iLimit = 20 * * @return array */ public function Process($oAccount, $sQuery, $iLimit = 20) { return array(array($oAccount->Email(), ''), array('xxx@xxx', 'xxx')); }
/** * @param \RainLoop\Model\Account $oAccount * @param string $sQuery * * @return array */ private function ldapSearch($oAccount, $sQuery) { $sSearchEscaped = $this->escape($sQuery); $aResult = array(); $oCon = @\ldap_connect($this->sHostName, $this->iHostPort); if ($oCon) { $this->oLogger->Write('ldap_connect: connected', \MailSo\Log\Enumerations\Type::INFO, 'LDAP'); @\ldap_set_option($oCon, LDAP_OPT_PROTOCOL_VERSION, 3); if (!@\ldap_bind($oCon, $this->sAccessDn, $this->sAccessPassword)) { $this->logLdapError($oCon, 'ldap_bind'); return $aResult; } $sDomain = \MailSo\Base\Utils::GetDomainFromEmail($oAccount->Email()); $sSearchDn = \strtr($this->sUsersDn, array('{domain}' => $sDomain, '{domain:dc}' => 'dc=' . \strtr($sDomain, array('.' => ',dc=')), '{email}' => $oAccount->Email(), '{email:user}' => \MailSo\Base\Utils::GetAccountNameFromEmail($oAccount->Email()), '{email:domain}' => $sDomain, '{login}' => $oAccount->Login(), '{imap:login}' => $oAccount->Login(), '{imap:host}' => $oAccount->DomainIncHost(), '{imap:port}' => $oAccount->DomainIncPort())); $aEmails = empty($this->sEmailField) ? array() : \explode(',', $this->sEmailField); $aNames = empty($this->sNameField) ? array() : \explode(',', $this->sNameField); $aEmails = \array_map('trim', $aEmails); $aNames = \array_map('trim', $aNames); $aFields = \array_merge($aEmails, $aNames); $aItems = array(); $sSubFilter = ''; foreach ($aFields as $sItem) { if (!empty($sItem)) { $aItems[] = $sItem; $sSubFilter .= '(' . $sItem . '=*' . $sSearchEscaped . '*)'; } } $sFilter = '(&(objectclass=' . $this->sObjectClass . ')'; $sFilter .= (1 < count($aItems) ? '(|' : '') . $sSubFilter . (1 < count($aItems) ? ')' : ''); $sFilter .= ')'; $this->oLogger->Write('ldap_search: start: ' . $sSearchDn . ' / ' . $sFilter, \MailSo\Log\Enumerations\Type::INFO, 'LDAP'); $oS = @\ldap_search($oCon, $sSearchDn, $sFilter, $aItems, 0, 30, 30); if ($oS) { $aEntries = @\ldap_get_entries($oCon, $oS); if (is_array($aEntries)) { if (isset($aEntries['count'])) { unset($aEntries['count']); } foreach ($aEntries as $aItem) { if ($aItem) { $sName = $sEmail = ''; list($sEmail, $sName) = $this->findNameAndEmail($aItem, $aEmails, $aNames); if (!empty($sEmail)) { $aResult[] = array($sEmail, $sName); } } } } else { $this->logLdapError($oCon, 'ldap_get_entries'); } } else { $this->logLdapError($oCon, 'ldap_search'); } } else { return $aResult; } return $aResult; }