You've already forked Mailu
mirror of
https://github.com/Mailu/Mailu.git
synced 2025-11-23 22:04:47 +02:00
Merge #1754
1754: centralize Webmail authentication behind the admin panel (SSO) r=mergify[bot] a=nextgens ## What type of PR? Enhancement: it centralizes the authentication of webmails to the admin interface. ## What does this PR do? It implements the glue required for webmails to do SSO using the admin interface. One of the main advantages of centralizing things this way is that it reduces significantly the attack surface available to an unauthenticated attacker (no webmail access until there is a valid Flask session). Others include the ability to implement 2FA down the line and rate-limit things as required. ### Related issue(s) - #783 ## Prerequistes Before we can consider review and merge, please make sure the following list is done and checked. If an entry in not applicable, you can check it or remove it from the list. - [x] In case of feature or enhancement: documentation updated accordingly - [x] Unless it's docs or a minor change: add [changelog](https://mailu.io/master/contributors/guide.html#changelog) entry file. Co-authored-by: Florent Daigniere <nextgens@freenetproject.org>
This commit is contained in:
@@ -35,6 +35,7 @@ RUN apt-get update && apt-get install -y \
|
||||
&& rm -rf /var/lib/apt/lists
|
||||
|
||||
COPY include.php /var/www/html/include.php
|
||||
COPY sso.php /var/www/html/sso.php
|
||||
COPY php.ini /php.ini
|
||||
|
||||
COPY application.ini /application.ini
|
||||
|
||||
@@ -8,6 +8,10 @@ allow_admin_panel = Off
|
||||
|
||||
[labs]
|
||||
allow_gravatar = Off
|
||||
{% if ADMIN == "true" %}
|
||||
custom_login_link='sso.php'
|
||||
custom_logout_link='{{ WEB_ADMIN }}/ui/logout'
|
||||
{% endif %}
|
||||
|
||||
[contacts]
|
||||
enable = On
|
||||
|
||||
31
webmails/rainloop/sso.php
Normal file
31
webmails/rainloop/sso.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
$_ENV['RAINLOOP_INCLUDE_AS_API'] = true;
|
||||
if (!defined('APP_VERSION')) {
|
||||
$version = file_get_contents('/data/VERSION');
|
||||
if ($version) {
|
||||
define('APP_VERSION', $version);
|
||||
define('APP_INDEX_ROOT_FILE', __FILE__);
|
||||
define('APP_INDEX_ROOT_PATH', str_replace('\\', '/', rtrim(dirname(__FILE__), '\\/').'/'));
|
||||
}
|
||||
}
|
||||
|
||||
if (file_exists(APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/include.php')) {
|
||||
include APP_INDEX_ROOT_PATH.'rainloop/v/'.APP_VERSION.'/include.php';
|
||||
} else {
|
||||
echo '[105] Missing version directory';
|
||||
exit(105);
|
||||
}
|
||||
|
||||
// Retrieve email and password
|
||||
if (in_array('HTTP_X_REMOTE_USER', $_SERVER) && in_array('HTTP_X_REMOTE_USER_TOKEN', $_SERVER)) {
|
||||
$email = $_SERVER['HTTP_X_REMOTE_USER'];
|
||||
$password = $_SERVER['HTTP_X_REMOTE_USER_TOKEN'];
|
||||
$ssoHash = \RainLoop\Api::GetUserSsoHash($email, $password);
|
||||
|
||||
// redirect to webmail sso url
|
||||
header('Location: index.php?sso&hash='.$ssoHash);
|
||||
}
|
||||
else {
|
||||
header('HTTP/1.0 403 Forbidden');
|
||||
}
|
||||
@@ -24,6 +24,7 @@ conf.jinja("/application.ini", os.environ, "/data/_data_/_default_/configs/appli
|
||||
conf.jinja("/php.ini", os.environ, "/usr/local/etc/php/conf.d/rainloop.ini")
|
||||
|
||||
os.system("chown -R www-data:www-data /data")
|
||||
os.system("chmod -R a+rX /var/www/html/")
|
||||
|
||||
os.execv("/usr/local/bin/apache2-foreground", ["apache2-foreground"])
|
||||
|
||||
|
||||
@@ -46,6 +46,7 @@ RUN apt-get update && apt-get install -y \
|
||||
|
||||
COPY php.ini /php.ini
|
||||
COPY config.inc.php /var/www/html/config/
|
||||
COPY mailu.php /var/www/html/plugins/mailu/mailu.php
|
||||
COPY start.py /start.py
|
||||
|
||||
EXPOSE 80/tcp
|
||||
|
||||
@@ -36,7 +36,11 @@ $config['managesieve_host'] = $imap;
|
||||
$config['managesieve_usetls'] = false;
|
||||
|
||||
// Customization settings
|
||||
$config['support_url'] = getenv('WEB_ADMIN') ? '../..' . getenv('WEB_ADMIN') : '';
|
||||
if (filter_var(getenv('ADMIN'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) {
|
||||
array_push($config['plugins'], 'mailu');
|
||||
$config['support_url'] = getenv('WEB_ADMIN') ? '../..' . getenv('WEB_ADMIN') : '';
|
||||
$config['sso_logout_url'] = getenv('WEB_ADMIN').'/ui/logout';
|
||||
}
|
||||
$config['product_name'] = 'Mailu Webmail';
|
||||
|
||||
// We access the IMAP and SMTP servers locally with internal names, SSL
|
||||
|
||||
59
webmails/roundcube/mailu.php
Normal file
59
webmails/roundcube/mailu.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
class mailu extends rcube_plugin
|
||||
{
|
||||
|
||||
function init()
|
||||
{
|
||||
$this->add_hook('startup', array($this, 'startup'));
|
||||
$this->add_hook('authenticate', array($this, 'authenticate'));
|
||||
$this->add_hook('login_after', array($this, 'login'));
|
||||
$this->add_hook('login_failed', array($this, 'login_failed'));
|
||||
$this->add_hook('logout_after', array($this, 'logout'));
|
||||
}
|
||||
|
||||
function startup($args)
|
||||
{
|
||||
if (empty($_SESSION['user_id'])) {
|
||||
$args['action'] = 'login';
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
function authenticate($args)
|
||||
{
|
||||
if (!in_array('HTTP_X_REMOTE_USER', $_SERVER) || !in_array('HTTP_X_REMOTE_USER_TOKEN', $_SERVER)) {
|
||||
header('HTTP/1.0 403 Forbidden');
|
||||
die();
|
||||
}
|
||||
$args['user'] = $_SERVER['HTTP_X_REMOTE_USER'];
|
||||
$args['pass'] = $_SERVER['HTTP_X_REMOTE_USER_TOKEN'];
|
||||
|
||||
$args['cookiecheck'] = false;
|
||||
$args['valid'] = true;
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
function logout($args) {
|
||||
// Redirect to global SSO logout path.
|
||||
$this->load_config();
|
||||
|
||||
$sso_logout_url = rcmail::get_instance()->config->get('sso_logout_url');
|
||||
header("Location: " . $sso_logout_url, true);
|
||||
exit;
|
||||
}
|
||||
|
||||
function login($args)
|
||||
{
|
||||
header('Location: index.php');
|
||||
exit();
|
||||
}
|
||||
function login_failed($args)
|
||||
{
|
||||
header('Location: sso.php');
|
||||
exit();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,6 +37,8 @@ conf.jinja("/php.ini", os.environ, "/usr/local/etc/php/conf.d/roundcube.ini")
|
||||
os.system("mkdir -p /data/gpg /var/www/html/logs")
|
||||
os.system("touch /var/www/html/logs/errors.log")
|
||||
os.system("chown -R www-data:www-data /var/www/html/logs")
|
||||
os.system("chmod -R a+rX /var/www/html/")
|
||||
os.system("ln -sf /var/www/html/index.php /var/www/html/sso.php")
|
||||
|
||||
try:
|
||||
print("Initializing database")
|
||||
|
||||
Reference in New Issue
Block a user