def _PersistBit9Binary(event, file_catalog, signing_chain): """Creates or updates a Bit9Binary from the given Event protobuf.""" changed = False # Grab the corresponding Bit9Binary. bit9_binary = yield bit9.Bit9Binary.get_by_id_async(file_catalog.sha256) detected_installer = bool(file_catalog.file_flags & bit9_constants.FileFlags.DETECTED_INSTALLER) is_installer = (bit9_utils.GetEffectiveInstallerState( file_catalog.file_flags)) # Doesn't exist? Guess we better fix that. if bit9_binary is None: logging.info('Creating new Bit9Binary') bit9_binary = bit9.Bit9Binary( id=file_catalog.sha256, id_type=bit9_constants.SHA256_TYPE.MAP_TO_ID_TYPE[ file_catalog.sha256_hash_type], blockable_hash=file_catalog.sha256, file_name=event.file_name, company=file_catalog.company, product_name=file_catalog.product_name, version=file_catalog.product_version, cert_key=_GetCertKey(signing_chain), occurred_dt=event.timestamp, sha1=file_catalog.sha1, product_version=file_catalog.product_version, first_seen_name=file_catalog.file_name, first_seen_date=file_catalog.date_created, first_seen_path=file_catalog.path_name, first_seen_computer=str(file_catalog.computer_id), publisher=file_catalog.publisher, file_type=file_catalog.file_type, md5=file_catalog.md5, file_size=file_catalog.file_size, detected_installer=detected_installer, is_installer=is_installer, file_catalog_id=str(file_catalog.id)) bit9_binary.PersistRow(constants.BLOCK_ACTION.FIRST_SEEN, timestamp=bit9_binary.recorded_dt) metrics.DeferLookupMetric(file_catalog.sha256, constants.ANALYSIS_REASON.NEW_BLOCKABLE) changed = True # If the file catalog ID has changed, update it. if (not bit9_binary.file_catalog_id or bit9_binary.file_catalog_id != str(file_catalog.id)): bit9_binary.file_catalog_id = str(file_catalog.id) changed = True # Binary state comes from clients, which may have outdated policies. Only # update Bit9Binary state if the client claims BANNED and the # Bit9Binary is still UNTRUSTED. if (event.subtype == bit9_constants.SUBTYPE.BANNED and bit9_binary.state == constants.STATE.UNTRUSTED): logging.info('Changing Bit9Binary state from %s to %s', bit9_binary.state, constants.STATE.BANNED) bit9_binary.state = constants.STATE.BANNED bit9_binary.PersistRow(constants.BLOCK_ACTION.STATE_CHANGE, timestamp=event.timestamp) changed = True if bit9_binary.detected_installer != detected_installer: bit9_binary.detected_installer = detected_installer bit9_binary.is_installer = bit9_binary.CalculateInstallerState() changed = True # Create installer Rules for Bit9Binary installer status if it's been forced # one way or the other in Bit9. marked = file_catalog.file_flags & bit9_constants.FileFlags.MARKED_INSTALLER marked_not = (file_catalog.file_flags & bit9_constants.FileFlags.MARKED_NOT_INSTALLER) if marked or marked_not: bit9_policy = (constants.RULE_POLICY.FORCE_INSTALLER if marked else constants.RULE_POLICY.FORCE_NOT_INSTALLER) changed_installer_state = yield _CheckAndResolveInstallerState( bit9_binary.key, bit9_policy) if changed_installer_state: bit9_binary.is_installer = ( bit9_policy == constants.RULE_POLICY.FORCE_INSTALLER) changed = changed_installer_state or changed # Only persist if needed. if changed: logging.info('Attempting to put Bit9Binary...') yield bit9_binary.put_async() # Indicate whether there was a change, primarily for better unit testing. raise ndb.Return(changed)
def testCalculateInstallerState_NoInstallerRule_DefaultToDetected(self): unput_binary = bit9.Bit9Binary(id='foo', detected_installer=True, is_installer=False) self.assertTrue(unput_binary.CalculateInstallerState())