예제 #1
0
 /**
  * Handles a webservice command
  *
  * @param int       $commandCode
  *
  * @access public
  * @return boolean
  * @throws SoapFault
  */
 public function Handle($commandCode)
 {
     if (Request::GetDeviceType() !== "webservice" || Request::GetDeviceID() !== "webservice") {
         throw new FatalException("Invalid device id and type for webservice execution");
     }
     if (Request::GetGETUser() != Request::GetAuthUser()) {
         ZLog::Write(LOGLEVEL_INFO, sprintf("Webservice::HandleWebservice('%s'): user '%s' executing action for user '%s'", $commandCode, Request::GetAuthUser(), Request::GetGETUser()));
     }
     // initialize non-wsdl soap server
     $this->server = new SoapServer(null, array('uri' => "http://z-push.sf.net/webservice"));
     // the webservice command is handled by its class
     if ($commandCode == ZPush::COMMAND_WEBSERVICE_DEVICE) {
         ZLog::Write(LOGLEVEL_DEBUG, sprintf("Webservice::HandleWebservice('%s'): executing WebserviceDevice service", $commandCode));
         include_once 'webservicedevice.php';
         $this->server->setClass("WebserviceDevice");
     }
     // the webservice command is handled by its class
     if ($commandCode == ZPush::COMMAND_WEBSERVICE_USERS) {
         if (!defined("ALLOW_WEBSERVICE_USERS_ACCESS") || ALLOW_WEBSERVICE_USERS_ACCESS !== true) {
             throw new HTTPReturnCodeException(sprintf("Access to the WebserviceUsers service is disabled in configuration. Enable setting ALLOW_WEBSERVICE_USERS_ACCESS.", Request::GetAuthUser()), 403);
         }
         ZLog::Write(LOGLEVEL_DEBUG, sprintf("Webservice::HandleWebservice('%s'): executing WebserviceUsers service", $commandCode));
         if (ZPush::GetBackend()->Setup("SYSTEM", true) == false) {
             throw new AuthenticationRequiredException(sprintf("User '%s' has no admin privileges", Request::GetAuthUser()));
         }
         include_once 'webserviceusers.php';
         $this->server->setClass("WebserviceUsers");
     }
     $this->server->handle();
     ZLog::Write(LOGLEVEL_DEBUG, sprintf("Webservice::HandleWebservice('%s'): sucessfully sent %d bytes", $commandCode, ob_get_length()));
     return true;
 }
예제 #2
0
 /**
  * Returns a list of folders of the Request::GetGETUser().
  * If the user has not enough permissions an empty result is returned.
  *
  * @access public
  * @return array
  */
 public function ListUserFolders()
 {
     $user = Request::GetGETUser();
     $output = array();
     $hasRights = ZPush::GetBackend()->Setup($user);
     ZLog::Write(LOGLEVEL_INFO, sprintf("WebserviceInfo::ListUserFolders(): permissions to open store '%s': %s", $user, Utils::PrintAsString($hasRights)));
     if ($hasRights) {
         $folders = ZPush::GetBackend()->GetHierarchy();
         ZPush::GetTopCollector()->AnnounceInformation(sprintf("Retrieved details of %d folders", count($folders)), true);
         foreach ($folders as $folder) {
             $folder->StripData();
             unset($folder->Store, $folder->flags, $folder->content, $folder->NoBackendFolder);
             $output[] = $folder;
         }
     }
     return $output;
 }
예제 #3
0
 /**
  * Only used to load additional folder sync information for hierarchy changes
  *
  * @param array    $state               current state of additional hierarchy folders
  *
  * @access public
  * @return boolean
  */
 public function Config($state, $flags = 0)
 {
     // we should never forward this changes to a backend
     if (!isset($this->destinationImporter)) {
         foreach ($state as $addKey => $addFolder) {
             ZLog::Write(LOGLEVEL_DEBUG, sprintf("ChangesMemoryWrapper->Config(AdditionalFolders) : process folder '%s'", $addFolder->displayname));
             if (isset($addFolder->NoBackendFolder) && $addFolder->NoBackendFolder == true) {
                 // check rights for readonly access only
                 $hasRights = ZPush::GetBackend()->Setup($addFolder->Store, true, $addFolder->BackendId, true);
                 // delete the folder on the device
                 if (!$hasRights) {
                     // delete the folder only if it was an additional folder before, else ignore it
                     $synchedfolder = $this->GetFolder($addFolder->serverid);
                     if (isset($synchedfolder->NoBackendFolder) && $synchedfolder->NoBackendFolder == true) {
                         $this->ImportFolderDeletion($addFolder);
                     }
                     continue;
                 }
             }
             // add folder to the device - if folder is already on the device, nothing will happen
             $this->ImportFolderChange($addFolder);
         }
         // look for folders which are currently on the device if there are now not to be synched anymore
         $alreadyDeleted = $this->GetDeletedFolders();
         foreach ($this->ExportFolders(true) as $sid => $folder) {
             // we are only looking at additional folders
             if (isset($folder->NoBackendFolder)) {
                 // look if this folder is still in the list of additional folders and was not already deleted (e.g. missing permissions)
                 if (!array_key_exists($sid, $state) && !array_key_exists($sid, $alreadyDeleted)) {
                     ZLog::Write(LOGLEVEL_INFO, sprintf("ChangesMemoryWrapper->Config(AdditionalFolders) : previously synchronized folder '%s' is not to be synched anymore. Sending delete to mobile.", $folder->displayname));
                     $this->ImportFolderDeletion($folder);
                 }
             }
         }
     }
     return true;
 }
