Example #1
0
 /**
  * Initializes the logging
  *
  * @access public
  * @return boolean
  */
 public static function Initialize()
 {
     global $specialLogUsers;
     // define some constants for the logging
     if (!defined('LOGUSERLEVEL')) {
         define('LOGUSERLEVEL', LOGLEVEL_OFF);
     }
     if (!defined('LOGLEVEL')) {
         define('LOGLEVEL', LOGLEVEL_OFF);
     }
     list($user, ) = Utils::SplitDomainUser(Request::GetGETUser());
     if (!defined('WBXML_DEBUG') && $user) {
         // define the WBXML_DEBUG mode on user basis depending on the configurations
         if (LOGLEVEL >= LOGLEVEL_WBXML || LOGUSERLEVEL >= LOGLEVEL_WBXML && in_array($user, $specialLogUsers)) {
             define('WBXML_DEBUG', true);
         } else {
             define('WBXML_DEBUG', false);
         }
     }
     if ($user) {
         self::$user = '[' . $user . '] ';
     } else {
         self::$user = '';
     }
     // log the device id if the global loglevel is set to log devid or the user is in  and has the right log level
     if (Request::GetDeviceID() != "" && (LOGLEVEL >= LOGLEVEL_DEVICEID || LOGUSERLEVEL >= LOGLEVEL_DEVICEID && in_array($user, $specialLogUsers))) {
         self::$devid = '[' . Request::GetDeviceID() . '] ';
     } else {
         self::$devid = '';
     }
     return true;
 }
 /**
  * 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;
 }
 /**
  * Authenticates the remote user
  * The sent HTTP authentication information is used to on Backend->Logon().
  * As second step the GET-User verified by Backend->Setup() for permission check
  * Request::GetGETUser() is usually the same as the Request::GetAuthUser().
  * If the GETUser is different from the AuthUser, the AuthUser MUST HAVE admin
  * permissions on GETUsers data store. Only then the Setup() will be sucessfull.
  * This allows the user 'john' to do operations as user 'joe' if he has sufficient privileges.
  *
  * @access public
  * @return
  * @throws AuthenticationRequiredException
  */
 public static function Authenticate()
 {
     self::$userIsAuthenticated = false;
     $backend = ZPush::GetBackend();
     if ($backend->Logon(Request::GetAuthUser(), Request::GetAuthDomain(), Request::GetAuthPassword()) == false) {
         throw new AuthenticationRequiredException("Access denied. Username or password incorrect");
     }
     // mark this request as "authenticated"
     self::$userIsAuthenticated = true;
     // check Auth-User's permissions on GETUser's store
     if ($backend->Setup(Request::GetGETUser(), true) == false) {
         throw new AuthenticationRequiredException(sprintf("Not enough privileges of '%s' to setup for user '%s': Permission denied", Request::GetAuthUser(), Request::GetGETUser()));
     }
 }
Example #4
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;
 }
Example #5
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");
     }
     $this->server->handle();
     ZLog::Write(LOGLEVEL_DEBUG, sprintf("Webservice::HandleWebservice('%s'): sucessfully sent %d bytes", $commandCode, ob_get_length()));
     return true;
 }
 /**
  * Constructor
  *
  * @access public
  */
 public function DeviceManager()
 {
     $this->statemachine = ZPush::GetStateMachine();
     $this->deviceHash = false;
     $this->devid = Request::GetDeviceID();
     $this->windowSize = array();
     $this->latestFolder = false;
     $this->hierarchySyncRequired = false;
     // only continue if deviceid is set
     if ($this->devid) {
         $this->device = new ASDevice($this->devid, Request::GetDeviceType(), Request::GetGETUser(), Request::GetUserAgent());
         $this->loadDeviceData();
         ZPush::GetTopCollector()->SetUserAgent($this->device->GetDeviceUserAgent());
     } else {
         throw new FatalNotImplementedException("Can not proceed without a device id.");
     }
     $this->loopdetection = new LoopDetection();
     $this->loopdetection->ProcessLoopDetectionInit();
     $this->loopdetection->ProcessLoopDetectionPreviousConnectionFailed();
     $this->stateManager = new StateManager();
     $this->stateManager->SetDevice($this->device);
 }
