From 081726d7641f4eec22de271feb8e25388d37c3f6 Mon Sep 17 00:00:00 2001 From: Philipp Mundhenk Date: Sun, 21 Jan 2024 14:57:47 +0100 Subject: [PATCH 1/3] added automatic login --- plugins/proxy-auth/index.php | 32 ++++++++++++++++++++++++++++- plugins/proxy-auth/js/auto-login.js | 32 +++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 plugins/proxy-auth/js/auto-login.js diff --git a/plugins/proxy-auth/index.php b/plugins/proxy-auth/index.php index fb108d8ce2..8ba04c7bee 100644 --- a/plugins/proxy-auth/index.php +++ b/plugins/proxy-auth/index.php @@ -15,7 +15,9 @@ class ProxyAuthPlugin extends \RainLoop\Plugins\AbstractPlugin public function Init() : void { + $this->addJs('js/auto-login.js'); $this->addPartHook('ProxyAuth', 'ServiceProxyAuth'); + $this->addPartHook('UserHeaderSet', 'ServiceUserHeaderSet'); $this->addHook('login.credentials', 'MapEmailAddress'); } @@ -140,6 +142,28 @@ public function ServiceProxyAuth() : bool return true; } + public function ServiceUserHeaderSet() : bool + { + $oActions = \RainLoop\Api::Actions(); + + $oLogger = $oActions->Logger(); + $sLevel = LOG_DEBUG; + $sPrefix = "ProxyAuth"; + + $sHeaderName = \trim($this->Config()->getDecrypted('plugin', 'header_name', '')); + + $sRemoteUser = $this->Manager()->Actions()->Http()->GetHeader($sHeaderName); + $sMsg = "Remote User: " . $sRemoteUser; + $oLogger->Write($sMsg, $sLevel, $sPrefix); + + if (strlen($sRemoteUser) > 0) { + \MailSo\Base\Http::StatusHeader('200'); + } else { + \MailSo\Base\Http::StatusHeader('401'); + } + return true; + } + protected function configMapping() : array { return array( @@ -178,7 +202,13 @@ protected function configMapping() : array ->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT) ->SetDescription('IP or Subnet of proxy, auth header will only be accepted from this address') ->SetDefaultValue('10.1.0.0/24') - ->SetEncrypted() + ->SetEncrypted(), + \RainLoop\Plugins\Property::NewInstance('auto_login') + ->SetAllowedInJs(true) + ->SetLabel('Activate automatic login') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL) + ->SetDescription('Activates automatic login, if User Header is set (note: logout not possible)') + ->SetDefaultValue(true) ); } } diff --git a/plugins/proxy-auth/js/auto-login.js b/plugins/proxy-auth/js/auto-login.js new file mode 100644 index 0000000000..6d2c72b1c4 --- /dev/null +++ b/plugins/proxy-auth/js/auto-login.js @@ -0,0 +1,32 @@ +(rl => { + + rl && addEventListener('rl-view-model', e => { + const id = e.detail.viewModelTemplateID; + if (e.detail && ('Login' === id)) { + let + auto_login = window.rl.pluginSettingsGet('proxy-auth', 'auto_login'); + ; + + const + ForwardProxyAuth = () => { + if (auto_login) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", "/?UserHeaderSet", true); + + xhr.onreadystatechange = function () { + if (xhr.readyState == 4 && xhr.status == 200) { + window.location.href = "/?ProxyAuth"; + } + }; + + xhr.send(); + } + }; + + window.ForwardProxyAuth = ForwardProxyAuth; + + ForwardProxyAuth(); + } + }); +})(window.rl); + From 59c0f5cc946eafac89edc68f5929a59c4245473f Mon Sep 17 00:00:00 2001 From: Philipp Mundhenk Date: Sun, 21 Jan 2024 15:09:31 +0100 Subject: [PATCH 2/3] documented auto login, improved security documentation --- plugins/proxy-auth/README.md | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/plugins/proxy-auth/README.md b/plugins/proxy-auth/README.md index 0a4c5dc345..b3df52d249 100644 --- a/plugins/proxy-auth/README.md +++ b/plugins/proxy-auth/README.md @@ -12,7 +12,7 @@ The following example is for Traefik with Authelia and Dovecot as mailserver. The following steps are require in SnappyMail: -- To open SnappyMail through a reverse proxy server, make sure to enable the correct secfetch policies: ```mode=navigate,dest=document,site=cross-site,user=true``` in the admin panel -> Config -> Security -> secfetch_allow. +- To open SnappyMail through a reverse proxy server (with redirect of authentication system), make sure to enable the correct secfetch policies: ```mode=navigate,dest=document,site=cross-site,user=true;mode=navigate,dest=document,site=same-site,user=true``` in the admin panel -> Config -> Security -> secfetch_allow. - Activate plugin in admin panel -> Extensions - Configure the plugin with the required data: - Master User Separator is dependent on Dovecot config (see below) @@ -21,6 +21,7 @@ The following steps are require in SnappyMail: - Header Name is dependent on authentication solution. This is the header containing the name of currently logged in user. In case of Authelia, this is "Remote-User". - Check Proxy: Since this plugin partially bypasses authentication, it is important to only allow this access from well-defined hosts. It is highly recommended to activate this option! - When checking for reverse proxy, it is required to set the IP filter to either an IP address or a subnet. + - Automatic Login: Automatically logs in the user of user header is present (see below) This concludes the setup of SnappyMail. @@ -50,12 +51,16 @@ passdb { You then need to create a master user in /etc/dovecot/master-users: ``` -admin:PASSWORD +admin:PASSWORD::::::allow_nets=local,172.17.0.0/16 ``` where the encrypted password ```PASSWORD``` can be created from a cleartext password with ```doveadm pw -s CRYPT```. It should start with ```{CRYPT}```. Username and password need to configured in the SnappyMail ProxyAuth plugin (see above). +You likely also want to limit the access by an IP address filter, e.g., to ```local,172.17.0.0/16```, if you are running Postfix (```local```) and within a default Docker environment (```172.17.0.0/16```). +Otherwise, master user login (assuming password is known) is possible from every connectable system. +This is an unnecessary security risk. + Additionally, you need to set the master user separator in /etc/dovecot/conf.d/10-auth.conf, e.g., ```auth_master_user_separator = *```. The separator needs to be configured in the SnappyMail ProxyAuth plugin (see above). @@ -64,3 +69,12 @@ The separator needs to be configured in the SnappyMail ProxyAuth plugin (see abo Once configured correctly, you should be able to access SnappyMail through your reverse proxy at ```https://snappymail.tld/?ProxyAuth```. If your reverse proxy provides the username in the configured header (e.g., Remote-User), you will automatically be logged in to your account. If not, you will be redirected to the login page. + +## Automatic Login + +By default, automatic login is activated. +Behind the scenes, this checks for the existence of the configured user header (through ```/?UserHeaderSet```) and automatically redirects to ```https://snappymail.tld/?ProxyAuth```, trying to log in the user. +Note that due to this implementation, logout is impossible, as once logged out, the user will automatically be logged in again. +The user is always considered logged in, as authentication is handled through reverse proxy and authentication system. + +Auto login can be disabled in the plugin settings. From b947db2eb1530c4ad88cc04773cd2e6bc61e2c54 Mon Sep 17 00:00:00 2001 From: Philipp Mundhenk Date: Sun, 21 Jan 2024 15:31:32 +0100 Subject: [PATCH 3/3] added documentation for usage of custom_logout_link --- plugins/proxy-auth/README.md | 2 ++ plugins/proxy-auth/index.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/proxy-auth/README.md b/plugins/proxy-auth/README.md index b3df52d249..7a3004d702 100644 --- a/plugins/proxy-auth/README.md +++ b/plugins/proxy-auth/README.md @@ -78,3 +78,5 @@ Note that due to this implementation, logout is impossible, as once logged out, The user is always considered logged in, as authentication is handled through reverse proxy and authentication system. Auto login can be disabled in the plugin settings. +You can also change the logout link in admin panel -> Config -> custom_logout_link to the one of your authentication system, e.g., ```https://auth.yourdomain.com/logout```. +In this case, you can log out from your overall system via SnappyMail. diff --git a/plugins/proxy-auth/index.php b/plugins/proxy-auth/index.php index 8ba04c7bee..a69dd23de5 100644 --- a/plugins/proxy-auth/index.php +++ b/plugins/proxy-auth/index.php @@ -207,7 +207,7 @@ protected function configMapping() : array ->SetAllowedInJs(true) ->SetLabel('Activate automatic login') ->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL) - ->SetDescription('Activates automatic login, if User Header is set (note: logout not possible)') + ->SetDescription('Activates automatic login, if User Header is set (note: Use custom_logout_link to enable logout, see plugin README)') ->SetDefaultValue(true) ); }