diff --git a/demo.py b/demo.py index b85fc01..d0dda7f 100755 --- a/demo.py +++ b/demo.py @@ -24,32 +24,6 @@ import paramiko ##### utility functions -def load_host_keys(): - # this file won't exist on windows, but windows doesn't have a standard - # location for this file anyway. - filename = os.path.expanduser('~/.ssh/known_hosts') - keys = {} - try: - f = open(filename, 'r') - except Exception, e: - print '*** Unable to open host keys file (%s)' % filename - return - for line in f: - keylist = line.split(' ') - if len(keylist) != 3: - continue - hostlist, keytype, key = keylist - hosts = hostlist.split(',') - for host in hosts: - if not keys.has_key(host): - keys[host] = {} - if keytype == 'ssh-rsa': - keys[host][keytype] = paramiko.RSAKey(data=base64.decodestring(key)) - elif keytype == 'ssh-dss': - keys[host][keytype] = paramiko.DSSKey(data=base64.decodestring(key)) - f.close() - return keys - def agent_auth(username, t, event): agent = paramiko.Agent() agent_keys = agent.get_keys() @@ -137,7 +111,12 @@ try: sys.exit(1) # print repr(t) - keys = load_host_keys() + try: + keys = paramiko.util.load_host_keys(os.path.expanduser('~/.ssh/known_hosts')) + except IOError: + print '*** Unable to open host keys file' + keys = {} + key = t.get_remote_server_key() if not keys.has_key(hostname): print '*** WARNING: Unknown host key!' diff --git a/paramiko/__init__.py b/paramiko/__init__.py index 6224f4f..d13477d 100644 --- a/paramiko/__init__.py +++ b/paramiko/__init__.py @@ -65,7 +65,7 @@ __license__ = "GNU Lesser General Public License (LGPL)" import transport, auth_transport, channel, rsakey, dsskey, message -import ssh_exception, file, packet, agent, server +import ssh_exception, file, packet, agent, server, util import sftp_client, sftp_attr, sftp_handle, sftp_server, sftp_si randpool = transport.randpool @@ -126,6 +126,7 @@ __all__ = [ 'Transport', 'pkey', 'message', 'ssh_exception', + 'sftp', 'sftp_client', 'sftp_server', 'sftp_attr', diff --git a/paramiko/util.py b/paramiko/util.py index 1b620b8..163fb03 100644 --- a/paramiko/util.py +++ b/paramiko/util.py @@ -172,6 +172,46 @@ def generate_key_bytes(hashclass, salt, key, nbytes): nbytes -= size return keydata +def load_host_keys(filename): + """ + Read a file of known SSH host keys, in the format used by openssh, and + return a compound dict of C{hostname -> keytype ->} L{PKey}. The hostname + may be an IP address or DNS name. The keytype will be either C{"ssh-rsa"} + or C{"ssh-dss"}. + + This type of file unfortunately doesn't exist on Windows, but on posix, + it will usually be stored in C{os.path.expanduser("~/.ssh/known_hosts")}. + + @param filename: name of the file to read host keys from + @type filename: str + @return: dict of host keys, indexed by hostname and then keytype + @rtype: dict(hostname, dict(keytype, L{PKey})) + """ + import base64 + from rsakey import RSAKey + from dsskey import DSSKey + + keys = {} + f = file(filename, 'r') + for line in f: + line = line.strip() + if (len(line) == 0) or (line[0] == '#'): + continue + keylist = line.split(' ') + if len(keylist) != 3: + continue + hostlist, keytype, key = keylist + hosts = hostlist.split(',') + for host in hosts: + if not keys.has_key(host): + keys[host] = {} + if keytype == 'ssh-rsa': + keys[host][keytype] = RSAKey(data=base64.decodestring(key)) + elif keytype == 'ssh-dss': + keys[host][keytype] = DSSKey(data=base64.decodestring(key)) + f.close() + return keys + def mod_inverse(x, m): # it's crazy how small python can make this function. u1, u2, u3 = 1, 0, m