コード例 #1
0
def _PersistBit9Events(event, file_catalog, computer, signing_chain):
  """Creates a Bit9Event from the given Event protobuf.

  Args:
    event: The api.Event instance to be synced to Upvote.
    file_catalog: The api.FileCatalog instance associated with this event.
    computer: The api.Computer instance associated with this event.
    signing_chain: List of api.Certificate instances associated with this event.

  Returns:
    An ndb.Future that resolves when all events are created.
  """
  logging.info('Creating new Bit9Event')

  host_id = str(computer.id)
  blockable_key = ndb.Key(binary_models.Bit9Binary, file_catalog.sha256)
  host_users = list(bit9_utils.ExtractHostUsers(computer.users))
  occurred_dt = event.timestamp

  _CheckAndResolveAnomalousBlock(blockable_key, host_id)

  new_event = event_models.Bit9Event(
      blockable_key=blockable_key,
      cert_key=_GetCertKey(signing_chain),
      event_type=constants.EVENT_TYPE.BLOCK_BINARY,
      last_blocked_dt=occurred_dt,
      first_blocked_dt=occurred_dt,
      host_id=host_id,
      file_name=event.file_name,
      file_path=event.path_name,
      publisher=file_catalog.publisher,
      version=file_catalog.product_version,
      description=event.description,
      executing_user=bit9_utils.ExtractHostUser(event.user_name),
      bit9_id=event.id)

  tables.EXECUTION.InsertRow(
      sha256=new_event.blockable_key.id(),
      device_id=host_id,
      timestamp=occurred_dt,
      platform=new_event.GetPlatformName(),
      client=new_event.GetClientName(),
      file_path=new_event.file_path,
      file_name=new_event.file_name,
      executing_user=new_event.executing_user,
      associated_users=host_users,
      decision=new_event.event_type)

  keys_to_insert = model_utils.GetEventKeysToInsert(
      new_event, host_users, host_users)

  futures = [_PersistBit9Event(new_event, key) for key in keys_to_insert]
  return datastore_utils.GetMultiFuture(futures)
コード例 #2
0
ファイル: sync.py プロジェクト: crudbug/upvote
def _PersistBit9Host(computer, occurred_dt):
    """Creates a Bit9Host from the Event protobuf if one does not already exist.

  NOTE: This function could be transactional but, at least for now, host puts in
  multiple requests don't really need to be processed in a fixed order.
  last_event_dt is the only frequently modified property and there's currently
  no need for it to be perfectly accurate.

  Args:
    computer: api.Computer object associated with the event.
    occurred_dt: datetime object corresponding to the time of the event.

  Returns:
    ndb.Future that resolves when the host is updated.
  """
    host_id = str(computer.id)
    policy = computer.policy_id
    policy_key = (ndb.Key(bit9.Bit9Policy, str(policy))
                  if policy is not None else None)
    hostname = bit9_utils.ExpandHostname(
        bit9_utils.StripDownLevelDomain(computer.name))
    policy_entity = policy_key.get()
    mode = (policy_entity.enforcement_level
            if policy_entity is not None else constants.HOST_MODE.UNKNOWN)

    # Grab the corresponding Bit9Host.
    bit9_host = yield bit9.Bit9Host.get_by_id_async(host_id)

    existing_users = set(bit9_host.users if bit9_host is not None else [])
    extracted_users = list(bit9_utils.ExtractHostUsers(computer.users))

    # Ignore any 'Desktop Window Manager' users, otherwise a user can temporarily
    # become disassociated with their machine. If they vote for something to be
    # locally whitelisted during such a period, they won't get a rule for it.
    incoming_users = set()
    for extracted_user in extracted_users:
        if r'Window Manager\DWM-' in extracted_user:
            logging.warning('Ignoring user "%s"', extracted_user)
        else:
            incoming_users.add(extracted_user)

    # If there are incoming users, either because it was only all 'Desktop Window
    # Manager' entries, or because Bit9 didn't report any users for whatever
    # reason, then just stick with the existing users, otherwise we'll
    # disassociate the machine from the user.
    if not incoming_users:
        incoming_users = existing_users

    # Perform initialization for users new to this host.
    new_users = incoming_users - existing_users
    for new_user in new_users:

        # Create User if we haven't seen this user before.
        email = user_map.UsernameToEmail(new_user)
        user = user_models.User.GetOrInsert(email_addr=email)

        # Copy the user's local rules over from a pre-existing host.
        yield _CopyLocalRules(user.key, host_id)

    # List of all row action that need to be persisted.
    row_actions = []

    # Doesn't exist? Guess we better fix that.
    if bit9_host is None:
        logging.info('Creating new Bit9Host')
        bit9_host = bit9.Bit9Host(id=host_id,
                                  hostname=hostname,
                                  last_event_dt=occurred_dt,
                                  policy_key=policy_key,
                                  users=sorted(list(incoming_users)))

        row_actions.append(constants.HOST_ACTION.FIRST_SEEN)

    else:
        changed = False

        if not bit9_host.last_event_dt or bit9_host.last_event_dt < occurred_dt:
            bit9_host.last_event_dt = occurred_dt
            changed = True

        if bit9_host.hostname != hostname:
            logging.info('Hostname for %s changed from %s to %s', host_id,
                         bit9_host.hostname, hostname)
            bit9_host.hostname = hostname
            changed = True

        if bit9_host.policy_key != policy_key:
            bit9_host.policy_key = policy_key
            changed = True
            row_actions.append(constants.HOST_ACTION.MODE_CHANGE)

        if existing_users != incoming_users:
            existing_users_list = sorted(list(existing_users))
            incoming_users_list = sorted(list(incoming_users))
            logging.info('Users for %s changed from %s to %s', host_id,
                         existing_users_list, incoming_users_list)
            bit9_host.users = incoming_users_list
            changed = True
            row_actions.append(constants.HOST_ACTION.USERS_CHANGE)

        if not changed:
            raise ndb.Return()

    logging.info('Attempting to put Bit9Host...')
    yield bit9_host.put_async()

    for action in row_actions:
        tables.HOST.InsertRow(device_id=host_id,
                              timestamp=(bit9_host.recorded_dt if action
                                         == constants.HOST_ACTION.FIRST_SEEN
                                         else bit9_host.last_event_dt),
                              action=action,
                              hostname=hostname,
                              platform=constants.PLATFORM.WINDOWS,
                              users=sorted(list(incoming_users)),
                              mode=mode)
コード例 #3
0
ファイル: utils_test.py プロジェクト: crudbug/upvote
 def testMixedCase(self):
     user_str = r'HOST\user,{0}\USer'.format(settings.AD_DOMAIN)
     expected = [r'HOST\user', r'user']
     actual = utils.ExtractHostUsers(user_str)
     self.assertEqual(expected, actual)
コード例 #4
0
ファイル: utils_test.py プロジェクト: crudbug/upvote
 def testSkip(self):
     user_str = r'HOST\user,{0}\user,HOST\skipuser$,{0}\skipuser$'.format(
         settings.AD_DOMAIN)
     expected = [r'HOST\user', r'user']
     actual = utils.ExtractHostUsers(user_str)
     self.assertEqual(expected, actual)
コード例 #5
0
ファイル: utils_test.py プロジェクト: crudbug/upvote
 def testNone(self):
     self.assertEqual([], utils.ExtractHostUsers(None))
コード例 #6
0
ファイル: utils_test.py プロジェクト: crudbug/upvote
 def testEmpty(self):
     self.assertEqual([], utils.ExtractHostUsers(''))