| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 1 | <?php | 
 | 2 | require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/vars.inc.php'; | 
 | 3 | require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.inc.php'; | 
 | 4 | $default_autodiscover_config = $autodiscover_config; | 
 | 5 | if(file_exists('inc/vars.local.inc.php')) { | 
 | 6 |   include_once 'inc/vars.local.inc.php'; | 
 | 7 | } | 
 | 8 | $autodiscover_config = array_merge($default_autodiscover_config, $autodiscover_config); | 
 | 9 |  | 
 | 10 | // Redis | 
 | 11 | $redis = new Redis(); | 
 | 12 | try { | 
 | 13 |   if (!empty(getenv('REDIS_SLAVEOF_IP'))) { | 
 | 14 |     $redis->connect(getenv('REDIS_SLAVEOF_IP'), getenv('REDIS_SLAVEOF_PORT')); | 
 | 15 |   } | 
 | 16 |   else { | 
 | 17 |     $redis->connect('redis-mailcow', 6379); | 
 | 18 |   } | 
 | 19 | } | 
 | 20 | catch (Exception $e) { | 
 | 21 |   exit; | 
 | 22 | } | 
 | 23 |  | 
 | 24 | error_reporting(0); | 
 | 25 |  | 
 | 26 | $data = trim(file_get_contents("php://input")); | 
 | 27 |  | 
 | 28 | if (strpos($data, 'autodiscover/outlook/responseschema') !== false) { | 
 | 29 |   $autodiscover_config['autodiscoverType'] = 'imap'; | 
 | 30 |   if ($autodiscover_config['useEASforOutlook'] == 'yes' && | 
 | 31 |     // Office for macOS does not support EAS | 
 | 32 |     strpos($_SERVER['HTTP_USER_AGENT'], 'Mac') === false && | 
 | 33 |     // Outlook 2013 (version 15) or higher | 
 | 34 |     preg_match('/(Outlook|Office).+1[5-9]\./', $_SERVER['HTTP_USER_AGENT']) | 
 | 35 |   ) { | 
 | 36 |     $autodiscover_config['autodiscoverType'] = 'activesync'; | 
 | 37 |   } | 
 | 38 | } | 
 | 39 |  | 
 | 40 | if (getenv('SKIP_SOGO') == "y") { | 
 | 41 |   $autodiscover_config['autodiscoverType'] = 'imap'; | 
 | 42 | } | 
 | 43 |  | 
 | 44 | //$dsn = $database_type . ":host=" . $database_host . ";dbname=" . $database_name; | 
 | 45 | $dsn = $database_type . ":unix_socket=" . $database_sock . ";dbname=" . $database_name; | 
 | 46 | $opt = [ | 
 | 47 |   PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION, | 
 | 48 |   PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, | 
 | 49 |   PDO::ATTR_EMULATE_PREPARES   => false, | 
 | 50 | ]; | 
 | 51 | $pdo = new PDO($dsn, $database_user, $database_pass, $opt); | 
 | 52 | $login_user = strtolower(trim($_SERVER['PHP_AUTH_USER'])); | 
 | 53 | $login_pass = trim(htmlspecialchars_decode($_SERVER['PHP_AUTH_PW'])); | 
 | 54 |  | 
 | 55 | if (empty($_SERVER['PHP_AUTH_USER']) || empty($_SERVER['PHP_AUTH_PW'])) { | 
 | 56 |   $json = json_encode( | 
 | 57 |     array( | 
 | 58 |       "time" => time(), | 
 | 59 |       "ua" => $_SERVER['HTTP_USER_AGENT'], | 
 | 60 |       "user" => "none", | 
| Matthias Andreas Benkard | 12a5735 | 2021-12-28 18:02:04 +0100 | [diff] [blame] | 61 |       "ip" => $_SERVER['REMOTE_ADDR'], | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 62 |       "service" => "Error: must be authenticated" | 
 | 63 |     ) | 
 | 64 |   ); | 
 | 65 |   $redis->lPush('AUTODISCOVER_LOG', $json); | 
 | 66 |   header('WWW-Authenticate: Basic realm="' . $_SERVER['HTTP_HOST'] . '"'); | 
 | 67 |   header('HTTP/1.0 401 Unauthorized'); | 
 | 68 |   exit(0); | 
 | 69 | } | 
 | 70 |  | 
