mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-04-21 13:05:04 -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
|
\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!
|
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
|
\S{pageant-cmdline-keylist} Starting with the key list visible
|
||||||
|
|
||||||
Start Pageant with the \i\c{--keylist} option to show the main window
|
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;
|
MSG msg;
|
||||||
const char *command = NULL;
|
const char *command = NULL;
|
||||||
|
const char *unixsocket = NULL;
|
||||||
bool show_keylist_on_startup = false;
|
bool show_keylist_on_startup = false;
|
||||||
int argc;
|
int argc;
|
||||||
char **argv, **argstart;
|
char **argv, **argstart;
|
||||||
@ -1494,6 +1495,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
|||||||
show_keylist_on_startup = true;
|
show_keylist_on_startup = true;
|
||||||
} else if (match_optval("-openssh-config", "-openssh_config")) {
|
} else if (match_optval("-openssh-config", "-openssh_config")) {
|
||||||
openssh_config_file = val;
|
openssh_config_file = val;
|
||||||
|
} else if (match_optval("-unix")) {
|
||||||
|
unixsocket = val;
|
||||||
} else if (match_opt("-c")) {
|
} else if (match_opt("-c")) {
|
||||||
/*
|
/*
|
||||||
* If we see `-c', then the rest of the command line
|
* 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.
|
* running, so set up all the machinery to answer requests.
|
||||||
*/
|
*/
|
||||||
if (!already_running) {
|
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.
|
* Initialise the cross-platform Pageant code.
|
||||||
*/
|
*/
|
||||||
@ -1546,9 +1574,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
|||||||
/*
|
/*
|
||||||
* Set up a named-pipe listener.
|
* Set up a named-pipe listener.
|
||||||
*/
|
*/
|
||||||
Plug *pl_plug;
|
|
||||||
wpc->plc.vt = &winpgnt_vtable;
|
wpc->plc.vt = &winpgnt_vtable;
|
||||||
wpc->plc.suppress_logging = true;
|
wpc->plc.suppress_logging = true;
|
||||||
|
{
|
||||||
|
Plug *pl_plug;
|
||||||
struct pageant_listen_state *pl =
|
struct pageant_listen_state *pl =
|
||||||
pageant_listener_new(&pl_plug, &wpc->plc);
|
pageant_listener_new(&pl_plug, &wpc->plc);
|
||||||
char *pipename = agent_named_pipe_name();
|
char *pipename = agent_named_pipe_name();
|
||||||
@ -1569,9 +1598,10 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
|||||||
if (openssh_config_file) {
|
if (openssh_config_file) {
|
||||||
FILE *fp = fopen(openssh_config_file, "w");
|
FILE *fp = fopen(openssh_config_file, "w");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
char *err = dupprintf("Unable to write OpenSSH config file "
|
char *err = dupprintf("Unable to write OpenSSH config "
|
||||||
"to %s", openssh_config_file);
|
"file to %s", openssh_config_file);
|
||||||
MessageBox(NULL, err, "Pageant Error", MB_ICONERROR | MB_OK);
|
MessageBox(NULL, err, "Pageant Error",
|
||||||
|
MB_ICONERROR | MB_OK);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
fprintf(fp, "IdentityAgent %s\n", pipename);
|
fprintf(fp, "IdentityAgent %s\n", pipename);
|
||||||
@ -1579,6 +1609,31 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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
|
* 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;
|
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 */
|
/* Set up a system tray icon */
|
||||||
AddTrayIcon(traywindow);
|
AddTrayIcon(traywindow);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user