$sLine) { $sEncrypted = ''; \openssl_public_encrypt($sLine, $sEncrypted, $oPubKey); $aString[$iIndex] = $sEncrypted; } $aString[] = $sKey; $sResult = \serialize($aString); \openssl_free_key($oPubKey); } \openssl_free_key($oPrivKey); } return $sResult; } static public function DecryptStringRSA(string $sString, string $sKey = '') : string { $sResult = ''; $sKey = \md5($sKey); $sPrivateKey = static::RsaPrivateKey(); if (!empty($sPrivateKey) && !empty($sString)) { $oPrivKey = \openssl_pkey_get_private($sPrivateKey); $aString = \unserialize($sString); if (\is_array($aString)) { if ($sKey === \array_pop($aString)) { foreach ($aString as $iIndex => $sLine) { $sDecrypted = ''; \openssl_private_decrypt($sLine, $sDecrypted, $oPrivKey); $aString[$iIndex] = $sDecrypted; } $sResult = \implode('', $aString); } } \openssl_free_key($oPrivKey); } return $sResult; } static public function EncryptString(string $sString, string $sKey) : string { return \MailSo\Base\Crypt::Encrypt($sString, $sKey); } static public function DecryptString(string $sEncryptedString, string $sKey) : string { return \MailSo\Base\Crypt::Decrypt($sEncryptedString, $sKey); } static public function EncryptStringQ(string $sString, string $sKey) : string { // if (\MailSo\Base\Utils::FunctionExistsAndEnabled('openssl_pkey_get_private')) // { // return static::EncryptStringRSA($sString, // $sKey.'Q'.static::GetShortToken()); // } return \MailSo\Base\Crypt::Encrypt($sString, $sKey.'Q'.static::GetShortToken()); } static public function DecryptStringQ(string $sEncryptedString, string $sKey) : string { // if (\MailSo\Base\Utils::FunctionExistsAndEnabled('openssl_pkey_get_private')) // { // return static::DecryptStringRSA($sEncryptedString, // $sKey.'Q'.static::GetShortToken()); // } return \MailSo\Base\Crypt::Decrypt($sEncryptedString, $sKey.'Q'.static::GetShortToken()); } static public function EncodeKeyValues(array $aValues, string $sCustomKey = '') : string { return \MailSo\Base\Utils::UrlSafeBase64Encode( static::EncryptString(\serialize($aValues), \md5(APP_SALT.$sCustomKey))); } static public function DecodeKeyValues(string $sEncodedValues, string $sCustomKey = '') : array { $aResult = \unserialize( static::DecryptString( \MailSo\Base\Utils::UrlSafeBase64Decode($sEncodedValues), \md5(APP_SALT.$sCustomKey))); return \is_array($aResult) ? $aResult : array(); } static public function EncodeKeyValuesQ(array $aValues, string $sCustomKey = '') : string { return \MailSo\Base\Utils::UrlSafeBase64Encode( static::EncryptStringQ( \serialize($aValues), \md5(APP_SALT.$sCustomKey))); } static public function DecodeKeyValuesQ(string $sEncodedValues, string $sCustomKey = '') : array { $aResult = \unserialize( static::DecryptStringQ( \MailSo\Base\Utils::UrlSafeBase64Decode($sEncodedValues), \md5(APP_SALT.$sCustomKey))); return \is_array($aResult) ? $aResult : array(); } static public function GetConnectionToken() : string { $sKey = 'rltoken'; $sToken = static::GetCookie($sKey, null); if (null === $sToken) { $sToken = \MailSo\Base\Utils::Md5Rand(APP_SALT); static::SetCookie($sKey, $sToken, \time() + 60 * 60 * 24 * 30); } return \md5('Connection'.APP_SALT.$sToken.'Token'.APP_SALT); } static public function Fingerprint() : string { return \md5(empty($_SERVER['HTTP_USER_AGENT']) ? 'RainLoopFingerprint' : $_SERVER['HTTP_USER_AGENT']); } static public function GetShortToken() : string { $sKey = 'rlsession'; $sToken = static::GetCookie($sKey, null); if (null === $sToken) { $sToken = \MailSo\Base\Utils::Md5Rand(APP_SALT); static::SetCookie($sKey, $sToken, 0); } return \md5('Session'.APP_SALT.$sToken.'Token'.APP_SALT); } static public function UpdateConnectionToken() : void { $sKey = 'rltoken'; $sToken = static::GetCookie($sKey, ''); if (!empty($sToken)) { static::SetCookie($sKey, $sToken, \time() + 60 * 60 * 24 * 30); } } static public function GetCsrfToken() : string { return \md5('Csrf'.APP_SALT.self::GetConnectionToken().'Token'.APP_SALT); } public static function PathMD5(string $sPath) : string { $sResult = ''; if (\is_dir($sPath)) { $oDirIterator = new \RecursiveDirectoryIterator($sPath); $oIterator = new \RecursiveIteratorIterator($oDirIterator, \RecursiveIteratorIterator::SELF_FIRST); foreach ($oIterator as $oFile) { $sResult = \md5($sResult.($oFile->isFile() ? \md5_file($oFile) : $oFile)); } } return $sResult; } public static function ReadAndAddLang(string $sFileName, array &$aResultLang) : void { if (\file_exists($sFileName)) { if ('.yml' === substr($sFileName, -4)) { //- $aLang = \yaml_parse(\str_replace(array(': >-', ': |-', ': |+'), array(': >', ': |', ': |'), \file_get_contents($sFileName))); $aLang = \yaml_parse_file($sFileName); if (\is_array($aLang)) { \reset($aLang); $sLangKey = key($aLang); if (isset($aLang[$sLangKey]) && is_array($aLang[$sLangKey])) { $aLang = $aLang[$sLangKey]; } else { $aLang = null; } } } else { $aLang = static::CustomParseIniFile($sFileName, true); } if (\is_array($aLang)) { foreach ($aLang as $sKey => $mValue) { if (\is_array($mValue)) { foreach ($mValue as $sSecKey => $mSecValue) { $aResultLang[$sKey.'/'.$sSecKey] = $mSecValue; } } else { $aResultLang[$sKey] = $mValue; } } } } } public static function FolderFiles(string $sDir, string $sType = '') : array { $aResult = array(); if (\is_dir($sDir)) { if (false !== ($rDirHandle = \opendir($sDir))) { while (false !== ($sFile = \readdir($rDirHandle))) { if (empty($sType) || $sType === \substr($sFile, -\strlen($sType))) { if (\is_file($sDir.'/'.$sFile)) { $aResult[] = $sFile; } } } \closedir($rDirHandle); } } return $aResult; } public static function ClearHtmlOutput(string $sHtml) : string { // return $sHtml; return \trim(\str_replace('> <', '><', \str_replace('" />', '"/>', \preg_replace('/[\s]+ /i', ' ', \preg_replace('/ [\s]+/i', ' ', \preg_replace('/[\r\n\t]+/', ' ', $sHtml )))))); } public static function FastCheck(string $sKey) : bool { $bResult = false; $aMatches = array(); if (!empty($sKey) && 0 < \strlen($sKey) && \preg_match('/^(RL[\d]+)\-(.+)\-([^\-]+)$/', $sKey, $aMatches) && 3 === \count($aMatches)) { $bResult = $aMatches[3] === \strtoupper(\base_convert(\crc32(\md5( $aMatches[1].'-'.$aMatches[2].'-')), 10, 32)); } return $bResult; } public static function CompileTemplates(array &$aList, string $sDirName, string $sNameSuffix = '') { if (\file_exists($sDirName)) { $aFileList = static::FolderFiles($sDirName, '.html'); foreach ($aFileList as $sName) { $sTemplateName = \substr($sName, 0, -5).$sNameSuffix; $aList[$sTemplateName] = $sDirName.'/'.$sName; } } } /** * @param mixed $mDefault = null * @return mixed */ public static function GetCookie(string $sName, $mDefault = null) { if (null === static::$Cookies) { static::$Cookies = is_array($_COOKIE) ? $_COOKIE : array(); } return isset(static::$Cookies[$sName]) ? static::$Cookies[$sName] : $mDefault; } public static function SetCookie(string $sName, string $sValue = '', int $iExpire = 0, ?string $sPath = null, ?string $sDomain = null, ?bool $bSecure = null, bool $bHttpOnly = true) { if (null === static::$Cookies) { static::$Cookies = is_array($_COOKIE) ? $_COOKIE : array(); } if (null === $sPath) { $sPath = static::$CookieDefaultPath; $sPath = $sPath && 0 < \strlen($sPath) ? $sPath : null; } if (null === $bSecure) { $bSecure = static::$CookieDefaultSecure; } static::$Cookies[$sName] = $sValue; \setcookie($sName, $sValue, $iExpire, $sPath, $sDomain, $bSecure, $bHttpOnly); } public static function ClearCookie(string $sName) { if (null === static::$Cookies) { static::$Cookies = is_array($_COOKIE) ? $_COOKIE : array(); } $sPath = static::$CookieDefaultPath; $sPath = $sPath && 0 < \strlen($sPath) ? $sPath : null; unset(static::$Cookies[$sName]); \setcookie($sName, '', \time() - 3600 * 24 * 30, $sPath); } public static function UrlEncode(string $sV, bool $bEncode = false) : string { return $bEncode ? \urlencode($sV) : $sV; } public static function WebPath() : string { $sAppPath = ''; return $sAppPath; } public static function WebVersionPath() : string { return self::WebPath().'rainloop/v/'.APP_VERSION.'/'; } public static function WebStaticPath() : string { return self::WebVersionPath().'static/'; } public static function RemoveSuggestionDuplicates(array $aSuggestions) : array { $aResult = array(); foreach ($aSuggestions as $aItem) { $sLine = \implode('~~', $aItem); if (!isset($aResult[$sLine])) { $aResult[$sLine] = $aItem; } } return array_values($aResult); } public static function CustomParseIniFile(string $sFileName, bool $bProcessSections = false) : array { // if (\MailSo\Base\Utils::FunctionExistsAndEnabled('parse_ini_file')) // { // return \parse_ini_file($sFileName, !!$bProcessSections); // } return @\parse_ini_string(\file_get_contents($sFileName), $bProcessSections) ?: array(); } public static function CustomBaseConvert(string $sNumberInput, string $sFromBaseInput = '0123456789', string $sToBaseInput = '0123456789') { if ($sFromBaseInput === $sToBaseInput) { return $sNumberInput; } $mFromBase = \str_split($sFromBaseInput, 1); $mToBase = \str_split($sToBaseInput, 1); $aNumber = \str_split($sNumberInput, 1); $iFromLen = \strlen($sFromBaseInput); $iToLen = \strlen($sToBaseInput); $numberLen = \strlen($sNumberInput); $mRetVal = ''; if ($sToBaseInput === '0123456789') { $mRetVal = 0; for ($iIndex = 1; $iIndex <= $numberLen; $iIndex++) { $mRetVal = \bcadd($mRetVal, \bcmul(\array_search($aNumber[$iIndex - 1], $mFromBase), \bcpow($iFromLen, $numberLen - $iIndex))); } return $mRetVal; } if ($sFromBaseInput != '0123456789') { $sBase10 = static::CustomBaseConvert($sNumberInput, $sFromBaseInput, '0123456789'); } else { $sBase10 = $sNumberInput; } if ($sBase10 < \strlen($sToBaseInput)) { return $mToBase[$sBase10]; } while ($sBase10 !== '0') { $mRetVal = $mToBase[\bcmod($sBase10, $iToLen)].$mRetVal; $sBase10 = \bcdiv($sBase10, $iToLen, 0); } return $mRetVal; } }