1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-07-01 03:22:48 -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:
Simon Tatham
2022-01-27 20:37:50 +00:00
parent 82971a3ebb
commit 6f8db22972
2 changed files with 120 additions and 51 deletions

View File

@ -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);