blob: 40fff58563f008e335bfb27d1f9825783ffb49c2 [file] [log] [blame]
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +01001<?php
2
3$ALLOW_ADMIN_EMAIL_LOGIN = (preg_match(
4 "/^([yY][eE][sS]|[yY])+$/",
5 $_ENV["ALLOW_ADMIN_EMAIL_LOGIN"]
6));
7
8$session_var_user_allowed = 'sogo-sso-user-allowed';
9$session_var_pass = 'sogo-sso-pass';
10
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010011// validate credentials for basic auth requests
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020012if (isset($_SERVER['PHP_AUTH_USER'])) {
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010013 // load prerequisites only when required
14 require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
15 $username = $_SERVER['PHP_AUTH_USER'];
16 $password = $_SERVER['PHP_AUTH_PW'];
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010017 $is_eas = false;
18 $is_dav = false;
19 $original_uri = isset($_SERVER['HTTP_X_ORIGINAL_URI']) ? $_SERVER['HTTP_X_ORIGINAL_URI'] : '';
20 if (preg_match('/^(\/SOGo|)\/dav.*/', $original_uri) === 1) {
21 $is_dav = true;
22 }
23 elseif (preg_match('/^(\/SOGo|)\/Microsoft-Server-ActiveSync.*/', $original_uri) === 1) {
24 $is_eas = true;
25 }
26 $login_check = check_login($username, $password, array('dav' => $is_dav, 'eas' => $is_eas));
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010027 if ($login_check === 'user') {
28 header("X-User: $username");
29 header("X-Auth: Basic ".base64_encode("$username:$password"));
30 header("X-Auth-Type: Basic");
31 exit;
32 } else {
33 header('HTTP/1.0 401 Unauthorized');
34 echo 'Invalid login';
35 exit;
36 }
37}
38// check permissions and redirect for direct GET ?login=xy requests
39elseif (isset($_GET['login'])) {
40 // load prerequisites only when required
41 require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php';
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020042 // check if dual_login is active
43 $is_dual = (!empty($_SESSION["dual-login"]["username"])) ? true : false;
44 // check permissions (if dual_login is active, deny sso when acl is not given)
45 $login = html_entity_decode(rawurldecode($_GET["login"]));
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020046 if (isset($_SESSION['mailcow_cc_role']) &&
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010047 (($_SESSION['acl']['login_as'] == "1" && $ALLOW_ADMIN_EMAIL_LOGIN !== 0) || ($is_dual === false && $login == $_SESSION['mailcow_cc_username']))) {
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010048 if (filter_var($login, FILTER_VALIDATE_EMAIL)) {
Matthias Andreas Benkard7b2a3a12021-08-16 10:57:25 +020049 if (user_get_alias_details($login) !== false) {
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010050 // load master password
51 $sogo_sso_pass = file_get_contents("/etc/sogo-sso/sogo-sso.pass");
52 // register username and password in session
53 $_SESSION[$session_var_user_allowed][] = $login;
54 $_SESSION[$session_var_pass] = $sogo_sso_pass;
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010055 // update sasl logs
56 $service = ($app_passwd_data['eas'] === true) ? 'EAS' : 'DAV';
57 $stmt = $pdo->prepare("REPLACE INTO sasl_log (`service`, `app_password`, `username`, `real_rip`) VALUES ('SSO', 0, :username, :remote_addr)");
58 $stmt->execute(array(
59 ':username' => $login,
60 ':remote_addr' => ($_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR'])
61 ));
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010062 // redirect to sogo (sogo will get the correct credentials via nginx auth_request
Matthias Andreas Benkardd1f5b682023-11-18 13:18:30 +010063 header("Location: /SOGo/so/{$login}");
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010064 exit;
65 }
66 }
67 }
68 header('HTTP/1.0 403 Forbidden');
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010069 echo "Forbidden";
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010070 exit;
71}
72// only check for admin-login on sogo GUI requests
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010073elseif (isset($_SERVER['HTTP_X_ORIGINAL_URI']) && strcasecmp(substr($_SERVER['HTTP_X_ORIGINAL_URI'], 0, 9), "/SOGo/so/") === 0) {
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010074 // this is an nginx auth_request call, we check for existing sogo-sso session variables
75 session_start();
76 // extract email address from "/SOGo/so/user@domain/xy"
77 $url_parts = explode("/", $_SERVER['HTTP_X_ORIGINAL_URI']);
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010078 $email_list = array(
79 $url_parts[3], // Requested mailbox
80 ($_SESSION['mailcow_cc_username'] ?? ''), // Current user
81 ($_SESSION["dual-login"]["username"] ?? ''), // Dual login user
82 );
83 foreach($email_list as $email) {
84 // check if this email is in session allowed list
85 if (
86 !empty($email) &&
87 filter_var($email, FILTER_VALIDATE_EMAIL) &&
88 is_array($_SESSION[$session_var_user_allowed]) &&
89 in_array($email, $_SESSION[$session_var_user_allowed])
90 ) {
91 $username = $email;
92 $password = $_SESSION[$session_var_pass];
93 header("X-User: $username");
94 header("X-Auth: Basic ".base64_encode("$username:$password"));
95 header("X-Auth-Type: Basic");
96 exit;
97 }
Matthias Andreas Benkardb382b102021-01-02 15:32:21 +010098 }
99}
100
101// if username is empty, SOGo will use the normal login methods / login form
102header("X-User: ");
103header("X-Auth: ");
104header("X-Auth-Type: ");