Commit 11e51873 authored by Sebastian Kummer's avatar Sebastian Kummer

Merge pull request #544 in ZP/z-push from develop to release/2.3

* commit '54cb4db0':
  ZP-1200 Added dots to the end of phrases.
  ZP-1200 Use Request::HEX_EXTENDED to filter bad IP addresses.
  ZP-1200 Allow dots (.) in Request::HEX_EXTENDED filter.
  ZP-1229 Fixed whitespace.
  ZP-1229  Add new optional parameter to Syncobject.equals() for strict type checking, and undo the global change made to use strict checking introduced by ZP-1088. Released under the Affero GNU General Public License (AGPL) version 3.
  ZP-1228 Accept SYNC_FOLDER_TYPE_OTHER as valid type.
  ZP-1227 Sync the KOE GAB folder first by adding it to the top of the SyncCollection list.
  ZP-1200 Attempt to use OS backed IP resolution to support ipv4/6.
parents 901daea4 54cb4db0
...@@ -865,7 +865,7 @@ class ASDevice extends StateObject { ...@@ -865,7 +865,7 @@ class ASDevice extends StateObject {
} }
// check if type is of a additional user type // check if type is of a additional user type
if (!in_array($type, array(SYNC_FOLDER_TYPE_USER_CONTACT, SYNC_FOLDER_TYPE_USER_APPOINTMENT, SYNC_FOLDER_TYPE_USER_TASK, SYNC_FOLDER_TYPE_USER_MAIL, SYNC_FOLDER_TYPE_USER_NOTE, SYNC_FOLDER_TYPE_USER_JOURNAL))) { if (!in_array($type, array(SYNC_FOLDER_TYPE_USER_CONTACT, SYNC_FOLDER_TYPE_USER_APPOINTMENT, SYNC_FOLDER_TYPE_USER_TASK, SYNC_FOLDER_TYPE_USER_MAIL, SYNC_FOLDER_TYPE_USER_NOTE, SYNC_FOLDER_TYPE_USER_JOURNAL, SYNC_FOLDER_TYPE_OTHER))) {
ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->AddAdditionalFolder(): folder can not be added because the specified type '%s' is not a permitted user type.", $type)); ZLog::Write(LOGLEVEL_ERROR, sprintf("ASDevice->AddAdditionalFolder(): folder can not be added because the specified type '%s' is not a permitted user type.", $type));
return false; return false;
} }
...@@ -1049,7 +1049,7 @@ class ASDevice extends StateObject { ...@@ -1049,7 +1049,7 @@ class ASDevice extends StateObject {
// transform our array in a key/value array where folderids are keys and do some basic checks // transform our array in a key/value array where folderids are keys and do some basic checks
$toOrder = array(); $toOrder = array();
$ordered = array(); $ordered = array();
$validTypes = array(SYNC_FOLDER_TYPE_USER_CONTACT, SYNC_FOLDER_TYPE_USER_APPOINTMENT, SYNC_FOLDER_TYPE_USER_TASK, SYNC_FOLDER_TYPE_USER_MAIL, SYNC_FOLDER_TYPE_USER_NOTE, SYNC_FOLDER_TYPE_USER_JOURNAL); $validTypes = array(SYNC_FOLDER_TYPE_USER_CONTACT, SYNC_FOLDER_TYPE_USER_APPOINTMENT, SYNC_FOLDER_TYPE_USER_TASK, SYNC_FOLDER_TYPE_USER_MAIL, SYNC_FOLDER_TYPE_USER_NOTE, SYNC_FOLDER_TYPE_USER_JOURNAL, SYNC_FOLDER_TYPE_OTHER);
foreach($folders as $f) { foreach($folders as $f) {
// fail early // fail early
if (!$f['folderid'] || !$f['name']) { if (!$f['folderid'] || !$f['name']) {
......
...@@ -267,7 +267,7 @@ class ChangesMemoryWrapper extends HierarchyCache implements IImportChanges, IEx ...@@ -267,7 +267,7 @@ class ChangesMemoryWrapper extends HierarchyCache implements IImportChanges, IEx
// The Zarafa/Kopano HierarchyExporter exports all kinds of changes for folders (e.g. update no. of unread messages in a folder). // The Zarafa/Kopano HierarchyExporter exports all kinds of changes for folders (e.g. update no. of unread messages in a folder).
// These changes are not relevant for the mobiles, as something changes but the relevant displayname and parentid // These changes are not relevant for the mobiles, as something changes but the relevant displayname and parentid
// stay the same. These changes will be dropped and are not sent! // stay the same. These changes will be dropped and are not sent!
if ($folder->equals($this->GetFolder($folder->serverid))) { if ($folder->equals($this->GetFolder($folder->serverid), false, true)) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Change for folder '%s' will not be sent as modification is not relevant.", $folder->displayname)); ZLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->ImportFolderChange(): Change for folder '%s' will not be sent as modification is not relevant.", $folder->displayname));
return false; return false;
} }
......
...@@ -256,7 +256,14 @@ class SyncCollections implements Iterator { ...@@ -256,7 +256,14 @@ class SyncCollections implements Iterator {
if (! $spa->HasFolderId()) if (! $spa->HasFolderId())
return false; return false;
$this->collections[$spa->GetFolderId()] = $spa; if ($spa->GetKoeGabFolder() === true) {
// put KOE GAB at the beginning of the sync
$this->collections = [$spa->GetFolderId() => $spa] + $this->collections;
ZLog::Write(LOGLEVEL_DEBUG, "SyncCollections->AddCollection(): Prioritizing KOE GAB folder for synchronization");
}
else {
$this->collections[$spa->GetFolderId()] = $spa;
}
ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncCollections->AddCollection(): Folder id '%s' : ref. PolicyKey '%s', ref. Lifetime '%s', last sync at '%s'", $spa->GetFolderId(), $spa->GetReferencePolicyKey(), $spa->GetReferenceLifetime(), $spa->GetLastSyncTime())); ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncCollections->AddCollection(): Folder id '%s' : ref. PolicyKey '%s', ref. Lifetime '%s', last sync at '%s'", $spa->GetFolderId(), $spa->GetReferencePolicyKey(), $spa->GetReferenceLifetime(), $spa->GetLastSyncTime()));
if ($spa->HasLastSyncTime() && $spa->GetLastSyncTime() > $this->lastSyncTime) { if ($spa->HasLastSyncTime() && $spa->GetLastSyncTime() > $this->lastSyncTime) {
......
...@@ -123,7 +123,7 @@ class Request { ...@@ -123,7 +123,7 @@ class Request {
self::$method = self::filterEvilInput($_SERVER["REQUEST_METHOD"], self::LETTERS_ONLY); self::$method = self::filterEvilInput($_SERVER["REQUEST_METHOD"], self::LETTERS_ONLY);
// TODO check IPv6 addresses // TODO check IPv6 addresses
if(isset($_SERVER["REMOTE_ADDR"])) if(isset($_SERVER["REMOTE_ADDR"]))
self::$remoteAddr = self::filterEvilInput($_SERVER["REMOTE_ADDR"], self::NUMBERSDOT_ONLY); self::$remoteAddr = self::filterIP($_SERVER["REMOTE_ADDR"]);
// in protocol version > 14 mobile send these inputs as encoded query string // 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'])) { if (!isset(self::$command) && !empty($_SERVER['QUERY_STRING']) && Utils::IsBase64String($_SERVER['QUERY_STRING'])) {
...@@ -237,7 +237,7 @@ class Request { ...@@ -237,7 +237,7 @@ class Request {
} }
if (defined('USE_X_FORWARDED_FOR_HEADER') && USE_X_FORWARDED_FOR_HEADER == true && isset(self::$headers["x-forwarded-for"])) { 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); $forwardedIP = self::filterIP(self::$headers["x-forwarded-for"]);
if ($forwardedIP) { if ($forwardedIP) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("'X-Forwarded-for' indicates remote IP: %s - connect is coming from IP: %s", $forwardedIP, self::$remoteAddr)); ZLog::Write(LOGLEVEL_DEBUG, sprintf("'X-Forwarded-for' indicates remote IP: %s - connect is coming from IP: %s", $forwardedIP, self::$remoteAddr));
self::$remoteAddr = $forwardedIP; self::$remoteAddr = $forwardedIP;
...@@ -677,13 +677,30 @@ class Request { ...@@ -677,13 +677,30 @@ class Request {
else if ($filter == self::WORDCHAR_ONLY) $re = "/[^A-Za-z0-9]/"; else if ($filter == self::WORDCHAR_ONLY) $re = "/[^A-Za-z0-9]/";
else if ($filter == self::NUMBERS_ONLY) $re = "/[^0-9]/"; else if ($filter == self::NUMBERS_ONLY) $re = "/[^0-9]/";
else if ($filter == self::NUMBERSDOT_ONLY) $re = "/[^0-9\.]/"; else if ($filter == self::NUMBERSDOT_ONLY) $re = "/[^0-9\.]/";
else if ($filter == self::HEX_EXTENDED) $re = "/[^A-Fa-f0-9\:]/"; else if ($filter == self::HEX_EXTENDED) $re = "/[^A-Fa-f0-9\:\.]/";
else if ($filter == self::HEX_EXTENDED2) $re = "/[^A-Fa-f0-9\:USG]/"; // Folder origin constants from DeviceManager::FLD_ORIGIN_* (C already hex) else if ($filter == self::HEX_EXTENDED2) $re = "/[^A-Fa-f0-9\:USG]/"; // Folder origin constants from DeviceManager::FLD_ORIGIN_* (C already hex)
else if ($filter == self::ISO8601) $re = "/[^\d{8}T\d{6}Z]/"; else if ($filter == self::ISO8601) $re = "/[^\d{8}T\d{6}Z]/";
return ($re) ? preg_replace($re, $replacevalue, $input) : ''; return ($re) ? preg_replace($re, $replacevalue, $input) : '';
} }
/**
* If $input is a valid IPv4 or IPv6 address, returns a valid compact IPv4 or IPv6 address string.
* Otherwise, it will strip all characters that are neither numerical or '.' and prefix with "bad-ip".
*
* @param string $input The ipv4/ipv6 address
*
* @access public
* @return string
*/
static private function filterIP($input) {
$in_addr = @inet_pton($input);
if ($in_addr === false) {
return 'badip-' . self::filterEvilInput($input, self::HEX_EXTENDED);
}
return inet_ntop($in_addr);
}
/** /**
* Returns base64 encoded "php://input" * Returns base64 encoded "php://input"
* With POST request (our case), you can open and read * With POST request (our case), you can open and read
......
...@@ -182,6 +182,11 @@ class Sync extends RequestProcessor { ...@@ -182,6 +182,11 @@ class Sync extends RequestProcessor {
} }
} }
// determine if this is the KOE GAB folder so it can be prioritized by SyncCollections
if (KOE_CAPABILITY_GAB && self::$deviceManager->IsKoe() && $spa->GetBackendFolderId() == self::$deviceManager->GetKoeGabBackendFolderId()) {
$spa->SetKoeGabFolder(true);
}
// done basic SPA initialization/loading -> add to SyncCollection // done basic SPA initialization/loading -> add to SyncCollection
$sc->AddCollection($spa); $sc->AddCollection($spa);
$sc->AddParameter($spa, "requested", true); $sc->AddParameter($spa, "requested", true);
...@@ -380,7 +385,7 @@ class Sync extends RequestProcessor { ...@@ -380,7 +385,7 @@ class Sync extends RequestProcessor {
} }
// unset filtertype for KOE GAB folder // unset filtertype for KOE GAB folder
if (KOE_CAPABILITY_GAB && self::$deviceManager->IsKoe() && $spa->GetBackendFolderId() == self::$deviceManager->GetKoeGabBackendFolderId()) { if ($spa->GetKoeGabFolder() === true) {
$spa->SetFilterType(SYNC_FILTERTYPE_ALL); $spa->SetFilterType(SYNC_FILTERTYPE_ALL);
ZLog::Write(LOGLEVEL_DEBUG, "HandleSync(): KOE GAB folder - setting filter type to unlimited"); ZLog::Write(LOGLEVEL_DEBUG, "HandleSync(): KOE GAB folder - setting filter type to unlimited");
} }
......
...@@ -95,9 +95,11 @@ abstract class SyncObject extends Streamer { ...@@ -95,9 +95,11 @@ abstract class SyncObject extends Streamer {
* *
* @see SyncObject * @see SyncObject
* @param SyncObject $odo other SyncObject * @param SyncObject $odo other SyncObject
* @param boolean $log flag to turn on logging
* @param boolean $strictTypeCompare to enforce type matching
* @return boolean * @return boolean
*/ */
public function equals($odo, $log = false) { public function equals($odo, $log = false, $strictTypeCompare = false) {
if ($odo === false) if ($odo === false)
return false; return false;
...@@ -131,9 +133,16 @@ abstract class SyncObject extends Streamer { ...@@ -131,9 +133,16 @@ abstract class SyncObject extends Streamer {
} }
else { else {
if (isset($this->$val) && isset($odo->$val)) { if (isset($this->$val) && isset($odo->$val)) {
if ($this->$val !== $odo->$val){ if ($strictTypeCompare){
ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncObject->equals() false on field '%s': '%s' != '%s'", $val, Utils::PrintAsString($this->$val), Utils::PrintAsString($odo->$val))); if ($this->$val !== $odo->$val){
return false; ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncObject->equals() false on field '%s': '%s' != '%s' using strictTypeCompare", $val, Utils::PrintAsString($this->$val), Utils::PrintAsString($odo->$val)));
return false;
}
} else {
if ($this->$val != $odo->$val){
ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncObject->equals() false on field '%s': '%s' != '%s'", $val, Utils::PrintAsString($this->$val), Utils::PrintAsString($odo->$val)));
return false;
}
} }
} }
else if (!isset($this->$val) && !isset($odo->$val)) { else if (!isset($this->$val) && !isset($odo->$val)) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment