Open amurzeau opened 2 years ago
Workaround: Use something like https://github.com/tprasadtp/pipe-ssh-pageant or https://github.com/amurzeau/ssh-agent-bridge to redirect requests on \.\pipe\openssh-ssh-agent made by commands in the container through VSCode's own ssh agent bridge to either pageant or git bash' agent.
But I also successfully made VSCode forward ssh-agent requests to git bash' ssh-agent with this change. The following is a diff between:
The extension.js file is here: %USERPROFILE%\.vscode\extensions\ms-vscode-remote.remote-containers-0.234.0\dist\extension\extension.js
The modification consists in changing existing code that trigger when
\\.\pipe\
I don't know what was the purpose of the original code, but it seemed close enough to the implementation of Git Bash' ssh-agent given what it does and when it is triggered.
I've changed the way the handshake is made based on what Git Bash' ssh-agent expect:
!<socket >63488 s 44693F4F-E2572CA5-537862AB-248DFDEF
63488
skipUnixSocketHeader
)skipUnixSocketHeader
; this is a function that just skip the handshake data).As the server send back data in the handshake phase (16 + 12 bytes), I need to skip them through the use of skipUnixSocketHeader
.
Then actual data transfer can take place.
See also: https://stackoverflow.com/questions/23086038/what-mechanism-is-used-by-msys-cygwin-to-emulate-unix-domain-sockets https://github.com/abourget/secrets-bridge/blob/094959a1553943e0727f6524289e12e8aab697bf/pkg/agentfwd/agentconn_windows.go#L15
--- orig.js 2022-05-24 23:26:59.410007100 +0200
+++ fixed.js 2022-05-24 23:28:30.064495500 +0200
@@ -41675,25 +41675,64 @@
connect: n
}
}
+function unixSocketCookieToBuffer(guid) {
+ var bytes = [];
+ guid.split('-').map((number, index) => {
+ var bytesInChar = number.match(/.{1,2}/g).reverse();
+ bytesInChar.map((byte) => {
+ bytes.push(parseInt(byte, 16));
+ });
+ });
+ return Buffer.from(bytes);
+}
+function skipUnixSocketHeader() {
+ var headerSize = 16 + 12;
+ var Through = fT();
+ return Through(function (buf) {
+ if (buf.length > headerSize) {
+ var removeSize = buf.length - headerSize;
+ buf.copy(buf, 0, removeSize);
+ headerSize = 0;
+ this.queue(buf);
+ } else {
+ headerSize = headerSize - buf.length;
+ }
+ })
+}
function Z9(t) {
if (process.platform !== "win32" || t.startsWith("\\\\.\\pipe\\"))
return kD.duplex(Kp.connect(t));
let e = new Kp.Socket;
- return (async() => {
- let r = await Oe(t),
- n = r.indexOf(10),
- i = parseInt(r.slice(0, n).toString(), 10),
- o = r.slice(n + 1);
- e.connect(i, "127.0.0.1", () => {
- e.write(o, s => {
- s && (console.error(s), e.destroy())
+ (async() => {
+ let unixDomainSocketFileData = await Oe(t),
+ str = unixDomainSocketFileData.toString(),
+ params = str.match(/!<socket >(\d+)( s)? ([A-Fa-f0-9-]+)/),
+ portStr = params[1],
+ unixDomainSocketCookie = unixSocketCookieToBuffer(params[3]),
+ port = parseInt(portStr, 10);
+ e.connect(port, "127.0.0.1", () => {
+ e.write(unixDomainSocketCookie, s => {
+ if (s) {
+ console.error(s);
+ e.destroy();
+ } else {
+ var buf = Buffer.alloc(12);
+ buf.writeUInt32LE(process.pid, 0);
+ e.write(buf, s => {
+ s && (console.error(s), e.destroy())
+ });
+ }
})
})
})().catch(r => {
console.error(r),
e.destroy()
- }),
- kD.duplex(e)
+ });
+ var connection = kD.duplex(e);
+ return {
+ source: skipUnixSocketHeader()(connection.source),
+ sink: connection.sink
+ }
}
function AD(t, e, r) {
return t === "linux" ? e === r : e.toLowerCase() === r.toLowerCase()
I think that function is also here: https://github.com/devcontainers/cli/blob/839ef66ae95820b41b3faec09764e6d30fc8abb4/src/spec-common/cliHost.ts#L88
Start script in git bash:
ssh-agent sh -c 'ssh-add ~/.ssh/id_rsa; ./code.exe'
Log of
ssh-add -l
in powershell (local command to check that SSH_AUTH_SOCK and ssh are working, key content replaced with 0s):Starting a devcontainer using Docker Desktop give this message:
C:/Users/user/AppData/Local/Temp/ssh-EXqkeSdl9JlB/agent.2428
match theSSH_AUTH_SOCK
set by ssh-agent.When trying to
ssh-add -l
in a terminal inside the devcontainer, I get this error:And at the same time, the devcontainer logs shows this:
Steps to Reproduce:
~/.ssh/id_rsa
in Git bash for Windowsssh-agent sh -c 'ssh-add ~/.ssh/id_rsa; ./code.exe'
ssh-add -l
, it shows the added keyssh-add -l
I expect Git for Windows' ssh-agent to be forwarded inside the devcontainer as it is with Powershell OpenSSH Win32 ssh-agent. I can't use the later because the ssh-agent Windows' service is disabled by the enterprise and I don't have admin rights to change that.
Does this issue occur when you try this locally?: No Does this issue occur when you try this locally and all extensions are disabled?: No