Dangers of setting SSH path in Git config

March 18th 2022 Git Windows SSH Visual Studio

Using SSH with Git on Windows mostly works out of the box. The .gitignore file allows a lot of additional configuration. The sshCommand in the core section allows you to specify the path and arguments for the ssh.exe command. However, specifying a path there is mostly asking for trouble.

The ssh.exe command is located in C:\Windows\System32\OpenSSH on Windows. So the correct setting in .gitignore should be:

[core]
  sshCommand = \"C:\\Windows\\System32\\OpenSSH\\ssh.exe\"

If you try to use Git with SSH from the command line after setting this, it will actually work as expected. However, if you try to use it from Visual Studio, it fails with the following error message:

"C:\Windows\System32\OpenSSH\ssh.exe": C:\Windows\System32\OpenSSH\ssh.exe: No such file or directory

The reason for this is the Windows file system redirector which redirects some of the system paths for 32-bit processes, as stated in the documentation:

In most cases, whenever a 32-bit application attempts to access %windir%\System32, %windir%\lastgood\system32, or %windir%\regedit.exe, the access is redirected to an architecture-specific path.

So, for a 32-bit process, the above path is actually C:\Windows\SysWOW64\OpenSSH\ssh.exe. This file does not exist, hence the error.

It is also interesting to note that the error occurs in both Visual Studio 2019 (which is 32-bit) and Visual Studio 2022 (which is 64-bit). This is the case because both call Git from a separate 32-bit process.

There is a way for a 32-bit process to access C:\Windows\System32\OpenSSH\ssh.exe, as stated in the documentation:

32-bit applications can access the native system directory by substituting %windir%\Sysnative for %windir%\System32. WOW64 recognizes Sysnative as a special alias used to indicate that the file system should not redirect the access. This mechanism is flexible and easy to use, therefore, it is the recommended mechanism to bypass file system redirection. Note that 64-bit applications cannot use the Sysnative alias as it is a virtual directory not a real one.

This means that the correct path in .gitignore for 32-bit applications would be as follows:

[core]
  sshCommand = \"C:\\Windows\\SysNative\\OpenSSH\\ssh.exe\"

With this setting Visual Studio works fine. But now Git does not work from the command line because the Sysnative alias does not work for 64-bit applications, as explained in the quote above:

"C:\Windows\SysNative\OpenSSH\ssh.exe": C:\Windows\SysNative\OpenSSH\ssh.exe: No such file or directory

There is simply no path that could be used for a file in a system folder like C:\Windows\System32 that would work for both 32-bit and 64-bit applications. This means that you should not specify such a path in a configuration file that is read by both 32-bit and 64-bit processes.

So what is the recommendation for the sshCommand setting in .gitignore? Do not use it to set a path to the command. The folder containing ssh.exe (and related commands) should be in the path by default, so you can invoke the command from anywhere without having to specify the path. If it is not, simply add C:\Windows\System32\OpenSSH to the path.

Get notified when a new blog post is published (usually every Friday):

If you're looking for online one-on-one mentorship on a related topic, you can find me on Codementor.
If you need a team of experienced software engineers to help you with a project, contact us at Razum.
Copyright
Creative Commons License