예제 #4
0
 /**
  * Checks the hierarchy for changes.
  *
  * @param boolean       export changes, default: false
  *
  * @access private
  * @return boolean      indicating if changes were found or not
  */
 private function countHierarchyChange($exportChanges = false)
 {
     $folderid = false;
     $spa = $this->GetCollection($folderid);
     // Check with device manager if the hierarchy should be reloaded.
     // New additional folders are loaded here.
     if (ZPush::GetDeviceManager()->IsHierarchySyncRequired()) {
         ZLog::Write(LOGLEVEL_DEBUG, "SyncCollections->countHierarchyChange(): DeviceManager says HierarchySync is required.");
         return true;
     }
     $changecount = false;
     if ($exportChanges || $this->hierarchyExporterChecked === false) {
         try {
             // if this is a validation (not first run), make sure to load the hierarchy data again
             if ($this->hierarchyExporterChecked === true && !$this->LoadCollection(false, true, false)) {
                 throw new StatusException("Invalid states found while re-loading hierarchy data.");
             }
             $changesMem = ZPush::GetDeviceManager()->GetHierarchyChangesWrapper();
             // the hierarchyCache should now fully be initialized - check for changes in the additional folders
             $changesMem->Config(ZPush::GetAdditionalSyncFolders(false));
             // reset backend to the main store
             ZPush::GetBackend()->Setup(false);
             $exporter = ZPush::GetBackend()->GetExporter();
             if ($exporter !== false && isset($this->addparms[$folderid]["state"])) {
                 $exporter->Config($this->addparms[$folderid]["state"]);
                 $ret = $exporter->InitializeExporter($changesMem);
                 while (is_array($exporter->Synchronize())) {
                 }
                 if ($ret !== false) {
                     $changecount = $changesMem->GetChangeCount();
                 }
                 $this->hierarchyExporterChecked = true;
             }
         } catch (StatusException $ste) {
             throw new StatusException("SyncCollections->countHierarchyChange(): exporter can not be re-configured.", self::ERROR_WRONG_HIERARCHY, null, LOGLEVEL_WARN);
         }
         // start over if exporter can not be configured atm
         if ($changecount === false) {
             ZLog::Write(LOGLEVEL_WARN, "SyncCollections->countHierarchyChange(): no changes received from Exporter.");
         }
     }
     return $changecount > 0;
 }
