Add support for checking presence of a fingerprint (no UI yet)
This commit is contained in:
parent
320445ab25
commit
e4042c0664
|
@ -0,0 +1,51 @@
|
|||
import enum
|
||||
|
||||
import entry
|
||||
import hashing
|
||||
|
||||
class result(enum.Enum):
|
||||
notfound, ok, fail = range(3)
|
||||
|
||||
def check_fingerprint(entries, domain, port, fingerprint):
|
||||
"""check_fingerprint([Entry], str, u16, bytes[32]) → (enum result: result, str / None: comment)
|
||||
Checks if the given host is found with the given fingerprint.
|
||||
Will return the comment on the host if the host is found, regardless
|
||||
of whether the fingerprint checks out."""
|
||||
assert type(entries) == list and all(type(i) == entry.Entry for i in entries)
|
||||
assert type(domain) == str
|
||||
assert type(port) == int and 0 <= port <= (1<<16) - 1
|
||||
assert type(fingerprint) == bytes and len(fingerprint) == 32
|
||||
|
||||
# Normalize the host here, so we don't have to do it every time we
|
||||
# check for a possible match
|
||||
normalized_hosts = [entry.normalize_host(domain, port)]
|
||||
|
||||
# If we are looking at non-22 port, also check the general form of
|
||||
# the host without a port specifier. This seems to be how OpenSSH
|
||||
# does it too
|
||||
if port != 22:
|
||||
normalized_hosts.append(entry.normalize_host(domain, 22))
|
||||
|
||||
for possible_match in entries:
|
||||
for normalized_host in normalized_hosts:
|
||||
hashed_host = hashing.hash_with_salt(normalized_host, possible_match.salt)
|
||||
if hashed_host == possible_match.hashed_host:
|
||||
# Convert the comment to a string
|
||||
# We put replacement characters where
|
||||
# decoding fails instead of throwing an
|
||||
# error, because even whilethe comment
|
||||
# field must be valid utf-8, failing in this
|
||||
# situation is bad UX
|
||||
comment = possible_match.comment.decode('utf-8', errors = 'replace')
|
||||
# TODO: Justify this
|
||||
# We only care about the first match, so we
|
||||
# return here
|
||||
if fingerprint == possible_match.fingerprint:
|
||||
# Fingerprint matches, it passes
|
||||
return (result.ok, comment)
|
||||
else:
|
||||
# Fingerprint different, it fails
|
||||
return (result.fail, comment)
|
||||
|
||||
# We did not match, tell the caller so
|
||||
return (result.notfound, None)
|
|
@ -13,6 +13,8 @@ def process_line(line):
|
|||
a list of Entries based on it."""
|
||||
assert type(line) == str
|
||||
|
||||
# TODO: Skip over IPs somehow?
|
||||
|
||||
# Remove trailing newlines
|
||||
if line[-1] == '\n': line = line[:-1]
|
||||
|
||||
|
|
Loading…
Reference in New Issue