Beispiel #1
0
 /**
  * @return string
  */
 public function OutLogin()
 {
     $sLogin = $this->sLogin;
     if ($this->oDomain->OutShortLogin()) {
         $sLogin = \MailSo\Base\Utils::GetAccountNameFromEmail($this->sLogin);
     }
     return $sLogin;
 }
Beispiel #2
0
 /**
  * @param string $sStr
  * @param bool $bLowerIfAscii = false
  *
  * @return string
  */
 public static function IdnToAscii($sStr, $bLowerIfAscii = false)
 {
     $sStr = $bLowerIfAscii ? \MailSo\Base\Utils::StrToLowerIfAscii($sStr) : $sStr;
     $sUser = '';
     $sDomain = $sStr;
     if (false !== \strpos($sStr, '@')) {
         $sUser = \MailSo\Base\Utils::GetAccountNameFromEmail($sStr);
         $sDomain = \MailSo\Base\Utils::GetDomainFromEmail($sStr);
     }
     if (0 < \strlen($sDomain) && \preg_match('/[^\\x20-\\x7E]/', $sDomain)) {
         try {
             $sDomain = self::idn()->encode($sDomain);
         } catch (\Exception $oException) {
         }
     }
     return ('' === $sUser ? '' : $sUser . '@') . $sDomain;
 }
 /**
  * @param \RainLoop\Model\Account $oAccount
  * @param string $sPrevPassword
  * @param string $sNewPassword
  *
  * @return bool
  */
 public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword)
 {
     $this->WriteLog('Virtualmin: Try to change password for ' . $oAccount->Email());
     $bResult = false;
     if (!empty($this->sHost) && !empty($this->sAdminUser) && !empty($this->sAdminPassword) && $oAccount) {
         $this->WriteLog('Virtualmin:[Check] Required Fields Present');
         $sEmail = \trim(\strtolower($oAccount->Email()));
         $sEmailUser = \MailSo\Base\Utils::GetAccountNameFromEmail($sEmail);
         $sEmailDomain = \MailSo\Base\Utils::GetDomainFromEmail($sEmail);
         $sHost = \rtrim(\trim($this->sHost), '/');
         $sUrl = $sHost . '/virtual-server/remote.cgi';
         $sAdminUser = $this->sAdminUser;
         $sAdminPassword = $this->sAdminPassword;
         $iCode = 0;
         $aPost = array('user' => $sEmailUser, 'pass' => $sNewPassword, 'domain' => $sEmailDomain, 'program' => 'modify-user');
         $aOptions = array(CURLOPT_URL => $sUrl, CURLOPT_HEADER => false, CURLOPT_FAILONERROR => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_POSTFIELDS => \http_build_query($aPost, '', '&'), CURLOPT_TIMEOUT => 20, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_USERPWD => $sAdminUser . ':' . $sAdminPassword);
         $oCurl = \curl_init();
         \curl_setopt_array($oCurl, $aOptions);
         $this->WriteLog('Virtualmin: Send post request: ' . $sUrl);
         $mResult = \curl_exec($oCurl);
         $iCode = (int) \curl_getinfo($oCurl, CURLINFO_HTTP_CODE);
         $sContentType = (string) \curl_getinfo($oCurl, CURLINFO_CONTENT_TYPE);
         $this->WriteLog('Virtualmin: Post request result: (Status: ' . $iCode . ', ContentType: ' . $sContentType . ')');
         if (false === $mResult || 200 !== $iCode) {
             $this->WriteLog('Virtualmin: Error: ' . \curl_error($oCurl), \MailSo\Log\Enumerations\Type::WARNING);
         }
         if (\is_resource($oCurl)) {
             \curl_close($oCurl);
         }
         if (false !== $mResult && 200 === $iCode) {
             $aRes = null;
             @\parse_str($mResult, $aRes);
             if (\is_array($aRes) && (!isset($aRes['error']) || (int) $aRes['error'] !== 1)) {
                 $iPos = \strpos($mResult, 'Exit status: ');
                 if ($iPos !== false) {
                     $aStatus = \explode(' ', $mResult);
                     $sStatus = \trim(\array_pop($aStatus));
                     if ('0' === $sStatus) {
                         $this->WriteLog('Virtualmin: Password Change Status: Success');
                         $bResult = true;
                     } else {
                         $this->WriteLog('Virtualmin[Error]: Response: ' . $mResult);
                     }
                 }
             } else {
                 $this->WriteLog('Virtualmin[Error]: Response: ' . $mResult);
             }
         } else {
             $this->WriteLog('Virtualmin[Error]: Empty Response: Code: ' . $iCode);
         }
     }
     return $bResult;
 }
 /**
  * @param \RainLoop\Model\Account $oAccount
  * @param string $sPrevPassword
  * @param string $sNewPassword
  *
  * @return bool
  */
 public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword)
 {
     $bResult = false;
     try {
         $sDomain = \MailSo\Base\Utils::GetDomainFromEmail($oAccount->Email());
         $sUserDn = \strtr($this->sUserDnFormat, 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()));
         $oCon = @\ldap_connect($this->sHostName);
         if ($oCon) {
             @\ldap_set_option($oCon, LDAP_OPT_PROTOCOL_VERSION, 3);
             if (!@\ldap_bind($oCon, $sUserDn, $sPrevPassword)) {
                 if ($this->oLogger) {
                     $sError = $oCon ? @\ldap_error($oCon) : '';
                     $iErrno = $oCon ? @\ldap_errno($oCon) : 0;
                     $this->oLogger->Write('ldap_bind error: ' . $sError . ' (' . $iErrno . ')', \MailSo\Log\Enumerations\Type::WARNING, 'LDAP');
                 }
                 return false;
             }
         }
         $sEncodedNewPassword = $sNewPassword;
         switch (\strtolower($this->sPasswordEncType)) {
             case 'sha':
                 switch (true) {
                     default:
                     case \function_exists('sha1'):
                         $sEncodedNewPassword = '******' . \base64_encode(\pack('H*', \sha1($sNewPassword)));
                         break;
                     case \function_exists('hash'):
                         $sEncodedNewPassword = '******' . \base64_encode(\hash('sha1', $sNewPassword, true));
                         break;
                     case \function_exists('mhash') && defined('MHASH_SHA1'):
                         $sEncodedNewPassword = '******' . \base64_encode(\mhash(MHASH_SHA1, $sNewPassword));
                         break;
                 }
                 break;
             case 'md5':
                 $sEncodedNewPassword = '******' . \base64_encode(\pack('H*', \md5($sNewPassword)));
                 break;
             case 'crypt':
                 $sEncodedNewPassword = '******' . \crypt($sNewPassword, $this->getSalt(2));
                 break;
         }
         $aEntry = array();
         $aEntry[$this->sPasswordField] = (string) $sEncodedNewPassword;
         if (!!@\ldap_modify($oCon, $sUserDn, $aEntry)) {
             $bResult = true;
         } else {
             if ($this->oLogger) {
                 $sError = $oCon ? @\ldap_error($oCon) : '';
                 $iErrno = $oCon ? @\ldap_errno($oCon) : 0;
                 $this->oLogger->Write('ldap_modify error: ' . $sError . ' (' . $iErrno . ')', \MailSo\Log\Enumerations\Type::WARNING, 'LDAP');
             }
         }
     } catch (\Exception $oException) {
         if ($this->oLogger) {
             $this->oLogger->WriteException($oException, \MailSo\Log\Enumerations\Type::WARNING, 'LDAP');
         }
         $bResult = false;
     }
     return $bResult;
 }