예제 #5
0
 /**
  * Reads an email object from MAPI
  *
  * @param mixed             $mapimessage
  * @param ContentParameters $contentparameters
  *
  * @access private
  * @return SyncEmail
  */
 private function getEmail($mapimessage, $contentparameters)
 {
     $message = new SyncMail();
     $this->getPropsFromMAPI($message, $mapimessage, MAPIMapping::GetEmailMapping());
     $emailproperties = MAPIMapping::GetEmailProperties();
     $messageprops = $this->getProps($mapimessage, $emailproperties);
     if (isset($messageprops[PR_SOURCE_KEY])) {
         $sourcekey = $messageprops[PR_SOURCE_KEY];
     } else {
         return false;
     }
     //set the body according to contentparameters and supported AS version
     $this->setMessageBody($mapimessage, $contentparameters, $message);
     $fromname = $fromaddr = "";
     if (isset($messageprops[$emailproperties["representingname"]])) {
         // remove encapsulating double quotes from the representingname
         $fromname = preg_replace('/^\\"(.*)\\"$/', "\${1}", $messageprops[$emailproperties["representingname"]]);
     }
     if (isset($messageprops[$emailproperties["representingentryid"]])) {
         $fromaddr = $this->getSMTPAddressFromEntryID($messageprops[$emailproperties["representingentryid"]]);
     }
     if ($fromname == $fromaddr) {
         $fromname = "";
     }
     if ($fromname) {
         $from = "\"" . w2u($fromname) . "\" <" . w2u($fromaddr) . ">";
     } else {
         //START CHANGED dw2412 HTC shows "error" if sender name is unknown
         $from = "\"" . w2u($fromaddr) . "\" <" . w2u($fromaddr) . ">";
     }
     //END CHANGED dw2412 HTC shows "error" if sender name is unknown
     $message->from = $from;
     // process Meeting Requests
     if (isset($message->messageclass) && strpos($message->messageclass, "IPM.Schedule.Meeting") === 0) {
         $message->meetingrequest = new SyncMeetingRequest();
         $this->getPropsFromMAPI($message->meetingrequest, $mapimessage, MAPIMapping::GetMeetingRequestMapping());
         $meetingrequestproperties = MAPIMapping::GetMeetingRequestProperties();
         $props = $this->getProps($mapimessage, $meetingrequestproperties);
         // Get the GOID
         if (isset($props[$meetingrequestproperties["goidtag"]])) {
             $message->meetingrequest->globalobjid = base64_encode($props[$meetingrequestproperties["goidtag"]]);
         }
         // Set Timezone
         if (isset($props[$meetingrequestproperties["timezonetag"]])) {
             $tz = $this->getTZFromMAPIBlob($props[$meetingrequestproperties["timezonetag"]]);
         } else {
             $tz = $this->getGMTTZ();
         }
         $message->meetingrequest->timezone = base64_encode(TimezoneUtil::GetSyncBlobFromTZ($tz));
         // send basedate if exception
         if (isset($props[$meetingrequestproperties["recReplTime"]]) || isset($props[$meetingrequestproperties["lidIsException"]]) && $props[$meetingrequestproperties["lidIsException"]] == true) {
             if (isset($props[$meetingrequestproperties["recReplTime"]])) {
                 $basedate = $props[$meetingrequestproperties["recReplTime"]];
                 $message->meetingrequest->recurrenceid = $this->getGMTTimeByTZ($basedate, $this->getGMTTZ());
             } else {
                 if (!isset($props[$meetingrequestproperties["goidtag"]]) || !isset($props[$meetingrequestproperties["recurStartTime"]]) || !isset($props[$meetingrequestproperties["timezonetag"]])) {
                     ZLog::Write(LOGLEVEL_WARN, "Missing property to set correct basedate for exception");
                 } else {
                     $basedate = Utils::ExtractBaseDate($props[$meetingrequestproperties["goidtag"]], $props[$meetingrequestproperties["recurStartTime"]]);
                     $message->meetingrequest->recurrenceid = $this->getGMTTimeByTZ($basedate, $tz);
                 }
             }
         }
         // Organizer is the sender
         if (strpos($message->messageclass, "IPM.Schedule.Meeting.Resp") === 0) {
             $message->meetingrequest->organizer = $message->to;
         } else {
             $message->meetingrequest->organizer = $message->from;
         }
         // Process recurrence
         if (isset($props[$meetingrequestproperties["isrecurringtag"]]) && $props[$meetingrequestproperties["isrecurringtag"]]) {
             $myrec = new SyncMeetingRequestRecurrence();
             // get recurrence -> put $message->meetingrequest as message so the 'alldayevent' is set correctly
             $this->getRecurrence($mapimessage, $props, $message->meetingrequest, $myrec, $tz);
             $message->meetingrequest->recurrences = array($myrec);
         }
         // Force the 'alldayevent' in the object at all times. (non-existent == 0)
         if (!isset($message->meetingrequest->alldayevent) || $message->meetingrequest->alldayevent == "") {
             $message->meetingrequest->alldayevent = 0;
         }
         // Instancetype
         // 0 = single appointment
         // 1 = master recurring appointment
         // 2 = single instance of recurring appointment
         // 3 = exception of recurring appointment
         $message->meetingrequest->instancetype = 0;
         if (isset($props[$meetingrequestproperties["isrecurringtag"]]) && $props[$meetingrequestproperties["isrecurringtag"]] == 1) {
             $message->meetingrequest->instancetype = 1;
         } else {
             if ((!isset($props[$meetingrequestproperties["isrecurringtag"]]) || $props[$meetingrequestproperties["isrecurringtag"]] == 0) && isset($message->meetingrequest->recurrenceid)) {
                 if (isset($props[$meetingrequestproperties["appSeqNr"]]) && $props[$meetingrequestproperties["appSeqNr"]] == 0) {
                     $message->meetingrequest->instancetype = 2;
                 } else {
                     $message->meetingrequest->instancetype = 3;
                 }
             }
         }
         // Disable reminder if it is off
         if (!isset($props[$meetingrequestproperties["reminderset"]]) || $props[$meetingrequestproperties["reminderset"]] == false) {
             $message->meetingrequest->reminder = "";
         } else {
             ///set the default reminder time to seconds
             if ($props[$meetingrequestproperties["remindertime"]] == 0x5ae980e1) {
                 $message->meetingrequest->reminder = 900;
             } else {
                 $message->meetingrequest->reminder = $props[$meetingrequestproperties["remindertime"]] * 60;
             }
         }
         // Set sensitivity to 0 if missing
         if (!isset($message->meetingrequest->sensitivity)) {
             $message->meetingrequest->sensitivity = 0;
         }
         // If the user is working from a location other than the office the busystatus should be interpreted as free.
         if (isset($message->meetingrequest->busystatus) && $message->meetingrequest->busystatus == fbWorkingElsewhere) {
             $message->meetingrequest->busystatus = fbFree;
         }
         // If the busystatus has the value of -1, we should be interpreted as tentative (1) / ZP-581
         if (isset($message->meetingrequest->busystatus) && $message->meetingrequest->busystatus == -1) {
             $message->meetingrequest->busystatus = fbTentative;
         }
         // if a meeting request response hasn't been processed yet,
         // do it so that the attendee status is updated on the mobile
         if (!isset($messageprops[$emailproperties["processed"]])) {
             // check if we are not sending the MR so we can process it - ZP-581
             $cuser = ZPush::GetBackend()->GetUserDetails(ZPush::GetBackend()->GetCurrentUsername());
             if (isset($cuser["emailaddress"]) && $cuser["emailaddress"] != $fromaddr) {
                 $req = new Meetingrequest($this->store, $mapimessage, $this->session);
                 if ($req->isMeetingRequestResponse()) {
                     $req->processMeetingRequestResponse();
                 }
                 if ($req->isMeetingCancellation()) {
                     $req->processMeetingCancellation();
                 }
             }
         }
         $message->contentclass = DEFAULT_CALENDAR_CONTENTCLASS;
     }
     // Add attachments
     $attachtable = mapi_message_getattachmenttable($mapimessage);
     $rows = mapi_table_queryallrows($attachtable, array(PR_ATTACH_NUM));
     $entryid = bin2hex($messageprops[$emailproperties["entryid"]]);
     foreach ($rows as $row) {
         if (isset($row[PR_ATTACH_NUM])) {
             if (Request::GetProtocolVersion() >= 12.0) {
                 $attach = new SyncBaseAttachment();
             } else {
                 $attach = new SyncAttachment();
             }
             $mapiattach = mapi_message_openattach($mapimessage, $row[PR_ATTACH_NUM]);
             $attachprops = mapi_getprops($mapiattach, array(PR_ATTACH_LONG_FILENAME, PR_ATTACH_FILENAME, PR_ATTACHMENT_HIDDEN, PR_ATTACH_CONTENT_ID, PR_ATTACH_CONTENT_ID_W, PR_ATTACH_MIME_TAG, PR_ATTACH_MIME_TAG_W, PR_ATTACH_METHOD, PR_DISPLAY_NAME, PR_DISPLAY_NAME_W, PR_ATTACH_SIZE));
             if (isset($attachprops[PR_ATTACH_MIME_TAG]) && strpos(strtolower($attachprops[PR_ATTACH_MIME_TAG]), 'signed') !== false || isset($attachprops[PR_ATTACH_MIME_TAG_W]) && strpos(strtolower($attachprops[PR_ATTACH_MIME_TAG_W]), 'signed') !== false) {
                 continue;
             }
             // the displayname is handled equaly for all AS versions
             $attach->displayname = w2u(isset($attachprops[PR_ATTACH_LONG_FILENAME]) ? $attachprops[PR_ATTACH_LONG_FILENAME] : (isset($attachprops[PR_ATTACH_FILENAME]) ? $attachprops[PR_ATTACH_FILENAME] : (isset($attachprops[PR_DISPLAY_NAME]) ? $attachprops[PR_DISPLAY_NAME] : "attachment.bin")));
             // fix attachment name in case of inline images
             if ($attach->displayname == "inline.txt" && (isset($attachprops[PR_ATTACH_MIME_TAG]) || $attachprops[PR_ATTACH_MIME_TAG_W])) {
                 $mimetype = isset($attachprops[PR_ATTACH_MIME_TAG]) ? $attachprops[PR_ATTACH_MIME_TAG] : $attachprops[PR_ATTACH_MIME_TAG_W];
                 $mime = explode("/", $mimetype);
                 if (count($mime) == 2 && $mime[0] == "image") {
                     $attach->displayname = "inline." . $mime[1];
                 }
             }
             // set AS version specific parameters
             if (Request::GetProtocolVersion() >= 12.0) {
                 $attach->filereference = $entryid . ":" . $row[PR_ATTACH_NUM];
                 $attach->method = isset($attachprops[PR_ATTACH_METHOD]) ? $attachprops[PR_ATTACH_METHOD] : ATTACH_BY_VALUE;
                 // if displayname does not have the eml extension for embedde messages, android and WP devices won't open it
                 if ($attach->method == ATTACH_EMBEDDED_MSG) {
                     if (strtolower(substr($attach->displayname, -4)) != '.eml') {
                         $attach->displayname .= '.eml';
                     }
                 }
                 $attach->estimatedDataSize = $attachprops[PR_ATTACH_SIZE];
                 if (isset($attachprops[PR_ATTACH_CONTENT_ID]) && $attachprops[PR_ATTACH_CONTENT_ID]) {
                     $attach->contentid = $attachprops[PR_ATTACH_CONTENT_ID];
                 }
                 if (!isset($attach->contentid) && isset($attachprops[PR_ATTACH_CONTENT_ID_W]) && $attachprops[PR_ATTACH_CONTENT_ID_W]) {
                     $attach->contentid = $attachprops[PR_ATTACH_CONTENT_ID_W];
                 }
                 if (isset($attachprops[PR_ATTACHMENT_HIDDEN]) && $attachprops[PR_ATTACHMENT_HIDDEN]) {
                     $attach->isinline = 1;
                 }
                 if (!isset($message->asattachments)) {
                     $message->asattachments = array();
                 }
                 array_push($message->asattachments, $attach);
             } else {
                 $attach->attsize = $attachprops[PR_ATTACH_SIZE];
                 $attach->attname = $entryid . ":" . $row[PR_ATTACH_NUM];
                 if (!isset($message->attachments)) {
                     $message->attachments = array();
                 }
                 array_push($message->attachments, $attach);
             }
         }
     }
     // Get To/Cc as SMTP addresses (this is different from displayto and displaycc because we are putting
     // in the SMTP addresses as well, while displayto and displaycc could just contain the display names
     $message->to = array();
     $message->cc = array();
     $reciptable = mapi_message_getrecipienttable($mapimessage);
     $rows = mapi_table_queryallrows($reciptable, array(PR_RECIPIENT_TYPE, PR_DISPLAY_NAME, PR_ADDRTYPE, PR_EMAIL_ADDRESS, PR_SMTP_ADDRESS, PR_ENTRYID));
     foreach ($rows as $row) {
         $address = "";
         $fulladdr = "";
         $addrtype = isset($row[PR_ADDRTYPE]) ? $row[PR_ADDRTYPE] : "";
         if (isset($row[PR_SMTP_ADDRESS])) {
             $address = $row[PR_SMTP_ADDRESS];
         } elseif ($addrtype == "SMTP" && isset($row[PR_EMAIL_ADDRESS])) {
             $address = $row[PR_EMAIL_ADDRESS];
         } elseif ($addrtype == "ZARAFA" && isset($row[PR_ENTRYID])) {
             $address = $this->getSMTPAddressFromEntryID($row[PR_ENTRYID]);
         }
         $name = isset($row[PR_DISPLAY_NAME]) ? $row[PR_DISPLAY_NAME] : "";
         if ($name == "" || $name == $address) {
             $fulladdr = w2u($address);
         } else {
             if (substr($name, 0, 1) != '"' && substr($name, -1) != '"') {
                 $fulladdr = "\"" . w2u($name) . "\" <" . w2u($address) . ">";
             } else {
                 $fulladdr = w2u($name) . "<" . w2u($address) . ">";
             }
         }
         if ($row[PR_RECIPIENT_TYPE] == MAPI_TO) {
             array_push($message->to, $fulladdr);
         } else {
             if ($row[PR_RECIPIENT_TYPE] == MAPI_CC) {
                 array_push($message->cc, $fulladdr);
             }
         }
     }
     if (is_array($message->to) && !empty($message->to)) {
         $message->to = implode(", ", $message->to);
     }
     if (is_array($message->cc) && !empty($message->cc)) {
         $message->cc = implode(", ", $message->cc);
     }
     // without importance some mobiles assume "0" (low) - Mantis #439
     if (!isset($message->importance)) {
         $message->importance = IMPORTANCE_NORMAL;
     }
     //TODO contentclass and nativebodytype and internetcpid
     if (!isset($message->internetcpid)) {
         $message->internetcpid = defined('STORE_INTERNET_CPID') ? constant('STORE_INTERNET_CPID') : INTERNET_CPID_WINDOWS1252;
     }
     $this->setFlag($mapimessage, $message);
     if (!isset($message->contentclass)) {
         $message->contentclass = DEFAULT_EMAIL_CONTENTCLASS;
     }
     if (!isset($message->nativebodytype)) {
         $message->nativebodytype = $this->getNativeBodyType($messageprops);
     }
     // reply, reply to all, forward flags
     if (isset($message->lastverbexecuted) && $message->lastverbexecuted) {
         $message->lastverbexecuted = Utils::GetLastVerbExecuted($message->lastverbexecuted);
     }
     return $message;
 }
