def check_hosts(self, patlists, results=None, host='host', addr='1.2.3.4', port=22, from_file=False, from_bytes=False): """Check a known_hosts file built from the specified patterns""" prefixes = ('', '@cert-authority ', '@revoked ') known_hosts = '# Comment line\n # Comment line with whitespace\n\n' for prefix, patlist, key in zip(prefixes, patlists, self.keylists): for pattern, key in zip(patlist, key): known_hosts += '%s%s %s' % (prefix, pattern, key) if from_file: with open('known_hosts', 'w') as f: f.write(known_hosts) known_hosts = 'known_hosts' elif from_bytes: known_hosts = known_hosts.encode() else: known_hosts = asyncssh.import_known_hosts(known_hosts) return self.check_match(known_hosts, results, host, addr, port)
def test_import_known_hosts(self): """Test connecting with known hosts object from import_known_hosts""" known_hosts_path = os.path.join('.ssh', 'known_hosts') with open(known_hosts_path, 'r') as f: known_hosts = asyncssh.import_known_hosts(f.read()) with (yield from self.connect(known_hosts=known_hosts)) as conn: pass yield from conn.wait_closed()
def check_hosts(self, patlists, results=None, host='host', addr='1.2.3.4', port=22, from_file=False, from_bytes=False, as_callable=False, as_tuple=False): """Check a known_hosts file built from the specified patterns""" def call_match(host, addr, port): """Test passing callable as known_hosts""" return asyncssh.match_known_hosts(_known_hosts, host, addr, port) prefixes = ('', '@cert-authority ', '@revoked ', '', '@revoked ', '', '@revoked ') known_hosts = '# Comment line\n # Comment line with whitespace\n\n' for prefix, patlist, keys in zip(prefixes, patlists, self.keylists): for pattern, key in zip(patlist, keys): known_hosts += '%s%s %s' % (prefix, pattern, key) if from_file: with open('known_hosts', 'w') as f: f.write(known_hosts) known_hosts = 'known_hosts' elif from_bytes: known_hosts = known_hosts.encode() elif as_callable: _known_hosts = asyncssh.import_known_hosts(known_hosts) known_hosts = call_match elif as_tuple: known_hosts = asyncssh.import_known_hosts(known_hosts) known_hosts = asyncssh.match_known_hosts(known_hosts, host, addr, port) else: known_hosts = asyncssh.import_known_hosts(known_hosts) return self.check_match(known_hosts, results, host, addr, port)
async def run_client(inst, cmd, sshAgent=None, scpSrcFilePath=None, dlDirPath='.', dlFileName=None, knownHostsOnly=False ): #logger.info( 'inst %s', inst) sshSpecs = inst['ssh'] #logger.info( 'iid %s, ssh: %s', inst['instanceId'], inst['ssh']) host = sshSpecs['host'] port = sshSpecs['port'] user = sshSpecs['user'] iid = inst['instanceId'] iidAbbrev = iid[0:16] # implement pasword-passing if present in ssh args password = sshSpecs.get('password', None ) try: if knownHostsOnly: known_hosts = os.path.expanduser( '~/.ssh/known_hosts' ) else: known_hosts = None if False: # 'returnedPubKey' in inst: keyStr = inst['returnedPubKey'] logger.info( 'importing %s', keyStr) key = asyncssh.import_public_key( keyStr ) logger.info( 'imported %s', key.export_public_key() ) #known_hosts = key # nope known_hosts = asyncssh.import_known_hosts(keyStr) logResult( 'operation', ['connect', host, port], iid ) #sshAgent = os.getenv( 'SSH_AUTH_SOCK' ) #async with asyncssh.connect(host, port=port, username=user, password=password, known_hosts=None) as conn: async with asyncssh.connect(host, port=port, username=user, keepalive_interval=15, keepalive_count_max=4, known_hosts=known_hosts, agent_path=sshAgent ) as conn: serverHostKey = conn.get_server_host_key() #logger.info( 'got serverHostKey (%s) %s', type(serverHostKey), serverHostKey ) serverPubKey = serverHostKey.export_public_key(format_name='openssh') #logger.info( 'serverPubKey (%s) %s', type(serverPubKey), serverPubKey ) serverPubKeyStr = str(serverPubKey,'utf8') #logger.info( 'serverPubKeyStr %s', serverPubKeyStr ) inst['returnedPubKey'] = serverPubKeyStr if scpSrcFilePath: logger.info( 'uploading %s to %s', scpSrcFilePath, iidAbbrev ) await asyncssh.scp( scpSrcFilePath, conn, preserve=True, recurse=True ) #logger.info( 'uploaded %s to %s', scpSrcFilePath, iidAbbrev ) logResult( 'operation', ['upload', scpSrcFilePath], iid ) proc = None # execute cmd on remote, if non-null cmd given if cmd: # substitute actual instanceId for '<<instanceId>>' in cmd cmd = cmd.replace( '<<instanceId>>', iid ) logResult( 'operation', ['command', cmd], iid ) async with conn.create_process(cmd) as proc: async for line in proc.stdout: logger.info('stdout[%s] %s', iidAbbrev, line.strip() ) logResult( 'stdout', line.rstrip(), iid ) async for line in proc.stderr: logger.info('stderr[%s] %s', iidAbbrev, line.strip() ) logResult( 'stderr', line.rstrip(), iid ) await proc.wait_closed() logResult( 'returncode', proc.returncode, iid ) if proc.returncode is None: logger.warning( 'returncode[%s] NONE', iidAbbrev ) #elif proc.returncode: # logger.warning( 'returncode %s for %s', proc.returncode, iidAbbrev ) if dlFileName: destDirPath = '%s/%s' % (dlDirPath, iid) logger.info( 'downloading %s from %s to %s', dlFileName, iidAbbrev, destDirPath ) await asyncssh.scp( (conn, dlFileName), destDirPath, preserve=True, recurse=True ) #logger.info( 'downloaded from %s to %s', iidAbbrev, destDirPath ) logResult( 'operation', ['download', dlFileName], iid ) if proc: return proc.returncode else: return 0 except Exception as exc: logger.warning( 'got exception (%s) %s', type(exc), exc, exc_info=False ) logResult( 'exception', {'type': type(exc).__name__, 'msg': str(exc) }, iid ) return exc return 'did we not connect?'