Beispiel #5
0
 /**
  * @return string
  */
 public function GetAccountName()
 {
     return \MailSo\Base\Utils::GetAccountNameFromEmail($this->GetEmail(false));
 }
 /**
  * @param string $sLine
  * @param \RainLoop\Model\Account $oAccount = null
  * @param bool $bUrlEncode = false
  *
  * @return string
  */
 private function compileLogParams($sLine, $oAccount = null, $bUrlEncode = false)
 {
     if (false !== \strpos($sLine, '{date:')) {
         $iTimeOffset = (int) $this->Config()->Get('logs', 'time_offset', 0);
         $sLine = \preg_replace_callback('/\\{date:([^}]+)\\}/', function ($aMatch) use($iTimeOffset, $bUrlEncode) {
             return \RainLoop\Utils::UrlEncode(\MailSo\Log\Logger::DateHelper($aMatch[1], $iTimeOffset), $bUrlEncode);
         }, $sLine);
         $sLine = \preg_replace('/\\{date:([^}]*)\\}/', 'date', $sLine);
     }
     if (false !== \strpos($sLine, '{imap:') || false !== \strpos($sLine, '{smtp:')) {
         if (!$oAccount) {
             $this->ParseQueryAuthString();
             $oAccount = $this->getAccountFromToken(false);
         }
         if ($oAccount) {
             $sLine = \str_replace('{imap:login}', \RainLoop\Utils::UrlEncode($oAccount->IncLogin(), $bUrlEncode), $sLine);
             $sLine = \str_replace('{imap:host}', \RainLoop\Utils::UrlEncode($oAccount->DomainIncHost(), $bUrlEncode), $sLine);
             $sLine = \str_replace('{imap:port}', \RainLoop\Utils::UrlEncode($oAccount->DomainIncPort(), $bUrlEncode), $sLine);
             $sLine = \str_replace('{smtp:login}', \RainLoop\Utils::UrlEncode($oAccount->OutLogin(), $bUrlEncode), $sLine);
             $sLine = \str_replace('{smtp:host}', \RainLoop\Utils::UrlEncode($oAccount->DomainOutHost(), $bUrlEncode), $sLine);
             $sLine = \str_replace('{smtp:port}', \RainLoop\Utils::UrlEncode($oAccount->DomainOutPort(), $bUrlEncode), $sLine);
         }
         $sLine = \preg_replace('/\\{imap:([^}]*)\\}/i', 'imap', $sLine);
         $sLine = \preg_replace('/\\{smtp:([^}]*)\\}/i', 'smtp', $sLine);
     }
     if (false !== \strpos($sLine, '{request:')) {
         if (false !== \strpos($sLine, '{request:ip}')) {
             $sLine = \str_replace('{request:ip}', \RainLoop\Utils::UrlEncode($this->Http()->GetClientIp($this->Config()->Get('labs', 'http_client_ip_check_proxy', false)), $bUrlEncode), $sLine);
         }
         if (false !== \strpos($sLine, '{request:domain}')) {
             $sLine = \str_replace('{request:domain}', \RainLoop\Utils::UrlEncode($this->Http()->GetHost(false, true, true), $bUrlEncode), $sLine);
         }
         if (false !== \strpos($sLine, '{request:domain-clear}')) {
             $sLine = \str_replace('{request:domain-clear}', \RainLoop\Utils::UrlEncode(\MailSo\Base\Utils::GetClearDomainName($this->Http()->GetHost(false, true, true)), $bUrlEncode), $sLine);
         }
         $sLine = \preg_replace('/\\{request:([^}]*)\\}/i', 'request', $sLine);
     }
     if (false !== \strpos($sLine, '{user:'******'{user:uid}')) {
             $sLine = \str_replace('{user:uid}', \RainLoop\Utils::UrlEncode(\base_convert(\sprintf('%u', \crc32(\md5(\RainLoop\Utils::GetConnectionToken()))), 10, 32), $bUrlEncode), $sLine);
         }
         if (false !== \strpos($sLine, '{user:ip}')) {
             $sLine = \str_replace('{user:ip}', \RainLoop\Utils::UrlEncode($this->Http()->GetClientIp($this->Config()->Get('labs', 'http_client_ip_check_proxy', false)), $bUrlEncode), $sLine);
         }
         if (\preg_match('/\\{user:(email|login|domain)\\}/i', $sLine)) {
             if (!$oAccount) {
                 $this->ParseQueryAuthString();
                 $oAccount = $this->getAccountFromToken(false);
             }
             if ($oAccount) {
                 $sEmail = $oAccount->Email();
                 $sLine = \str_replace('{user:email}', \RainLoop\Utils::UrlEncode($sEmail, $bUrlEncode), $sLine);
                 $sLine = \str_replace('{user:login}', \RainLoop\Utils::UrlEncode(\MailSo\Base\Utils::GetAccountNameFromEmail($sEmail), $bUrlEncode), $sLine);
                 $sLine = \str_replace('{user:domain}', \RainLoop\Utils::UrlEncode(\MailSo\Base\Utils::GetDomainFromEmail($sEmail), $bUrlEncode), $sLine);
                 $sLine = \str_replace('{user:domain-clear}', \RainLoop\Utils::UrlEncode(\MailSo\Base\Utils::GetClearDomainName(\MailSo\Base\Utils::GetDomainFromEmail($sEmail)), $bUrlEncode), $sLine);
             }
         }
         $sLine = \preg_replace('/\\{user:([^}]*)\\}/i', 'unknown', $sLine);
     }
     if (false !== \strpos($sLine, '{labs:')) {
         $sLine = \preg_replace_callback('/\\{labs:rand:([1-9])\\}/', function ($aMatch) {
             return \rand(\pow(10, $aMatch[1] - 1), \pow(10, $aMatch[1]) - 1);
         }, $sLine);
         $sLine = \preg_replace('/\\{labs:([^}]*)\\}/', 'labs', $sLine);
     }
     return $sLine;
 }
