From 2285d016cf0103f03e05e53e22025282c104a164 Mon Sep 17 00:00:00 2001 From: jacob Date: Sat, 19 Mar 2005 02:26:58 +0000 Subject: [PATCH] Try to make our PGP signing more useful: * All the PuTTY tools for Windows and Unix now contain the fingerprints of the Master Keys. The method for accessing them is crude but universal: a new "-pgpfp" command-line option. (Except Unix PuTTYgen, which takes "--pgpfp" just to be awkward.) * Move the key policy discussion from putty-website/keys.html to putty/doc/pgpkeys.but, and autogenerate the former from the latter. Also tweak the text somewhat and include the fingerprints of the Master Keys themselves. (I've merged the existing autogeneration scripts into a single new one; I've left the old scripts and keys.html around until such time as the webmonster reviews the changes and plumbs in the new script; he should remove the old files then.) git-svn-id: svn://svn.tartarus.org/sgt/putty@5524 cda61777-01e9-0310-a592-d414129be87e --- cmdgen.c | 6 +- doc/Makefile | 2 +- doc/index.but | 1 + doc/man-pg.but | 12 ++++ doc/man-pl.but | 5 ++ doc/man-pscp.but | 5 ++ doc/man-psft.but | 5 ++ doc/man-ptel.but | 5 ++ doc/man-pter.but | 5 ++ doc/man-putt.but | 5 ++ doc/pgpkeys.but | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++ doc/plink.but | 3 +- doc/pscp.but | 3 +- doc/using.but | 6 ++ pscp.c | 6 +- psftp.c | 6 +- putty.h | 12 +++- unix/gtkwin.c | 6 +- unix/uxmisc.c | 18 ++++++ unix/uxplink.c | 6 +- windows/wincons.c | 16 ++++++ windows/window.c | 3 + windows/winhelp.h | 2 + windows/winpgen.c | 25 +++++---- windows/winpgnt.c | 120 ++++++++++++++++++++-------------------- windows/winplink.c | 6 +- windows/winutils.c | 20 +++++++ 27 files changed, 387 insertions(+), 79 deletions(-) create mode 100644 doc/pgpkeys.but diff --git a/cmdgen.c b/cmdgen.c index d1c94ac0..c4fcc9e1 100644 --- a/cmdgen.c +++ b/cmdgen.c @@ -313,7 +313,11 @@ int main(int argc, char **argv) } else if (!strcmp(opt, "-version")) { showversion(); nogo = TRUE; - } + } else if (!strcmp(opt, "-pgpfp")) { + /* support "-pgpfp" for consistency with others */ + pgp_fingerprints(); + nogo = TRUE; + } /* * A sample option requiring an argument: * diff --git a/doc/Makefile b/doc/Makefile index 9ac45e8a..cb72bb8e 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -35,7 +35,7 @@ VERSIONIDS=vids endif CHAPTERS := $(SITE) blurb intro gs using config pscp psftp plink pubkey -CHAPTERS += pageant errors faq feedback licence udp +CHAPTERS += pageant errors faq feedback licence udp pgpkeys CHAPTERS += index $(VERSIONIDS) INPUTS = $(patsubst %,%.but,$(CHAPTERS)) diff --git a/doc/index.but b/doc/index.but index bc128079..a8ce02a2 100644 --- a/doc/index.but +++ b/doc/index.but @@ -109,6 +109,7 @@ saved sessions from \IM{-1} \c{-1} command-line option \IM{-2} \c{-2} command-line option \IM{-i} \c{-i} command-line option +\IM{-pgpfp} \c{-pgpfp} command-line option \IM{removing registry entries} removing registry entries \IM{removing registry entries} registry entries, removing diff --git a/doc/man-pg.but b/doc/man-pg.but index 92a9aa8a..5e3d9eab 100644 --- a/doc/man-pg.but +++ b/doc/man-pg.but @@ -142,6 +142,18 @@ fingerprint. Otherwise, the \c{\-o} option is required. \dd Synonym for \q{\cw{-O public}}. +The following options do not run PuTTYgen as normal, but print +informational messages and then quit: + +\dt \cw{\-\-help} + +\dd Display a message summarizing the available options. + +\dt \cw{\-\-pgpfp} + +\dd Display the fingerprints of the PuTTY PGP Master Keys, to aid +in verifying new files released by the PuTTY team. + \S{puttygen-manpage-examples} EXAMPLES To generate an SSH-2 RSA key pair and save it in PuTTY's own format diff --git a/doc/man-pl.but b/doc/man-pl.but index cf0d4194..d70ae965 100644 --- a/doc/man-pl.but +++ b/doc/man-pl.but @@ -23,6 +23,11 @@ The command-line options supported by \cw{plink} are: \dd Show version information and exit. +\dt \cw{-pgpfp} + +\dd Display the fingerprints of the PuTTY PGP Master Keys and exit, +to aid in verifying new files released by the PuTTY team. + \dt \cw{-v} \dd Show verbose messages. diff --git a/doc/man-pscp.but b/doc/man-pscp.but index d848043b..ae43bb7c 100644 --- a/doc/man-pscp.but +++ b/doc/man-pscp.but @@ -28,6 +28,11 @@ The command-line options supported by \e{pscp} are: \dd Show version information and exit. +\dt \cw{-pgpfp} + +\dd Display the fingerprints of the PuTTY PGP Master Keys and exit, +to aid in verifying new files released by the PuTTY team. + \dt \cw{-ls} \dd Remote directory listing. diff --git a/doc/man-psft.but b/doc/man-psft.but index a71e918e..29939b92 100644 --- a/doc/man-psft.but +++ b/doc/man-psft.but @@ -24,6 +24,11 @@ The command-line options supported by \cw{psftp} are: \dd Show version information and exit. +\dt \cw{-pgpfp} + +\dd Display the fingerprints of the PuTTY PGP Master Keys and exit, +to aid in verifying new files released by the PuTTY team. + \dt \cw{-b} \e{batchfile} \dd Use specified batchfile. diff --git a/doc/man-ptel.but b/doc/man-ptel.but index 4364c230..08004f28 100644 --- a/doc/man-ptel.but +++ b/doc/man-ptel.but @@ -149,6 +149,11 @@ keys. \dd Display a message summarizing the available options. +\dt \cw{\-pgpfp} + +\dd Display the fingerprints of the PuTTY PGP Master Keys, to aid +in verifying new files released by the PuTTY team. + \dt \cw{\-load} \e{session} \dd Load a saved session by name. This allows you to run a saved session diff --git a/doc/man-pter.but b/doc/man-pter.but index f647223e..12da5921 100644 --- a/doc/man-pter.but +++ b/doc/man-pter.but @@ -205,6 +205,11 @@ example: \dd Display a message summarizing the available options. +\dt \cw{\-pgpfp} + +\dd Display the fingerprints of the PuTTY PGP Master Keys, to aid +in verifying new files released by the PuTTY team. + \S{pterm-manpage-x-resources} X RESOURCES \cw{pterm} can be more completely configured by means of X diff --git a/doc/man-putt.but b/doc/man-putt.but index fb600677..1dc1ab6e 100644 --- a/doc/man-putt.but +++ b/doc/man-putt.but @@ -149,6 +149,11 @@ keys. \dd Display a message summarizing the available options. +\dt \cw{\-pgpfp} + +\dd Display the fingerprints of the PuTTY PGP Master Keys, to aid +in verifying new files released by the PuTTY team. + \dt \cw{\-load} \e{session} \dd Load a saved session by name. This allows you to run a saved session diff --git a/doc/pgpkeys.but b/doc/pgpkeys.but new file mode 100644 index 00000000..b3d104d9 --- /dev/null +++ b/doc/pgpkeys.but @@ -0,0 +1,157 @@ +\define{versionidpgpkeys} \versionid $Id$ + +\A{pgpkeys} PuTTY download keys and signatures + +\cfg{winhelp-topic}{pgpfingerprints} + +We create \i{PGP signatures} for all the PuTTY +files distributed from our web site, so that users can be confident +that the files have not been tampered with. Here we identify +our public keys, and explain our signature policy so you can have an +accurate idea of what each signature guarantees. +This description is provided as both a web page on the PuTTY site, and +an appendix in the PuTTY manual. + +As of the next release, all of the PuTTY executables will contain +\#{XXX-REMOVE-BEFORE-RELEASE: fix this up for forthcoming release +As of release 0.58, all of the PuTTY executables contain} +fingerprint material (usually accessed via the \i\c{-pgpfp} +command-line option), such that if you have an executable you trust, +you can use it to establish a trust path, for instance to a newer +version downloaded from the Internet. + +(Note that none of the keys, signatures, etc mentioned here have +anything to do with keys used with SSH - they are purely for verifying +the origin of files distributed by the PuTTY team.) + +\H{pgpkeys-pubkey} Public keys + +We supply two complete sets of keys. We supply a set of RSA keys, +compatible with both \W{http://www.gnupg.org/}{GnuPG} and PGP2, +and also a set of DSA keys compatible with GnuPG. + +In each format, we have three keys: + +\b A Development Snapshots key, used to sign the nightly builds. + +\b A Releases key, used to sign actual releases. + +\b A Master Key. The Master Key is used to sign the other two keys, and +they sign it in return. + +Therefore, we have six public keys in total: + +\b RSA: + +\lcont{ + +\b \W{http://www.chiark.greenend.org.uk/~sgtatham/putty/keys/master-rsa.asc}{Master Key} + +\lcont{ +1024-bit; fingerprint: +\cw{8F\_15\_97\_DA\_25\_30\_AB\_0D\_\_88\_D1\_92\_54\_11\_CF\_0C\_4C} +} + +\b \W{http://www.chiark.greenend.org.uk/~sgtatham/putty/keys/release-rsa.asc}{Release key} + +\b \W{http://www.chiark.greenend.org.uk/~sgtatham/putty/keys/snapshot-rsa.asc}{Snapshot key} + +} + +\b DSA: + +\lcont{ + +\b \W{http://www.chiark.greenend.org.uk/~sgtatham/putty/keys/master-dsa.asc}{Master Key} + +\lcont{ +1024-bit; fingerprint: +\cw{313C\_3E76\_4B74\_C2C5\_F2AE\_\_83A8\_4F5E\_6DF5\_6A93\_B34E} +} + +\b \W{http://www.chiark.greenend.org.uk/~sgtatham/putty/keys/release-dsa.asc}{Release key} + +\b \W{http://www.chiark.greenend.org.uk/~sgtatham/putty/keys/snapshot-dsa.asc}{Snapshot key} + +} + +\H{pgpkeys-security} Security details + +The various keys have various different security levels. This +section explains what those security levels are, and how far you can +expect to trust each key. + +\S{pgpkeys-snapshot} The Development Snapshots keys + +These keys are stored \e{without passphrases}. This is +necessary, because the snapshots are generated every night without +human intervention, so nobody would be able to type a passphrase. + +The actual snapshots are built on a team member's home Windows box. +The keys themselves are stored on an independently run Unix box +(the same one that hosts our Subversion repository). After +being built, the binaries are uploaded to this Unix box and then +signed automatically. + +Therefore, a signature from one of the Development Snapshots keys +\e{DOES} protect you against: + +\b People tampering with the PuTTY binaries between the PuTTY web site +and you. + +But it \e{DOES NOT} protect you against: + +\b People tampering with the binaries before they are uploaded to the +independent Unix box. + +\b The sysadmin of the independent Unix box using his root privilege to +steal the private keys and abuse them, or tampering with the +binaries before they are signed. + +\b Somebody getting root on the Unix box. + +Of course, we don't believe any of those things is very likely. We +know our sysadmin personally and trust him (both to be competent and +to be non-malicious), and we take all reasonable precautions to +guard the build machine. But when you see a signature, you should +always be certain of precisely what it guarantees and precisely what +it does not. + +\S{pgpkeys-release} The Releases keys + +The Release keys have passphrases and we can be more careful about +how we use them. + +The Release keys are kept safe on the developers' own local +machines, and only used to sign releases that have been built by +hand. A signature from a Release key protects you from almost any +plausible attack. + +(Some of the developers' machines have cable modem connections and +might in theory be crackable, but of course the private keys are +still encrypted, so the crack would have to go unnoticed for long +enough to steal a passphrase.) + +\S{pgpkeys-master} The Master Keys + +The Master Keys sign almost nothing. Their purpose is to bind the +other keys together and certify that they are all owned by the same +people and part of the same integrated setup. The only signatures +produced by the Master Keys, \e{ever}, should be the signatures +on the other keys. + +We intend to arrange for the Master Keys to sign each other, to +certify that the DSA keys and RSA keys are part of the same setup. +We have not yet got round to this at the time of writing. + +We have collected a few third-party signatures on the Master Keys, +in order to increase the chances that you can find a suitable trust +path to them. We intend to collect more. (Note that the keys on the +keyservers appear to have also collected some signatures from people +who haven't performed any verification of the Master Keys.) + +We have uploaded our various keys to public keyservers, so that +even if you don't know any of the people who have signed our +keys, you can still be reasonably confident that an attacker would +find it hard to substitute fake keys on all the public keyservers at +once. diff --git a/doc/plink.but b/doc/plink.but index 744f66cb..374355e0 100644 --- a/doc/plink.but +++ b/doc/plink.but @@ -47,7 +47,8 @@ use Plink: \c Usage: plink [options] [user@]host [command] \c ("host" can also be a PuTTY saved session name) \c Options: -\c -V print version information +\c -V print version information and exit +\c -pgpfp print PGP key fingerprints and exit \c -v show verbose messages \c -load sessname Load settings from saved session \c -ssh -telnet -rlogin -raw diff --git a/doc/pscp.but b/doc/pscp.but index 50b36086..5e8e59a6 100644 --- a/doc/pscp.but +++ b/doc/pscp.but @@ -46,6 +46,8 @@ use PSCP: \c pscp [options] source [source...] [user@]host:target \c pscp [options] -ls [user@]host:filespec \c Options: +\c -V print version information and exit +\c -pgpfp print PGP key fingerprints and exit \c -p preserve file attributes \c -q quiet, don't show statistics \c -r copy directories recursively @@ -60,7 +62,6 @@ use PSCP: \c -i key private key file for authentication \c -batch disable all interactive prompts \c -unsafe allow server-side wildcards (DANGEROUS) -\c -V print version information \c -sftp force use of SFTP protocol \c -scp force use of SCP protocol diff --git a/doc/using.but b/doc/using.but index d97e9d08..663fb5f1 100644 --- a/doc/using.but +++ b/doc/using.but @@ -782,3 +782,9 @@ For general information on \i{public-key authentication}, see This option is equivalent to the \q{Private key file for authentication} box in the Auth panel of the PuTTY configuration box (see \k{config-ssh-privkey}). + +\S2{using-cmdline-pgpfp} \i\c{-pgpfp}: display PGP key fingerprints + +This option causes the PuTTY tools not to run as normal, but instead +to display the fingerprints of the PuTTY PGP Master Keys, in order to +aid with verifying new versions. See \k{pgpkeys} for more information. diff --git a/pscp.c b/pscp.c index ebe1f4fa..9259dd08 100644 --- a/pscp.c +++ b/pscp.c @@ -2139,6 +2139,8 @@ static void usage(void) (" pscp [options] source [source...] [user@]host:target\n"); printf(" pscp [options] -ls [user@]host:filespec\n"); printf("Options:\n"); + printf(" -V print version information and exit\n"); + printf(" -pgpfp print PGP key fingerprints and exit\n"); printf(" -p preserve file attributes\n"); printf(" -q quiet, don't show statistics\n"); printf(" -r copy directories recursively\n"); @@ -2153,7 +2155,6 @@ static void usage(void) printf(" -i key private key file for authentication\n"); printf(" -batch disable all interactive prompts\n"); printf(" -unsafe allow server-side wildcards (DANGEROUS)\n"); - printf(" -V print version information\n"); printf(" -sftp force use of SFTP protocol\n"); printf(" -scp force use of SCP protocol\n"); #if 0 @@ -2223,6 +2224,9 @@ int psftp_main(int argc, char *argv[]) /* We have our own verbosity in addition to `flags'. */ if (flags & FLAG_VERBOSE) verbose = 1; + } else if (strcmp(argv[i], "-pgpfp") == 0) { + pgp_fingerprints(); + return 1; } else if (strcmp(argv[i], "-r") == 0) { recursive = 1; } else if (strcmp(argv[i], "-p") == 0) { diff --git a/psftp.c b/psftp.c index 272079e3..ba3266b0 100644 --- a/psftp.c +++ b/psftp.c @@ -2573,6 +2573,8 @@ static void usage(void) printf("%s\n", ver); printf("Usage: psftp [options] [user@]host\n"); printf("Options:\n"); + printf(" -V print version information and exit\n"); + printf(" -pgpfp print PGP key fingerprints and exit\n"); printf(" -b file use specified batchfile\n"); printf(" -bc output batchfile commands\n"); printf(" -be don't stop batchfile processing if errors\n"); @@ -2586,7 +2588,6 @@ static void usage(void) printf(" -C enable compression\n"); printf(" -i key private key file for authentication\n"); printf(" -batch disable all interactive prompts\n"); - printf(" -V print version information\n"); cleanup_exit(1); } @@ -2850,6 +2851,9 @@ int psftp_main(int argc, char *argv[]) } else if (strcmp(argv[i], "-h") == 0 || strcmp(argv[i], "-?") == 0) { usage(); + } else if (strcmp(argv[i], "-pgpfp") == 0) { + pgp_fingerprints(); + return 1; } else if (strcmp(argv[i], "-V") == 0) { version(); } else if (strcmp(argv[i], "-batch") == 0) { diff --git a/putty.h b/putty.h index 07d1acf5..430fd96e 100644 --- a/putty.h +++ b/putty.h @@ -27,6 +27,15 @@ typedef struct terminal_tag Terminal; #include "network.h" #include "misc.h" +/* + * Fingerprints of the PGP master keys that can be used to establish a trust + * path between an executable and other files. + */ +#define PGP_RSA_MASTER_KEY_FP \ + "8F 15 97 DA 25 30 AB 0D 88 D1 92 54 11 CF 0C 4C" +#define PGP_DSA_MASTER_KEY_FP \ + "313C 3E76 4B74 C2C5 F2AE 83A8 4F5E 6DF5 6A93 B34E" + /* Three attribute types: * The ATTRs (normal attributes) are stored with the characters in * the main display arrays @@ -893,9 +902,10 @@ int wc_match(const char *wildcard, const char *target); int wc_unescape(char *output, const char *wildcard); /* - * Exports from windlg.c + * Exports from frontend (windlg.c etc) */ void logevent(void *frontend, const char *); +void pgp_fingerprints(void); /* * verify_ssh_host_key() can return one of three values: * diff --git a/unix/gtkwin.c b/unix/gtkwin.c index 91c13054..c93aedad 100644 --- a/unix/gtkwin.c +++ b/unix/gtkwin.c @@ -2561,7 +2561,11 @@ int do_cmdline(int argc, char **argv, int do_everything, } else if(!strcmp(p, "-help") || !strcmp(p, "--help")) { help(stdout); exit(0); - + + } else if (!strcmp(p, "-pgpfp")) { + pgp_fingerprints(); + exit(1); + } else if(p[0] != '-' && (!do_everything || process_nonoption_arg(p, cfg))) { /* do nothing */ diff --git a/unix/uxmisc.c b/unix/uxmisc.c index 505d43d3..28ae83a2 100644 --- a/unix/uxmisc.c +++ b/unix/uxmisc.c @@ -100,3 +100,21 @@ char *get_username(void) return dupstr(ret); } + +/* + * Display the fingerprints of the PGP Master Keys to the user. + * (This is here rather than in uxcons because it's appropriate even for + * Unix GUI apps.) + */ +void pgp_fingerprints(void) +{ + fputs("These are the fingerprints of the PuTTY PGP Master Keys. They can\n" + "be used to establish a trust path from this executable to another\n" + "one. See the manual for more information.\n" + "(Note: these fingerprints have nothing to do with SSH!)\n" + "\n" + "PuTTY Master Key (RSA), 1024-bit:\n" + " " PGP_RSA_MASTER_KEY_FP "\n" + "PuTTY Master Key (DSA), 1024-bit:\n" + " " PGP_DSA_MASTER_KEY_FP "\n", stdout); +} diff --git a/unix/uxplink.c b/unix/uxplink.c index 851cefda..6bc1b61b 100644 --- a/unix/uxplink.c +++ b/unix/uxplink.c @@ -212,7 +212,8 @@ static void usage(void) printf("Usage: plink [options] [user@]host [command]\n"); printf(" (\"host\" can also be a PuTTY saved session name)\n"); printf("Options:\n"); - printf(" -V print version information\n"); + printf(" -V print version information and exit\n"); + printf(" -pgpfp print PGP key fingerprints and exit\n"); printf(" -v show verbose messages\n"); printf(" -load sessname Load settings from saved session\n"); printf(" -ssh -telnet -rlogin -raw\n"); @@ -318,6 +319,9 @@ int main(int argc, char **argv) use_subsystem = 1; } else if (!strcmp(p, "-V")) { version(); + } else if (!strcmp(p, "-pgpfp")) { + pgp_fingerprints(); + exit(1); } else if (!strcmp(p, "-o")) { if (argc <= 1) { fprintf(stderr, diff --git a/windows/wincons.c b/windows/wincons.c index 0106fed0..c38fa011 100644 --- a/windows/wincons.c +++ b/windows/wincons.c @@ -271,6 +271,22 @@ void old_keyfile_warning(void) fputs(message, stderr); } +/* + * Display the fingerprints of the PGP Master Keys to the user. + */ +void pgp_fingerprints(void) +{ + fputs("These are the fingerprints of the PuTTY PGP Master Keys. They can\n" + "be used to establish a trust path from this executable to another\n" + "one. See the manual for more information.\n" + "(Note: these fingerprints have nothing to do with SSH!)\n" + "\n" + "PuTTY Master Key (RSA), 1024-bit:\n" + " " PGP_RSA_MASTER_KEY_FP "\n" + "PuTTY Master Key (DSA), 1024-bit:\n" + " " PGP_DSA_MASTER_KEY_FP "\n", stdout); +} + void console_provide_logctx(void *logctx) { console_logctx = logctx; diff --git a/windows/window.c b/windows/window.c index 3d865e7f..05f0c618 100644 --- a/windows/window.c +++ b/windows/window.c @@ -479,6 +479,9 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) sfree(s1); sfree(s2); exit(0); + } else if (!strcmp(p, "-pgpfp")) { + pgp_fingerprints(); + exit(1); } else if (*p != '-') { char *q = p; if (got_host) { diff --git a/windows/winhelp.h b/windows/winhelp.h index 51e1b9c4..388538de 100644 --- a/windows/winhelp.h +++ b/windows/winhelp.h @@ -142,3 +142,5 @@ #define WINHELP_CTXID_errors_cantloadkey 3 #define WINHELP_CTX_option_cleanup "options.cleanup" #define WINHELP_CTXID_option_cleanup 4 +#define WINHELP_CTX_pgp_fingerprints "pgpfingerprints" +#define WINHELP_CTXID_pgp_fingerprints 5 diff --git a/windows/winpgen.c b/windows/winpgen.c index baaf3d98..dc9d2730 100644 --- a/windows/winpgen.c +++ b/windows/winpgen.c @@ -1404,16 +1404,6 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) int argc; char **argv; - split_into_argv(cmdline, &argc, &argv, NULL); - - if (argc > 0) { - /* - * Assume the first argument to be a private key file, and - * attempt to load it. - */ - cmdline_keyfile = argv[0]; - } - InitCommonControls(); hinst = inst; hwnd = NULL; @@ -1438,6 +1428,21 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) help_path = NULL; } + split_into_argv(cmdline, &argc, &argv, NULL); + + if (argc > 0) { + if (!strcmp(argv[0], "-pgpfp")) { + pgp_fingerprints(); + exit(1); + } else { + /* + * Assume the first argument to be a private key file, and + * attempt to load it. + */ + cmdline_keyfile = argv[0]; + } + } + random_ref(); return DialogBox(hinst, MAKEINTRESOURCE(201), NULL, MainDlgProc) != IDOK; diff --git a/windows/winpgnt.c b/windows/winpgnt.c index 6962ed89..07d59d60 100644 --- a/windows/winpgnt.c +++ b/windows/winpgnt.c @@ -2058,67 +2058,14 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) /* * Find out if Pageant is already running. */ - already_running = FALSE; - if (agent_exists()) - already_running = TRUE; - else { - - if (!prev) { - wndclass.style = 0; - wndclass.lpfnWndProc = WndProc; - wndclass.cbClsExtra = 0; - wndclass.cbWndExtra = 0; - wndclass.hInstance = inst; - wndclass.hIcon = LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON)); - wndclass.hCursor = LoadCursor(NULL, IDC_IBEAM); - wndclass.hbrBackground = GetStockObject(BLACK_BRUSH); - wndclass.lpszMenuName = NULL; - wndclass.lpszClassName = APPNAME; - - RegisterClass(&wndclass); - } - - keylist = NULL; - - hwnd = CreateWindow(APPNAME, APPNAME, - WS_OVERLAPPEDWINDOW | WS_VSCROLL, - CW_USEDEFAULT, CW_USEDEFAULT, - 100, 100, NULL, NULL, inst, NULL); - - /* Set up a system tray icon */ - AddTrayIcon(hwnd); - - /* Accelerators used: nsvkxa */ - systray_menu = CreatePopupMenu(); - if (putty_path) { - session_menu = CreateMenu(); - AppendMenu(systray_menu, MF_ENABLED, IDM_PUTTY, "&New Session"); - AppendMenu(systray_menu, MF_POPUP | MF_ENABLED, - (UINT) session_menu, "&Saved Sessions"); - AppendMenu(systray_menu, MF_SEPARATOR, 0, 0); - } - AppendMenu(systray_menu, MF_ENABLED, IDM_VIEWKEYS, - "&View Keys"); - AppendMenu(systray_menu, MF_ENABLED, IDM_ADDKEY, "Add &Key"); - AppendMenu(systray_menu, MF_SEPARATOR, 0, 0); - if (help_path) - AppendMenu(systray_menu, MF_ENABLED, IDM_HELP, "&Help"); - AppendMenu(systray_menu, MF_ENABLED, IDM_ABOUT, "&About"); - AppendMenu(systray_menu, MF_SEPARATOR, 0, 0); - AppendMenu(systray_menu, MF_ENABLED, IDM_CLOSE, "E&xit"); - initial_menuitems_count = GetMenuItemCount(session_menu); - - /* Set the default menu item. */ - SetMenuDefaultItem(systray_menu, IDM_VIEWKEYS, FALSE); + already_running = agent_exists(); - ShowWindow(hwnd, SW_HIDE); - - /* - * Initialise storage for RSA keys. - */ + /* + * Initialise storage for RSA keys. + */ + if (!already_running) { rsakeys = newtree234(cmpkeys_rsa); ssh2keys = newtree234(cmpkeys_ssh2); - } /* @@ -2131,7 +2078,12 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) */ split_into_argv(cmdline, &argc, &argv, &argstart); for (i = 0; i < argc; i++) { - if (!strcmp(argv[i], "-c")) { + if (!strcmp(argv[i], "-pgpfp")) { + pgp_fingerprints(); + if (advapi) + FreeLibrary(advapi); + return 1; + } else if (!strcmp(argv[i], "-c")) { /* * If we see `-c', then the rest of the * command line should be treated as a @@ -2182,6 +2134,56 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prev, LPSTR cmdline, int show) return 0; } + if (!prev) { + wndclass.style = 0; + wndclass.lpfnWndProc = WndProc; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = 0; + wndclass.hInstance = inst; + wndclass.hIcon = LoadIcon(inst, MAKEINTRESOURCE(IDI_MAINICON)); + wndclass.hCursor = LoadCursor(NULL, IDC_IBEAM); + wndclass.hbrBackground = GetStockObject(BLACK_BRUSH); + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = APPNAME; + + RegisterClass(&wndclass); + } + + keylist = NULL; + + hwnd = CreateWindow(APPNAME, APPNAME, + WS_OVERLAPPEDWINDOW | WS_VSCROLL, + CW_USEDEFAULT, CW_USEDEFAULT, + 100, 100, NULL, NULL, inst, NULL); + + /* Set up a system tray icon */ + AddTrayIcon(hwnd); + + /* Accelerators used: nsvkxa */ + systray_menu = CreatePopupMenu(); + if (putty_path) { + session_menu = CreateMenu(); + AppendMenu(systray_menu, MF_ENABLED, IDM_PUTTY, "&New Session"); + AppendMenu(systray_menu, MF_POPUP | MF_ENABLED, + (UINT) session_menu, "&Saved Sessions"); + AppendMenu(systray_menu, MF_SEPARATOR, 0, 0); + } + AppendMenu(systray_menu, MF_ENABLED, IDM_VIEWKEYS, + "&View Keys"); + AppendMenu(systray_menu, MF_ENABLED, IDM_ADDKEY, "Add &Key"); + AppendMenu(systray_menu, MF_SEPARATOR, 0, 0); + if (help_path) + AppendMenu(systray_menu, MF_ENABLED, IDM_HELP, "&Help"); + AppendMenu(systray_menu, MF_ENABLED, IDM_ABOUT, "&About"); + AppendMenu(systray_menu, MF_SEPARATOR, 0, 0); + AppendMenu(systray_menu, MF_ENABLED, IDM_CLOSE, "E&xit"); + initial_menuitems_count = GetMenuItemCount(session_menu); + + /* Set the default menu item. */ + SetMenuDefaultItem(systray_menu, IDM_VIEWKEYS, FALSE); + + ShowWindow(hwnd, SW_HIDE); + /* * Main message loop. */ diff --git a/windows/winplink.c b/windows/winplink.c index 9fca63c1..66af5413 100644 --- a/windows/winplink.c +++ b/windows/winplink.c @@ -210,7 +210,8 @@ static void usage(void) printf("Usage: plink [options] [user@]host [command]\n"); printf(" (\"host\" can also be a PuTTY saved session name)\n"); printf("Options:\n"); - printf(" -V print version information\n"); + printf(" -V print version information and exit\n"); + printf(" -pgpfp print PGP key fingerprints and exit\n"); printf(" -v show verbose messages\n"); printf(" -load sessname Load settings from saved session\n"); printf(" -ssh -telnet -rlogin -raw\n"); @@ -339,6 +340,9 @@ int main(int argc, char **argv) use_subsystem = 1; } else if (!strcmp(p, "-V")) { version(); + } else if (!strcmp(p, "-pgpfp")) { + pgp_fingerprints(); + exit(1); } else { fprintf(stderr, "plink: unknown option \"%s\"\n", p); errors = 1; diff --git a/windows/winutils.c b/windows/winutils.c index b1ee0113..2f21c767 100644 --- a/windows/winutils.c +++ b/windows/winutils.c @@ -7,6 +7,7 @@ #include #include "winstuff.h" +#include "putty.h" #include "misc.h" #ifdef TESTMODE @@ -105,6 +106,7 @@ static VOID CALLBACK message_box_help_callback(LPHELPINFO lpHelpInfo) CHECK_CTX(errors_hostkey_changed); CHECK_CTX(errors_cantloadkey); CHECK_CTX(option_cleanup); + CHECK_CTX(pgp_fingerprints); #undef CHECK_CTX if (context) { /* We avoid using malloc, in case we're in a situation where @@ -140,6 +142,24 @@ int message_box(LPCTSTR text, LPCTSTR caption, DWORD style, DWORD helpctxid) } /* + * Display the fingerprints of the PGP Master Keys to the user. + */ +void pgp_fingerprints(void) +{ + message_box("These are the fingerprints of the PuTTY PGP Master Keys. They can\n" + "be used to establish a trust path from this executable to another\n" + "one. See the manual for more information.\n" + "(Note: these fingerprints have nothing to do with SSH!)\n" + "\n" + "PuTTY Master Key (RSA), 1024-bit:\n" + " " PGP_RSA_MASTER_KEY_FP "\n" + "PuTTY Master Key (DSA), 1024-bit:\n" + " " PGP_DSA_MASTER_KEY_FP, + "PGP fingerprints", MB_ICONINFORMATION | MB_OK, + HELPCTXID(pgp_fingerprints)); +} + +/* * Split a complete command line into argc/argv, attempting to do * it exactly the same way Windows itself would do it (so that * console utilities, which receive argc and argv from Windows, -- 2.11.0