policy.py (2677B)
1 import logging 2 import os.path 3 import threading 4 import paramiko 5 6 7 def load_host_keys(path): 8 if os.path.exists(path) and os.path.isfile(path): 9 return paramiko.hostkeys.HostKeys(filename=path) 10 return paramiko.hostkeys.HostKeys() 11 12 13 def get_policy_dictionary(): 14 dic = { 15 k.lower(): v for k, v in vars(paramiko.client).items() if type(v) 16 is type and issubclass(v, paramiko.client.MissingHostKeyPolicy) 17 and v is not paramiko.client.MissingHostKeyPolicy 18 } 19 return dic 20 21 22 def get_policy_class(policy): 23 origin_policy = policy 24 policy = policy.lower() 25 if not policy.endswith('policy'): 26 policy += 'policy' 27 28 dic = get_policy_dictionary() 29 logging.debug(dic) 30 31 try: 32 cls = dic[policy] 33 except KeyError: 34 raise ValueError('Unknown policy {!r}'.format(origin_policy)) 35 return cls 36 37 38 def check_policy_setting(policy_class, host_keys_settings): 39 host_keys = host_keys_settings['host_keys'] 40 host_keys_filename = host_keys_settings['host_keys_filename'] 41 system_host_keys = host_keys_settings['system_host_keys'] 42 43 if policy_class is paramiko.client.AutoAddPolicy: 44 host_keys.save(host_keys_filename) # for permission test 45 elif policy_class is paramiko.client.RejectPolicy: 46 if not host_keys and not system_host_keys: 47 raise ValueError( 48 'Reject policy could not be used without host keys.' 49 ) 50 51 52 class AutoAddPolicy(paramiko.client.MissingHostKeyPolicy): 53 """ 54 thread-safe AutoAddPolicy 55 """ 56 lock = threading.Lock() 57 58 def is_missing_host_key(self, client, hostname, key): 59 k = client._system_host_keys.lookup(hostname) or \ 60 client._host_keys.lookup(hostname) 61 if k is None: 62 return True 63 host_key = k.get(key.get_name(), None) 64 if host_key is None: 65 return True 66 if host_key != key: 67 raise paramiko.BadHostKeyException(hostname, key, host_key) 68 69 def missing_host_key(self, client, hostname, key): 70 with self.lock: 71 if self.is_missing_host_key(client, hostname, key): 72 keytype = key.get_name() 73 logging.info( 74 'Adding {} host key for {}'.format(keytype, hostname) 75 ) 76 client._host_keys._entries.append( 77 paramiko.hostkeys.HostKeyEntry([hostname], key) 78 ) 79 80 with open(client._host_keys_filename, 'a') as f: 81 f.write('{} {} {}\n'.format( 82 hostname, keytype, key.get_base64() 83 )) 84 85 86 paramiko.client.AutoAddPolicy = AutoAddPolicy