/** * Reads and processes the request headers * * @access public * @return */ public static function ProcessHeaders() { self::$headers = array_change_key_case(apache_request_headers(), CASE_LOWER); self::$useragent = isset(self::$headers["user-agent"]) ? self::$headers["user-agent"] : self::UNKNOWN; if (!isset(self::$asProtocolVersion)) { self::$asProtocolVersion = isset(self::$headers["ms-asprotocolversion"]) ? self::filterEvilInput(self::$headers["ms-asprotocolversion"], self::NUMBERSDOT_ONLY) : ZPush::GetLatestSupportedASVersion(); } //if policykey is not yet set, try to set it from the header //the policy key might be set in Request::Initialize from the base64 encoded query if (!isset(self::$policykey)) { if (isset(self::$headers["x-ms-policykey"])) { self::$policykey = (int) self::filterEvilInput(self::$headers["x-ms-policykey"], self::NUMBERS_ONLY); } else { self::$policykey = 0; } } if (!empty($_SERVER['QUERY_STRING']) && Utils::IsBase64String($_SERVER['QUERY_STRING'])) { ZLog::Write(LOGLEVEL_DEBUG, "Using data from base64 encoded query string"); if (isset(self::$policykey)) { self::$headers["x-ms-policykey"] = self::$policykey; } if (isset(self::$asProtocolVersion)) { self::$headers["ms-asprotocolversion"] = self::$asProtocolVersion; } } if (!isset(self::$acceptMultipart) && isset(self::$headers["ms-asacceptmultipart"]) && strtoupper(self::$headers["ms-asacceptmultipart"]) == "T") { self::$acceptMultipart = true; } ZLog::Write(LOGLEVEL_DEBUG, sprintf("Request::ProcessHeaders() ASVersion: %s", self::$asProtocolVersion)); if (defined('USE_X_FORWARDED_FOR_HEADER') && USE_X_FORWARDED_FOR_HEADER == true && isset(self::$headers["x-forwarded-for"])) { $forwardedIP = self::filterEvilInput(self::$headers["x-forwarded-for"], self::NUMBERSDOT_ONLY); if ($forwardedIP) { self::$remoteAddr = $forwardedIP; ZLog::Write(LOGLEVEL_INFO, sprintf("'X-Forwarded-for' indicates remote IP: %s", self::$remoteAddr)); } } }
/** * Reads and processes the request headers * * @access public * @return */ public static function ProcessHeaders() { self::$headers = array_change_key_case(apache_request_headers(), CASE_LOWER); self::$useragent = isset(self::$headers["user-agent"]) ? self::$headers["user-agent"] : self::UNKNOWN; if (!isset(self::$asProtocolVersion)) { self::$asProtocolVersion = isset(self::$headers["ms-asprotocolversion"]) ? self::filterEvilInput(self::$headers["ms-asprotocolversion"], self::NUMBERSDOT_ONLY) : ZPush::GetLatestSupportedASVersion(); } //if policykey is not yet set, try to set it from the header //the policy key might be set in Request::Initialize from the base64 encoded query if (!isset(self::$policykey)) { if (isset(self::$headers["x-ms-policykey"])) { self::$policykey = (int) self::filterEvilInput(self::$headers["x-ms-policykey"], self::NUMBERS_ONLY); } else { self::$policykey = 0; } } if (!empty($_SERVER['QUERY_STRING']) && Utils::IsBase64String($_SERVER['QUERY_STRING'])) { ZLog::Write(LOGLEVEL_DEBUG, "Using data from base64 encoded query string"); if (isset(self::$policykey)) { self::$headers["x-ms-policykey"] = self::$policykey; } if (isset(self::$asProtocolVersion)) { self::$headers["ms-asprotocolversion"] = self::$asProtocolVersion; } } if (!isset(self::$acceptMultipart) && isset(self::$headers["ms-asacceptmultipart"]) && strtoupper(self::$headers["ms-asacceptmultipart"]) == "T") { self::$acceptMultipart = true; } ZLog::Write(LOGLEVEL_DEBUG, sprintf("Request::ProcessHeaders() ASVersion: %s", self::$asProtocolVersion)); if (isset(self::$headers["x-push-plugin"])) { list($version, $build, $buildDate) = explode("/", self::$headers["x-push-plugin"]); self::$koeVersion = self::filterEvilInput($version, self::NUMBERSDOT_ONLY); self::$koeBuild = self::filterEvilInput($build, self::HEX_ONLY); self::$koeBuildDate = strtotime(self::filterEvilInput($buildDate, self::ISO8601)); } if (defined('USE_X_FORWARDED_FOR_HEADER') && USE_X_FORWARDED_FOR_HEADER == true && isset(self::$headers["x-forwarded-for"])) { $forwardedIP = self::filterEvilInput(self::$headers["x-forwarded-for"], self::NUMBERSDOT_ONLY); if ($forwardedIP) { ZLog::Write(LOGLEVEL_DEBUG, sprintf("'X-Forwarded-for' indicates remote IP: %s - connect is coming from IP: %s", $forwardedIP, self::$remoteAddr)); self::$remoteAddr = $forwardedIP; } } // Mobile devices send Authorization header using UTF-8 charset. Outlook sends it using ISO-8859-1 encoding. // For the successful authentication the user and password must be UTF-8 encoded. Try to determine which // charset was sent by the client and convert it to UTF-8. See https://jira.z-hub.io/browse/ZP-864. if (isset($_SERVER['PHP_AUTH_USER'])) { $encoding = mb_detect_encoding(self::$authUser, "UTF-8, ISO-8859-1"); if (!$encoding) { $encoding = mb_detect_encoding(self::$authUser, Utils::GetAvailableCharacterEncodings()); if ($encoding) { ZLog::Write(LOGLEVEL_WARN, sprintf("Request->ProcessHeaders(): mb_detect_encoding detected '%s' charset. This charset is not in the default detect list. Please report it to Z-Push developers.", $encoding)); } else { ZLog::Write(LOGLEVEL_ERROR, "Request->ProcessHeaders(): mb_detect_encoding failed to detect the Authorization header charset. It's possible that user won't be able to login."); } } if ($encoding && strtolower($encoding) != "utf-8") { ZLog::Write(LOGLEVEL_DEBUG, sprintf("Request->ProcessHeaders(): mb_detect_encoding detected '%s' charset. Authorization header will be converted to UTF-8 from it.", $encoding)); self::$authUser = mb_convert_encoding(self::$authUser, "UTF-8", $encoding); self::$authPassword = mb_convert_encoding(self::$authPassword, "UTF-8", $encoding); } } }
/** * Initializes request data * * @access public * @return */ public static function Initialize() { // try to open stdin & stdout self::$input = fopen("php://input", "r"); self::$output = fopen("php://output", "w+"); // Parse the standard GET parameters if (isset($_GET["Cmd"])) { self::$command = self::filterEvilInput($_GET["Cmd"], self::LETTERS_ONLY); } // getUser is unfiltered, as everything is allowed.. even "/", "\" or ".." if (isset($_GET["User"])) { self::$getUser = strtolower($_GET["User"]); } if (isset($_GET["DeviceId"])) { self::$devid = self::filterEvilInput($_GET["DeviceId"], self::WORDCHAR_ONLY); } if (isset($_GET["DeviceType"])) { self::$devtype = self::filterEvilInput($_GET["DeviceType"], self::LETTERS_ONLY); } if (isset($_GET["AttachmentName"])) { self::$attachmentName = self::filterEvilInput($_GET["AttachmentName"], self::HEX_EXTENDED); } if (isset($_GET["CollectionId"])) { self::$collectionId = self::filterEvilInput($_GET["CollectionId"], self::HEX_ONLY); } if (isset($_GET["ItemId"])) { self::$itemId = self::filterEvilInput($_GET["ItemId"], self::HEX_ONLY); } if (isset($_GET["SaveInSent"]) && $_GET["SaveInSent"] == "T") { self::$saveInSent = true; } if (isset($_SERVER["REQUEST_METHOD"])) { self::$method = self::filterEvilInput($_SERVER["REQUEST_METHOD"], self::LETTERS_ONLY); } // TODO check IPv6 addresses if (isset($_SERVER["REMOTE_ADDR"])) { self::$remoteAddr = self::filterEvilInput($_SERVER["REMOTE_ADDR"], self::NUMBERSDOT_ONLY); } // in protocol version > 14 mobile send these inputs as encoded query string if (!isset(self::$command) && !empty($_SERVER['QUERY_STRING']) && Utils::IsBase64String($_SERVER['QUERY_STRING'])) { $query = Utils::DecodeBase64URI($_SERVER['QUERY_STRING']); if (!isset(self::$command) && isset($query['Command'])) { self::$command = Utils::GetCommandFromCode($query['Command']); } if (!isset(self::$getUser) && isset($query[self::COMMANDPARAM_USER])) { self::$getUser = strtolower($query[self::COMMANDPARAM_USER]); } if (!isset(self::$devid) && isset($query['DevID'])) { self::$devid = self::filterEvilInput($query['DevID'], self::WORDCHAR_ONLY); } if (!isset(self::$devtype) && isset($query['DevType'])) { self::$devtype = self::filterEvilInput($query['DevType'], self::LETTERS_ONLY); } if (isset($query['PolKey'])) { self::$policykey = (int) self::filterEvilInput($query['PolKey'], self::NUMBERS_ONLY); } if (isset($query['ProtVer'])) { self::$asProtocolVersion = self::filterEvilInput($query['ProtVer'], self::NUMBERS_ONLY) / 10; } if (isset($query[self::COMMANDPARAM_ATTACHMENTNAME])) { self::$attachmentName = self::filterEvilInput($query[self::COMMANDPARAM_ATTACHMENTNAME], self::HEX_EXTENDED); } if (isset($query[self::COMMANDPARAM_COLLECTIONID])) { self::$collectionId = self::filterEvilInput($query[self::COMMANDPARAM_COLLECTIONID], self::HEX_ONLY); } if (isset($query[self::COMMANDPARAM_ITEMID])) { self::$itemId = self::filterEvilInput($query[self::COMMANDPARAM_ITEMID], self::HEX_ONLY); } if (isset($query[self::COMMANDPARAM_OPTIONS]) && ord($query[self::COMMANDPARAM_OPTIONS]) & self::COMMANDPARAM_OPTIONS_SAVEINSENT) { self::$saveInSent = true; } if (isset($query[self::COMMANDPARAM_OPTIONS]) && ord($query[self::COMMANDPARAM_OPTIONS]) & self::COMMANDPARAM_OPTIONS_ACCEPTMULTIPART) { self::$acceptMultipart = true; } } // in base64 encoded query string user is not necessarily set if (!isset(self::$getUser) && isset($_SERVER['PHP_AUTH_USER'])) { list(self::$getUser, ) = Utils::SplitDomainUser(strtolower($_SERVER['PHP_AUTH_USER'])); } }
/** * Reads and processes the request headers * * @access public * @return */ public static function ProcessHeaders() { self::$useragent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : self::UNKNOWN; if (!isset(self::$asProtocolVersion)) { self::$asProtocolVersion = isset($_SERVER['HTTP_MS_ASPROTOCOLVERSION']) ? self::filterEvilInput($_SERVER['HTTP_MS_ASPROTOCOLVERSION'], self::NUMBERSDOT_ONLY) : ZPush::GetLatestSupportedASVersion(); } //if policykey is not yet set, try to set it from the header //the policy key might be set in Request::Initialize from the base64 encoded query if (!isset(self::$policykey)) { if (isset($_SERVER['HTTP_X_MS_POLICYKEY'])) { self::$policykey = (int) self::filterEvilInput($_SERVER['HTTP_X_MS_POLICYKEY'], self::NUMBERS_ONLY); } else { self::$policykey = 0; } } if (!isset(self::$acceptMultipart) && isset($_SERVER['HTTP_MS_ASACCEPTMULTIPART']) && strtoupper($_SERVER['HTTP_MS_ASACCEPTMULTIPART']) == "T") { self::$acceptMultipart = true; } ZLog::Write(LOGLEVEL_DEBUG, sprintf("Request::ProcessHeaders() ASVersion: %s", self::$asProtocolVersion)); if (defined('USE_X_FORWARDED_FOR_HEADER') && USE_X_FORWARDED_FOR_HEADER == true && isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { $forwardedIP = self::filterEvilInput($_SERVER['HTTP_X_FORWARDED_FOR'], self::NUMBERSDOT_ONLY); if ($forwardedIP) { self::$remoteAddr = $forwardedIP; ZLog::Write(LOGLEVEL_INFO, sprintf("'X-Forwarded-for' indicates remote IP: %s", self::$remoteAddr)); } } }