예제 #6
0
 /**
  * Checks a folder for changes performing Exporter->GetChangeCount()
  *
  * @param string    $folderid   counts changes for a folder
  *
  * @access private
  * @return boolean      indicating if changes were found or not
  */
 private function CountChange($folderid)
 {
     $spa = $this->GetCollection($folderid);
     // switch user store if this is a additional folder (additional true -> do not debug)
     ZPush::GetBackend()->Setup(ZPush::GetAdditionalSyncFolderStore($folderid, true));
     $changecount = false;
     try {
         $exporter = ZPush::GetBackend()->GetExporter($folderid);
         if ($exporter !== false && isset($this->addparms[$folderid]["state"])) {
             $importer = false;
             $exporter->Config($this->addparms[$folderid]["state"], BACKEND_DISCARD_DATA);
             $exporter->ConfigContentParameters($spa->GetCPO());
             $ret = $exporter->InitializeExporter($importer);
             if ($ret !== false) {
                 $changecount = $exporter->GetChangeCount();
             }
         }
     } catch (StatusException $ste) {
         throw new StatusException("SyncCollections->CountChange(): exporter can not be re-configured.", self::ERROR_WRONG_HIERARCHY, null, LOGLEVEL_WARN);
     }
     // start over if exporter can not be configured atm
     if ($changecount === false) {
         ZLog::Write(LOGLEVEL_WARN, "SyncCollections->CountChange(): no changes received from Exporter.");
     }
     $this->changes[$folderid] = $changecount;
     if (isset($this->addparms[$folderid]['savestate'])) {
         try {
             // Discard any data
             while (is_array($exporter->Synchronize())) {
             }
             $this->addparms[$folderid]['savestate'] = $exporter->GetState();
         } catch (StatusException $ste) {
             throw new StatusException("SyncCollections->CountChange(): could not get new state from exporter", self::ERROR_WRONG_HIERARCHY, null, LOGLEVEL_WARN);
         }
     }
     return $changecount > 0;
 }
