diff --git a/plugins/change-password-docker-mailserver/ChangePasswordVanVanDriver.php b/plugins/change-password-docker-mailserver/ChangePasswordVanVanDriver.php new file mode 100755 index 0000000000..b5ea7ad528 --- /dev/null +++ b/plugins/change-password-docker-mailserver/ChangePasswordVanVanDriver.php @@ -0,0 +1,216 @@ + + * + */ + +class ChangePasswordVanVanDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface +{ + /** + * @var string + */ + private $sHost = '127.0.0.1'; + + /** + * @var int + */ + private $iPort = 21; + + /** + * @var string + */ + private $sUser = 'root'; + + /** + * @var string + */ + private $sPassword = ''; + + /** + * @var string + */ + private $sLocation = 'setup.sh'; + + /** + * @var string + */ + private $bCheckExecution = true; + + /** + * @var string + */ + private $sAllowedEmails = ''; + + /** + * @var \MailSo\Log\Logger + */ + private $oLogger = null; + + /** + * @param string $sHost + * + * @return \ChangePasswordVanVanDriver + */ + public function SetHost($sHost) + { + $this->sHost = $sHost; + return $this; + } + + /** + * @param int $iPort + * + * @return \ChangePasswordVanVanDriver + */ + public function SetPort($iPort) + { + $this->iPort = (int) $iPort; + return $this; + } + + /** + * @param string $sHost + * + * @return \ChangePasswordVanVanDriver + */ + public function SetUser($sUser) + { + $this->sUser = $sUser; + return $this; + } + + /** + * @param string $sPassword + * + * @return \ChangePasswordVanVanDriver + */ + public function SetPassword($sPassword) + { + $this->sPassword = $sPassword; + return $this; + } + + /** + * @param string $sLocation + * + * @return \ChangePasswordVanVanDriver + */ + public function SetLocation($sLocation) + { + $this->sLocation = $sLocation; + return $this; + } + + /** + * @param boolean $bCheckExecution + * + * @return \ChangePasswordVanVanDriver + */ + public function SetCheckExecution($bCheckExecution) + { + $this->bCheckExecution = $bCheckExecution; + return $this; + } + + /** + * @param string $sAllowedEmails + * + * @return \ChangePasswordVanVanDriver + */ + public function SetAllowedEmails($sAllowedEmails) + { + $this->sAllowedEmails = $sAllowedEmails; + return $this; + } + + /** + * @param \MailSo\Log\Logger $oLogger + * + * @return \ChangePasswordVanVanDriver + */ + public function SetLogger($oLogger) + { + if ($oLogger instanceof \MailSo\Log\Logger) + { + $this->oLogger = $oLogger; + } + + return $this; + } + + /** + * @param \RainLoop\Account $oAccount + * + * @return bool + */ + public function PasswordChangePossibility($oAccount) + { + return $oAccount && $oAccount->Email() && + \RainLoop\Plugins\Helper::ValidateWildcardValues($oAccount->Email(), $this->sAllowedEmails); + } + + /** + * @param \RainLoop\Account $oAccount + * @param string $sPrevPassword + * @param string $sNewPassword + * + * @return bool + */ + public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword) + { + $bResult = false; + + try + { + if(strpos("'", $oAccount->Email()) !== false || strpos('"', $oAccount->Email()) !== false) + return false; + if(strpos("'", $sNewPassword) !== false || strpos('"', $sNewPassword) !== false) + return false; + + + $connection = ssh2_connect($this->sHost, $this->iPort); + if ($connection) + if (ssh2_auth_password($connection, $this->sUser, $this->sPassword)) { + $sftp = ssh2_sftp($connection); + $streamFile = file_exists('ssh2.sftp://' . intval($sftp) . $this->sLocation); + if ($streamFile && $stream = ssh2_exec($connection, ($this->sUser=='root'?'':'sudo ').$this->sLocation . ' email update "' . $oAccount->Email() . '" "' . $sNewPassword . '"')) { + stream_set_blocking($stream, true); + $stream_out = ssh2_fetch_stream($stream, SSH2_STREAM_STDIO); + $stream_out_error = ssh2_fetch_stream($stream, SSH2_STREAM_STDERR); + $outputString = stream_get_contents($stream_out); + $errorString = stream_get_contents($stream_out_error); + sleep(1); + if (!$this->bCheckExecution || (strlen($outputString) == 0 && (strlen($errorString) == 0 || strpos($errorString, 'error') === false))) + $bResult = true; + } + } + } + catch (\Exception $oException) + { + $bResult = false; + } + + return $bResult; + } + + /** + * @param string $path + * @return string + */ + public static function get_absolute_path($path) { + $path = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $path); + $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen'); + $absolutes = array(); + foreach ($parts as $part) { + if ('.' == $part) continue; + if ('..' == $part) { + array_pop($absolutes); + } else { + $absolutes[] = $part; + } + } + return implode(DIRECTORY_SEPARATOR, $absolutes); + } +} diff --git a/plugins/change-password-docker-mailserver/LICENSE b/plugins/change-password-docker-mailserver/LICENSE new file mode 100755 index 0000000000..83a9136d59 --- /dev/null +++ b/plugins/change-password-docker-mailserver/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 RainLoop Team + +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/plugins/change-password-docker-mailserver/README b/plugins/change-password-docker-mailserver/README new file mode 100755 index 0000000000..aff07c249b --- /dev/null +++ b/plugins/change-password-docker-mailserver/README @@ -0,0 +1 @@ +Plugin that adds functionality to change the email account password (docker-mailserver). \ No newline at end of file diff --git a/plugins/change-password-docker-mailserver/README.md b/plugins/change-password-docker-mailserver/README.md new file mode 100755 index 0000000000..6d50e216ce --- /dev/null +++ b/plugins/change-password-docker-mailserver/README.md @@ -0,0 +1,18 @@ +# Plugin Change-Password-Docker-Mailserver +Plugin that adds functionality to change the email account password (docker-mailserver). + +## ▶️ [Plugin Configuration](#configuration) + + +| URL | Description | +|---------------------------|----------------------------------------------------------------------------------------------------------| +| `SSH Docker Host` | Host running docker-mailserver docker container | +| `SSH Port` | SSH Port of host running docker-mailserver docker container | +| `SSH User` | For security reasons, you should use unprivileged user with sudoers access to docker-mailserver setup.sh | +| `SSH Password` | SSH password | +| `setup.sh Location` | Full path location of setup.sh from docker-mailserver | +| `Check execution success` | Enable or disable verification of setup.sh execution | +| `Allowed emails` | Allowed emails, space as delimiter, wildcard supported | + +## Authors +[VanVan](https://github.com/VanVan) \ No newline at end of file diff --git a/plugins/change-password-docker-mailserver/VERSION b/plugins/change-password-docker-mailserver/VERSION new file mode 100755 index 0000000000..9f8e9b69a3 --- /dev/null +++ b/plugins/change-password-docker-mailserver/VERSION @@ -0,0 +1 @@ +1.0 \ No newline at end of file diff --git a/plugins/change-password-docker-mailserver/index.php b/plugins/change-password-docker-mailserver/index.php new file mode 100755 index 0000000000..f4d43c87de --- /dev/null +++ b/plugins/change-password-docker-mailserver/index.php @@ -0,0 +1,91 @@ + + * + */ + +class ChangePasswordDockerMailserverPlugin extends \RainLoop\Plugins\AbstractPlugin +{ + /** + * @return void + */ + public function Init() + { + $this->addHook('main.fabrica', 'MainFabrica'); + } + + /** + * @return string + */ + public function Supported() + { + if (!\function_exists('ssh2_exec')) + { + return 'The PECL SSH2 PHP exention must be installed to use this plugin'; + } + + return ''; + } + + /** + * @param string $sName + * @param mixed $oProvider + * + * @return void + */ + public function MainFabrica($sName, &$oProvider) + { + switch ($sName) + { + case 'change-password': + + include_once __DIR__.'/ChangePasswordVanVanDriver.php'; + + $oProvider = new ChangePasswordVanVanDriver(); + + $oProvider + ->SetHost($this->Config()->Get('plugin', 'host', '')) + ->SetPort((int) $this->Config()->Get('plugin', 'port', 22)) + ->SetUser($this->Config()->Get('plugin', 'user', 'root')) + ->SetPassword($this->Config()->Get('plugin', 'password', '')) + ->SetLocation($this->Config()->Get('plugin', 'location', '/data/mailserver/setup.sh')) + ->SetCheckExecution($this->Config()->Get('plugin', 'check_execution', true)) + ->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('host')->SetLabel('SSH Docker Host') + ->SetDefaultValue('127.0.0.1')->SetDescription('Host running docker-mailserver docker container'), + \RainLoop\Plugins\Property::NewInstance('port')->SetLabel('SSH Port') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::INT) + ->SetDefaultValue(22), + \RainLoop\Plugins\Property::NewInstance('user')->SetLabel('SSH User') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING) + ->SetDefaultValue('root')->SetDescription('For security reasons, you should use unprivileged user with sudoers access to docker-mailserver setup.sh'), + \RainLoop\Plugins\Property::NewInstance('password')->SetLabel('SSH Password') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD), + \RainLoop\Plugins\Property::NewInstance('location')->SetLabel('setup.sh Location')->SetDefaultValue('/data/mailserver/setup.sh') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT) + ->SetDescription('Full path Location of setup.sh from docker-mailserver. No location edit hack protection. Protect access of your RainLoop Admin Panel'), + \RainLoop\Plugins\Property::NewInstance('checkExecution')->SetLabel('Check setup.sh execution success')->SetDefaultValue(true) + ->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL) + ->SetDescription('Check the correct execution of the command before considering the password correctly changed'), + \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.fr user2@domain1.fr *@domain2.fr') + ->SetDefaultValue('*') + ); + } +}