Control: tags -1 fixed-upstream patch Control: severity -1 important Hello
ECDSA patches where merged upstream last October. This is the default algorithm in Jessie, so I'm rising the severity to important: That package is now not very useful because it doesn't produce the one record we need. Attached is the pull request above[2], refreshed against debian version (no change), with PEP3 headers, all ready for d/patches/. -- Nirgal [1] https://github.com/xelerance/sshfp/pull/2 [2] git diff 796d772c65234276e1af047713a67095e5cf7b8a 33d2783ab94c8ba90164533ee2fc3024f652525b
Description: Add support for ECDSA. See RFC 6594. This is the default algorithm in Jessie. Origin: https://github.com/xelerance/sshfp/pull/2 Author: Danny Fullerton <nort...@mantor.org> Bug: https://github.com/xelerance/sshfp/issues/1 Bug-Debian: http://bugs.debian.org/719442 Last-Update: 2015-01-23 Reviewed-by: Jean-Michel Nirgal Vourgère <jmv_...@nirgal.com> Applied-Upstream: commit:33d2783ab94c8ba90164533ee2fc3024f652525b Index: sshfp-1.2.2/sshfp =================================================================== --- sshfp-1.2.2.orig/sshfp +++ sshfp-1.2.2/sshfp @@ -22,13 +22,12 @@ except ImportError: print >> sys.stderr, "openSUSE: zypper in python-dnspython" sys.exit(1) +ishashlib = False try: import hashlib - digest = hashlib.sha1 + ishashlib = True except ImportError: import sha - digest = sha.new - global all_hosts global khfile @@ -38,6 +37,7 @@ global quiet global port global timeout global algo +global fphashes VERSION = "1.2.2" DEFAULT_KNOWN_HOSTS_FILE = "~/.ssh/known_hosts" @@ -48,22 +48,34 @@ def show_version(): print >> sys.stderr, "Author:\n Paul Wouters <p...@xelerance.com>" print >> sys.stderr, " James Brown <jbr...@yelp.com>" -def create_sshfp(hostname, keytype, keyblob): +def create_sshfp(hostname, keytype, keyblob, fphash): """Creates an SSH fingerprint""" if keytype == "ssh-rsa": keytype = "1" + elif keytype == "ssh-dss": + keytype = "2" + elif keytype == "ecdsa-sha2-nistp256": + keytype = "3" else: - if keytype == "ssh-dss": - keytype = "2" - else: - return "" + return "" try: rawkey = base64.b64decode(keyblob) except TypeError: print >> sys.stderr, "FAILED on hostname "+hostname+" with keyblob "+keyblob return "ERROR" - fpsha1 = digest(rawkey).hexdigest().upper() + + hashcode = "1" + if ishashlib: + if fphash == "sha2": + digest = hashlib.sha256 + hashcode = "2" + else: + digest = hashlib.sha1 + else: + digest = sha.new + fp = digest(rawkey).hexdigest().upper() + # check for Reverse entries reverse = 1 parts = hostname.split(".", 3) @@ -78,7 +90,7 @@ def create_sshfp(hostname, keytype, keyb if trailing and not reverse: if hostname[-1:] != ".": hostname = hostname + "." - return hostname + " IN SSHFP " + keytype + " 1 " + fpsha1 + return hostname + " IN SSHFP " + keytype + " " + hashcode + " " + fp def get_known_host_entry(known_hosts, host): """Get a single entry out of a known_hosts file @@ -134,19 +146,26 @@ def check_keytype(keytype, hostname): for algo in algos: if "ssh-%s" % algo[:-1] == keytype[:-1]: return True - if not quiet: - print >> sys.stderr, "Could only find key type %s for %s" % (keytype, hostname) + if "ecdsa" == algo and "ecdsa-sha2-nistp256" == keytype: + return True return False def process_record(record, hostname): + global fphashes + all_records = [] (host, keytype, key) = record.split(" ") key = key.rstrip() if check_keytype(keytype, hostname): - record = create_sshfp(hostname, keytype, key) - return record - return "" + for fphash in fphashes: + all_records.append(create_sshfp(host, keytype, key, fphash)) + if all_records: + all_records.sort() + return "\n".join(all_records) + else: + return "" def process_records(data, hostnames): + global fphashes """Process all records in a string. If the global "all_hosts" is True, then return SSHFP entries @@ -155,6 +174,7 @@ def process_records(data, hostnames): If "all_hosts is False and hostnames is non-empty, return only the items in hostnames """ + all_records = [] for record in data.split("\n"): if record.startswith("#") or not record: @@ -170,7 +190,8 @@ def process_records(data, hostnames): if all_hosts or host in hostnames or host == hostnames: if not check_keytype(keytype, host): continue - all_records.append(create_sshfp(host, keytype, key)) + for fphash in fphashes: + all_records.append(create_sshfp(host, keytype, key, fphash)) if all_records: all_records.sort() return "\n".join(all_records) @@ -252,6 +273,7 @@ def main(): global port global timeout global algos + global fphashes parser = optparse.OptionParser() parser.add_option("-k", "--knownhosts", "--known-hosts", @@ -301,7 +323,7 @@ def main(): action="append", type="choice", dest="algo", - choices=["rsa", "dsa"], + choices=["rsa", "dsa", "ecdsa"], default=[], help="key type to fetch (may be specified more than once, default dsa,rsa)") parser.add_option("-n", "--nameserver", @@ -310,6 +332,13 @@ def main(): dest="nameserver", default="", help="nameserver to use for AXFR (only valid with -s -a)") + parser.add_option("-H", "--hashfunction", + action="append", + type="choice", + dest="fphashes", + choices=["sha1", "sha2"], + default=[], + help="Hash function to use, default sha1,sha2") (options, args) = parser.parse_args() # parse options @@ -322,9 +351,10 @@ def main(): data = "" trailing = options.trailing_dot timeout = options.timeout - algos = options.algo or ["dsa", "rsa"] + algos = options.algo or ["dsa", "rsa", "ecdsa"] all_hosts = options.all_hosts port = options.port + fphashes = options.fphashes or ["sha1", "sha2"] hostnames = () if options.version: @@ -342,6 +372,9 @@ def main(): if not args: print >> sys.stderr, "WARNING: Assuming -a" all_hosts = True + if not ishashlib and "sha2" in options.fphashes: + print >> sys.stderr, "WARNING: Hashlib not supported, ignoring -H sha2" + fphashes = ["sha1"] if options.scan and options.all_hosts: datal = []
signature.asc
Description: OpenPGP digital signature