예제 #7
0
 /**
  * Imports a move of a message. This occurs when a user moves an item to another folder
  *
  * Normally, we would implement this via the 'offical' importmessagemove() function on the ICS importer,
  * but the Zarafa importer does not support this. Therefore we currently implement it via a standard mapi
  * call. This causes a mirror 'add/delete' to be sent to the PDA at the next sync.
  * Manfred, 2010-10-21. For some mobiles import was causing duplicate messages in the destination folder
  * (Mantis #202). Therefore we will create a new message in the destination folder, copy properties
  * of the source message to the new one and then delete the source message.
  *
  * @param string        $id
  * @param string        $newfolder      destination folder
  *
  * @access public
  * @return boolean
  * @throws StatusException
  */
 public function ImportMessageMove($id, $newfolder)
 {
     if (strtolower($newfolder) == strtolower(bin2hex($this->folderid))) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, source and destination are equal", $id, $newfolder), SYNC_MOVEITEMSSTATUS_SAMESOURCEANDDEST);
     }
     // Get the entryid of the message we're moving
     $entryid = mapi_msgstore_entryidfromsourcekey($this->store, $this->folderid, hex2bin($id));
     if (!$entryid) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to resolve source message id", $id, $newfolder), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
     }
     //open the source message
     $srcmessage = mapi_msgstore_openentry($this->store, $entryid);
     if (!$srcmessage) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to open source message: 0x%X", $id, $newfolder, mapi_last_hresult()), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
     }
     // get correct mapi store for the destination folder
     $dststore = ZPush::GetBackend()->GetMAPIStoreForFolderId(ZPush::GetAdditionalSyncFolderStore($newfolder), $newfolder);
     if ($dststore === false) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to open store of destination folder", $id, $newfolder), SYNC_MOVEITEMSSTATUS_INVALIDDESTID);
     }
     $dstentryid = mapi_msgstore_entryidfromsourcekey($dststore, hex2bin($newfolder));
     if (!$dstentryid) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to resolve destination folder", $id, $newfolder), SYNC_MOVEITEMSSTATUS_INVALIDDESTID);
     }
     $dstfolder = mapi_msgstore_openentry($dststore, $dstentryid);
     if (!$dstfolder) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to open destination folder", $id, $newfolder), SYNC_MOVEITEMSSTATUS_INVALIDDESTID);
     }
     $newmessage = mapi_folder_createmessage($dstfolder);
     if (!$newmessage) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to create message in destination folder: 0x%X", $id, $newfolder, mapi_last_hresult()), SYNC_MOVEITEMSSTATUS_INVALIDDESTID);
     }
     // Copy message
     mapi_copyto($srcmessage, array(), array(), $newmessage);
     if (mapi_last_hresult()) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, copy to destination message failed: 0x%X", $id, $newfolder, mapi_last_hresult()), SYNC_MOVEITEMSSTATUS_CANNOTMOVE);
     }
     $srcfolderentryid = mapi_msgstore_entryidfromsourcekey($this->store, $this->folderid);
     if (!$srcfolderentryid) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to resolve source folder", $id, $newfolder), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
     }
     $srcfolder = mapi_msgstore_openentry($this->store, $srcfolderentryid);
     if (!$srcfolder) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to open source folder: 0x%X", $id, $newfolder, mapi_last_hresult()), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
     }
     // Save changes
     mapi_savechanges($newmessage);
     if (mapi_last_hresult()) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, mapi_savechanges() failed: 0x%X", $id, $newfolder, mapi_last_hresult()), SYNC_MOVEITEMSSTATUS_CANNOTMOVE);
     }
     // Delete the old message
     if (!mapi_folder_deletemessages($srcfolder, array($entryid))) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, delete of source message failed: 0x%X. Possible duplicates.", $id, $newfolder, mapi_last_hresult()), SYNC_MOVEITEMSSTATUS_SOURCEORDESTLOCKED);
     }
     $sourcekeyprops = mapi_getprops($newmessage, array(PR_SOURCE_KEY));
     if (isset($sourcekeyprops[PR_SOURCE_KEY]) && $sourcekeyprops[PR_SOURCE_KEY]) {
         return bin2hex($sourcekeyprops[PR_SOURCE_KEY]);
     }
     return false;
 }
예제 #8
0
 /**
  * Does the complete autodiscover.
  * @access public
  * @throws AuthenticationRequiredException if login to the backend failed.
  * @throws ZPushException if the incoming XML is invalid..
  *
  * @return void
  */
 public function DoAutodiscover()
 {
     if (!defined('REAL_BASE_PATH')) {
         define('REAL_BASE_PATH', str_replace('autodiscover/', '', BASE_PATH));
     }
     set_include_path(get_include_path() . PATH_SEPARATOR . REAL_BASE_PATH);
     $response = "";
     try {
         $incomingXml = $this->getIncomingXml();
         $backend = ZPush::GetBackend();
         $username = $this->login($backend, $incomingXml);
         $userDetails = $backend->GetUserDetails($username);
         $email = $this->getAttribFromUserDetails($userDetails, 'emailaddress') ? $this->getAttribFromUserDetails($userDetails, 'emailaddress') : $incomingXml->Request->EMailAddress;
         $userFullname = $this->getAttribFromUserDetails($userDetails, 'fullname') ? $this->getAttribFromUserDetails($userDetails, 'fullname') : $email;
         ZLog::Write(LOGLEVEL_WBXML, sprintf("Resolved user's '%s' fullname to '%s'", $username, $userFullname));
         $response = $this->createResponse($email, $userFullname);
         setcookie("membername", $username);
     } catch (AuthenticationRequiredException $ex) {
         if (isset($incomingXml)) {
             ZLog::Write(LOGLEVEL_ERROR, sprintf("Unable to complete autodiscover because login failed for user with email '%s'", $incomingXml->Request->EMailAddress));
         } else {
             ZLog::Write(LOGLEVEL_ERROR, sprintf("Unable to complete autodiscover incorrect request: '%s'", $ex->getMessage()));
         }
         header('HTTP/1.1 401 Unauthorized');
         header('WWW-Authenticate: Basic realm="ZPush"');
         http_response_code(401);
     } catch (ZPushException $ex) {
         ZLog::Write(LOGLEVEL_ERROR, sprintf("Unable to complete autodiscover because of ZPushException. Error: %s", $ex->getMessage()));
         if (!headers_sent()) {
             header('HTTP/1.1 ' . $ex->getHTTPCodeString());
             foreach ($ex->getHTTPHeaders() as $h) {
                 header($h);
             }
         }
     }
     $this->sendResponse($response);
 }
예제 #9
0
 /**
  * Gets the policy name set in the backend or in device data.
  *
  * @access private
  * @return string
  */
 private function getPolicyName()
 {
     $policyName = ZPush::GetBackend()->GetUserPolicyName();
     $policyName = !empty($policyName) && $policyName !== false ? $policyName : ASDevice::DEFAULTPOLICYNAME;
     ZLog::Write(LOGLEVEL_DEBUG, sprintf("DeviceManager->getPolicyName(): determined policy name: '%s'", $policyName));
     return $policyName;
 }
