From 00bf9f3eafff6f29b4fcf18d7c1f2ab2b1310c16 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 15 Feb 2020 11:05:43 +0100 Subject: Rename bupper to lbup. bupper already exists. lbup is a randomly chosen word containing bup --- lbup/_ssh_client.py | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 lbup/_ssh_client.py (limited to 'lbup/_ssh_client.py') diff --git a/lbup/_ssh_client.py b/lbup/_ssh_client.py new file mode 100644 index 0000000..dec3390 --- /dev/null +++ b/lbup/_ssh_client.py @@ -0,0 +1,51 @@ +import paramiko.client as pmc + +from ._sshfp_policy import SSHFPPolicy + +class SSHConnection: + """ + An SSH client connection to a remote server, with support for a proxy "jump" + host, like OpenSSH's 'ssh -J'. Uses only SSHFP for host key verification. + + May be used as a context manager. + + :param SSHRemote remote: Remote host to connect to. + """ + _proxy_conn = None + _client = None + _remote = None + + def __init__(self, remote): + sock = None + if remote.proxy_remote is not None: + self._proxy_conn = SSHConnection(remote.proxy_remote) + t = self._proxy_conn.get_transport() + sock = t.open_channel('direct-tcpip', (remote.host, remote.port), ('localhost', 0)) + + self._client = pmc.SSHClient() + self._client.set_missing_host_key_policy(SSHFPPolicy()) + self._client.connect(remote.host, remote.port, remote.username, + sock = sock) + + self._remote = remote + + def close(self): + if self._client: + self._client.close() + self._client = None + if self._proxy_conn: + self._proxy_conn.close() + self._proxy_conn = None + + def exec_command(self, *args, **kwargs): + return self._client.exec_command(*args, **kwargs) + def get_transport(self): + return self._client.get_transport() + + def __enter__(self): + return self + def __exit__(self, exc_type, exc_value, traceback): + self.close() + + def __str__(self): + return 'ssh:%s' % str(self._remote) -- cgit v1.2.3