"""
This program is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Copyright © 2019 Cloud Linux Software Inc.
This software is also available under ImunifyAV commercial license,
see
"""
from imav.patchman.fs_scanner.matcher import HashesMatcher
class DummyDB:
def __init__(self):
self.inserted = []
class DummyTable:
def __init__(self, outer):
self.outer = outer
def buffered_insert(self, row):
self.outer.inserted.append(row)
self.hashes_matches = DummyTable(self)
def test_hashes_matcher_filters_and_matches(tmp_path):
# type 1/7/8 = malware family (ignored); state 2 = superseded (ignored).
# The two "multihash" lines share a digest but differ in
# vuln_id/type/state, so they are two distinct, valid detections.
hashes_content = (
"1:1000:malwarehash:0\n" # malware -> filtered out
"2:2000:goodhash1:0\n" # valid, single detection
"2:2001:supersededhash:2\n" # superseded -> filtered out
"7:3000:rulehash:0\n" # malware rule -> filtered out
"8:4000:dryrunhash:0\n" # malware rule dryrun -> filtered out
"2:2002:multihash:0\n" # valid, same digest as next line
"10:2003:multihash:1\n" # valid (plugin vuln), same digest
)
hashes_file = tmp_path / "hashes"
hashes_file.write_text(hashes_content)
matcher = HashesMatcher(str(hashes_file))
db = DummyDB()
# single matching definition
assert matcher.match_and_save("/f/a.php", "goodhash1", db) is True
# a digest matching TWO distinct definitions -> BOTH emitted, none dropped
assert matcher.match_and_save("/f/b.php", "multihash", db) is True
# digests that only match filtered (malware / superseded) definitions
assert matcher.match_and_save("/f/c.php", "malwarehash", db) is False
assert matcher.match_and_save("/f/d.php", "supersededhash", db) is False
assert db.inserted == [
("/f/a.php", "goodhash1", 2, 2000, 0),
("/f/b.php", "multihash", 2, 2002, 0),
("/f/b.php", "multihash", 10, 2003, 1),
]