예제 #10
0
 /**
  * Called at the end of the request
  * Statistics about received/sent data is saved here
  *
  * @access public
  * @return boolean
  */
 public function Save()
 {
     // TODO save other stuff
     // check if previousily ignored messages were synchronized for the current folder
     // on multifolder operations of AS14 this is done by setLatestFolder()
     if ($this->latestFolder !== false) {
         $this->checkBrokenMessages($this->latestFolder);
     }
     // update the user agent and AS version on the device
     $this->device->SetUserAgent(Request::GetUserAgent());
     $this->device->SetASVersion(Request::GetProtocolVersion());
     // data to be saved
     $data = $this->device->GetData();
     if ($data && Request::IsValidDeviceID()) {
         ZLog::Write(LOGLEVEL_DEBUG, "DeviceManager->Save(): Device data changed");
         try {
             // check if this is the first time the device data is saved and it is authenticated. If so, link the user to the device id
             if ($this->device->IsNewDevice() && RequestProcessor::isUserAuthenticated()) {
                 ZLog::Write(LOGLEVEL_INFO, sprintf("Linking device ID '%s' to user '%s'", $this->devid, $this->device->GetDeviceUser()));
                 $this->statemachine->LinkUserDevice($this->device->GetDeviceUser(), $this->devid);
             }
             if (RequestProcessor::isUserAuthenticated() || $this->device->GetForceSave()) {
                 $this->statemachine->SetState($data, $this->devid, IStateMachine::DEVICEDATA);
                 ZLog::Write(LOGLEVEL_DEBUG, "DeviceManager->Save(): Device data saved");
             }
         } catch (StateNotFoundException $snfex) {
             ZLog::Write(LOGLEVEL_ERROR, "DeviceManager->Save(): Exception: " . $snfex->getMessage());
         }
     }
     // remove old search data
     $oldpid = $this->loopdetection->ProcessLoopDetectionGetOutdatedSearchPID();
     if ($oldpid) {
         ZPush::GetBackend()->GetSearchProvider()->TerminateSearch($oldpid);
     }
     // we terminated this process
     if ($this->loopdetection) {
         $this->loopdetection->ProcessLoopDetectionTerminate();
     }
     return true;
 }
예제 #11
0
        $versions = ZPush::GetSupportedProtocolVersions(true);
        ZLog::Write(LOGLEVEL_INFO, sprintf("Announcing latest AS version to device: %s", $versions));
        header("X-MS-RP: " . $versions);
    }
    RequestProcessor::Initialize();
    RequestProcessor::HandleRequest();
    // eventually the RequestProcessor wants to send other headers to the mobile
    foreach (RequestProcessor::GetSpecialHeaders() as $header) {
        header($header);
    }
    // log amount of data transferred
    // TODO check $len when streaming more data (e.g. Attachments), as the data will be send chunked
    ZPush::GetDeviceManager()->SentData(ob_get_length());
    ZPush::FinishResponse();
    // destruct backend after all data is on the stream
    ZPush::GetBackend()->Logoff();
} catch (NoPostRequestException $nopostex) {
    $len = ob_get_length();
    if ($len) {
        ZLog::Write(LOGLEVEL_WARN, sprintf("Cleaning %d octets of data", $len));
        ob_clean();
    }
    if ($nopostex->getCode() == NoPostRequestException::OPTIONS_REQUEST) {
        header(ZPush::GetServerHeader());
        header(ZPush::GetSupportedProtocolVersions());
        header(ZPush::GetSupportedCommands());
        ZLog::Write(LOGLEVEL_INFO, $nopostex->getMessage());
    } else {
        if ($nopostex->getCode() == NoPostRequestException::GET_REQUEST) {
            if (Request::GetUserAgent()) {
                ZLog::Write(LOGLEVEL_INFO, sprintf("User-agent: '%s'", Request::GetUserAgent()));
예제 #12
0
 /**
  * Imports a move of a message. This occurs when a user moves an item to another folder
  *
  * Normally, we would implement this via the 'offical' importmessagemove() function on the ICS importer,
  * but the Zarafa/Kopano importer does not support this. Therefore we currently implement it via a standard mapi
  * call. This causes a mirror 'add/delete' to be sent to the PDA at the next sync.
  * Manfred, 2010-10-21. For some mobiles import was causing duplicate messages in the destination folder
  * (Mantis #202). Therefore we will create a new message in the destination folder, copy properties
  * of the source message to the new one and then delete the source message.
  *
  * @param string        $id
  * @param string        $newfolder      destination folder
  *
  * @access public
  * @return boolean
  * @throws StatusException
  */
 public function ImportMessageMove($id, $newfolder)
 {
     list(, $sk) = Utils::SplitMessageId($id);
     if (strtolower($newfolder) == strtolower(bin2hex($this->folderid))) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, source and destination are equal", $id, $newfolder), SYNC_MOVEITEMSSTATUS_SAMESOURCEANDDEST);
     }
     // Get the entryid of the message we're moving
     $entryid = mapi_msgstore_entryidfromsourcekey($this->store, $this->folderid, hex2bin($sk));
     $srcmessage = false;
     if ($entryid) {
         //open the source message
         $srcmessage = mapi_msgstore_openentry($this->store, $entryid);
     }
     if (!$entryid || !$srcmessage) {
         $code = SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID;
         // if we move to the trash and the source message is not found, we can also just tell the mobile that we successfully moved to avoid errors (ZP-624)
         if ($newfolder == ZPush::GetBackend()->GetWasteBasket()) {
             $code = SYNC_MOVEITEMSSTATUS_SUCCESS;
         }
         $errorCase = !$entryid ? "resolve source message id" : "open source message";
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to %s: 0x%X", $sk, $newfolder, $errorCase, mapi_last_hresult()), $code);
     }
     // check if the source message is in the current syncinterval
     if (!$this->isMessageInSyncInterval($sk)) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Source message is outside the sync interval. Move not performed.", $sk, $newfolder), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
     }
     // get correct mapi store for the destination folder
     $dststore = ZPush::GetBackend()->GetMAPIStoreForFolderId(ZPush::GetAdditionalSyncFolderStore($newfolder), $newfolder);
     if ($dststore === false) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to open store of destination folder", $sk, $newfolder), SYNC_MOVEITEMSSTATUS_INVALIDDESTID);
     }
     $dstentryid = mapi_msgstore_entryidfromsourcekey($dststore, hex2bin($newfolder));
     if (!$dstentryid) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to resolve destination folder", $sk, $newfolder), SYNC_MOVEITEMSSTATUS_INVALIDDESTID);
     }
     $dstfolder = mapi_msgstore_openentry($dststore, $dstentryid);
     if (!$dstfolder) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to open destination folder", $sk, $newfolder), SYNC_MOVEITEMSSTATUS_INVALIDDESTID);
     }
     $newmessage = mapi_folder_createmessage($dstfolder);
     if (!$newmessage) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to create message in destination folder: 0x%X", $sk, $newfolder, mapi_last_hresult()), SYNC_MOVEITEMSSTATUS_INVALIDDESTID);
     }
     // Copy message
     mapi_copyto($srcmessage, array(), array(), $newmessage);
     if (mapi_last_hresult()) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, copy to destination message failed: 0x%X", $sk, $newfolder, mapi_last_hresult()), SYNC_MOVEITEMSSTATUS_CANNOTMOVE);
     }
     $srcfolderentryid = mapi_msgstore_entryidfromsourcekey($this->store, $this->folderid);
     if (!$srcfolderentryid) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to resolve source folder", $sk, $newfolder), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
     }
     $srcfolder = mapi_msgstore_openentry($this->store, $srcfolderentryid);
     if (!$srcfolder) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, unable to open source folder: 0x%X", $sk, $newfolder, mapi_last_hresult()), SYNC_MOVEITEMSSTATUS_INVALIDSOURCEID);
     }
     // Save changes
     mapi_savechanges($newmessage);
     if (mapi_last_hresult()) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, mapi_savechanges() failed: 0x%X", $sk, $newfolder, mapi_last_hresult()), SYNC_MOVEITEMSSTATUS_CANNOTMOVE);
     }
     // Delete the old message
     if (!mapi_folder_deletemessages($srcfolder, array($entryid))) {
         throw new StatusException(sprintf("ImportChangesICS->ImportMessageMove('%s','%s'): Error, delete of source message failed: 0x%X. Possible duplicates.", $sk, $newfolder, mapi_last_hresult()), SYNC_MOVEITEMSSTATUS_SOURCEORDESTLOCKED);
     }
     $sourcekeyprops = mapi_getprops($newmessage, array(PR_SOURCE_KEY));
     if (isset($sourcekeyprops[PR_SOURCE_KEY]) && $sourcekeyprops[PR_SOURCE_KEY]) {
         $prefix = "";
         // prepend the destination short folderid, if it exists
         $destShortId = ZPush::GetDeviceManager()->GetFolderIdForBackendId($newfolder);
         if ($destShortId !== $newfolder) {
             $prefix = $destShortId . ":";
         }
         return $prefix . bin2hex($sourcekeyprops[PR_SOURCE_KEY]);
     }
     return false;
 }
