32
from binascii import hexlify
33
34
# debian squeeze's paramiko is a bit old, so we silence randompool depreciation warning
34
35
# note also: passphrased private keys work with squeeze's paramiko only if done with DES, not AES
78
80
except Exception, e:
79
81
raise BackendException("could not load /etc/ssh/ssh_known_hosts, maybe corrupt?")
81
self.client.load_system_host_keys()
83
# use load_host_keys() to signal it's writable to paramiko
84
# load if file exists or add filename to create it if needed
85
file = os.path.expanduser('~/.ssh/known_hosts')
86
if os.path.isfile(file):
87
self.client.load_host_keys(file)
89
self.client._host_keys_filename = file
82
90
except Exception, e:
83
91
raise BackendException("could not load ~/.ssh/known_hosts, maybe corrupt?")
320
328
return sshconfig.lookup(host)
330
class AgreedAddPolicy (paramiko.AutoAddPolicy):
332
Policy for showing a yes/no prompt and adding the hostname and new
333
host key to the known host file accordingly.
335
This class simply extends the AutoAddPolicy class with a yes/no prompt.
337
def missing_host_key(self, client, hostname, key):
338
fp = hexlify(key.get_fingerprint())
339
fingerprint = ':'.join(a+b for a,b in zip(fp[::2], fp[1::2]))
340
question = """The authenticity of host '%s' can't be established.
341
%s key fingerprint is %s.
342
Are you sure you want to continue connecting (yes/no)? """ % (hostname, key.get_name().upper(), fingerprint)
344
sys.stdout.write(question)
345
choice = raw_input().lower()
346
if choice in ['yes','y']:
347
super(AgreedAddPolicy, self).missing_host_key(client, hostname, key)
349
elif choice in ['no','n']:
350
raise AuthenticityException( hostname )
352
question = "Please type 'yes' or 'no': "
354
class AuthenticityException (paramiko.SSHException):
355
def __init__(self, hostname):
356
paramiko.SSHException.__init__(self, 'Host key verification for server %s failed.' % hostname)
324
359
duplicity.backend.register_backend("sftp", SftpBackend)