def test_scp_send_write_exc(self): class WriteError(Exception): pass def write_exc(func, data): raise WriteError cur_dir = os.path.dirname(__file__) file_name = 'file1' file_copy_to = 'file_copied' file_path_from = os.path.sep.join([cur_dir, file_name]) file_copy_to_dirpath = os.path.expanduser('~/') + file_copy_to client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1) for _path in (file_path_from, file_copy_to_dirpath): try: os.unlink(_path) except OSError: pass try: with open(file_path_from, 'wb') as fh: fh.write(b"adsfasldkfjabafj") client.eagain_write = write_exc self.assertRaises(SCPError, client.scp_send, file_path_from, file_copy_to_dirpath) # File created on SCP channel open self.assertTrue(os.path.isfile(file_copy_to_dirpath)) finally: for _path in (file_path_from, file_copy_to_dirpath): try: os.unlink(_path) except Exception: pass
def test_tunnel_channel_failure(self): remote_host = '127.0.0.8' remote_server = OpenSSHServer(listen_ip=remote_host, port=self.port) remote_server.start_server() in_q, out_q = deque(), deque() try: tunnel = Tunnel(self.proxy_host, in_q, out_q, port=self.port, pkey=self.user_key, num_retries=1) tunnel.daemon = True tunnel.start() in_q.append((remote_host, self.port)) while not tunnel.tunnel_open.is_set(): sleep(.1) if not tunnel.is_alive(): raise ProxyError self.assertTrue(tunnel.tunnel_open.is_set()) self.assertIsNotNone(tunnel.client) while True: try: _port = out_q.pop() except IndexError: sleep(.5) else: break proxy_client = SSHClient( '127.0.0.1', pkey=self.user_key, port=_port, num_retries=1, _auth_thread_pool=False) tunnel.cleanup() spawn(proxy_client.execute, 'echo me') proxy_client.disconnect() self.assertTrue(proxy_client.sock.closed) finally: remote_server.stop()
def test_client_read_timeout(self): client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1) host_out = client.run_command('sleep 2; echo me', timeout=0.2) self.assertRaises(Timeout, list, host_out.stdout)
def test_agent_fwd(self): client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1, allow_agent=True, forward_ssh_agent=True) out = client.run_command(self.cmd) client.wait_finished(out)
def test_sftp_init_exc(self): def _make_sftp(): raise Exception client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1) client._make_sftp_eagain = _make_sftp self.assertRaises(SFTPError, client._make_sftp)
def scope_killer(): for _ in range(5): client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1, allow_agent=False) host_out = client.run_command(self.cmd) output = list(host_out.stdout) self.assertListEqual(output, [self.resp]) client.disconnect()
def test_open_session_timeout(self): client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1, timeout=1) def _session(timeout=2): sleep(2) client.open_session = _session self.assertRaises(GTimeout, client.run_command, self.cmd)
def test_open_session_exc(self): class Error(Exception): pass def _session(): raise Error client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1) client._open_session = _session self.assertRaises(SessionError, client.open_session)
def test_handshake_fail(self): client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1) client.session.disconnect() self.assertRaises(SocketDisconnectError, client._init)
def test_manual_auth(self): client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1, allow_agent=False) client.session.disconnect() del client.session del client.sock client._connect(self.host, self.port) client._init_session() # Identity auth client.pkey = None client.session.disconnect() del client.session del client.sock client._connect(self.host, self.port) client.session = Session() client.session.handshake(client.sock) self.assertRaises(AuthenticationException, client.auth)
def test_tunnel_server_same_port(self): remote_host = '127.0.0.7' remote_server = OpenSSHServer(listen_ip=remote_host, port=self.proxy_port) remote_server.start_server() try: client = SSHClient( remote_host, port=self.proxy_port, pkey=self.user_key, num_retries=1, proxy_host=self.proxy_host, ) output = client.run_command(self.cmd) _stdout = list(output.stdout) self.assertListEqual(_stdout, [self.resp]) self.assertEqual(remote_host, client.host) self.assertEqual(self.proxy_port, client.port) finally: remote_server.stop()
def test_forwarder_exit(self): def _start_server(): raise Exception forwarder = LocalForwarder() forwarder.daemon = True forwarder.start() forwarder.started.wait() client = SSHClient(self.proxy_host, port=self.proxy_port, pkey=self.user_key) forwarder.enqueue(client, self.proxy_host, self.port) forwarder.out_q.get() self.assertTrue(len(forwarder._servers) > 0) client.sock.close() client.disconnect() forwarder._cleanup_servers() self.assertEqual(len(forwarder._servers), 0) forwarder._start_server = _start_server forwarder.enqueue(client, self.proxy_host, self.port) sleep(.1)
def test_forwarder(self): forwarder = LocalForwarder() forwarder.daemon = True forwarder.start() forwarder.started.wait() client = SSHClient(self.proxy_host, port=self.proxy_port, pkey=self.user_key) forwarder.enqueue(client, self.proxy_host, self.port) forwarder.out_q.get() self.assertTrue(len(forwarder._servers) > 0) forwarder.shutdown()
def test_tunnel_channel_failure(self): remote_host = '127.0.0.8' remote_server = OpenSSHServer(listen_ip=remote_host, port=self.port) remote_server.start_server() in_q, out_q = deque(), deque() try: tunnel = Tunnel(self.proxy_host, in_q, out_q, port=self.port, pkey=self.user_key, num_retries=1) tunnel.daemon = True tunnel.start() in_q.append((remote_host, self.port)) while not tunnel.tunnel_open.is_set(): sleep(.1) if not tunnel.is_alive(): raise ProxyError self.assertTrue(tunnel.tunnel_open.is_set()) self.assertIsNotNone(tunnel.client) while True: try: _port = out_q.pop() except IndexError: sleep(.5) else: break proxy_client = SSHClient('127.0.0.1', pkey=self.user_key, port=_port, num_retries=1, _auth_thread_pool=False) sleep(1) cmd = spawn(proxy_client.execute, 'echo me') proxy_client.disconnect() joinall([cmd]) self.assertEqual(proxy_client.sock, None) finally: remote_server.stop()
def test_password_auth_failure(self): try: client = SSHClient( self.host, port=self.port, num_retries=1, allow_agent=False, identity_auth=False, password='******', ) except AuthenticationException as ex: self.assertIsInstance(ex.args[3], SSH2AuthenticationError) else: raise AssertionError
def setUpClass(cls): _mask = int('0600') if version_info <= (2,) else 0o600 os.chmod(PKEY_FILENAME, _mask) cls.server = OpenSSHServer() cls.server.start_server() cls.host = '127.0.0.1' cls.port = 2222 cls.cmd = 'echo me' cls.resp = u'me' cls.user_key = PKEY_FILENAME cls.user_pub_key = PUB_FILE cls.user = pwd.getpwuid(os.geteuid()).pw_name cls.client = SSHClient(cls.host, port=cls.port, pkey=PKEY_FILENAME, num_retries=1)
def test_sftp_exc(self): def _sftp_exc(local_file, remote_file): raise SFTPProtocolError client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1) client._sftp_put = _sftp_exc local_file = 'local_file' try: with open(local_file, 'wb') as fh: fh.write(b'asdf') fh.flush() self.assertRaises(SFTPIOError, client.copy_file, local_file, 'remote_file') finally: try: os.unlink(local_file) except Exception: pass client._sftp_get = _sftp_exc remote_file = os.path.expanduser('~/remote_file') try: with open(remote_file, 'wb') as fh: fh.write(b'asdf') fh.flush() self.assertRaises(SFTPIOError, client.copy_remote_file, remote_file, 'local_file') finally: try: os.unlink(remote_file) except Exception: pass self.assertRaises(SFTPIOError, client.copy_remote_file, 'fake_remote_file_not_exists', 'local')
def test_agent_auth_fake_success(self): def _agent_auth(): return client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1, allow_agent=True, identity_auth=False) client.session.disconnect() client.pkey = None client._connect(self.host, self.port) client._agent_auth = _agent_auth self.assertIsNone(client.auth())
def test_disconnect_exc(self): class DiscError(Exception): pass def _disc(): raise DiscError client = SSHClient( self.host, port=self.port, pkey=self.user_key, retry_delay=.1, num_retries=1, timeout=1, ) client._disconnect_eagain = _disc client._connect_init_session_retry(1) client.disconnect()
def test_multiple_clients_exec_terminates_channels(self): # See #200 - Multiple clients should not interfere with # each other. session.disconnect can leave state in libssh2 # and break subsequent sessions even on different socket and # session for _ in range(5): client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1, allow_agent=False) channel = client.execute(self.cmd) output = list(client.read_output(channel)) self.assertListEqual(output, [b'me']) client.disconnect()
def test_agent_auth_failure(self): class UnknownError(Exception): pass def _agent_auth_unk(): raise UnknownError def _agent_auth_agent_err(): raise AgentConnectionError client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1, allow_agent=True, identity_auth=False) client.session.disconnect() client.pkey = None client._connect(self.host, self.port) client._agent_auth = _agent_auth_unk self.assertRaises(AuthenticationError, client.auth) client._agent_auth = _agent_auth_agent_err self.assertRaises(AuthenticationError, client.auth)
def test_socket_channel_error(self): class SocketError(Exception): pass class ChannelFailure(object): def read(self): raise SocketRecvError def write(self, data): raise SocketSendError def eof(self): return False def close(self): return class Channel(object): def __init__(self): self._eof = False def read(self): return 5, b"asdfa" def write(self, data): return 0, len(data) def eof(self): return self._eof def close(self): return class Socket(object): def recv(self, num): return b"asdfaf" def close(self): return class SocketFailure(object): def sendall(self, data): raise SocketError def recv(self, num): raise SocketError def close(self): return class SocketEmpty(object): def recv(self, num): return b"" def close(self): return client = SSHClient(self.proxy_host, port=self.proxy_port, pkey=self.user_key) server = TunnelServer(client, self.proxy_host, self.port) let = spawn(server._read_forward_sock, SocketEmpty(), Channel()) let.start() sleep(.01) self.assertRaises(SocketSendError, server._read_forward_sock, Socket(), ChannelFailure()) self.assertRaises(SocketError, server._read_forward_sock, SocketFailure(), Channel()) self.assertRaises(SocketError, server._read_channel, SocketFailure(), Channel()) self.assertRaises(SocketRecvError, server._read_channel, Socket(), ChannelFailure()) channel = Channel() _socket = Socket() source_let = spawn(server._read_forward_sock, _socket, channel) dest_let = spawn(server._read_channel, _socket, channel) channel._eof = True self.assertIsNone( server._wait_send_receive_lets(source_let, dest_let, channel, _socket)) let.kill()
def test_context_manager(self): with SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1) as client: self.assertIsInstance(client, SSHClient)
def test_manual_auth(self): client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1) client.session.disconnect() del client.session del client.sock client.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client._connect(self.host, self.port) client._init() # Identity auth client.pkey = None client.session.disconnect() del client.session del client.sock client.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client._connect(self.host, self.port) client.session = Session() client.session.handshake(client.sock) self.assertRaises(AuthenticationException, client.auth)
def test_identity_auth(self): class _SSHClient(SSHClient): IDENTITIES = (self.user_key, ) client = SSHClient(self.host, port=self.port, pkey=self.user_key, num_retries=1, allow_agent=False) client.disconnect() client.pkey = None del client.session del client.sock client._connect(self.host, self.port) client._init_session() client.IDENTITIES = (self.user_key, ) # Default identities auth only should succeed client._identity_auth() client.disconnect() client._connect(self.host, self.port) client._init_session() # Auth should succeed self.assertIsNone(client.auth()) # Standard init with custom identities client = _SSHClient(self.host, port=self.port, num_retries=1, allow_agent=False) self.assertIsInstance(client, SSHClient)