예제 #13
0
 /**
  * Sends an email notification to the user containing the data the user tried to save.
  *
  * @param SyncObject $message
  * @param SyncObject $oldmessage
  * @return void
  */
 private function sendNotificationEmail($message, $oldmessage)
 {
     // get email address and full name of the user
     $userinfo = ZPush::GetBackend()->GetUserDetails(Request::GetAuthUser());
     // get the name of the folder
     $foldername = "unknown";
     $folderid = bin2hex($this->folderid);
     $folders = ZPush::GetAdditionalSyncFolders();
     if (isset($folders[$folderid]) && isset($folders[$folderid]->displayname)) {
         $foldername = $folders[$folderid]->displayname;
     }
     // get the differences between the two objects
     $data = substr(get_class($oldmessage), 4) . "\r\n";
     // get the suppported fields as we need them to determine the ghosted properties
     $supportedFields = ZPush::GetDeviceManager()->GetSupportedFields(ZPush::GetDeviceManager()->GetFolderIdForBackendId($folderid));
     $dataarray = $oldmessage->EvaluateAndCompare($message, @constant('READ_ONLY_NOTIFY_YOURDATA'), $supportedFields);
     foreach ($dataarray as $key => $value) {
         $value = str_replace("\r", "", $value);
         $value = str_replace("\n", str_pad("\r\n", 25), $value);
         $data .= str_pad(ucfirst($key) . ":", 25) . $value . "\r\n";
     }
     // build a simple mime message
     $toEmail = $userinfo['emailaddress'];
     $mail = "From: Z-Push <no-reply>\r\n";
     $mail .= "To: {$toEmail}\r\n";
     $mail .= "Content-Type: text/plain; charset=utf-8\r\n";
     $mail .= "Subject: " . @constant('READ_ONLY_NOTIFY_SUBJECT') . "\r\n\r\n";
     $mail .= @constant('READ_ONLY_NOTIFY_BODY') . "\r\n";
     // replace values of template
     $mail = str_replace("**USERFULLNAME**", $userinfo['fullname'], $mail);
     $mail = str_replace("**DATE**", strftime(@constant('READ_ONLY_NOTIFY_DATE_FORMAT')), $mail);
     $mail = str_replace("**TIME**", strftime(@constant('READ_ONLY_NOTIFY_TIME_FORMAT')), $mail);
     $mail = str_replace("**FOLDERNAME**", $foldername, $mail);
     $mail = str_replace("**MOBILETYPE**", Request::GetDeviceType(), $mail);
     $mail = str_replace("**MOBILEDEVICEID**", Request::GetDeviceID(), $mail);
     $mail = str_replace("**DIFFERENCES**", $data, $mail);
     // user send email to himself
     $m = new SyncSendMail();
     $m->saveinsent = false;
     $m->replacemime = true;
     $m->mime = $mail;
     ZPush::GetBackend()->SendMail($m);
 }
예제 #14
0
 /**
  * Returns a list of all additional folders of the given device and the Request::GetGETUser().
  *
  * @param string    $deviceId       device id that should be listed.
  *
  * @access public
  * @return array
  */
 public function AdditionalFolderList($deviceId)
 {
     $user = Request::GetGETUser();
     $deviceId = preg_replace("/[^A-Za-z0-9]/", "", $deviceId);
     $folders = ZPushAdmin::AdditionalFolderList($user, $deviceId);
     ZLog::Write(LOGLEVEL_INFO, sprintf("WebserviceDevice::AdditionalFolderList(): found %d folders for device '%s' of user '%s'", count($folders), $deviceId, $user));
     // retrieve the permission flags from the backend
     $backend = ZPush::GetBackend();
     foreach ($folders as &$folder) {
         $folder['readable'] = $backend->Setup($folder['store'], true, $folder['folderid'], true);
         $folder['writeable'] = $backend->Setup($folder['store'], true, $folder['folderid']);
     }
     // make sure folder is not pointing to our last folder anymore
     unset($folder);
     ZPush::GetTopCollector()->AnnounceInformation(sprintf("Retrieved details of %d folders", count($folders)), true);
     return $folders;
 }
