Skip to content

Commit 701b2ae

Browse files
author
Pan
committed
Fix for overriden host name in openssh config causing key error for host in parallel client plus test. Resolves #93
1 parent 011dd0f commit 701b2ae

File tree

2 files changed

+51
-12
lines changed

2 files changed

+51
-12
lines changed

pssh/ssh_client.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,10 @@ def __init__(self, host,
101101
:type paramiko_kwargs: dict
102102
"""
103103
try:
104-
host, _user, _port, _pkey = read_openssh_config(
104+
_host, _user, _port, _pkey = read_openssh_config(
105105
host, config_file=_openssh_config_file)
106106
except TypeError:
107-
host, _user, _port, _pkey = host, None, 22, None
107+
_host, _user, _port, _pkey = None, None, 22, None
108108
user = user if user else _user
109109
client = paramiko.SSHClient()
110110
client.set_missing_host_key_policy(paramiko.MissingHostKeyPolicy())
@@ -115,6 +115,7 @@ def __init__(self, host,
115115
self.pkey = pkey if pkey else _pkey
116116
self.port = port if port else _port
117117
self.host = host
118+
self._host = _host
118119
self.allow_agent = allow_agent
119120
if agent:
120121
self.client._agent = agent
@@ -125,15 +126,16 @@ def __init__(self, host,
125126
self.proxy_password, self.proxy_pkey = proxy_host, proxy_port, \
126127
proxy_user, proxy_password, proxy_pkey
127128
self.proxy_client = None
129+
real_host = _host if _host is not None else host
128130
if self.proxy_host and self.proxy_port:
129131
logger.debug(
130132
"Proxy configured for destination host %s - Proxy host: %s:%s",
131-
self.host, self.proxy_host, self.proxy_port,)
132-
self._connect_tunnel(**paramiko_kwargs)
133+
real_host, self.proxy_host, self.proxy_port,)
134+
self._connect_tunnel(real_host, **paramiko_kwargs)
133135
else:
134-
self._connect(self.client, self.host, self.port, **paramiko_kwargs)
136+
self._connect(self.client, real_host, self.port, **paramiko_kwargs)
135137

136-
def _connect_tunnel(self, **paramiko_kwargs):
138+
def _connect_tunnel(self, host, **paramiko_kwargs):
137139
"""Connects to SSH server via an intermediate SSH tunnel server.
138140
client (me) -> tunnel (ssh server to proxy through) ->
139141
``self.host`` (ssh server to run command)
@@ -148,20 +150,20 @@ def _connect_tunnel(self, **paramiko_kwargs):
148150
user=self.proxy_user, password=self.proxy_password,
149151
pkey=self.proxy_pkey, **paramiko_kwargs)
150152
logger.info("Connecting via SSH proxy %s:%s -> %s:%s", self.proxy_host,
151-
self.proxy_port, self.host, self.port,)
153+
self.proxy_port, host, self.port,)
152154
try:
153155
proxy_channel = self.proxy_client.get_transport().open_channel(
154-
'direct-tcpip', (self.host, self.port,), ('127.0.0.1', 0),
156+
'direct-tcpip', (host, self.port,), ('127.0.0.1', 0),
155157
timeout=self.timeout)
156158
sleep(0)
157-
return self._connect(self.client, self.host, self.port,
159+
return self._connect(self.client, host, self.port,
158160
sock=proxy_channel,
159161
**paramiko_kwargs)
160162
except (ChannelException, paramiko.SSHException) as ex:
161163
error_type = ex.args[1] if len(ex.args) > 1 else ex.args[0]
162164
raise ConnectionErrorException(
163165
"Error connecting to host '%s:%s' - %s",
164-
self.host, self.port, str(error_type))
166+
host, self.port, str(error_type))
165167

166168
def _connect(self, client, host, port, sock=None, retries=1,
167169
user=None, password=None, pkey=None,
@@ -177,6 +179,7 @@ def _connect(self, client, host, port, sock=None, retries=1,
177179
:raises: :py:class:`pssh.exceptions.SSHException` on other undefined
178180
SSH errors
179181
"""
182+
logger.debug("Connecting to %s..", host)
180183
try:
181184
client.connect(host,
182185
username=user if user else self.user,
@@ -199,7 +202,7 @@ def _connect(self, client, host, port, sock=None, retries=1,
199202
self.num_retries)
200203
except sock_error as ex:
201204
logger.error("Error connecting to host '%s:%s' - retry %s/%s",
202-
self.host, self.port, retries, self.num_retries)
205+
host, self.port, retries, self.num_retries)
203206
while retries < self.num_retries:
204207
sleep(5)
205208
return self._connect(client, host, port,
@@ -209,7 +212,7 @@ def _connect(self, client, host, port, sock=None, retries=1,
209212
error_type = ex.args[1] if len(ex.args) > 1 else ex.args[0]
210213
raise ConnectionErrorException(
211214
"Error connecting to host '%s:%s' - %s - retry %s/%s",
212-
self.host, self.port, str(error_type), retries,
215+
host, self.port, str(error_type), retries,
213216
self.num_retries,)
214217
except paramiko.AuthenticationException as ex:
215218
msg = "Authentication error while connecting to %s:%s."

tests/test_pssh_client.py

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import shutil
3030
import sys
3131
from socket import timeout as socket_timeout
32+
from platform import python_version
3233

3334
from gevent import sleep
3435
from pssh import ParallelSSHClient, UnknownHostException, \
@@ -1090,6 +1091,41 @@ def test_proxy_remote_host_failure_timeout(self):
10901091
server.kill()
10911092
proxy_server.kill()
10921093

1094+
def test_openssh_config(self):
1095+
self.server.kill()
1096+
ssh_config = os.path.expanduser('~/.ssh/config')
1097+
mode = '0700' if python_version() < '3' else 0o700
1098+
if os.path.isfile(ssh_config):
1099+
shutil.move(ssh_config, '.')
1100+
elif not os.path.isdir(os.path.expanduser('~/.ssh')):
1101+
os.mkdir(os.path.expanduser('~/.ssh'), mode=mode)
1102+
config_file = open(ssh_config, 'w')
1103+
_host = "127.0.0.2"
1104+
_user = "config_user"
1105+
_server, _port = start_server_from_ip(_host)
1106+
content = [("""Host %s\n""" % (self.host,)),
1107+
(""" HostName %s\n""" % (_host,)),
1108+
(""" User %s\n""" % (_user,)),
1109+
(""" Port %s\n""" % (_port,)),
1110+
(""" IdentityFile %s\n""" % (PKEY_FILENAME,)),
1111+
]
1112+
config_file.writelines(content)
1113+
config_file.close()
1114+
try:
1115+
client = ParallelSSHClient([self.host],
1116+
num_retries=1)
1117+
output = client.run_command(self.fake_cmd)
1118+
self.assertTrue(self.host in output)
1119+
output = list(output[self.host].stdout)
1120+
expected = [self.fake_resp]
1121+
self.assertEqual(output, expected)
1122+
except Exception:
1123+
raise
1124+
finally:
1125+
os.unlink(ssh_config)
1126+
if os.path.isfile('config'):
1127+
shutil.move('config', os.path.expanduser('~/.ssh/'))
1128+
10931129

10941130
if __name__ == '__main__':
10951131
unittest.main()

0 commit comments

Comments
 (0)