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 {
}
// 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));
return false;
}
......@@ -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
$toOrder = 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) {
// fail early
if (!$f['folderid'] || !$f['name']) {
......
......@@ -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).
// 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!
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));
return false;
}
......
......@@ -256,7 +256,14 @@ class SyncCollections implements Iterator {
if (! $spa->HasFolderId())
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()));
if ($spa->HasLastSyncTime() && $spa->GetLastSyncTime() > $this->lastSyncTime) {
......
......@@ -123,7 +123,7 @@ class Request {
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);
self::$remoteAddr = self::filterIP($_SERVER["REMOTE_ADDR"]);
// 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'])) {
......@@ -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"])) {
$forwardedIP = self::filterEvilInput(self::$headers["x-forwarded-for"], self::NUMBERSDOT_ONLY);
$forwardedIP = self::filterIP(self::$headers["x-forwarded-for"]);
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;
......@@ -677,13 +677,30 @@ class Request {
else if ($filter == self::WORDCHAR_ONLY) $re = "/[^A-Za-z0-9]/";
else if ($filter == self::NUMBERS_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::ISO8601) $re = "/[^\d{8}T\d{6}Z]/";
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"
* With POST request (our case), you can open and read
......
......@@ -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
$sc->AddCollection($spa);
$sc->AddParameter($spa, "requested", true);
......@@ -380,7 +385,7 @@ class Sync extends RequestProcessor {
}
// 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);
ZLog::Write(LOGLEVEL_DEBUG, "HandleSync(): KOE GAB folder - setting filter type to unlimited");
}
......
......@@ -95,9 +95,11 @@ abstract class SyncObject extends Streamer {
*
* @see SyncObject
* @param SyncObject $odo other SyncObject
* @param boolean $log flag to turn on logging
* @param boolean $strictTypeCompare to enforce type matching
* @return boolean
*/
public function equals($odo, $log = false) {
public function equals($odo, $log = false, $strictTypeCompare = false) {
if ($odo === false)
return false;
......@@ -131,9 +133,16 @@ abstract class SyncObject extends Streamer {
}
else {
if (isset($this->$val) && isset($odo->$val)) {
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;
if ($strictTypeCompare){
if ($this->$val !== $odo->$val){
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)) {
......
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