@@ -112,14 +112,19 @@ func (o sshConfigOptions) equal(other sshConfigOptions) bool {
112
112
}
113
113
114
114
func (o sshConfigOptions )writeToBuffer (buf * bytes.Buffer )error {
115
- escapedCoderBinary ,err := sshConfigExecEscape (o .coderBinaryPath ,o .forceUnixSeparators )
115
+ escapedCoderBinaryProxy ,err := sshConfigProxyCommandEscape (o .coderBinaryPath ,o .forceUnixSeparators )
116
116
if err != nil {
117
- return xerrors .Errorf ("escape coder binary forssh failed: %w" ,err )
117
+ return xerrors .Errorf ("escape coder binary forProxyCommand failed: %w" ,err )
118
118
}
119
119
120
- escapedGlobalConfig ,err := sshConfigExecEscape (o .globalConfigPath , o . forceUnixSeparators )
120
+ escapedCoderBinaryMatchExec ,err := sshConfigMatchExecEscape (o .coderBinaryPath )
121
121
if err != nil {
122
- return xerrors .Errorf ("escape global config for ssh failed: %w" ,err )
122
+ return xerrors .Errorf ("escape coder binary for Match exec failed: %w" ,err )
123
+ }
124
+
125
+ escapedGlobalConfig ,err := sshConfigProxyCommandEscape (o .globalConfigPath ,o .forceUnixSeparators )
126
+ if err != nil {
127
+ return xerrors .Errorf ("escape global config for ProxyCommand failed: %w" ,err )
123
128
}
124
129
125
130
rootFlags := fmt .Sprintf ("--global-config %s" ,escapedGlobalConfig )
@@ -155,7 +160,7 @@ func (o sshConfigOptions) writeToBuffer(buf *bytes.Buffer) error {
155
160
_ ,_ = buf .WriteString ("\t " )
156
161
_ ,_ = fmt .Fprintf (buf ,
157
162
"ProxyCommand %s %s ssh --stdio%s --ssh-host-prefix %s %%h" ,
158
- escapedCoderBinary ,rootFlags ,flags ,o .userHostPrefix ,
163
+ escapedCoderBinaryProxy ,rootFlags ,flags ,o .userHostPrefix ,
159
164
)
160
165
_ ,_ = buf .WriteString ("\n " )
161
166
}
@@ -174,11 +179,11 @@ func (o sshConfigOptions) writeToBuffer(buf *bytes.Buffer) error {
174
179
// the ^^ options should always apply, but we only want to use the proxy command if Coder Connect is not running.
175
180
if ! o .skipProxyCommand {
176
181
_ ,_ = fmt .Fprintf (buf ,"\n Match host *.%s !exec\" %s connect exists %%h\" \n " ,
177
- o .hostnameSuffix ,escapedCoderBinary )
182
+ o .hostnameSuffix ,escapedCoderBinaryMatchExec )
178
183
_ ,_ = buf .WriteString ("\t " )
179
184
_ ,_ = fmt .Fprintf (buf ,
180
185
"ProxyCommand %s %s ssh --stdio%s --hostname-suffix %s %%h" ,
181
- escapedCoderBinary ,rootFlags ,flags ,o .hostnameSuffix ,
186
+ escapedCoderBinaryProxy ,rootFlags ,flags ,o .hostnameSuffix ,
182
187
)
183
188
_ ,_ = buf .WriteString ("\n " )
184
189
}
@@ -759,7 +764,8 @@ func sshConfigSplitOnCoderSection(data []byte) (before, section []byte, after []
759
764
return data ,nil ,nil ,nil
760
765
}
761
766
762
- // sshConfigExecEscape quotes the string if it contains spaces, as per
767
+ // sshConfigProxyCommandEscape prepares the path for use in ProxyCommand.
768
+ // It quotes the string if it contains spaces, as per
763
769
// `man 5 ssh_config`. However, OpenSSH uses exec in the users shell to
764
770
// run the command, and as such the formatting/escape requirements
765
771
// cannot simply be covered by `fmt.Sprintf("%q", path)`.
@@ -804,7 +810,7 @@ func sshConfigSplitOnCoderSection(data []byte) (before, section []byte, after []
804
810
// This is a control flag, and that is ok. It is a control flag
805
811
// based on the OS of the user. Making this a different file is excessive.
806
812
// nolint:revive
807
- func sshConfigExecEscape (path string ,forceUnixPath bool ) (string ,error ) {
813
+ func sshConfigProxyCommandEscape (path string ,forceUnixPath bool ) (string ,error ) {
808
814
if forceUnixPath {
809
815
// This is a workaround for #7639, where the filepath separator is
810
816
// incorrectly the Windows separator (\) instead of the unix separator (/).
@@ -814,9 +820,9 @@ func sshConfigExecEscape(path string, forceUnixPath bool) (string, error) {
814
820
// This is unlikely to ever happen, but newlines are allowed on
815
821
// certain filesystems, but cannot be used inside ssh config.
816
822
if strings .ContainsAny (path ,"\n " ) {
817
- return "" ,xerrors .Errorf ("invalid path: %s " ,path )
823
+ return "" ,xerrors .Errorf ("invalid path: %q " ,path )
818
824
}
819
- // In the unlikelyeven that a path contains quotes, they must be
825
+ // In the unlikelyevent that a path contains quotes, they must be
820
826
// escaped so that they are not interpreted as shell quotes.
821
827
if strings .Contains (path ,"\" " ) {
822
828
path = strings .ReplaceAll (path ,"\" " ,"\\ \" " )