| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 1 | <?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 Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 11 | // validate credentials for basic auth requests | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 12 | if (isset($_SERVER['PHP_AUTH_USER'])) { | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 13 |   // 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 Benkard | 12a5735 | 2021-12-28 18:02:04 +0100 | [diff] [blame] | 17 |   $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 Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 27 |   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 | 
 | 39 | elseif (isset($_GET['login'])) { | 
 | 40 |   // load prerequisites only when required | 
 | 41 |   require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/prerequisites.inc.php'; | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 42 |   // 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 Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 46 |   if (isset($_SESSION['mailcow_cc_role']) && | 
| Matthias Andreas Benkard | 12a5735 | 2021-12-28 18:02:04 +0100 | [diff] [blame] | 47 |     (($_SESSION['acl']['login_as'] == "1" && $ALLOW_ADMIN_EMAIL_LOGIN !== 0) || ($is_dual === false && $login == $_SESSION['mailcow_cc_username']))) { | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 48 |     if (filter_var($login, FILTER_VALIDATE_EMAIL)) { | 
| Matthias Andreas Benkard | 7b2a3a1 | 2021-08-16 10:57:25 +0200 | [diff] [blame] | 49 |       if (user_get_alias_details($login) !== false) { | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 50 |         // 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 Benkard | 12a5735 | 2021-12-28 18:02:04 +0100 | [diff] [blame] | 55 |         // 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 Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 62 |         // redirect to sogo (sogo will get the correct credentials via nginx auth_request | 
 | 63 |         header("Location: /SOGo/so/${login}"); | 
 | 64 |         exit; | 
 | 65 |       } | 
 | 66 |     } | 
 | 67 |   } | 
 | 68 |   header('HTTP/1.0 403 Forbidden'); | 
| Matthias Andreas Benkard | 12a5735 | 2021-12-28 18:02:04 +0100 | [diff] [blame] | 69 |   echo "Forbidden"; | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 70 |   exit; | 
 | 71 | } | 
 | 72 | // only check for admin-login on sogo GUI requests | 
| Matthias Andreas Benkard | 12a5735 | 2021-12-28 18:02:04 +0100 | [diff] [blame] | 73 | elseif (isset($_SERVER['HTTP_X_ORIGINAL_URI']) && strcasecmp(substr($_SERVER['HTTP_X_ORIGINAL_URI'], 0, 9), "/SOGo/so/") === 0) { | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 74 |   // 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 Benkard | 1ba5381 | 2022-12-27 17:32:58 +0100 | [diff] [blame] | 78 |   $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 Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 98 |   } | 
 | 99 | } | 
 | 100 |  | 
 | 101 | // if username is empty, SOGo will use the normal login methods / login form | 
 | 102 | header("X-User: "); | 
 | 103 | header("X-Auth: "); | 
 | 104 | header("X-Auth-Type: "); |