Example #7
0
     if ($ex instanceof ZPushException) {
         header('HTTP/1.1 ' . $ex->getHTTPCodeString());
         foreach ($ex->getHTTPHeaders() as $h) {
             header($h);
         }
     } else {
         header('HTTP/1.1 500 Internal Server Error');
     }
 } else {
     ZLog::Write(LOGLEVEL_FATAL, "Exception: ({$exclass}) - headers were already sent. Message: " . $ex->getMessage());
 }
 if ($ex instanceof AuthenticationRequiredException) {
     ZPush::PrintZPushLegal($exclass, sprintf('<pre>%s</pre>', $ex->getMessage()));
     // log the failed login attemt e.g. for fail2ban
     if (defined('LOGAUTHFAIL') && LOGAUTHFAIL != false) {
         ZLog::Write(LOGLEVEL_WARN, sprintf("IP: %s failed to authenticate user '%s'", Request::GetRemoteAddr(), Request::GetAuthUser() ? Request::GetAuthUser() : Request::GetGETUser()));
     }
 } else {
     if ($ex instanceof WBXMLException) {
         ZLog::Write(LOGLEVEL_FATAL, "Request could not be processed correctly due to a WBXMLException. Please report this.");
     } else {
         if (!$ex instanceof ZPushException || $ex->showLegalNotice()) {
             $cmdinfo = Request::GetCommand() ? sprintf(" processing command <i>%s</i>", Request::GetCommand()) : "";
             $extrace = $ex->getTrace();
             $trace = !empty($extrace) ? "\n\nTrace:\n" . print_r($extrace, 1) : "";
             ZPush::PrintZPushLegal($exclass . $cmdinfo, sprintf('<pre>%s</pre>', $ex->getMessage() . $trace));
         }
     }
 }
 // Announce exception to process loop detection
 if (ZPush::GetDeviceManager(false)) {
Example #8
0
 /**
  * Marks a a device of the Request::GetGETUser() for resynchronization
  *
  * @param string    $deviceId       the device id
  *
  * @access public
  * @return boolean
  * @throws SoapFault
  */
 public function ResyncDevice($deviceId)
 {
     $deviceId = preg_replace("/[^A-Za-z0-9]/", "", $deviceId);
     ZLog::Write(LOGLEVEL_INFO, sprintf("WebserviceDevice::ResyncDevice('%s'): mark device of user '%s' for resynchronization", $deviceId, Request::GetGETUser()));
     if (!ZPushAdmin::ResyncDevice(Request::GetGETUser(), $deviceId)) {
         ZPush::GetTopCollector()->AnnounceInformation(ZLog::GetLastMessage(LOGLEVEL_ERROR), true);
         throw new SoapFault("ERROR", ZLog::GetLastMessage(LOGLEVEL_ERROR));
     }
     ZPush::GetTopCollector()->AnnounceInformation(sprintf("Resync requested - device id '%s'", $deviceId), true);
     return true;
 }
Example #9
0
 /**
  * Authenticates the remote user
  * The sent HTTP authentication information is used to on Backend->Logon().
  * As second step the GET-User verified by Backend->Setup() for permission check
  * Request::GetGETUser() is usually the same as the Request::GetAuthUser().
  * If the GETUser is different from the AuthUser, the AuthUser MUST HAVE admin
  * permissions on GETUsers data store. Only then the Setup() will be sucessfull.
  * This allows the user 'john' to do operations as user 'joe' if he has sufficient privileges.
  *
  * @access public
  * @return
  * @throws AuthenticationRequiredException
  */
 public static function Authenticate()
 {
     self::$userIsAuthenticated = false;
     // when a certificate is sent, allow authentication only as the certificate owner
     if (defined("CERTIFICATE_OWNER_PARAMETER") && isset($_SERVER[CERTIFICATE_OWNER_PARAMETER]) && strtolower($_SERVER[CERTIFICATE_OWNER_PARAMETER]) != strtolower(Request::GetAuthUser())) {
         throw new AuthenticationRequiredException(sprintf("Access denied. Access is allowed only for the certificate owner '%s'", $_SERVER[CERTIFICATE_OWNER_PARAMETER]));
     }
     $backend = ZPush::GetBackend();
     if ($backend->Logon(Request::GetAuthUser(), Request::GetAuthDomain(), Request::GetAuthPassword()) == false) {
         throw new AuthenticationRequiredException("Access denied. Username or password incorrect");
     }
     // mark this request as "authenticated"
     self::$userIsAuthenticated = true;
     // check Auth-User's permissions on GETUser's store
     if ($backend->Setup(Request::GetGETUser(), true) == false) {
         throw new AuthenticationRequiredException(sprintf("Not enough privileges of '%s' to setup for user '%s': Permission denied", Request::GetAuthUser(), Request::GetGETUser()));
     }
 }
Example #10
0
        ZPush::PrintZPushLegal($exclass, sprintf('<pre>%s</pre>', $ex->getMessage()));
        // log the failed login attemt e.g. for fail2ban
        if (defined('LOGAUTHFAIL') && LOGAUTHFAIL != false) {
            ZLog::Write(LOGLEVEL_WARN, sprintf("IP: %s failed to authenticate user '%s'", Request::GetRemoteAddr(), Request::GetAuthUser() ? Request::GetAuthUser() : Request::GetGETUser()));
        }
    } else {
        if ($ex instanceof WBXMLException) {
            ZLog::Write(LOGLEVEL_FATAL, "Request could not be processed correctly due to a WBXMLException. Please report this including the 'WBXML debug data' logged. Be aware that the debug data could contain confidential information.");
        } else {
            if (!$ex instanceof ZPushException || $ex->showLegalNotice()) {
                $cmdinfo = Request::GetCommand() ? sprintf(" processing command <i>%s</i>", Request::GetCommand()) : "";
                $extrace = $ex->getTrace();
                $trace = !empty($extrace) ? "\n\nTrace:\n" . print_r($extrace, 1) : "";
                ZPush::PrintZPushLegal($exclass . $cmdinfo, sprintf('<pre>%s</pre>', $ex->getMessage() . $trace));
            }
        }
    }
    // Announce exception to process loop detection
    if (ZPush::GetDeviceManager(false)) {
        ZPush::GetDeviceManager()->AnnounceProcessException($ex);
    }
    // Announce exception if the TopCollector if available
    ZPush::GetTopCollector()->AnnounceInformation(get_class($ex), true);
}
// save device data if the DeviceManager is available
if (ZPush::GetDeviceManager(false)) {
    ZPush::GetDeviceManager()->Save();
}
// end gracefully
ZLog::Write(LOGLEVEL_INFO, sprintf("cmd='%s' memory='%s/%s' time='%ss' devType='%s' devId='%s' getUser='%s' from='%s' version='%s' method='%s' httpcode='%s'", Request::GetCommand(), Utils::FormatBytes(memory_get_peak_usage(false)), Utils::FormatBytes(memory_get_peak_usage(true)), number_format(microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"], 2), Request::GetDeviceType(), Request::GetDeviceID(), Request::GetGETUser(), Request::GetRemoteAddr(), @constant('ZPUSH_VERSION'), Request::GetMethod(), http_response_code()));
ZLog::Write(LOGLEVEL_DEBUG, "-------- End");
Example #11
0
 /**
  * Removes an additional folder from the given device and the Request::GetGETUser().
  *
  * @param string    $deviceId       device id of where the folder should be removed.
  * @param string    $add_folderid   the folder id of the additional folder.
  *
  * @access public
  * @return boolean
  */
 public function AdditionalFolderRemove($deviceId, $add_folderid)
 {
     $user = Request::GetGETUser();
     $deviceId = preg_replace("/[^A-Za-z0-9]/", "", $deviceId);
     $add_folderid = preg_replace("/[^A-Za-z0-9]/", "", $add_folderid);
     $status = ZPushAdmin::AdditionalFolderRemove($user, $deviceId, $add_folderid);
     if (!$status) {
         ZPush::GetTopCollector()->AnnounceInformation(ZLog::GetLastMessage(LOGLEVEL_ERROR), true);
         throw new SoapFault("ERROR", ZLog::GetLastMessage(LOGLEVEL_ERROR));
     }
     ZLog::Write(LOGLEVEL_INFO, sprintf("WebserviceDevice::AdditionalFolderRemove(): removed folder for device '%s' of user '%s': %s", $deviceId, $user, Utils::PrintAsString($status)));
     ZPush::GetTopCollector()->AnnounceInformation("Removed additional folder", true);
     return $status;
 }
Example #12
0
 /**
  * Constructor
  *
  * @access public
  */
 public function __construct()
 {
     $this->statemachine = ZPush::GetStateMachine();
     $this->deviceHash = false;
     $this->devid = Request::GetDeviceID();
     $this->saveDevice = true;
     $this->windowSize = array();
     $this->latestFolder = false;
     $this->hierarchySyncRequired = false;
     // only continue if deviceid is set
     if ($this->devid) {
         $this->device = new ASDevice($this->devid, Request::GetDeviceType(), Request::GetGETUser(), Request::GetUserAgent());
         $this->loadDeviceData();
         ZPush::GetTopCollector()->SetUserAgent($this->device->GetDeviceUserAgent());
     } else {
         throw new FatalNotImplementedException("Can not proceed without a device id.");
     }
     $this->loopdetection = new LoopDetection();
     $this->loopdetection->ProcessLoopDetectionInit();
     $this->loopdetection->ProcessLoopDetectionPreviousConnectionFailed();
     $this->stateManager = new StateManager();
     $this->stateManager->SetDevice($this->device);
     $this->additionalFoldersHash = $this->getAdditionalFoldersHash();
     if ($this->IsKoe() && $this->device->GetKoeVersion() !== false) {
         ZLog::Write(LOGLEVEL_DEBUG, sprintf("KOE: %s / %s / %s", $this->device->GetKoeVersion(), $this->device->GetKoeBuild(), strftime("%Y-%m-%d %H:%M", $this->device->GetKoeBuildDate())));
     }
 }
Example #13
0
 /**
  * Returns the logger object. If no logger has been initialized, FileLog will be initialized and returned.
  *
  * @access private
  * @return Log
  * @throws Exception thrown if the logger class cannot be instantiated.
  */
 private static function getLogger()
 {
     if (!self::$logger) {
         global $specialLogUsers;
         // This variable comes from the configuration file (config.php)
         $logger = LOGBACKEND_CLASS;
         if (!class_exists($logger)) {
             $errmsg = 'The configured logging class `' . $logger . '` does not exist. Check your configuration.';
             error_log($errmsg);
             throw new \Exception($errmsg);
         }
         list($user) = Utils::SplitDomainUser(strtolower(Request::GetGETUser()));
         $user = '[' . $user . ']';
         self::$logger = new $logger();
         self::$logger->SetUser($user);
         self::$logger->SetAuthUser(Request::GetAuthUser());
         self::$logger->SetSpecialLogUsers($specialLogUsers);
         self::$logger->SetDevid('[' . Request::GetDeviceID() . ']');
         self::$logger->SetPidstr('[' . str_pad(@getmypid(), 5, " ", STR_PAD_LEFT) . ']');
         self::$logger->AfterInitialize();
     }
     return self::$logger;
 }