diff --git a/lib/AutodiscoverJson.php b/lib/AutodiscoverJson.php --- a/lib/AutodiscoverJson.php +++ b/lib/AutodiscoverJson.php @@ -29,13 +29,49 @@ class AutodiscoverJson extends Autodiscover { + /** + * process incoming request + */ public function handle_request() { + Log::debug('Request [json]: ' . $_SERVER['REQUEST_URI']); + + // check protocol (at this state we don't know if autodiscover is configured) + $allowedProtocols = ['activesync','autodiscoverv1']; + if (empty($_GET['Protocol'])) { + $this->error( + "A valid value must be provided for the query parameter 'Protocol'", + 'MandatoryParameterMissing' + ); + } + elseif (!in_array(strtolower($_GET['Protocol']), $allowedProtocols)) { + $this->error( + sprintf( + "The given protocol value '%s' is invalid. Supported values are '%s'", + $_GET['Protocol'], + implode(",", $allowedProtocols) + ), + 'InvalidProtocol' + ); + } + + // check email if (preg_match('|autodiscover.json/v1.0/([^\?]+)|', $_SERVER['REQUEST_URI'], $regs)) { $this->email = $regs[1]; } + elseif (!empty($_GET['Email'])) { + $this->email = $_GET['Email']; + } + elseif (!empty($_GET['email'])) { + $this->email = $_GET['email']; + } - Log::debug('Request [json]: ' . $_SERVER['REQUEST_URI']); + if (empty($this->email) || !strpos($this->email, '@')) { + $this->error( + 'A valid smtp address must be provided', + 'MandatoryParameterMissing' + ); + } } /** @@ -43,9 +79,18 @@ */ protected function handle_response() { - if (strtolower($_GET['Protocol']) == 'activesync' - && !empty($this->config['activesync']) - ) { + if (strtolower($_GET['Protocol']) == 'activesync') { + // throw error if activesync is disable + if (empty($this->config['activesync'])) { + $this->error( + sprintf( + "The given protocol value '%s' is invalid. Supported values are '%s'", + $_GET['Protocol'], 'autodiscoverv1' + ), + 'InvalidProtocol' + ); + } + if (!preg_match('/^https?:/i', $this->config['activesync'])) { $this->config['activesync'] = 'https://' . $this->config['activesync'] . '/Microsoft-Server-ActiveSync'; } @@ -56,27 +101,34 @@ } elseif (strtolower($_GET['Protocol']) == 'autodiscoverv1') { $json = array( - 'Protocol' => 'ActiveSync', + 'Protocol' => 'AutodiscoverV1', 'Url' => 'https://' . $_SERVER['HTTP_HOST'] . '/Autodiscover/Autodiscover.xml' ); } - else { - http_response_code(400); - $json = array( - 'ErrorCore' => 'InvalidProtocol', - 'ErrorMessage' => 'The given protocol value \u0027' - . $_GET['Protocol'] - . '\u0027 is invalid. Supported values are \u0027' - . (!empty($this->config['activesync']) ? 'ActiveSync,' : '') - . 'AutodiscoverV1\u0027' - ); - } - $response = json_encode($json, JSON_PRETTY_PRINT); + $response = json_encode($json, JSON_PRETTY_PRINT | JSON_HEX_APOS | JSON_HEX_QUOT); Log::debug('Response [json]: ' . $response); header('Content-Type: application/json; charset=' . Autodiscover::CHARSET); echo $response; exit; } + + /** + * Send error to the client and exit + */ + protected function error($msg, $code="InternalServerError") + { + http_response_code(400); + $json = array( + 'ErrorCode' => $code, + 'ErrorMessage' => $msg + ); + $response = json_encode($json, JSON_PRETTY_PRINT | JSON_HEX_APOS | JSON_HEX_QUOT); + Log::debug('Error [json]: ' . $response); + header('Content-Type: application/json; charset=' . Autodiscover::CHARSET); + echo $response; + exit; + } + } diff --git a/lib/AutodiscoverMicrosoft.php b/lib/AutodiscoverMicrosoft.php --- a/lib/AutodiscoverMicrosoft.php +++ b/lib/AutodiscoverMicrosoft.php @@ -111,6 +111,42 @@ exit; } + /** + * Send error to the client and exit + */ + protected function error($msg) + { + $xml = new DOMDocument('1.0', Autodiscover::CHARSET); + $doc = $xml->createElementNS(self::NS, 'Autodiscover'); + $doc = $xml->appendChild($doc); + + $response = $xml->createElement('Response'); + $response = $doc->appendChild($response); + + $error = $xml->createElement('Error'); + list($usec, $sec) = explode(' ', microtime()); + $error->setAttribute('Time',date('H:i:s',$sec).".".substr($usec, 2, 6)); + $error->setAttribute('Id',2177155290); + $response->appendChild($error); + + $code = $xml->createElement('ErrorCode'); + $code->appendChild($xml->createTextNode(600)); + $error->appendChild($code); + + $message = $xml->createElement('Message'); + $message->appendChild($xml->createTextNode($msg)); + $error->appendChild($message); + + $response->appendChild($xml->createElement('DebugData')); + + $xml->formatOutput = true; + Log::debug('Error [microsoft]: ' . $msg); + + header('Content-type: text/xml; charset=' . Autodiscover::CHARSET); + echo $xml->saveXML(); + exit; + } + /** * Generates XML response for Activesync */