Author: Michael J Rubinsky (mrubinsk@horde.org)
Example #1
0
 public function testDefaultXml()
 {
     $stream = fopen('php://memory', 'w+');
     $encoder = new Horde_ActiveSync_Wbxml_Encoder($stream);
     $handler = new Horde_ActiveSync_Policies($encoder);
     $handler->toXml();
     rewind($stream);
     $results = stream_get_contents($stream);
     fclose($stream);
     $fixture = file_get_contents(__DIR__ . '/fixtures/default_policies.xml');
     $this->assertEquals($fixture, $results);
 }
Example #2
0
 /**
  * Handle the Provision request. This is a 3-phase process. Phase 1 is
  * actually the enforcement, when the server rejects a request and forces
  * the client to perform this PROVISION request...so we are handling phase
  * 2 (download policies) and 3 (acknowledge policies) here.
  *
  * @return boolean
  * @throws Horde_ActiveSync_Exception
  */
 protected function _handle()
 {
     // Be optimistic
     $status = self::STATUS_SUCCESS;
     $policyStatus = self::STATUS_SUCCESS;
     if ($error = $this->_activeSync->checkGlobalError()) {
         $this->_globalError($error);
         return true;
     }
     // Start by assuming we are in stage 2
     $phase2 = true;
     if (!$this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_PROVISION)) {
         return $this->_globalError(self::STATUS_PROTERROR);
     }
     // Handle remote wipe status response for Android devices.
     if ($this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_REMOTEWIPE)) {
         if (!$this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_STATUS)) {
             return $this->_globalError(self::STATUS_PROTERROR);
         }
         $status = $this->_decoder->getElementContent();
         if (!$this->_decoder->getElementEndTag() || !$this->_decoder->getElementEndTag()) {
             return $this->_globalError(self::STATUS_PROTERROR);
         }
         if ($status == self::STATUS_CLIENT_SUCCESS) {
             $this->_state->setDeviceRWStatus($this->_devId, Horde_ActiveSync::RWSTATUS_WIPED);
         }
         $policytype = Horde_ActiveSync::POLICYTYPE_XML;
     } else {
         if ($deviceinfo = $this->_handleSettings()) {
             $deviceinfo['version'] = $this->_device->version;
             $this->_device->setDeviceProperties($deviceinfo);
             $this->_device->save();
         }
         if (!$this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_POLICIES) || !$this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_POLICY)) {
             return $this->_globalError(self::STATUS_PROTERROR);
         }
         // iOS (at least 5.0.1) incorrectly sends a STATUS tag before the
         // REMOTEWIPE response.
         if (!$this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_POLICYTYPE)) {
             if ($this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_STATUS)) {
                 $this->_decoder->getElementContent();
                 $this->_decoder->getElementEndTag();
                 // status
             }
         } else {
             $policytype = $this->_decoder->getElementContent();
             if ($this->_device->version < Horde_ActiveSync::VERSION_TWELVE && $policytype != Horde_ActiveSync::POLICYTYPE_XML) {
                 $this->_logger->err('EAS version < 12.0 but policy type is not POLICYTYPE_XML');
                 $policyStatus = self::STATUS_POLICYUNKNOWN;
             }
             if ($this->_device->version >= Horde_ActiveSync::VERSION_TWELVE && $policytype != Horde_ActiveSync::POLICYTYPE_WBXML) {
                 $this->_logger->err('EAS version >= 12.0 but policy type is not POLICYTYPE_WBXML');
                 $policyStatus = self::STATUS_POLICYUNKNOWN;
             }
             if (!$this->_decoder->getElementEndTag()) {
                 //policytype
                 return $this->_globalError(self::STATUS_PROTERROR);
             }
         }
         // POLICYKEY is only sent by client in phase 3
         if ($this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_POLICYKEY)) {
             $policykey = $this->_decoder->getElementContent();
             $this->_logger->info('[' . $this->_device->id . '] PHASE 3 policykey sent from client: ' . $policykey);
             if (!$this->_decoder->getElementEndTag() || !$this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_STATUS)) {
                 return $this->_globalError(self::STATUS_PROTERROR);
             }
             if ($this->_decoder->getElementContent() != self::STATUS_SUCCESS) {
                 $this->_logger->err('Policy not accepted by device: ' . $this->_device->id);
                 if ($this->_provisioning == Horde_ActiveSync::PROVISIONING_LOOSE) {
                     // Loose provisioning, don't error out, just don't reqiure provision.
                     $this->_sendNoProvisionNeededResponse($status);
                     return true;
                 }
                 $policyStatus = self::STATUS_POLICYCORRUPT;
             }
             if (!$this->_decoder->getElementEndTag()) {
                 return $this->_globalError(self::STATUS_PROTERROR);
             }
             $phase2 = false;
         }
         if (!$this->_decoder->getElementEndTag() || !$this->_decoder->getElementEndTag()) {
             return $this->_globalError(self::STATUS_PROTERROR);
         }
         // Handle remote wipe status for other devices
         if ($this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_REMOTEWIPE)) {
             if (!$this->_decoder->getElementStartTag(Horde_ActiveSync::PROVISION_STATUS)) {
                 return $this->_globalError(self::STATUS_PROTERROR);
             }
             $status = $this->_decoder->getElementContent();
             if (!$this->_decoder->getElementEndTag() || !$this->_decoder->getElementEndTag()) {
                 return $this->_globalError(self::STATUS_PROTERROR);
             }
             if ($status == self::STATUS_CLIENT_SUCCESS) {
                 $this->_state->setDeviceRWStatus($this->_device->id, Horde_ActiveSync::RWSTATUS_WIPED);
             }
         }
     }
     if (!$this->_decoder->getElementEndTag()) {
         //provision
         return $this->_globalError(self::STATUS_PROTERROR);
     }
     // Check to be sure that we *need* to PROVISION
     if ($this->_provisioning === false) {
         $this->_sendNoProvisionNeededResponse($status);
         return true;
     }
     // Start handling request and sending output
     $this->_encoder->StartWBXML();
     // End of Phase 3 - We create the "final" policy key, store it, then
     // send it to the client.
     if (!$phase2) {
         // Verify intermediate key
         $this->_logger->info(sprintf('Verifying Phase 3 policykey: From Device: %s, Stored: %s', $policykey, $this->_device->policykey));
         if ($this->_state->getPolicyKey($this->_device->id) != $policykey) {
             $policyStatus = self::STATUS_POLKEYMISM;
         } else {
             // Set the final key
             $policykey = $this->_state->generatePolicyKey();
             $this->_state->setPolicyKey($this->_device->id, $policykey);
             $this->_state->setDeviceRWStatus($this->_device->id, Horde_ActiveSync::RWSTATUS_OK);
         }
         $this->_cleanUpAfterPairing();
     } elseif (empty($policykey)) {
         // This is phase2 - we need to set the intermediate key
         $policykey = $this->_state->generatePolicyKey();
         $this->_logger->info(sprintf('Generating PHASE2 policy key: %s', $policykey));
         $this->_state->setPolicyKey($this->_device->id, $policykey);
     }
     // If we are phase2 we need to check this here, before the status is
     // sent. Prevents devices not supporting the required policies from
     // being able to connect.
     if ($phase2 && $status == self::STATUS_SUCCESS && $policyStatus == self::STATUS_SUCCESS && $this->_provisioning == Horde_ActiveSync::PROVISIONING_FORCE) {
         $policyHandler = new Horde_ActiveSync_Policies($this->_encoder, $this->_device->version, $this->_driver->getCurrentPolicy($deviceinfo));
         if (!$policyHandler->validatePolicyVersion()) {
             $this->_handleVersionMismatch();
             return true;
         }
     }
     $this->_encoder->startTag(Horde_ActiveSync::PROVISION_PROVISION);
     $this->_encoder->startTag(Horde_ActiveSync::PROVISION_STATUS);
     $this->_encoder->content($status);
     $this->_encoder->endTag();
     $this->_encoder->startTag(Horde_ActiveSync::PROVISION_POLICIES);
     $this->_encoder->startTag(Horde_ActiveSync::PROVISION_POLICY);
     $this->_encoder->startTag(Horde_ActiveSync::PROVISION_POLICYTYPE);
     $this->_encoder->content($policytype);
     $this->_encoder->endTag();
     $this->_encoder->startTag(Horde_ActiveSync::PROVISION_STATUS);
     $this->_encoder->content($policyStatus);
     $this->_encoder->endTag();
     $this->_encoder->startTag(Horde_ActiveSync::PROVISION_POLICYKEY);
     $this->_encoder->content($policykey);
     $this->_encoder->endTag();
     // Send security policies.
     if ($phase2 && $status == self::STATUS_SUCCESS && $policyStatus == self::STATUS_SUCCESS) {
         $this->_encoder->startTag(Horde_ActiveSync::PROVISION_DATA);
         if ($policytype == Horde_ActiveSync::POLICYTYPE_XML) {
             $policyHandler->toXml();
         } else {
             $policyHandler->toWbxml();
         }
         $this->_encoder->endTag();
         //data
     }
     $this->_encoder->endTag();
     //policy
     $this->_encoder->endTag();
     //policies
     // Remote wipe if requested.
     $rwstatus = $this->_state->getDeviceRWStatus($this->_device->id);
     if ($rwstatus == Horde_ActiveSync::RWSTATUS_PENDING || $rwstatus == Horde_ActiveSync::RWSTATUS_WIPED) {
         $this->_encoder->startTag(Horde_ActiveSync::PROVISION_REMOTEWIPE, false, true);
         $this->_state->setDeviceRWStatus($this->_device->id, Horde_ActiveSync::RWSTATUS_WIPED);
     }
     $this->_encoder->endTag();
     //provision
     return true;
 }
Example #3
0
 /**
  * Return a policy array suitable for transforming into either wbxml or xml
  * to send to the device in the provision response.
  *
  * @param boolean $deviceinfo  EAS 14.1 DEVICESETTINGS sent with PROVISION.
  *
  * @return array
  */
 protected function _getPolicyFromPerms($deviceinfo = false)
 {
     $prefix = 'horde:activesync:provisioning:';
     $policy = array();
     $perms = $GLOBALS['injector']->getInstance('Horde_Perms');
     if (!$perms->exists('horde:activesync:provisioning')) {
         return $policy;
     }
     $policies = new Horde_ActiveSync_Policies(null, $this->_version);
     $properties = $policies->getAvailablePolicies();
     foreach ($properties as $property) {
         if ($perms->exists($prefix . $property)) {
             $p = $perms->getPermissions($prefix . $property, $this->_user);
             $policy[$property] = $this->_getPolicyValue($property, $p);
         }
     }
     return $policy;
 }