mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-04-10 23:58:06 -05:00
Windows Pageant: option to open an AF_UNIX socket.
There's now a command-line option to make Pageant open an AF_UNIX socket at a pathname of your choice. This allows it to act as an SSH agent for any client program willing to use a WinSock AF_UNIX socket. In particular, this allows WSL 1 processes to talk directly to Windows Pageant without needing any intermediate process, because the AF_UNIX sockets in the WSL 1 world interoperate with WinSock's ones. (However, not WSL 2, which isn't very surprising.)
This commit is contained in:
parent
82971a3ebb
commit
6f8db22972
@ -217,6 +217,45 @@ point at a different program. You could point it at
|
||||
\cw{c:\\Windows\\System32\\OpenSSH\\ssh.exe} once you've done this
|
||||
setup \dash but it's just as easy to point it at Plink!
|
||||
|
||||
\S{pageant-cmdline-unix} Unix-domain sockets: integrating with WSL 1
|
||||
|
||||
Pageant can listen on the WinSock implementation of \q{Unix-domain
|
||||
sockets}. These interoperate with the Unix-domain sockets found in the
|
||||
original Windows Subsystem for Linux (now known as WSL 1). So if you
|
||||
ask Pageant to listen on one of these, then your WSL 1 processes can
|
||||
talk directly to Pageant.
|
||||
|
||||
To configure this, run Pageant with the option \c{--unix}, followed
|
||||
with a pathname. Then, in WSL 1, set the environment variable
|
||||
\cw{SSH_AUTH_SOCK} to point at the WSL translation of that pathname.
|
||||
|
||||
For example, you might run
|
||||
|
||||
\c pageant --unix C:\Users\Simon\.ssh\agent.sock
|
||||
|
||||
and in WSL 1, set the environment variable
|
||||
|
||||
\c SSH_AUTH_SOCK=/mnt/c/Users/Simon/.ssh/agent.sock
|
||||
|
||||
Alternatively, you can add a line to your \cw{.ssh/config} file inside
|
||||
WSL that says
|
||||
|
||||
\c IdentityAgent /mnt/c/Users/Simon/.ssh/agent.sock
|
||||
|
||||
although doing it like that may mean that \cw{ssh-add} commands won't
|
||||
find the agent, even though \cw{ssh} itself will.
|
||||
|
||||
\s{Security note}: Unix-domain sockets are protected against access by
|
||||
other users by the file protections on their containing directory. So
|
||||
if your Windows machine is multiuser, make sure you create the socket
|
||||
inside a directory that other users can't access at all. (In fact,
|
||||
that's a good idea on general principles.)
|
||||
|
||||
\s{Compatibility note}: WSL 2 processes cannot talk to Pageant by this
|
||||
mechanism, because WSL 2's Unix-domain sockets are managed by a
|
||||
separate Linux kernel, and not by the same kernel that WinSock talks
|
||||
to.
|
||||
|
||||
\S{pageant-cmdline-keylist} Starting with the key list visible
|
||||
|
||||
Start Pageant with the \i\c{--keylist} option to show the main window
|
||||
|
@ -1391,6 +1391,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
{
|
||||
MSG msg;
|
||||
const char *command = NULL;
|
||||
const char *unixsocket = NULL;
|
||||
bool show_keylist_on_startup = false;
|
||||
int argc;
|
||||
char **argv, **argstart;
|
||||
@ -1494,6 +1495,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
show_keylist_on_startup = true;
|
||||
} else if (match_optval("-openssh-config", "-openssh_config")) {
|
||||
openssh_config_file = val;
|
||||
} else if (match_optval("-unix")) {
|
||||
unixsocket = val;
|
||||
} else if (match_opt("-c")) {
|
||||
/*
|
||||
* If we see `-c', then the rest of the command line
|
||||
@ -1538,6 +1541,31 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
* running, so set up all the machinery to answer requests.
|
||||
*/
|
||||
if (!already_running) {
|
||||
/*
|
||||
* Set up the window class for the hidden window that receives
|
||||
* all the messages to do with our presence in the system tray.
|
||||
*/
|
||||
|
||||
if (!prev) {
|
||||
WNDCLASS wndclass;
|
||||
|
||||
memset(&wndclass, 0, sizeof(wndclass));
|
||||
wndclass.lpfnWndProc = TrayWndProc;
|
||||
wndclass.hInstance = inst;
|
||||
wndclass.hIcon = LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON));
|
||||
wndclass.lpszClassName = TRAYCLASSNAME;
|
||||
|
||||
RegisterClass(&wndclass);
|
||||
}
|
||||
|
||||
keylist = NULL;
|
||||
|
||||
traywindow = CreateWindow(TRAYCLASSNAME, TRAYWINTITLE,
|
||||
WS_OVERLAPPEDWINDOW | WS_VSCROLL,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
100, 100, NULL, NULL, inst, NULL);
|
||||
winselgui_set_hwnd(traywindow);
|
||||
|
||||
/*
|
||||
* Initialise the cross-platform Pageant code.
|
||||
*/
|
||||
@ -1546,39 +1574,66 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
/*
|
||||
* Set up a named-pipe listener.
|
||||
*/
|
||||
Plug *pl_plug;
|
||||
wpc->plc.vt = &winpgnt_vtable;
|
||||
wpc->plc.suppress_logging = true;
|
||||
struct pageant_listen_state *pl =
|
||||
pageant_listener_new(&pl_plug, &wpc->plc);
|
||||
char *pipename = agent_named_pipe_name();
|
||||
Socket *sock = new_named_pipe_listener(pipename, pl_plug);
|
||||
if (sk_socket_error(sock)) {
|
||||
char *err = dupprintf("Unable to open named pipe at %s "
|
||||
"for SSH agent:\n%s", pipename,
|
||||
sk_socket_error(sock));
|
||||
MessageBox(NULL, err, "Pageant Error", MB_ICONERROR | MB_OK);
|
||||
return 1;
|
||||
}
|
||||
pageant_listener_got_socket(pl, sock);
|
||||
|
||||
/*
|
||||
* If we've been asked to write out an OpenSSH config file
|
||||
* pointing at the named pipe, do so.
|
||||
*/
|
||||
if (openssh_config_file) {
|
||||
FILE *fp = fopen(openssh_config_file, "w");
|
||||
if (!fp) {
|
||||
char *err = dupprintf("Unable to write OpenSSH config file "
|
||||
"to %s", openssh_config_file);
|
||||
{
|
||||
Plug *pl_plug;
|
||||
struct pageant_listen_state *pl =
|
||||
pageant_listener_new(&pl_plug, &wpc->plc);
|
||||
char *pipename = agent_named_pipe_name();
|
||||
Socket *sock = new_named_pipe_listener(pipename, pl_plug);
|
||||
if (sk_socket_error(sock)) {
|
||||
char *err = dupprintf("Unable to open named pipe at %s "
|
||||
"for SSH agent:\n%s", pipename,
|
||||
sk_socket_error(sock));
|
||||
MessageBox(NULL, err, "Pageant Error", MB_ICONERROR | MB_OK);
|
||||
return 1;
|
||||
}
|
||||
fprintf(fp, "IdentityAgent %s\n", pipename);
|
||||
fclose(fp);
|
||||
pageant_listener_got_socket(pl, sock);
|
||||
|
||||
/*
|
||||
* If we've been asked to write out an OpenSSH config file
|
||||
* pointing at the named pipe, do so.
|
||||
*/
|
||||
if (openssh_config_file) {
|
||||
FILE *fp = fopen(openssh_config_file, "w");
|
||||
if (!fp) {
|
||||
char *err = dupprintf("Unable to write OpenSSH config "
|
||||
"file to %s", openssh_config_file);
|
||||
MessageBox(NULL, err, "Pageant Error",
|
||||
MB_ICONERROR | MB_OK);
|
||||
return 1;
|
||||
}
|
||||
fprintf(fp, "IdentityAgent %s\n", pipename);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
sfree(pipename);
|
||||
}
|
||||
|
||||
sfree(pipename);
|
||||
/*
|
||||
* Set up an AF_UNIX listener too, if we were asked to.
|
||||
*/
|
||||
if (unixsocket) {
|
||||
sk_init();
|
||||
|
||||
/* FIXME: diagnose any error except file-not-found. Also,
|
||||
* check the file type if possible? */
|
||||
remove(unixsocket);
|
||||
|
||||
Plug *pl_plug;
|
||||
struct pageant_listen_state *pl =
|
||||
pageant_listener_new(&pl_plug, &wpc->plc);
|
||||
Socket *sock = sk_newlistener_unix(unixsocket, pl_plug);
|
||||
if (sk_socket_error(sock)) {
|
||||
char *err = dupprintf("Unable to open AF_UNIX socket at %s "
|
||||
"for SSH agent:\n%s", unixsocket,
|
||||
sk_socket_error(sock));
|
||||
MessageBox(NULL, err, "Pageant Error", MB_ICONERROR | MB_OK);
|
||||
return 1;
|
||||
}
|
||||
pageant_listener_got_socket(pl, sock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the window class for the hidden window that receives
|
||||
@ -1661,31 +1716,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the window class for the hidden window that receives
|
||||
* all the messages to do with our presence in the system tray.
|
||||
*/
|
||||
|
||||
if (!prev) {
|
||||
WNDCLASS wndclass;
|
||||
|
||||
memset(&wndclass, 0, sizeof(wndclass));
|
||||
wndclass.lpfnWndProc = TrayWndProc;
|
||||
wndclass.hInstance = inst;
|
||||
wndclass.hIcon = LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON));
|
||||
wndclass.lpszClassName = TRAYCLASSNAME;
|
||||
|
||||
RegisterClass(&wndclass);
|
||||
}
|
||||
|
||||
keylist = NULL;
|
||||
|
||||
traywindow = CreateWindow(TRAYCLASSNAME, TRAYWINTITLE,
|
||||
WS_OVERLAPPEDWINDOW | WS_VSCROLL,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
100, 100, NULL, NULL, inst, NULL);
|
||||
winselgui_set_hwnd(traywindow);
|
||||
|
||||
/* Set up a system tray icon */
|
||||
AddTrayIcon(traywindow);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user