-
Notifications
You must be signed in to change notification settings - Fork 324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for AF_UNIX #674
base: latestw_all
Are you sure you want to change the base?
Conversation
57dabcc
to
3a77587
Compare
@tgauth Would it be fine if we guard the different code paths with |
I don't see why not. If you haven't seen it yet, can add it to: https://github.com/PowerShell/openssh-portable/blob/latestw_all/contrib/win32/openssh/config.h.vs Thanks for working on this! |
@tgauth Thanks for the quick feedback! I added the |
There's a |
@tgauth Yes, I can confirm that config.h in the root got updated.
Still, it doesn't seem to be compiling with |
oh, my bad - seems like config.h needs to be explicitly included in posix_compat where |
@tgauth That did the trick, thanks! I added the include statement in both files because doing so in I'm testing now a different approach for temp folder where the unix socket will live. I'm changing the implementation so that it uses fileapi.h |
yep, that makes sense to me! |
@tgauth I think I have addressed the different issues now. Take a look at the code that generates the temporal directory. Last commit was pushed using this feature 😎 |
@tgauth Was looking at the failing tests. They generally timeout ? Some tests seem to have failed but they look unrelated (at first glance). I wonder if having Any insight ? |
I think I know what is going on. Will try to fix it over the weekend. |
dafedf8
to
8ca026c
Compare
@tgauth Tests are passing now :) I had to change a few other calls to I think that a subsequent change could replace the named pipes usage in agent.c and use a native AF_UNIX socket to simplify the implementation. I'm moved Anything else I might be missing ? Thanks so much looking at the changes! |
Based on https://devblogs.microsoft.com/commandline/af_unix-comes-to-windows/ support started with Windows 10. We have a similar check already defined that I think can also be utilized here: https://github.com/PowerShell/openssh-portable/blob/latestw_all/contrib/win32/win32compat/misc_internal.h#L15
Ideally, would like to have some test coverage for agent forwarding! There are some upstream agent tests that the CI currently skips - https://github.com/PowerShell/openssh-portable/blob/latestw_all/regress/agent.sh, https://github.com/PowerShell/openssh-portable/blob/latestw_all/contrib/win32/openssh/bash_tests_iterator.ps1#L189. If the tests applicable to agent forwarding could be modified as necessary for Windows and not skipped, that would be great! A single bash test can be run with the following command: |
For maintainability, I'm in favor of doing the transformation so that |
@tgauth Thanks for the feedback! I'll take a look at the tests and doing the transformation for In regards to using IsWindows8OrGreater/IsWin7OrLess, you are thinking of replacing the HAVE_AFUNIX_H with calls to those functions at runtime ? Not sure how Microsoft build process works but Just want to make sure I fully understand how we want to protect the paths. |
795b52e
to
fd096f5
Compare
@tgauth I was able to include a fraction of the I had to continue excluding some of the tests for two reasons:
Having said that, with these changes, we have a little bit more coverage while keeping all the other tests passing. I also made the change to compare with |
Ping @tgauth |
@bilby91, thank you for working on this! The changes look good from an initial review, but we need some additional time to do a comprehensive review, since this would be a new feature for Win32-OpenSSH. For example, upstream has made some agent restrictions that have not yet been implemented for Windows that would be required to achieve parity. |
@tgauth Thanks for the feedback! I totally get that this kind of change needs an important level of review before shipping to Windows. Is there anything on my end that you think I can help with in the meantime? |
Not that I can think of right now, but will keep you posted - thanks for your patience! |
@tgauth was wondering if you had any updates about this topic! Thanks! |
This is delayed due to focusing on more simple PRs into the 9.4 release as well as an in depth security review of the behavior change. Because this is a new feature, not a bug fix, it requires further scrutiny. |
@maertendMSFT I understand. Thanks for the feedback! |
@bilby91 Do you know if this would also work for mux and |
@arixmkii To be honest I don't know. Any chance you have local development environment where you could test it ? If not I might be able to help over the weekend. |
@bilby91 I rebased your changes to 9.4.0.0 and built locally. Unfortunately it didn't work, but the error is suspicious, I don't have logs at hand, but it was about socket naming. Might be an error at command parsing level. I will debug it at the end of this week to figure out more details. |
Answering my question. No Mux will not work as everything mux is now covered by no_ops stubs. I will try to investigate the possible subset of Mux, which could be achieved with AF_UNIX additions from this PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bilby91, I just noticed your PR. I am just a bit confused as it looks like it might contradict parts of what I have researched over the weekend. (See also PowerShell/Win32-OpenSSH#1024 (comment).)
I also looked over your PR and made a few comments. However, I was missing some context and could therefore not really understand all of it. (Also note that I am not affiliated with Microsoft.)
What I don't understand at your PR is what has agent forwarding to do with whether SSH on Windows uses unix domain sockets instead of named pipes? This seems like two unrelated topics for me. I assume the changes in session.c
apply to sshd
? Is it possible that you could also have used named pipes here and then skipped all the other changes regarding unix domain sockets?
I've also tested that WSL can successfully use the SSH Agent sock as long as the
SSH_AUTH_SOCK
is defined in the bash session.
Are you talking about WSL1? Because I thought that WSL2 does not support interoperability with unix domain sockets (yet).
if(wcstombs(pipeid, AGENT_PIPE_ID, len + 1) != (size_t) -1 && strcmp(addr->sun_path, pipeid) == 0) | ||
return w32_fileio_socket(SOCK_STREAM, 0); | ||
else | ||
return w32_unix_socket(SOCK_STREAM, 0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I understand the code correctly, you could technically just call w32_socket(AF_INET, SOCK_STREAM, 0)
and w32_socket(AF_UNIX, SOCK_STREAM, 0)
, instead of introducing two new methods? Although I understand that AF_INET
would be misleading.
Besides, instead of checking whether addr->sun_path
equals AGENT_PIPE_ID
, I guess you could also just check the prefix. If the path starts with \\.\pipe\
, I think you can assume that it is a named pipe. This way, the solution stays compatible with other named pipes as well. For example, if a user uses Pageant (PuTTY authentication agent), they might also use named pipes, but the pipe may be named //./pipe/pageant.<username>.<random_sequence>
. (This means you should probably also accept both, slash (/
) and backslash (\
) in the prefix.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Originally I was thinking of behaving this way just for this implementation but I think the prefix makes sense in order to support other implementations.
if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) | ||
#ifdef HAVE_AFUNIX_H | ||
sock = w32_afunix_socket(&sunaddr); | ||
#else | ||
sock = socket(AF_UNIX, SOCK_STREAM, 0); | ||
#endif | ||
|
||
if (sock == -1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you need this #ifdef
condition? Shouldn't you be able to always call w32_afunix_socket
as this method already handles the #ifdef
condition internally? Same question applies to misc.c
and mux.c
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you are right. Will look into simplifying! Thanks
#ifdef HAVE_AFUNIX_H | ||
context->accept_socket = socket(addr.ss_family, SOCK_STREAM, IPPROTO_IP); | ||
#else | ||
context->accept_socket = socket(addr.ss_family, SOCK_STREAM, IPPROTO_TCP); | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this #ifdef
condition necessary? If IPPROTO_TCP
does not work for some reason, would it be possible to always use IPPROTO_IP
(or just 0
)? man socket(2) suggests that specifying 0
(which is the value of IPPROTO_IP
) will use the default, which again is TCP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would need to try this out. I don't recall if IPPROTO_TCP
was not working.
@JojOatXGME Thanks for taking a look at the code! It has been almost an year since I worked on this change but I'm pretty positive I tried using named pipes instead of the AF_UNIX sockets and it was not working. Could have been lack of understanding on my side so it's highly likely than an implementation based on them is possible. Regarding WSL1 vs WSL2, I think I was using WSL 2 in the machine I used for testing. Unfortunately I don't have that machine any more but I can look into double checking that in a different one potentially. Are you able to test yourself by any chance ? |
I have to see. I haven't worked on the project before. I actually did not work on any C-project for quite some time. I would have to set up some dev environment to build the project. Anyway, I will try to play with it within the next two weeks. PS: Assuming we could use named pipes in |
if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) | ||
#ifdef HAVE_AFUNIX_H | ||
sock = w32_afunix_socket(&addr); | ||
#elif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this elif intentional? It doesn't even compile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@thedarkcolour That's wrong, it should be an #else
. I'll fix it.
PR Summary
This pull requests adds support for AF_UNIX sockets.
The implementation modifies contrib/win32/win32compat/socketio.c
socketio_acceptEx
implementation so that it can handlesa_family == AF_UNIX
. contrib/win32/win32compat/w32fd.c has also been modified in order to remove the path that usesfileio_afunix_socket
.The unix socket name is conditionally using
C:\\tmp\\ssh-XXXXXXXXXX
instead of/tmp/ssh-XXXXXXXXXX
since it doesn't work correctly when usingssh
in the windows host. I'm not sure if/tmp
is the best directory to host the sock in Windows but I left it that way since unix users will expect the agent socks to live there. The caveat here is that you need to create the/tmp
folder in Windows in order to properly work.One known gap that the implementation is missing is conditionally using AF_UNIX. I know that a subset of Windows version support it but I'm not sure what is the best way to handle this. If I can get any guidance in terms of how to approach it I can test it and modify it.
PR Context
The motivation around working on this patch was to get support for SSH Agent Forwarding. With this patch applied,
ssh-add -l
will list the keys from the local system. I've also tested usinggit
to clone repositories and it's successfully able to use the local system private keys through the agent.I've also tested that WSL can successfully use the SSH Agent sock as long as the
SSH_AUTH_SOCK
is defined in the bash session.This pull request could potentially solve the following issues:
PowerShell/Win32-OpenSSH#1461
PowerShell/Win32-OpenSSH#1761
PowerShell/Win32-OpenSSH#1462