bug 70398:
allow constructions like:
    hostkeys['hostname'] = {}
to create an empty host entry object, so that future attempts to set
keys will at least not throw an exception.  (they'll still silently do
nothing, though.)
This commit is contained in:
Robey Pointer 2006-11-10 16:44:13 -08:00
parent 482d0bcef2
commit e736341e20
2 changed files with 20 additions and 6 deletions

View File

@ -82,6 +82,9 @@ class HostKeyEntry:
return '%s %s %s\n' % (','.join(self.hostnames), self.key.get_name(), return '%s %s %s\n' % (','.join(self.hostnames), self.key.get_name(),
self.key.get_base64()) self.key.get_base64())
return None return None
def __repr__(self):
return '<HostKeyEntry %r: %r>' % (self.hostnames, self.key)
class HostKeys (UserDict.DictMixin): class HostKeys (UserDict.DictMixin):
@ -178,7 +181,7 @@ class HostKeys (UserDict.DictMixin):
""" """
Find a hostkey entry for a given hostname or IP. If no entry is found, Find a hostkey entry for a given hostname or IP. If no entry is found,
C{None} is returned. Otherwise a dictionary of keytype to key is C{None} is returned. Otherwise a dictionary of keytype to key is
returned. returned. The keytype will be either C{"ssh-rsa"} or C{"ssh-dss"}.
@param hostname: the hostname (or IP) to lookup @param hostname: the hostname (or IP) to lookup
@type hostname: str @type hostname: str
@ -186,13 +189,15 @@ class HostKeys (UserDict.DictMixin):
@rtype: dict(str, L{PKey}) @rtype: dict(str, L{PKey})
""" """
ret = {} ret = {}
valid = False
for e in self._entries: for e in self._entries:
for h in e.hostnames: for h in e.hostnames:
if h.startswith('|1|') and (self.hash_host(hostname, h) == h): if (h.startswith('|1|') and (self.hash_host(hostname, h) == h)) or (h == hostname):
valid = True
if e.key is None:
continue
ret[e.key.get_name()] = e.key ret[e.key.get_name()] = e.key
elif h == hostname: if not valid:
ret[e.key.get_name()] = e.key
if len(ret) == 0:
return None return None
return ret return ret
@ -231,6 +236,9 @@ class HostKeys (UserDict.DictMixin):
def __setitem__(self, hostname, entry): def __setitem__(self, hostname, entry):
# don't use this please. # don't use this please.
if len(entry) == 0:
self._entries.append(HostKeyEntry([hostname], None))
return
for key_type in entry.keys(): for key_type in entry.keys():
found = False found = False
for e in self._entries: for e in self._entries:
@ -242,6 +250,7 @@ class HostKeys (UserDict.DictMixin):
self._entries.append(HostKeyEntry([hostname], entry[key_type])) self._entries.append(HostKeyEntry([hostname], entry[key_type]))
def keys(self): def keys(self):
# python 2.4 sets would be nice here.
ret = [] ret = []
for e in self._entries: for e in self._entries:
for h in e.hostnames: for h in e.hostnames:

View File

@ -104,9 +104,14 @@ class HostKeysTest (unittest.TestCase):
'ssh-rsa': key, 'ssh-rsa': key,
'ssh-dss': key_dss 'ssh-dss': key_dss
} }
self.assertEquals(2, len(hostdict)) hostdict['fake.example.com'] = {}
# this line will have no effect, but at least shouldn't crash:
hostdict['fake.example.com']['ssh-rsa'] = key
self.assertEquals(3, len(hostdict))
self.assertEquals(2, len(hostdict.values()[0])) self.assertEquals(2, len(hostdict.values()[0]))
self.assertEquals(1, len(hostdict.values()[1])) self.assertEquals(1, len(hostdict.values()[1]))
self.assertEquals(0, len(hostdict.values()[2]))
fp = hexlify(hostdict['secure.example.com']['ssh-rsa'].get_fingerprint()).upper() fp = hexlify(hostdict['secure.example.com']['ssh-rsa'].get_fingerprint()).upper()
self.assertEquals('7EC91BB336CB6D810B124B1353C32396', fp) self.assertEquals('7EC91BB336CB6D810B124B1353C32396', fp)
fp = hexlify(hostdict['secure.example.com']['ssh-dss'].get_fingerprint()).upper() fp = hexlify(hostdict['secure.example.com']['ssh-dss'].get_fingerprint()).upper()