diff options
-rw-r--r-- | paramiko/config.py | 12 | ||||
-rw-r--r-- | tests/configs/hostname-exec-tokenized | 2 | ||||
-rw-r--r-- | tests/configs/hostname-tokenized | 1 | ||||
-rw-r--r-- | tests/test_config.py | 10 |
4 files changed, 19 insertions, 6 deletions
diff --git a/paramiko/config.py b/paramiko/config.py index bef42610..e6877d01 100644 --- a/paramiko/config.py +++ b/paramiko/config.py @@ -60,6 +60,7 @@ class SSHConfig(object): # compatible across the board, e.g. OpenSSH 8.1 added %n to ProxyCommand. TOKENS_BY_CONFIG_KEY = { "controlpath": ["%h", "%l", "%L", "%n", "%p", "%r", "%u"], + "hostname": ["%h"], "identityfile": ["~", "%d", "%h", "%l", "%u", "%r"], "proxycommand": ["~", "%h", "%p", "%r"], # Doesn't seem worth making this 'special' for now, it will fit well @@ -412,13 +413,12 @@ class SSHConfig(object): # Short-circuit if no tokenization possible if not allowed_tokens: return value - # Obtain potentially configured (and even possibly itself tokenized) - # hostname, for use with %h in other values. + # Obtain potentially configured hostname, for use with %h. + # Special-case where we are tokenizing the hostname itself, to avoid + # replacing %h with a %h-bearing value, etc. configured_hostname = target_hostname - if "hostname" in config: - configured_hostname = config["hostname"].replace( - "%h", target_hostname - ) + if key != "hostname": + configured_hostname = config.get("hostname", configured_hostname) # Ditto the rest of the source values if "port" in config: port = config["port"] diff --git a/tests/configs/hostname-exec-tokenized b/tests/configs/hostname-exec-tokenized new file mode 100644 index 00000000..1cae2c03 --- /dev/null +++ b/tests/configs/hostname-exec-tokenized @@ -0,0 +1,2 @@ +Match exec "ping %h" + HostName pingable.%h diff --git a/tests/configs/hostname-tokenized b/tests/configs/hostname-tokenized new file mode 100644 index 00000000..1905c0cc --- /dev/null +++ b/tests/configs/hostname-tokenized @@ -0,0 +1 @@ +HostName prefix.%h diff --git a/tests/test_config.py b/tests/test_config.py index 7c86667a..5e9aa059 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -467,6 +467,10 @@ Host * cmd = config.lookup("some-random-host")["proxycommand"] assert cmd == "default-proxy" + def test_hostname_tokenization(self): + result = load_config("hostname-tokenized").lookup("whatever") + assert result["hostname"] == "prefix.whatever" + class TestSSHConfigDict(object): def test_SSHConfigDict_construct_empty(self): @@ -774,6 +778,12 @@ class TestMatchExec(object): with raises(ConfigParseError): load_config("match-exec-no-arg") + @patch("paramiko.config.invoke.run") + def test_works_with_tokenized_hostname(self, run): + run.side_effect = _expect("ping target") + result = load_config("hostname-exec-tokenized").lookup("target") + assert result["hostname"] == "pingable.target" + class TestMatchHost(object): def test_matches_target_name_when_no_hostname(self): |