Skip to content

Commit a090a3c

Browse files
committed
Matche Coder CLI behavior for escaping to SSH config
1 parent 9b8bdb7 commit a090a3c

16 files changed

+31
-26
lines changed

src/main/kotlin/com/coder/gateway/sdk/CoderCLIManager.kt

+7-6
Original file line numberDiff line numberDiff line change
@@ -507,12 +507,10 @@ class CoderCLIManager @JvmOverloads constructor(
507507
return if (cliMatches == null && dataCLIMatches != null) dataCLI else cli
508508
}
509509

510-
var escapeRegex = """(["\\])""".toRegex()
511-
512510
/**
513-
* Escape a command argument by wrapping it in double quotes and escaping
514-
* any slashes and double quotes in the argument. For example, echo "te\st"
515-
* becomes "echo \"te\\st\"".
511+
* Escape a command argument to be used in the ProxyCommand of an SSH
512+
* config. Surround with double quotes if the argument contains
513+
* whitespace and escape any existing double quotes.
516514
*
517515
* Throws if the argument is invalid.
518516
*/
@@ -521,7 +519,10 @@ class CoderCLIManager @JvmOverloads constructor(
521519
if (s.contains("\n")) {
522520
throw Exception("argument cannot contain newlines")
523521
}
524-
return "\"" + s.replace(escapeRegex, """\\$1""") + "\""
522+
if (s.contains(" ") || s.contains("\t")) {
523+
return "\"" + s.replace("\"", "\\\"") + "\""
524+
}
525+
return s.replace("\"", "\\\"")
525526
}
526527
}
527528
}

src/test/fixtures/outputs/append-blank-newlines.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# --- START CODER JETBRAINS test.coder.invalid
66
Host coder-jetbrains--foo-bar--test.coder.invalid
77
HostName coder.foo-bar
8-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" ssh --stdio foo-bar
8+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config ssh --stdio foo-bar
99
ConnectTimeout 0
1010
StrictHostKeyChecking no
1111
UserKnownHostsFile /dev/null

src/test/fixtures/outputs/append-blank.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# --- START CODER JETBRAINS test.coder.invalid
22
Host coder-jetbrains--foo-bar--test.coder.invalid
33
HostName coder.foo-bar
4-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" ssh --stdio foo-bar
4+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config ssh --stdio foo-bar
55
ConnectTimeout 0
66
StrictHostKeyChecking no
77
UserKnownHostsFile /dev/null

src/test/fixtures/outputs/append-no-blocks.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Host test2
66
# --- START CODER JETBRAINS test.coder.invalid
77
Host coder-jetbrains--foo-bar--test.coder.invalid
88
HostName coder.foo-bar
9-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" ssh --stdio foo-bar
9+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config ssh --stdio foo-bar
1010
ConnectTimeout 0
1111
StrictHostKeyChecking no
1212
UserKnownHostsFile /dev/null

src/test/fixtures/outputs/append-no-newline.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Host test2
55
# --- START CODER JETBRAINS test.coder.invalid
66
Host coder-jetbrains--foo-bar--test.coder.invalid
77
HostName coder.foo-bar
8-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" ssh --stdio foo-bar
8+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config ssh --stdio foo-bar
99
ConnectTimeout 0
1010
StrictHostKeyChecking no
1111
UserKnownHostsFile /dev/null

src/test/fixtures/outputs/append-no-related-blocks.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ some jetbrains config
1212
# --- START CODER JETBRAINS test.coder.invalid
1313
Host coder-jetbrains--foo-bar--test.coder.invalid
1414
HostName coder.foo-bar
15-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" ssh --stdio foo-bar
15+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config ssh --stdio foo-bar
1616
ConnectTimeout 0
1717
StrictHostKeyChecking no
1818
UserKnownHostsFile /dev/null

src/test/fixtures/outputs/header-command-windows.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# --- START CODER JETBRAINS test.coder.invalid
22
Host coder-jetbrains--header--test.coder.invalid
33
HostName coder.header
4-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" --header-command "C:\\Program Files\\My Header Command\\\"also has quotes\"\\HeaderCommand.exe" ssh --stdio header
4+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --header-command "C:\Program Files\My Header Command\\"also has quotes\"\HeaderCommand.exe" ssh --stdio header
55
ConnectTimeout 0
66
StrictHostKeyChecking no
77
UserKnownHostsFile /dev/null

src/test/fixtures/outputs/header-command.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# --- START CODER JETBRAINS test.coder.invalid
22
Host coder-jetbrains--header--test.coder.invalid
33
HostName coder.header
4-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" --header-command "my-header-command \"test\"" ssh --stdio header
4+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config --header-command "my-header-command \"test\"" ssh --stdio header
55
ConnectTimeout 0
66
StrictHostKeyChecking no
77
UserKnownHostsFile /dev/null

src/test/fixtures/outputs/multiple-workspaces.conf

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
# --- START CODER JETBRAINS test.coder.invalid
22
Host coder-jetbrains--foo--test.coder.invalid
33
HostName coder.foo
4-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" ssh --stdio foo
4+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config ssh --stdio foo
55
ConnectTimeout 0
66
StrictHostKeyChecking no
77
UserKnownHostsFile /dev/null
88
LogLevel ERROR
99
SetEnv CODER_SSH_SESSION_TYPE=JetBrains
1010
Host coder-jetbrains--bar--test.coder.invalid
1111
HostName coder.bar
12-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" ssh --stdio bar
12+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config ssh --stdio bar
1313
ConnectTimeout 0
1414
StrictHostKeyChecking no
1515
UserKnownHostsFile /dev/null