예제 #15
0
 /**
  * Does the complete autodiscover.
  * @access public
  * @throws AuthenticationRequiredException if login to the backend failed.
  * @throws ZPushException if the incoming XML is invalid..
  *
  * @return void
  */
 public function DoAutodiscover()
 {
     $response = "";
     try {
         $incomingXml = $this->getIncomingXml();
         $backend = ZPush::GetBackend();
         $username = $this->login($backend, $incomingXml);
         $userDetails = $backend->GetUserDetails($username);
         $email = $this->getAttribFromUserDetails($userDetails, 'emailaddress') ? $this->getAttribFromUserDetails($userDetails, 'emailaddress') : $incomingXml->Request->EMailAddress;
         $userFullname = $this->getAttribFromUserDetails($userDetails, 'fullname') ? $this->getAttribFromUserDetails($userDetails, 'fullname') : $email;
         ZLog::Write(LOGLEVEL_WBXML, sprintf("Resolved user's '%s' fullname to '%s'", $username, $userFullname));
         // At the moment Z-Push only supports mobile response schema for autodiscover. Send empty response if the client request outlook response schema.
         if ($incomingXml->Request->AcceptableResponseSchema == ZPushAutodiscover::ACCEPTABLERESPONSESCHEMAMOBILESYNC) {
             $response = $this->createResponse($email, $userFullname);
             setcookie("membername", $username);
         }
     } catch (AuthenticationRequiredException $ex) {
         if (isset($incomingXml)) {
             ZLog::Write(LOGLEVEL_ERROR, sprintf("Unable to complete autodiscover because login failed for user with email '%s'", $incomingXml->Request->EMailAddress));
         } else {
             ZLog::Write(LOGLEVEL_ERROR, sprintf("Unable to complete autodiscover incorrect request: '%s'", $ex->getMessage()));
         }
         http_response_code(401);
         header('WWW-Authenticate: Basic realm="ZPush"');
     } catch (ZPushException $ex) {
         ZLog::Write(LOGLEVEL_ERROR, sprintf("Unable to complete autodiscover because of ZPushException. Error: %s", $ex->getMessage()));
         if (!headers_sent()) {
             header('HTTP/1.1 ' . $ex->getHTTPCodeString());
             foreach ($ex->getHTTPHeaders() as $h) {
                 header($h);
             }
         }
     }
     $this->sendResponse($response);
 }
 /**
  * Initialize the RequestProcessor
  *
  * @access public
  * @return
  */
 public static function Initialize()
 {
     self::$backend = ZPush::GetBackend();
     self::$deviceManager = ZPush::GetDeviceManager();
     self::$topCollector = ZPush::GetTopCollector();
     if (!ZPush::CommandNeedsPlainInput(Request::GetCommandCode())) {
         self::$decoder = new WBXMLDecoder(Request::GetInputStream());
     }
     self::$encoder = new WBXMLEncoder(Request::GetOutputStream(), Request::GetGETAcceptMultipart());
 }
예제 #17
0
 ZLog::Initialize();
 ZLog::Write(LOGLEVEL_DEBUG, "-------- Start");
 ZLog::Write(LOGLEVEL_INFO, sprintf("Version='%s' method='%s' from='%s' cmd='%s' getUser='******' devId='%s' devType='%s'", @constant('ZPUSH_VERSION'), Request::GetMethod(), Request::GetRemoteAddr(), Request::GetCommand(), Request::GetGETUser(), Request::GetDeviceID(), Request::GetDeviceType()));
 // Stop here if this is an OPTIONS request
 if (Request::IsMethodOPTIONS()) {
     throw new NoPostRequestException("Options request", NoPostRequestException::OPTIONS_REQUEST);
 }
 ZPush::CheckAdvancedConfig();
 // Process request headers and look for AS headers
 Request::ProcessHeaders();
 // Check required GET parameters
 if (Request::IsMethodPOST() && (Request::GetCommandCode() === false || !Request::GetGETUser() || !Request::GetDeviceID() || !Request::GetDeviceType())) {
     throw new FatalException("Requested the Z-Push URL without the required GET parameters");
 }
 // Load the backend
 $backend = ZPush::GetBackend();
 // always request the authorization header
 if (!Request::AuthenticationInfo()) {
     throw new AuthenticationRequiredException("Access denied. Please send authorisation information");
 }
 // check the provisioning information
 if (PROVISIONING === true && Request::IsMethodPOST() && ZPush::CommandNeedsProvisioning(Request::GetCommandCode()) && (Request::WasPolicyKeySent() && Request::GetPolicyKey() == 0 || ZPush::GetDeviceManager()->ProvisioningRequired(Request::GetPolicyKey())) && (LOOSE_PROVISIONING === false || LOOSE_PROVISIONING === true && Request::WasPolicyKeySent())) {
     //TODO for AS 14 send a wbxml response
     throw new ProvisioningRequiredException();
 }
 // most commands require an authenticated user
 if (ZPush::CommandNeedsAuthentication(Request::GetCommandCode())) {
     RequestProcessor::Authenticate();
 }
 // Do the actual processing of the request
 if (Request::IsMethodGET()) {
예제 #18
0
 /**
  * Applies settings to and gets informations from the device
  *
  * @param SyncObject    $settings (SyncOOF or SyncUserInformation possible)
  *
  * @access public
  * @return SyncObject   $settings
  */
 public function Settings($settings)
 {
     if ($settings instanceof SyncOOF) {
         $isget = !empty($settings->bodytype);
         $settings = new SyncOOF();
         if ($isget) {
             //oof get
             $settings->oofstate = 0;
             $settings->Status = SYNC_SETTINGSSTATUS_SUCCESS;
         } else {
             //oof set
             $settings->Status = SYNC_SETTINGSSTATUS_PROTOCOLLERROR;
         }
     }
     if ($settings instanceof SyncUserInformation) {
         $settings->emailaddresses = array(ZPush::GetBackend()->GetUserDetails(Request::GetAuthUser())['emailaddress']);
         $settings->Status = SYNC_SETTINGSSTATUS_SUCCESS;
     }
     return $settings;
 }