diff --git a/doc/pageant.but b/doc/pageant.but index 8abb5cdf..392c1da1 100644 --- a/doc/pageant.but +++ b/doc/pageant.but @@ -170,6 +170,28 @@ by the command, like this: \c C:\PuTTY\pageant.exe d:\main.ppk -c C:\PuTTY\putty.exe +\S{pageant-cmdline-openssh} Integrating with Windows OpenSSH + +When Pageant starts up, it can optionally write out a file containing +an OpenSSH configuration directive that tells the Windows \c{ssh.exe} +where to find Pageant. If you include this file from your Windows SSH +configuration, then \c{ssh.exe} should automatically use Pageant as +its agent, so that you can keep your keys in one place and have both +SSH clients able to use them. + +The option is \c{--openssh-config}, and you follow it with a filename. + +To refer to this file from your main OpenSSH configuration, you can +use the \cq{Include} directive. For example, you might run Pageant +like this: + +\c pageant --openssh-config C:\Users\Simon\.ssh\pageant.conf + +and then add a directive like this to your main \cq{.ssh\\config} +file: + +\c Include C:\Users\Simon\.ssh\pageant.conf + \S{pageant-cmdline-keylist} Starting with the key list visible Start Pageant with the \i\c{--keylist} option to show the main window diff --git a/windows/pageant.c b/windows/pageant.c index a249f613..896b1fea 100644 --- a/windows/pageant.c +++ b/windows/pageant.c @@ -1390,6 +1390,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) bool show_keylist_on_startup = false; int argc; char **argv, **argstart; + const char *openssh_config_file = NULL; typedef struct CommandLineKey { Filename *fn; @@ -1487,6 +1488,8 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) add_keys_encrypted = true; } else if (match_opt("-keylist")) { show_keylist_on_startup = true; + } else if (match_optval("-openssh-config", "-openssh_config")) { + openssh_config_file = val; } else if (match_opt("-c")) { /* * If we see `-c', then the rest of the command line @@ -1554,6 +1557,23 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) 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); + MessageBox(NULL, err, "Pageant Error", MB_ICONERROR | MB_OK); + return 1; + } + fprintf(fp, "IdentityAgent %s\n", pipename); + fclose(fp); + } + sfree(pipename); /* @@ -1752,6 +1772,16 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) if (keypath) filereq_free(keypath); + if (openssh_config_file) { + /* + * Leave this file around, but empty it, so that it doesn't + * refer to a pipe we aren't listening on any more. + */ + FILE *fp = fopen(openssh_config_file, "w"); + if (fp) + fclose(fp); + } + cleanup_exit(msg.wParam); return msg.wParam; /* just in case optimiser complains */ }