src/test/fixtures/outputs/replace-end-no-newline.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Host test2
44
Port 443 # --- START CODER JETBRAINS test.coder.invalid
55
Host coder-jetbrains--foo-bar--test.coder.invalid
66
HostName coder.foo-bar
7-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" ssh --stdio foo-bar
7+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config ssh --stdio foo-bar
88
ConnectTimeout 0
99
StrictHostKeyChecking no
1010
UserKnownHostsFile /dev/null

src/test/fixtures/outputs/replace-end.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Host test2
55
# --- START CODER JETBRAINS test.coder.invalid
66
Host coder-jetbrains--foo-bar--test.coder.invalid
77
HostName coder.foo-bar
8-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" ssh --stdio foo-bar
8+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config ssh --stdio foo-bar
99
ConnectTimeout 0
1010
StrictHostKeyChecking no
1111
UserKnownHostsFile /dev/null

src/test/fixtures/outputs/replace-middle-ignore-unrelated.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ some coder config
66
# --- START CODER JETBRAINS test.coder.invalid
77
Host coder-jetbrains--foo-bar--test.coder.invalid
88
HostName coder.foo-bar
9-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" ssh --stdio foo-bar
9+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config ssh --stdio foo-bar
1010
ConnectTimeout 0
1111
StrictHostKeyChecking no
1212
UserKnownHostsFile /dev/null

src/test/fixtures/outputs/replace-middle.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Host test
33
# --- START CODER JETBRAINS test.coder.invalid
44
Host coder-jetbrains--foo-bar--test.coder.invalid
55
HostName coder.foo-bar
6-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" ssh --stdio foo-bar
6+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config ssh --stdio foo-bar
77
ConnectTimeout 0
88
StrictHostKeyChecking no
99
UserKnownHostsFile /dev/null

src/test/fixtures/outputs/replace-only.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# --- START CODER JETBRAINS test.coder.invalid
22
Host coder-jetbrains--foo-bar--test.coder.invalid
33
HostName coder.foo-bar
4-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" ssh --stdio foo-bar
4+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config ssh --stdio foo-bar
55
ConnectTimeout 0
66
StrictHostKeyChecking no
77
UserKnownHostsFile /dev/null

src/test/fixtures/outputs/replace-start.conf

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# --- START CODER JETBRAINS test.coder.invalid
22
Host coder-jetbrains--foo-bar--test.coder.invalid
33
HostName coder.foo-bar
4-
ProxyCommand "/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64" --global-config "/tmp/coder-gateway/test.coder.invalid/config" ssh --stdio foo-bar
4+
ProxyCommand /tmp/coder-gateway/test.coder.invalid/coder-linux-amd64 --global-config /tmp/coder-gateway/test.coder.invalid/config ssh --stdio foo-bar
55
ConnectTimeout 0
66
StrictHostKeyChecking no
77
UserKnownHostsFile /dev/null

src/test/groovy/CoderCLIManagerTest.groovy

+9-5
Original file line numberDiff line numberDiff line change
@@ -386,9 +386,13 @@ class CoderCLIManagerTest extends Specification {
386386

387387
where:
388388
str | expected
389-
$/C:\"quote after slash"/$ | $/"C:\\\"quote after slash\""/$
390-
$/C:\echo "hello world"/$ | $/"C:\\echo \"hello world\""/$
391-
$/"C:\Program Files\HeaderCommand.exe" --flag/$ | $/"\"C:\\Program Files\\HeaderCommand.exe\" --flag"/$
389+
$//tmp/coder/$ | $//tmp/coder/$
390+
$//tmp/c o d e r/$ | $/"/tmp/c o d e r"/$
391+
$/C:\no\spaces.exe/$ | $/C:\no\spaces.exe/$
392+
$/C:\"quote after slash"/$ | $/"C:\\"quote after slash\""/$
393+
$/C:\echo "hello world"/$ | $/"C:\echo \"hello world\""/$
394+
$/C:\"no"\"spaces"/$ | $/C:\\"no\"\\"spaces\"/$
395+
$/"C:\Program Files\HeaderCommand.exe" --flag/$ | $/"\"C:\Program Files\HeaderCommand.exe\" --flag"/$
392396
}
393397

394398
def "configures an SSH file"() {
@@ -405,8 +409,8 @@ class CoderCLIManagerTest extends Specification {
405409

406410
def expectedConf = Path.of("src/test/fixtures/outputs/").resolve(output + ".conf").toFile().text
407411
.replaceAll("\\r?\\n", System.lineSeparator())
408-
.replace("\"/tmp/coder-gateway/test.coder.invalid/config\"", CoderCLIManager.escape(coderConfigPath.toString()))
409-
.replace("\"/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64\"", CoderCLIManager.escape(ccm.localBinaryPath.toString()))
412+
.replace("/tmp/coder-gateway/test.coder.invalid/config", CoderCLIManager.escape(coderConfigPath.toString()))
413+
.replace("/tmp/coder-gateway/test.coder.invalid/coder-linux-amd64", CoderCLIManager.escape(ccm.localBinaryPath.toString()))
410414

411415
when:
412416
ccm.configSsh(workspaces.collect { DataGen.workspace(it) }, headerCommand)

0 commit comments

Comments
 (0)