예제 #1
0
  def CreatePolicyForExternalPolicyData(self, policy_key):
    """Returns an ExternalPolicyData protobuf for policy_key.

    If there is policy data for policy_key then the download url will be
    set so that it points to that data, and the appropriate hash is also set.
    Otherwise, the protobuf will be empty.

    Args:
      policy_key: The policy type and settings entity id, joined by '/'.

    Returns:
      A serialized ExternalPolicyData.
    """
    settings = ep.ExternalPolicyData()
    data = self.server.ReadPolicyDataFromDataDir(policy_key)
    if data:
      settings.download_url = urlparse.urljoin(
          self.server.GetBaseURL(), 'externalpolicydata?key=%s' % policy_key)
      settings.secure_hash = hashlib.sha256(data).digest()
    return settings.SerializeToString()
예제 #2
0
    def ProcessCloudPolicy(self, msg, token_info, response):
        """Handles a cloud policy request. (New protocol for policy requests.)

    Encodes the policy into protobuf representation, signs it and constructs
    the response.

    Args:
      msg: The CloudPolicyRequest message received from the client.
      token_info: the token extracted from the request.
      response: A PolicyFetchResponse message that should be filled with the
                response data.
    """

        if msg.machine_id:
            self.server.UpdateMachineId(token_info['device_token'],
                                        msg.machine_id)

        # Response is only given if the scope is specified in the config file.
        # Normally 'google/chromeos/device', 'google/chromeos/user' and
        # 'google/chromeos/publicaccount' should be accepted.
        policy = self.server.GetPolicies()
        policy_value = ''
        policy_key = msg.policy_type
        if msg.settings_entity_id:
            policy_key += '/' + msg.settings_entity_id
        if msg.policy_type in token_info['allowed_policy_types']:
            if (msg.policy_type == 'google/chromeos/user'
                    or msg.policy_type == 'google/chrome/user'
                    or msg.policy_type == 'google/chromeos/publicaccount'):
                settings = cp.CloudPolicySettings()
                payload = self.server.ReadPolicyFromDataDir(
                    policy_key, settings)
                if payload is None:
                    self.GatherUserPolicySettings(settings,
                                                  policy.get(policy_key, {}))
                    payload = settings.SerializeToString()
            elif dp is not None and msg.policy_type == 'google/chromeos/device':
                settings = dp.ChromeDeviceSettingsProto()
                payload = self.server.ReadPolicyFromDataDir(
                    policy_key, settings)
                if payload is None:
                    self.GatherDevicePolicySettings(settings,
                                                    policy.get(policy_key, {}))
                    payload = settings.SerializeToString()
            elif msg.policy_type == 'google/chrome/extension':
                settings = ep.ExternalPolicyData()
                payload = self.server.ReadPolicyFromDataDir(
                    policy_key, settings)
                if payload is None:
                    payload = self.CreatePolicyForExternalPolicyData(
                        policy_key)
            else:
                response.error_code = 400
                response.error_message = 'Invalid policy type'
                return
        else:
            response.error_code = 400
            response.error_message = 'Request not allowed for the token used'
            return

        # Sign with 'current_key_index', defaulting to key 0.
        signing_key = None
        req_key = None
        current_key_index = policy.get('current_key_index', 0)
        nkeys = len(self.server.keys)
        if (msg.signature_type == dm.PolicyFetchRequest.SHA1_RSA
                and current_key_index in range(nkeys)):
            signing_key = self.server.keys[current_key_index]
            if msg.public_key_version in range(1, nkeys + 1):
                # requested key exists, use for signing and rotate.
                req_key = self.server.keys[msg.public_key_version -
                                           1]['private_key']

        # Fill the policy data protobuf.
        policy_data = dm.PolicyData()
        policy_data.policy_type = msg.policy_type
        policy_data.timestamp = int(time.time() * 1000)
        policy_data.request_token = token_info['device_token']
        policy_data.policy_value = payload
        policy_data.machine_name = token_info['machine_name']
        policy_data.valid_serial_number_missing = (token_info['machine_id']
                                                   in BAD_MACHINE_IDS)
        policy_data.settings_entity_id = msg.settings_entity_id
        policy_data.service_account_identity = policy.get(
            'service_account_identity',
            'policy_testserver.py-service_account_identity')
        invalidation_source = policy.get('invalidation_source')
        if invalidation_source is not None:
            policy_data.invalidation_source = invalidation_source
        # Since invalidation_name is type bytes in the proto, the Unicode name
        # provided needs to be encoded as ASCII to set the correct byte pattern.
        invalidation_name = policy.get('invalidation_name')
        if invalidation_name is not None:
            policy_data.invalidation_name = invalidation_name.encode('ascii')

        if signing_key:
            policy_data.public_key_version = current_key_index + 1
        if msg.policy_type == 'google/chromeos/publicaccount':
            policy_data.username = msg.settings_entity_id
        else:
            # For regular user/device policy, there is no way for the testserver to
            # know the user name belonging to the GAIA auth token we received (short
            # of actually talking to GAIA). To address this, we read the username from
            # the policy configuration dictionary, or use a default.
            policy_data.username = policy.get('policy_user',
                                              '*****@*****.**')
        policy_data.device_id = token_info['device_id']
        signed_data = policy_data.SerializeToString()

        response.policy_data = signed_data
        if signing_key:
            response.policy_data_signature = (
                signing_key['private_key'].hashAndSign(signed_data).tostring())
            if msg.public_key_version != current_key_index + 1:
                response.new_public_key = signing_key['public_key']
                if req_key:
                    response.new_public_key_signature = (req_key.hashAndSign(
                        response.new_public_key).tostring())

        self.DumpMessage('Response', response)

        return (200, response.SerializeToString())