From a110378000168848f97947a5d88f7ed9db7373be Mon Sep 17 00:00:00 2001 From: Marcel Hofer Date: Wed, 27 Feb 2019 23:06:19 +0100 Subject: [PATCH 1/3] always check basic auth against user database for EAS and SOGo if ALLOW_ADMIN_EMAIL_LOGIN is enabled --- data/conf/nginx/site.conf | 41 +++++++++++++-------------------------- data/web/sogo-auth.php | 30 +++++++++++++++++++++++++--- docker-compose.yml | 5 ++--- 3 files changed, 43 insertions(+), 33 deletions(-) diff --git a/data/conf/nginx/site.conf b/data/conf/nginx/site.conf index a5dc0222..4c6d1daa 100644 --- a/data/conf/nginx/site.conf +++ b/data/conf/nginx/site.conf @@ -142,7 +142,19 @@ server { try_files /autoconfig.php =404; } + # auth_request endpoint if ALLOW_ADMIN_EMAIL_LOGIN is set + location /sogo-auth-verify { + internal; + proxy_set_header X-Original-URI $request_uri; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $http_host; + proxy_set_header Content-Length ""; + proxy_pass http://127.0.0.1:80/sogo-auth; + proxy_pass_request_body off; + } + location ^~ /Microsoft-Server-ActiveSync { + include /etc/nginx/conf.d/sogo_proxy_auth.active; include /etc/nginx/conf.d/sogo_eas.active; proxy_connect_timeout 4000; proxy_next_upstream timeout error; @@ -164,34 +176,9 @@ server { client_max_body_size 0; } - # auth_request endpoint if ALLOW_ADMIN_EMAIL_LOGIN is set - location /sogo-auth-verify { - internal; - proxy_set_header X-Original-URI $request_uri; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header Host $http_host; - proxy_set_header Content-Length ""; - proxy_pass http://127.0.0.1:80/sogo-auth; - proxy_pass_request_body off; - } - location ^~ /SOGo { - include /etc/nginx/conf.d/sogo_main.active; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - proxy_set_header Host $http_host; - proxy_set_header x-webobjects-server-protocol HTTP/1.0; - proxy_set_header x-webobjects-remote-host $remote_addr; - proxy_set_header x-webobjects-server-name $server_name; - proxy_set_header x-webobjects-server-url $client_req_scheme://$http_host; - proxy_set_header x-webobjects-server-port $server_port; - client_body_buffer_size 128k; - client_max_body_size 0; - break; - } - - location ^~ /SOGo/dav { - include /etc/nginx/conf.d/sogo_dav.active; + include /etc/nginx/conf.d/sogo_proxy_auth.active; + include /etc/nginx/conf.d/sogo.active; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; diff --git a/data/web/sogo-auth.php b/data/web/sogo-auth.php index b08ca4e7..ae882f26 100644 --- a/data/web/sogo-auth.php +++ b/data/web/sogo-auth.php @@ -8,11 +8,31 @@ $ALLOW_ADMIN_EMAIL_LOGIN = (preg_match( $session_var_user = 'sogo-sso-user'; $session_var_pass = 'sogo-sso-pass'; +// prevent if feature is disabled if (!$ALLOW_ADMIN_EMAIL_LOGIN) { - header('HTTP/1.0 401 Forbidden'); + header('HTTP/1.0 403 Forbidden'); echo "this feature is disabled"; exit; } +// validate credentials for basic auth requests +elseif (isset($_SERVER['PHP_AUTH_USER'])) { + // load prerequisites only when required + require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php'; + $username = $_SERVER['PHP_AUTH_USER']; + $password = $_SERVER['PHP_AUTH_PW']; + $login_check = check_login($username, $password); + if ($login_check === 'user') { + header("X-User: $username"); + header("X-Auth: Basic ".base64_encode("$username:$password")); + header("X-Auth-Type: Basic"); + exit; + } else { + header('HTTP/1.0 401 Unauthorized'); + echo 'Invalid login'; + exit; + } +} +// check permissions and redirect for direct GET ?login=xy requests elseif (isset($_GET['login'])) { // load prerequisites only when required require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php'; @@ -32,10 +52,14 @@ elseif (isset($_GET['login'])) { } } } - header('HTTP/1.0 401 Forbidden'); + header('HTTP/1.0 403 Forbidden'); exit; } -else { +// do not check for admin-login / sogo-sso for EAS and DAV requests, SOGo can check auth itself if no authorization header is set +elseif ( + substr($_SERVER['HTTP_X_ORIGINAL_URI'], 0, 28) !== "/Microsoft-Server-ActiveSync" && + substr($_SERVER['HTTP_X_ORIGINAL_URI'], 0, 9) !== "/SOGo/dav" +) { // this is an nginx auth_request call, we check for existing sogo-sso session variables session_start(); if (isset($_SESSION[$session_var_user]) && filter_var($_SESSION[$session_var_user], FILTER_VALIDATE_EMAIL)) { diff --git a/docker-compose.yml b/docker-compose.yml index 724c5c6b..efee7ade 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -268,10 +268,9 @@ services: command: /bin/sh -c "envsubst < /etc/nginx/conf.d/templates/listen_plain.template > /etc/nginx/conf.d/listen_plain.active && envsubst < /etc/nginx/conf.d/templates/listen_ssl.template > /etc/nginx/conf.d/listen_ssl.active && envsubst < /etc/nginx/conf.d/templates/server_name.template > /etc/nginx/conf.d/server_name.active && - . /etc/nginx/conf.d/templates/sogo.auth_request.template.sh > /etc/nginx/conf.d/sogo_main.active && - envsubst < /etc/nginx/conf.d/templates/sogo.template >> /etc/nginx/conf.d/sogo_main.active && - envsubst < /etc/nginx/conf.d/templates/sogo.template >> /etc/nginx/conf.d/sogo_dav.active && + envsubst < /etc/nginx/conf.d/templates/sogo.template > /etc/nginx/conf.d/sogo.active && envsubst < /etc/nginx/conf.d/templates/sogo_eas.template > /etc/nginx/conf.d/sogo_eas.active && + . /etc/nginx/conf.d/templates/sogo.auth_request.template.sh > /etc/nginx/conf.d/sogo_proxy_auth.active && nginx -qt && until ping phpfpm -c1 > /dev/null; do sleep 1; done && until ping sogo -c1 > /dev/null; do sleep 1; done && From fa80d66d6c855e75de14b298103828a0a9a5d469 Mon Sep 17 00:00:00 2001 From: Marcel Hofer Date: Wed, 27 Feb 2019 23:14:30 +0100 Subject: [PATCH 2/3] match EAS and SOGO/dav case insensitive --- data/web/sogo-auth.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/web/sogo-auth.php b/data/web/sogo-auth.php index ae882f26..37e6f75f 100644 --- a/data/web/sogo-auth.php +++ b/data/web/sogo-auth.php @@ -57,8 +57,8 @@ elseif (isset($_GET['login'])) { } // do not check for admin-login / sogo-sso for EAS and DAV requests, SOGo can check auth itself if no authorization header is set elseif ( - substr($_SERVER['HTTP_X_ORIGINAL_URI'], 0, 28) !== "/Microsoft-Server-ActiveSync" && - substr($_SERVER['HTTP_X_ORIGINAL_URI'], 0, 9) !== "/SOGo/dav" + strcasecmp(substr($_SERVER['HTTP_X_ORIGINAL_URI'], 0, 28), "/Microsoft-Server-ActiveSync") == 0 && + strcasecmp(substr($_SERVER['HTTP_X_ORIGINAL_URI'], 0, 9), "/SOGo/dav") == 0 ) { // this is an nginx auth_request call, we check for existing sogo-sso session variables session_start(); From 965577c5d820975d1c24cb11ab7b85f9d9f73c99 Mon Sep 17 00:00:00 2001 From: Marcel Hofer Date: Wed, 27 Feb 2019 23:16:23 +0100 Subject: [PATCH 3/3] fix path check --- data/web/sogo-auth.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/web/sogo-auth.php b/data/web/sogo-auth.php index 37e6f75f..0cc4beee 100644 --- a/data/web/sogo-auth.php +++ b/data/web/sogo-auth.php @@ -57,8 +57,8 @@ elseif (isset($_GET['login'])) { } // do not check for admin-login / sogo-sso for EAS and DAV requests, SOGo can check auth itself if no authorization header is set elseif ( - strcasecmp(substr($_SERVER['HTTP_X_ORIGINAL_URI'], 0, 28), "/Microsoft-Server-ActiveSync") == 0 && - strcasecmp(substr($_SERVER['HTTP_X_ORIGINAL_URI'], 0, 9), "/SOGo/dav") == 0 + strcasecmp(substr($_SERVER['HTTP_X_ORIGINAL_URI'], 0, 28), "/Microsoft-Server-ActiveSync") !== 0 && + strcasecmp(substr($_SERVER['HTTP_X_ORIGINAL_URI'], 0, 9), "/SOGo/dav") !== 0 ) { // this is an nginx auth_request call, we check for existing sogo-sso session variables session_start();