Skip to content

Commit 9a5c08e

Browse files
committed
Fix issue with SSH config reloading with Hostname aliases
This commit fixes an issue where SSH config was not evaluating properly when "Match final" was combined with Hostname directives. Thanks go to GitHub user commonism for reporting this issue and coming up with a reproducible test case and a potential fix.
1 parent f7b8baf commit 9a5c08e

2 files changed

Lines changed: 28 additions & 2 deletions

File tree

asyncssh/connection.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ async def _canonicalize_host(loop: asyncio.AbstractEventLoop,
282282
options: 'SSHConnectionOptions') -> Optional[str]:
283283
"""Canonicalize a host name"""
284284

285-
host = options.host
285+
host = options.orig_host
286286

287287
if not options.canonicalize_hostname or not options.canonical_domains:
288288
logger.info('Host canonicalization disabled')
@@ -474,7 +474,7 @@ async def _connect(options: _Options, config: DefTuple[ConfigPaths],
474474

475475
canon_host = await _canonicalize_host(loop, options)
476476

477-
host = canon_host if canon_host else options.host
477+
host = canon_host if canon_host else options.orig_host
478478
canonical = bool(canon_host)
479479
final = options.config.has_match_final()
480480

@@ -7295,6 +7295,7 @@ class SSHConnectionOptions(Options, Generic[_Options]):
72957295
waiter: Optional[asyncio.Future]
72967296
protocol_factory: _ProtocolFactory
72977297
version: bytes
7298+
orig_host: str
72987299
host: str
72997300
port: int
73007301
tunnel: object
@@ -7387,6 +7388,7 @@ def _split_cname_patterns(
73877388
self.protocol_factory = protocol_factory
73887389
self.version = _validate_version(version)
73897390

7391+
self.orig_host = host
73907392
self.host = cast(str, config.get('Hostname', host))
73917393
self.port = cast(int, port if port != () else
73927394
config.get('Port', DEFAULT_PORT))

tests/test_forward.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -435,6 +435,30 @@ async def test_proxy_jump_encrypted_key_missing_passphrase(self):
435435
finally:
436436
os.remove('.ssh/config')
437437

438+
@asynctest
439+
async def test_proxy_jump_config(self):
440+
"""Test ProxyJump to a host with config options"""
441+
442+
jump_host = await self.create_server(
443+
_TCPConnectionServer, authorized_client_keys='authorized_keys')
444+
jump_port = jump_host.get_port()
445+
446+
try:
447+
write_file('.ssh/config',
448+
'Host jumphost\n'
449+
' Hostname localhost\n'
450+
f' Port {jump_port}\n'
451+
'Match final host target\n'
452+
' Hostname localhost\n'
453+
f' Port {self._server_port}\n'
454+
' ProxyJump jumphost\n', 'w')
455+
456+
async with self.connect(host='target', username='ckey'):
457+
pass
458+
finally:
459+
jump_host.close()
460+
os.remove('.ssh/config')
461+
438462
@asynctest
439463
async def test_ssh_connect_reverse_tunnel(self):
440464
"""Test creating a tunneled reverse direction SSH connection"""

0 commit comments

Comments
 (0)