diff --git a/data/web/autodiscover.php b/data/web/autodiscover.php index c18edbfc..265d138e 100644 --- a/data/web/autodiscover.php +++ b/data/web/autodiscover.php @@ -67,7 +67,8 @@ if (empty($_SERVER['PHP_AUTH_USER']) || empty($_SERVER['PHP_AUTH_PW'])) { exit(0); } -$login_role = check_login($login_user, $login_pass); +$allow_app_passwords = $ALLOW_APP_PASSWORDS_IN_EAS === true || $autodiscover_config['autodiscoverType'] == 'imap'; +$login_role = check_login($login_user, $login_pass, $allow_app_passwords); if ($login_role === "user") { header("Content-Type: application/xml"); diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index 072bf0b4..8245c46e 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -807,7 +807,7 @@ function verify_hash($hash, $password) { } return false; } -function check_login($user, $pass) { +function check_login($user, $pass, $allow_app_passwords = false) { global $pdo; global $redis; global $imap_server; @@ -896,6 +896,18 @@ function check_login($user, $pass) { AND `username` = :user"); $stmt->execute(array(':user' => $user)); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); + if ($allow_app_passwords === true) { + $stmt = $pdo->prepare("SELECT `app_passwd`.`password` as `password`, `app_passwd`.`id` as `app_passwd_id` FROM `app_passwd` + INNER JOIN `mailbox` ON `mailbox`.`username` = `app_passwd`.`mailbox` + INNER JOIN `domain` ON `mailbox`.`domain` = `domain`.`domain` + WHERE `mailbox`.`kind` NOT REGEXP 'location|thing|group' + AND `mailbox`.`active` = '1' + AND `domain`.`active` = '1' + AND `app_passwd`.`active` = '1' + AND `app_passwd`.`mailbox` = :user"); + $stmt->execute(array(':user' => $user)); + $rows = array_merge($rows, $stmt->fetchAll(PDO::FETCH_ASSOC)); + } foreach ($rows as $row) { if (verify_hash($row['password'], $pass) !== false) { unset($_SESSION['ldelay']); diff --git a/data/web/inc/vars.inc.php b/data/web/inc/vars.inc.php index 91d2145d..8a83f964 100644 --- a/data/web/inc/vars.inc.php +++ b/data/web/inc/vars.inc.php @@ -188,6 +188,9 @@ $MAILBOX_DEFAULT_ATTRIBUTES['mailbox_format'] = 'maildir:'; // Show last IMAP and POP3 logins $SHOW_LAST_LOGIN = true; +// Allow app passwords in CardDav, CalDav and ActiveSync +$ALLOW_APP_PASSWORDS_IN_EAS = true; + // UV flag handling in FIDO2/WebAuthn - defaults to false to allow iOS logins // true = required // false = preferred diff --git a/data/web/sogo-auth.php b/data/web/sogo-auth.php index 3bd19c6e..e3557cc8 100644 --- a/data/web/sogo-auth.php +++ b/data/web/sogo-auth.php @@ -14,7 +14,8 @@ if (isset($_SERVER['PHP_AUTH_USER'])) { 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); + $is_eas = preg_match('/^(\/SOGo|)\/(dav|Microsoft-Server-ActiveSync).*/', $_SERVER['HTTP_X_ORIGINAL_URI']); + $login_check = check_login($username, $password, $is_eas && $ALLOW_APP_PASSWORDS_IN_EAS); if ($login_check === 'user') { header("X-User: $username"); header("X-Auth: Basic ".base64_encode("$username:$password"));