| Matthias Andreas Benkard | 1ba5381 | 2022-12-27 17:32:58 +0100 | [diff] [blame] | 71 | $login_role = check_login($login_user, $login_pass, array('eas' => TRUE)); | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 72 |  | 
 | 73 | if ($login_role === "user") { | 
 | 74 |   header("Content-Type: application/xml"); | 
 | 75 |   echo '<?xml version="1.0" encoding="utf-8" ?>' . PHP_EOL; | 
 | 76 | ?> | 
 | 77 | <Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006"> | 
 | 78 | <?php | 
 | 79 |   if(!$data) { | 
 | 80 |     try { | 
 | 81 |       $json = json_encode( | 
 | 82 |         array( | 
 | 83 |           "time" => time(), | 
 | 84 |           "ua" => $_SERVER['HTTP_USER_AGENT'], | 
 | 85 |           "user" => $_SERVER['PHP_AUTH_USER'], | 
| Matthias Andreas Benkard | 12a5735 | 2021-12-28 18:02:04 +0100 | [diff] [blame] | 86 |           "ip" => $_SERVER['REMOTE_ADDR'], | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 87 |           "service" => "Error: invalid or missing request data" | 
 | 88 |         ) | 
 | 89 |       ); | 
 | 90 |       $redis->lPush('AUTODISCOVER_LOG', $json); | 
 | 91 |       $redis->lTrim('AUTODISCOVER_LOG', 0, 100); | 
 | 92 |     } | 
 | 93 |     catch (RedisException $e) { | 
 | 94 |       $_SESSION['return'][] = array( | 
 | 95 |         'type' => 'danger', | 
 | 96 |         'msg' => 'Redis: '.$e | 
 | 97 |       ); | 
 | 98 |       return false; | 
 | 99 |     } | 
 | 100 |     list($usec, $sec) = explode(' ', microtime()); | 
 | 101 | ?> | 
 | 102 |   <Response> | 
 | 103 |     <Error Time="<?=date('H:i:s', $sec) . substr($usec, 0, strlen($usec) - 2);?>" Id="2477272013"> | 
 | 104 |       <ErrorCode>600</ErrorCode> | 
 | 105 |       <Message>Invalid Request</Message> | 
 | 106 |       <DebugData /> | 
 | 107 |     </Error> | 
 | 108 |   </Response> | 
 | 109 | </Autodiscover> | 
 | 110 | <?php | 
 | 111 |     exit(0); | 
 | 112 |   } | 
 | 113 |   try { | 
 | 114 |     $discover = new SimpleXMLElement($data); | 
 | 115 |     $email = $discover->Request->EMailAddress; | 
 | 116 |   } catch (Exception $e) { | 
 | 117 |     $email = $_SERVER['PHP_AUTH_USER']; | 
 | 118 |   } | 
 | 119 |  | 
 | 120 |   $username = trim($email); | 
 | 121 |   try { | 
 | 122 |     $stmt = $pdo->prepare("SELECT `name` FROM `mailbox` WHERE `username`= :username"); | 
 | 123 |     $stmt->execute(array(':username' => $username)); | 
 | 124 |     $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC); | 
 | 125 |   } | 
 | 126 |   catch(PDOException $e) { | 
 | 127 |     die("Failed to determine name from SQL"); | 
 | 128 |   } | 
 | 129 |   if (!empty($MailboxData['name'])) { | 
 | 130 |     $displayname = $MailboxData['name']; | 
 | 131 |   } | 
 | 132 |   else { | 
 | 133 |     $displayname = $email; | 
 | 134 |   } | 
 | 135 |   try { | 
 | 136 |     $json = json_encode( | 
 | 137 |       array( | 
 | 138 |         "time" => time(), | 
 | 139 |         "ua" => $_SERVER['HTTP_USER_AGENT'], | 
 | 140 |         "user" => $_SERVER['PHP_AUTH_USER'], | 
| Matthias Andreas Benkard | 12a5735 | 2021-12-28 18:02:04 +0100 | [diff] [blame] | 141 |         "ip" => $_SERVER['REMOTE_ADDR'], | 
| Matthias Andreas Benkard | b382b10 | 2021-01-02 15:32:21 +0100 | [diff] [blame] | 142 |         "service" => $autodiscover_config['autodiscoverType'] | 
 | 143 |       ) | 
 | 144 |     ); | 
 | 145 |     $redis->lPush('AUTODISCOVER_LOG', $json); | 
 | 146 |     $redis->lTrim('AUTODISCOVER_LOG', 0, 100); | 
 | 147 |   } | 
 | 148 |   catch (RedisException $e) { | 
 | 149 |     $_SESSION['return'][] = array( | 
 | 150 |       'type' => 'danger', | 
 | 151 |       'msg' => 'Redis: '.$e | 
 | 152 |     ); | 
 | 153 |     return false; | 
 | 154 |   } | 
 | 155 |   if ($autodiscover_config['autodiscoverType'] == 'imap') { | 
 | 156 | ?> | 
 | 157 |   <Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a"> | 
 | 158 |     <User> | 
 | 159 |       <DisplayName><?=htmlspecialchars($displayname, ENT_XML1 | ENT_QUOTES, 'UTF-8');?></DisplayName> | 
 | 160 |     </User> | 
 | 161 |     <Account> | 
 | 162 |       <AccountType>email</AccountType> | 
 | 163 |       <Action>settings</Action> | 
 | 164 |       <Protocol> | 
 | 165 |         <Type>IMAP</Type> | 
 | 166 |         <Server><?=$autodiscover_config['imap']['server'];?></Server> | 
 | 167 |         <Port><?=$autodiscover_config['imap']['port'];?></Port> | 
 | 168 |         <DomainRequired>off</DomainRequired> | 
 | 169 |         <LoginName><?=$email;?></LoginName> | 
 | 170 |         <SPA>off</SPA> | 
 | 171 |         <SSL>on</SSL> | 
 | 172 |         <AuthRequired>on</AuthRequired> | 
 | 173 |       </Protocol> | 
 | 174 |       <Protocol> | 
 | 175 |         <Type>SMTP</Type> | 
 | 176 |         <Server><?=$autodiscover_config['smtp']['server'];?></Server> | 
 | 177 |         <Port><?=$autodiscover_config['smtp']['port'];?></Port> | 
 | 178 |         <DomainRequired>off</DomainRequired> | 
 | 179 |         <LoginName><?=$email;?></LoginName> | 
 | 180 |         <SPA>off</SPA> | 
 | 181 |         <SSL>on</SSL> | 
 | 182 |         <AuthRequired>on</AuthRequired> | 
 | 183 |         <UsePOPAuth>on</UsePOPAuth> | 
 | 184 |         <SMTPLast>off</SMTPLast> | 
 | 185 |       </Protocol> | 
 | 186 |     <?php | 
 | 187 |     if (getenv('SKIP_SOGO') != "y") { | 
 | 188 |     ?> | 
 | 189 |       <Protocol> | 
 | 190 |         <Type>CalDAV</Type> | 
 | 191 |         <Server>https://<?=$autodiscover_config['caldav']['server'];?><?php if ($autodiscover_config['caldav']['port'] != 443) echo ':'.$autodiscover_config['caldav']['port']; ?>/SOGo/dav/<?=$email;?>/</Server> | 
 | 192 |         <DomainRequired>off</DomainRequired> | 
 | 193 |         <LoginName><?=$email;?></LoginName> | 
 | 194 |       </Protocol> | 
 | 195 |       <Protocol> | 
 | 196 |         <Type>CardDAV</Type> | 
 | 197 |         <Server>https://<?=$autodiscover_config['carddav']['server'];?><?php if ($autodiscover_config['caldav']['port'] != 443) echo ':'.$autodiscover_config['carddav']['port']; ?>/SOGo/dav/<?=$email;?>/</Server> | 
 | 198 |         <DomainRequired>off</DomainRequired> | 
 | 199 |         <LoginName><?=$email;?></LoginName> | 
 | 200 |       </Protocol> | 
 | 201 |     <?php | 
 | 202 |     } | 
 | 203 |     ?> | 
 | 204 |     </Account> | 
 | 205 |   </Response> | 
 | 206 | <?php | 
 | 207 |   } | 
 | 208 |   else if ($autodiscover_config['autodiscoverType'] == 'activesync') { | 
 | 209 | ?> | 
 | 210 |   <Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/mobilesync/responseschema/2006"> | 
 | 211 |     <Culture>en:en</Culture> | 
 | 212 |     <User> | 
 | 213 |       <DisplayName><?=htmlspecialchars($displayname, ENT_XML1 | ENT_QUOTES, 'UTF-8');?></DisplayName> | 
 | 214 |       <EMailAddress><?=$email;?></EMailAddress> | 
 | 215 |     </User> | 
 | 216 |     <Action> | 
 | 217 |       <Settings> | 
 | 218 |         <Server> | 
 | 219 |         <Type>MobileSync</Type> | 
 | 220 |         <Url><?=$autodiscover_config['activesync']['url'];?></Url> | 
 | 221 |         <Name><?=$autodiscover_config['activesync']['url'];?></Name> | 
 | 222 |         </Server> | 
 | 223 |       </Settings> | 
 | 224 |     </Action> | 
 | 225 |   </Response> | 
 | 226 | <?php | 
 | 227 |   } | 
 | 228 | ?> | 
 | 229 | </Autodiscover> | 
 | 230 | <?php | 
 | 231 | } | 
 | 232 | ?> |