Try to make our PGP signing more useful:
authorjacob <jacob@cda61777-01e9-0310-a592-d414129be87e>
Sat, 19 Mar 2005 02:26:58 +0000 (02:26 +0000)
committerjacob <jacob@cda61777-01e9-0310-a592-d414129be87e>
Sat, 19 Mar 2005 02:26:58 +0000 (02:26 +0000)
 * 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

27 files changed:
cmdgen.c
doc/Makefile
doc/index.but
doc/man-pg.but
doc/man-pl.but
doc/man-pscp.but
doc/man-psft.but
doc/man-ptel.but
doc/man-pter.but
doc/man-putt.but
doc/pgpkeys.but [new file with mode: 0644]
doc/plink.but
doc/pscp.but
doc/using.but
pscp.c
psftp.c
putty.h
unix/gtkwin.c
unix/uxmisc.c
unix/uxplink.c
windows/wincons.c
windows/window.c
windows/winhelp.h
windows/winpgen.c
windows/winpgnt.c
windows/winplink.c
windows/winutils.c

index d1c94ac..c4fcc9e 100644 (file)
--- 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:
                         * 
index 9ac45e8..cb72bb8 100644 (file)
@@ -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))
index bc12807..a8ce02a 100644 (file)
@@ -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
index 92a9aa8..5e3d9ea 100644 (file)
@@ -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
index cf0d419..d70ae96 100644 (file)
@@ -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.
index d848043..ae43bb7 100644 (file)
@@ -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.
index a71e918..29939b9 100644 (file)
@@ -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.
index 4364c23..08004f2 100644 (file)
@@ -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
index f647223..12da592 100644 (file)
@@ -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
index fb60067..1dc1ab6 100644 (file)
@@ -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 (file)
index 0000000..b3d104d
--- /dev/null
@@ -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.
index 744f66c..374355e 100644 (file)
@@ -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
index 50b3608..5e8e59a 100644 (file)
@@ -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
 
index d97e9d0..663fb5f 100644 (file)
@@ -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 ebe1f4f..9259dd0 100644 (file)
--- 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 272079e..ba3266b 100644 (file)
--- 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 07d1acf..430fd96 100644 (file)
--- 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:
  * 
index 91c1305..c93aeda 100644 (file)
@@ -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 */
index 505d43d..28ae83a 100644 (file)
@@ -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);
+}
index 851cefd..6bc1b61 100644 (file)
@@ -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,
index 0106fed..c38fa01 100644 (file)
@@ -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;
index 3d865e7..05f0c61 100644 (file)
@@ -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) {
index 51e1b9c..388538d 100644 (file)
 #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
index baaf3d9..dc9d273 100644 (file)
@@ -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;
index 6962ed8..07d59d6 100644 (file)
@@ -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.
      */
index 9fca63c..66af541 100644 (file)
@@ -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;
index b1ee011..2f21c76 100644 (file)
@@ -7,6 +7,7 @@
 #include <ctype.h>
 
 #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,