Beispiel #7
0
 /**
  * @param string $sEmail
  * @param string $sLogin = ''
  *
  * @return bool
  */
 public function ValidateWhiteList($sEmail, $sLogin = '')
 {
     $sW = \trim($this->sWhiteList);
     if (0 < strlen($sW)) {
         $sEmail = \MailSo\Base\Utils::IdnToUtf8($sEmail, true);
         $sLogin = \MailSo\Base\Utils::IdnToUtf8($sLogin);
         $sW = \preg_replace('/([^\\s]+)@[^\\s]*/', '$1', $sW);
         $sW = ' ' . \trim(\preg_replace('/[\\s;,\\r\\n\\t]+/', ' ', $sW)) . ' ';
         $sUserPart = \MailSo\Base\Utils::GetAccountNameFromEmail(0 < \strlen($sLogin) ? $sLogin : $sEmail);
         return false !== \strpos($sW, ' ' . $sUserPart . ' ');
     }
     return true;
 }
 /**
  * @param \RainLoop\Model\Account $oAccount
  * @param string $sPrevPassword
  * @param string $sNewPassword
  *
  * @return bool
  */
 public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword)
 {
     if ($this->oLogger) {
         $this->oLogger->Write('Try to change password for ' . $oAccount->Email());
     }
     if (!\class_exists('xmlapi')) {
         include_once __DIR__ . '/xmlapi.php';
     }
     $bResult = false;
     if (!empty($this->sHost) && 0 < $this->iPost && 0 < \strlen($this->sUser) && 0 < \strlen($this->sPassword) && $oAccount && \class_exists('xmlapi')) {
         $sEmail = $oAccount->Email();
         $sEmailUser = \MailSo\Base\Utils::GetAccountNameFromEmail($sEmail);
         $sEmailDomain = \MailSo\Base\Utils::GetDomainFromEmail($sEmail);
         $sHost = $this->sHost;
         $sHost = \str_replace('{user:domain}', $sEmailDomain, $sHost);
         $sUser = $this->sUser;
         $sUser = \str_replace('{user:email}', $sEmail, $sUser);
         $sUser = \str_replace('{user:login}', $sEmailUser, $sUser);
         $sPassword = $this->sPassword;
         $sPassword = \str_replace('{user:password}', $oAccount->Password(), $sPassword);
         try {
             $oXmlApi = new \xmlapi($sHost);
             $oXmlApi->set_port($this->iPost);
             $oXmlApi->set_protocol($this->bSsl ? 'https' : 'http');
             $oXmlApi->set_debug(false);
             $oXmlApi->set_output('json');
             //				$oXmlApi->set_http_client('fopen');
             $oXmlApi->set_http_client('curl');
             $oXmlApi->password_auth($sUser, $sPassword);
             $aArgs = array('email' => $sEmailUser, 'domain' => $sEmailDomain, 'password' => $sNewPassword);
             $sResult = $oXmlApi->api2_query($sUser, 'Email', 'passwdpop', $aArgs);
             if ($sResult) {
                 if ($this->oLogger) {
                     $this->oLogger->Write('CPANEL: ' . $sResult, \MailSo\Log\Enumerations\Type::INFO);
                 }
                 $aResult = @\json_decode($sResult, true);
                 $bResult = isset($aResult['cpanelresult']['data'][0]['result']) && !!$aResult['cpanelresult']['data'][0]['result'];
             }
             if (!$bResult && $this->oLogger) {
                 $this->oLogger->Write('CPANEL: ' . $sResult, \MailSo\Log\Enumerations\Type::ERROR);
             }
         } catch (\Exception $oException) {
             if ($this->oLogger) {
                 $this->oLogger->WriteException($oException);
             }
         }
     } else {
         if ($this->oLogger) {
             $this->oLogger->Write('CPANEL: Incorrent configuration data', \MailSo\Log\Enumerations\Type::ERROR);
         }
     }
     return $bResult;
 }
 /**
  * @param \RainLoop\Account $oAccount
  * @param string $sPrevPassword
  * @param string $sNewPassword
  *
  * @return bool
  */
 public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword)
 {
     if ($this->oLogger) {
         $this->oLogger->Write('Try to change password for ' . $oAccount->Email());
     }
     if (empty($this->mHost) || empty($this->mDatabase) || empty($this->mColumn) || empty($this->mTable)) {
         return false;
     }
     $bResult = false;
     $sDsn = 'mysql:host=' . $this->mHost . ';dbname=' . $this->mDatabase . ';charset=utf8';
     $aOptions = array(PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_PERSISTENT => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION);
     $sLoginPart = \MailSo\Base\Utils::GetAccountNameFromEmail($oAccount->Email());
     $sDomainPart = \MailSo\Base\Utils::GetDomainFromEmail($oAccount->Email());
     try {
         $oConn = new PDO($sDsn, $this->mUser, $this->mPass, $aOptions);
         $oSelect = $oConn->prepare('SELECT ' . $this->mColumn . ' FROM ' . $this->mTable . ' WHERE pw_name=? AND pw_domain=? LIMIT 1');
         $oSelect->execute(array($sLoginPart, $sDomainPart));
         $aColCrypt = $oSelect->fetchAll(PDO::FETCH_ASSOC);
         $sCryptPass = isset($aColCrypt[0][$this->mColumn]) ? $aColCrypt[0][$this->mColumn] : '';
         if (0 < \strlen($sCryptPass) && \crypt($sPrevPassword, $sCryptPass) === $sCryptPass) {
             $oUpdate = $oConn->prepare('UPDATE ' . $this->mTable . ' SET ' . $this->mColumn . '=ENCRYPT(?,concat("$1$",right(md5(rand()), 8 ),"$")), pw_clear_passwd=\'\' WHERE pw_name=? AND pw_domain=?');
             $oUpdate->execute(array($sNewPassword, $sLoginPart, $sDomainPart));
             $bResult = true;
             if ($this->oLogger) {
                 $this->oLogger->Write('Success! Password changed.');
             }
         } else {
             $bResult = false;
             if ($this->oLogger) {
                 $this->oLogger->Write('Something went wrong. Either current password is incorrect, or new password does not match criteria.');
             }
         }
     } catch (\Exception $oException) {
         $bResult = false;
         if ($this->oLogger) {
             $this->oLogger->WriteException($oException);
         }
     }
     return $bResult;
 }
 /**
  * @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;
 }
Beispiel #11
0
 /**
  * @return string
  */
 private function compileLogFileName()
 {
     $sFileName = (string) $this->Config()->Get('logs', 'filename', '');
     if (false !== \strpos($sFileName, '{date:')) {
         $sFileName = \preg_replace_callback('/\\{date:([^}]+)\\}/', function ($aMatch) {
             return \gmdate($aMatch[1]);
         }, $sFileName);
         $sFileName = \preg_replace('/\\{date:([^}]*)\\}/', 'date', $sFileName);
     }
     if (false !== \strpos($sFileName, '{user:'******'{user:uid}')) {
             $sFileName = \str_replace('{user:uid}', \base_convert(\sprintf('%u', \crc32(\md5(\RainLoop\Utils::GetConnectionToken()))), 10, 32), $sFileName);
         }
         if (false !== \strpos($sFileName, '{user:ip}')) {
             $sFileName = \str_replace('{user:ip}', $this->Http()->GetClientIp(), $sFileName);
         }
         if (\preg_match('/\\{user:(email|login|domain)\\}/i', $sFileName)) {
             $this->ParseQueryAuthString();
             $oAccount = $this->getAccountFromToken(false);
             if ($oAccount) {
                 $sEmail = $oAccount->Email();
                 $sFileName = \str_replace('{user:email}', $sEmail, $sFileName);
                 $sFileName = \str_replace('{user:login}', \MailSo\Base\Utils::GetAccountNameFromEmail($sEmail), $sFileName);
                 $sFileName = \str_replace('{user:domain}', \MailSo\Base\Utils::GetDomainFromEmail($sEmail), $sFileName);
             }
         }
         $sFileName = \preg_replace('/\\{user:([^}]*)\\}/i', 'unknown', $sFileName);
     }
     if (false !== \strpos($sFileName, '{labs:')) {
         $sFileName = \preg_replace_callback('/\\{labs:rand:([1-9])\\}/', function ($aMatch) {
             return \rand(\pow(10, $aMatch[1] - 1), \pow(10, $aMatch[1]) - 1);
         }, $sFileName);
         $sFileName = \preg_replace('/\\{labs:([^}]*)\\}/', 'labs', $sFileName);
     }
     if (0 === \strlen($sFileName)) {
         $sFileName = 'rainloop-log.txt';
     }
     $sFileName = \preg_replace('/[\\/]+/', '/', \preg_replace('/[.]+/', '.', $sFileName));
     $sFileName = \preg_replace('/[^a-zA-Z0-9@_+=\\-\\.\\/!()\\[\\]]/', '', $sFileName);
     return $sFileName;
 }