diff --git a/.docker/release/files/entrypoint.sh b/.docker/release/files/entrypoint.sh index 21e23f8f6..eed82bf5b 100644 --- a/.docker/release/files/entrypoint.sh +++ b/.docker/release/files/entrypoint.sh @@ -9,11 +9,6 @@ adduser --uid "$UID" --disabled-password --gid "$GID" --shell /bin/bash --home / sed -i "s//$UPLOAD_MAX_SIZE/g" /usr/local/etc/php-fpm.d/php-fpm.conf /etc/nginx/nginx.conf sed -i "s//$MEMORY_LIMIT/g" /usr/local/etc/php-fpm.d/php-fpm.conf -# Remove postfixadmin-change-password plugin if exist -if [ -d "/snappymail/data/_data_/_default_/plugins/postfixadmin-change-password" ]; then - rm -rf /snappymail/data/_data_/_default_/plugins/postfixadmin-change-password -fi - # Set log output to STDERR if wanted (LOG_TO_STDERR=true) if [ "$LOG_TO_STDERR" = true ]; then echo "[INFO] Logging to stderr activated" @@ -31,10 +26,6 @@ if [ "${SECURE_COOKIES}" = true ]; then } > /usr/local/etc/php/conf.d/cookies.ini; fi -# Add postfixadmin-change-password plugin -mkdir -p /snappymail/data/_data_/_default_/plugins/ -cp -r /usr/local/include/postfixadmin-change-password /snappymail/data/_data_/_default_/plugins/ - # Copy snappymail default config if absent SNAPPYMAIL_CONFIG_FILE=/snappymail/data/_data_/_default_/configs/application.ini if [ ! -f "$SNAPPYMAIL_CONFIG_FILE" ]; then diff --git a/.docker/release/files/usr/local/include/postfixadmin-change-password/ChangePasswordPostfixAdminDriver.php b/.docker/release/files/usr/local/include/postfixadmin-change-password/ChangePasswordPostfixAdminDriver.php deleted file mode 100644 index d52d13c11..000000000 --- a/.docker/release/files/usr/local/include/postfixadmin-change-password/ChangePasswordPostfixAdminDriver.php +++ /dev/null @@ -1,342 +0,0 @@ -sEngine = $sEngine; - return $this; - } - - /** - * @param string $sHost - * - * @return \ChangePasswordPostfixAdminDriver - */ - public function SetHost($sHost) - { - $this->sHost = $sHost; - return $this; - } - - /** - * @param int $iPort - * - * @return \ChangePasswordPostfixAdminDriver - */ - public function SetPort($iPort) - { - $this->iPort = (int) $iPort; - return $this; - } - - /** - * @param string $sDatabase - * - * @return \ChangePasswordPostfixAdminDriver - */ - public function SetDatabase($sDatabase) - { - $this->sDatabase = $sDatabase; - return $this; - } - - /** - * @param string $sTable - * - * @return \ChangePasswordPostfixAdminDriver - */ - public function SetTable($sTable) - { - $this->sTable = $sTable; - return $this; - } - - /** - * @param string $sUsercol - * - * @return \ChangePasswordPostfixAdminDriver - */ - public function SetUserColumn($sUsercol) - { - $this->sUsercol = $sUsercol; - return $this; - } - - /** - * @param string $sPasscol - * - * @return \ChangePasswordPostfixAdminDriver - */ - public function SetPasswordColumn($sPasscol) - { - $this->sPasscol = $sPasscol; - return $this; - } - - /** - * @param string $sUser - * - * @return \ChangePasswordPostfixAdminDriver - */ - public function SetUser($sUser) - { - $this->sUser = $sUser; - return $this; - } - - /** - * @param string $sPassword - * - * @return \ChangePasswordPostfixAdminDriver - */ - public function SetPassword($sPassword) - { - $this->sPassword = $sPassword; - return $this; - } - - /** - * @param string $sEncrypt - * - * @return \ChangePasswordPostfixAdminDriver - */ - public function SetEncrypt($sEncrypt) - { - $this->sEncrypt = $sEncrypt; - return $this; - } - - /** - * @param string $sAllowedEmails - * - * @return \ChangePasswordPostfixAdminDriver - */ - public function SetAllowedEmails($sAllowedEmails) - { - $this->sAllowedEmails = $sAllowedEmails; - return $this; - } - - /** - * @param \MailSo\Log\Logger $oLogger - * - * @return \ChangePasswordPostfixAdminDriver - */ - public function SetLogger($oLogger) - { - if ($oLogger instanceof \MailSo\Log\Logger) - { - $this->oLogger = $oLogger; - } - - return $this; - } - - /** - * @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 string $sPrevPassword - * @param string $sNewPassword - * - * @return bool - */ - public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword) - { - if ($this->oLogger) - { - $this->oLogger->Write('Postfix: Try to change password for '.$oAccount->Email()); - } - - unset($sPrevPassword); - - $bResult = false; - - if (0 < \strlen($sNewPassword)) - { - try - { - $sDsn = ''; - switch($this->sEngine){ - case 'MySQL': - $sDsn = 'mysql:host='.$this->sHost.';port='.$this->iPort.';dbname='.$this->sDatabase; - break; - case 'PostgreSQL': - $sDsn = 'pgsql:host='.$this->sHost.';port='.$this->iPort.';dbname='.$this->sDatabase; - break; - default: - $sDsn = 'mysql:host='.$this->sHost.';port='.$this->iPort.';dbname='.$this->sDatabase; - break; - } - - - $oPdo = new \PDO($sDsn, $this->sUser, $this->sPassword); - $oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); - - $sUpdatePassword = $this->cryptPassword($sNewPassword, $oPdo); - if (0 < \strlen($sUpdatePassword)) - { - $oStmt = $oPdo->prepare("UPDATE {$this->sTable} SET {$this->sPasscol} = ? WHERE {$this->sUsercol} = ?"); - $bResult = (bool) $oStmt->execute(array($sUpdatePassword, $oAccount->Email())); - } - else - { - if ($this->oLogger) - { - $this->oLogger->Write('Postfix: Encrypted password is empty', - \MailSo\Log\Enumerations\Type::ERROR); - } - } - - $oPdo = null; - } - catch (\Exception $oException) - { - if ($this->oLogger) - { - $this->oLogger->WriteException($oException); - } - } - } - - return $bResult; - } - - /** - * @param string $sPassword - * @param \PDO $oPdo - * - * @return string - */ - private function cryptPassword($sPassword, $oPdo) - { - $sResult = ''; - if (function_exists('random_bytes')) { - $sSalt = substr(base64_encode(random_bytes(32)), 0, 16); - } else { - $sSalt = substr(str_shuffle('./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'), 0, 16); - } - switch (strtolower($this->sEncrypt)) - { - default: - case 'plain': - case 'cleartext': - $sResult = '{PLAIN}' . $sPassword; - break; - - case 'md5crypt': - include_once __DIR__.'/md5crypt.php'; - $sResult = '{MD5-CRYPT}' . md5crypt($sPassword); - break; - - case 'md5': - $sResult = '{PLAIN-MD5}' . md5($sPassword); - break; - - case 'system': - $sResult = '{CRYPT}' . crypt($sPassword); - break; - - case 'sha256-crypt': - $sResult = '{SHA256-CRYPT}' . crypt($sPassword,'$5$'.$sSalt); - break; - - case 'sha512-crypt': - $sResult = '{SHA512-CRYPT}' . crypt($sPassword,'$6$'.$sSalt); - break; - - case 'mysql_encrypt': - if($this->sEngine == 'MySQL'){ - $oStmt = $oPdo->prepare('SELECT ENCRYPT(?) AS encpass'); - if ($oStmt->execute(array($sPassword))) - { - $aFetchResult = $oStmt->fetchAll(\PDO::FETCH_ASSOC); - if (\is_array($aFetchResult) && isset($aFetchResult[0]['encpass'])) - { - $sResult = $aFetchResult[0]['encpass']; - } - } - }else{ - throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CouldNotSaveNewPassword); - } - break; - } - - return $sResult; - } -} diff --git a/.docker/release/files/usr/local/include/postfixadmin-change-password/LICENSE b/.docker/release/files/usr/local/include/postfixadmin-change-password/LICENSE deleted file mode 100644 index c6cb63dbf..000000000 --- a/.docker/release/files/usr/local/include/postfixadmin-change-password/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 RainLoop Team, @zaffkea - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software is furnished to do so, -subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS -FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/.docker/release/files/usr/local/include/postfixadmin-change-password/README b/.docker/release/files/usr/local/include/postfixadmin-change-password/README deleted file mode 100644 index 342f4d4b5..000000000 --- a/.docker/release/files/usr/local/include/postfixadmin-change-password/README +++ /dev/null @@ -1 +0,0 @@ -Plugin that adds functionality to change the email account password (PostfixAdmin). \ No newline at end of file diff --git a/.docker/release/files/usr/local/include/postfixadmin-change-password/VERSION b/.docker/release/files/usr/local/include/postfixadmin-change-password/VERSION deleted file mode 100644 index 7e32cd569..000000000 --- a/.docker/release/files/usr/local/include/postfixadmin-change-password/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.3 diff --git a/.docker/release/files/usr/local/include/postfixadmin-change-password/index.php b/.docker/release/files/usr/local/include/postfixadmin-change-password/index.php deleted file mode 100644 index c0f9e40a7..000000000 --- a/.docker/release/files/usr/local/include/postfixadmin-change-password/index.php +++ /dev/null @@ -1,100 +0,0 @@ -addHook('main.fabrica', 'MainFabrica'); - } - - /** - * @return string - */ - public function Supported() - { - if (!extension_loaded('pdo') || !class_exists('PDO')) - { - return 'The PHP extension PDO must be installed to use this plugin'; - } - - $aDrivers = \PDO::getAvailableDrivers(); - if (!is_array($aDrivers) || (!in_array('mysql', $aDrivers) && !in_array('pgsql', $aDrivers))) - { - return 'The PHP extension PDO (mysql or pgsql) must be installed to use this plugin'; - } - - return ''; - } - - /** - * @param string $sName - * @param mixed $oProvider - */ - public function MainFabrica($sName, &$oProvider) - { - switch ($sName) - { - case 'change-password': - - include_once __DIR__.'/ChangePasswordPostfixAdminDriver.php'; - - $oProvider = new ChangePasswordPostfixAdminDriver(); - - $oProvider - ->SetEngine($this->Config()->Get('plugin', 'engine','')) - ->SetHost($this->Config()->Get('plugin', 'host', '')) - ->SetPort((int) $this->Config()->Get('plugin', 'port', 3306)) - ->SetDatabase($this->Config()->Get('plugin', 'database', '')) - ->SetTable($this->Config()->Get('plugin', 'table', '')) - ->SetUserColumn($this->Config()->Get('plugin', 'usercol', '')) - ->SetPasswordColumn($this->Config()->Get('plugin', 'passcol', '')) - ->SetUser($this->Config()->Get('plugin', 'user', '')) - ->SetPassword($this->Config()->Get('plugin', 'password', '')) - ->SetEncrypt($this->Config()->Get('plugin', 'encrypt', '')) - ->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', '')))) - ->SetLogger($this->Manager()->Actions()->Logger()) - ; - - break; - } - } - - /** - * @return array - */ - public function configMapping() - { - return array( - \RainLoop\Plugins\Property::NewInstance('engine')->SetLabel('Engine') - ->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION) - ->SetDefaultValue(array('MySQL', 'PostgreSQL')) - ->SetDescription('Database Engine'), - \RainLoop\Plugins\Property::NewInstance('host')->SetLabel('Host') - ->SetDefaultValue('127.0.0.1'), - \RainLoop\Plugins\Property::NewInstance('port')->SetLabel('Port') - ->SetType(\RainLoop\Enumerations\PluginPropertyType::INT) - ->SetDefaultValue(3306), - \RainLoop\Plugins\Property::NewInstance('database')->SetLabel('Database') - ->SetDefaultValue('postfixadmin'), - \RainLoop\Plugins\Property::NewInstance('table')->SetLabel('table') - ->SetDefaultValue('mailbox'), - \RainLoop\Plugins\Property::NewInstance('usercol')->SetLabel('username column') - ->SetDefaultValue('username'), - \RainLoop\Plugins\Property::NewInstance('passcol')->SetLabel('password column') - ->SetDefaultValue('password'), - \RainLoop\Plugins\Property::NewInstance('user')->SetLabel('User') - ->SetDefaultValue('postfixadmin'), - \RainLoop\Plugins\Property::NewInstance('password')->SetLabel('Password') - ->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD) - ->SetDefaultValue(''), - \RainLoop\Plugins\Property::NewInstance('encrypt')->SetLabel('Encrypt') - ->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION) - ->SetDefaultValue(array('md5crypt', 'md5', 'system', 'cleartext', 'mysql_encrypt', 'SHA256-CRYPT', 'SHA512-CRYPT')) - ->SetDescription('In what way do you want the passwords to be crypted ?'), - \RainLoop\Plugins\Property::NewInstance('allowed_emails')->SetLabel('Allowed emails') - ->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT) - ->SetDescription('Allowed emails, space as delimiter, wildcard supported. Example: user1@domain1.net user2@domain1.net *@domain2.net') - ->SetDefaultValue('*') - ); - } -} diff --git a/.docker/release/files/usr/local/include/postfixadmin-change-password/md5crypt.php b/.docker/release/files/usr/local/include/postfixadmin-change-password/md5crypt.php deleted file mode 100644 index 13f878eca..000000000 --- a/.docker/release/files/usr/local/include/postfixadmin-change-password/md5crypt.php +++ /dev/null @@ -1,139 +0,0 @@ - 0; $i -= 16) - { - if ($i > 16) - { - $ctx .= substr($final,0,16); - } - else - { - $ctx .= substr($final,0,$i); - } - } - - $i = strlen($pw); - - while ($i > 0) - { - if ($i & 1) - { - $ctx .= chr(0); - } - else - { - $ctx .= $pw[0]; - } - - $i = $i >> 1; - } - - $final = hex2bin(md5($ctx)); - - for ($i=0; $i<1000; $i++) - { - $ctx1 = ""; - if ($i & 1) - { - $ctx1 .= $pw; - } - else - { - $ctx1 .= substr($final,0,16); - } - if ($i % 3) - { - $ctx1 .= $salt; - } - if ($i % 7) - { - $ctx1 .= $pw; - } - if ($i & 1) - { - $ctx1 .= substr($final, 0, 16); - } - else - { - $ctx1 .= $pw; - } - - $final = hex2bin(md5($ctx1)); - } - - $passwd = ""; - $passwd .= to64(((ord($final[0]) << 16) | (ord($final[6]) << 8) | (ord($final[12]))), 4); - $passwd .= to64(((ord($final[1]) << 16) | (ord($final[7]) << 8) | (ord($final[13]))), 4); - $passwd .= to64(((ord($final[2]) << 16) | (ord($final[8]) << 8) | (ord($final[14]))), 4); - $passwd .= to64(((ord($final[3]) << 16) | (ord($final[9]) << 8) | (ord($final[15]))), 4); - $passwd .= to64(((ord($final[4]) << 16) | (ord($final[10]) << 8) | (ord($final[5]))), 4); - $passwd .= to64(ord($final[11]), 2); - - return $magic.$salt.'$'.$passwd; -} - -function create_salt() -{ - srand((double) microtime() * 1000000); - return substr(md5(rand(0,9999999)), 0, 8); -} - -// PHP around 5.3.8 includes hex2bin as native function - http://php.net/hex2bin -if (!function_exists('hex2bin')) -{ - function hex2bin($str) - { - $len = strlen($str); - $nstr = ""; - for ($i = 0; $i < $len; $i += 2) - { - $num = sscanf(substr($str, $i, 2), "%x"); - $nstr .= chr($num[0]); - } - - return $nstr; - } -} - -function to64($v, $n) -{ - $ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - $ret = ""; - - while (($n - 1) >= 0) - { - $n--; - $ret .= $ITOA64[$v & 0x3f]; - $v = $v >> 6; - } - - return $ret; -} \ No newline at end of file