浏览代码

PuTTY 0.68

Source commit: 7cf7830b6a7f41b1cd79a4573b00991af5140ee1
Martin Prikryl 8 年之前
父节点
当前提交
6e9db62495

+ 20 - 2
source/putty/WINDOWS/winhsock.c

@@ -42,6 +42,8 @@ struct Socket_handle_tag {
     /* Data received from stderr_H, if we have one. */
     /* Data received from stderr_H, if we have one. */
     bufchain stderrdata;
     bufchain stderrdata;
 
 
+    int defer_close, deferred_close;   /* in case of re-entrance */
+
     char *error;
     char *error;
 
 
     Plug plug;
     Plug plug;
@@ -57,7 +59,7 @@ static int handle_gotdata(struct handle *h, void *data, int len)
     } else if (len == 0) {
     } else if (len == 0) {
 	return plug_closing(ps->plug, NULL, 0, 0);
 	return plug_closing(ps->plug, NULL, 0, 0);
     } else {
     } else {
-        assert(ps->frozen != FREEZING && ps->frozen != THAWING);
+        assert(ps->frozen != FROZEN && ps->frozen != THAWING);
         if (ps->frozen == FREEZING) {
         if (ps->frozen == FREEZING) {
             /*
             /*
              * If we've received data while this socket is supposed to
              * If we've received data while this socket is supposed to
@@ -66,6 +68,7 @@ static int handle_gotdata(struct handle *h, void *data, int len)
              * the data for when we unfreeze.
              * the data for when we unfreeze.
              */
              */
             bufchain_add(&ps->inputdata, data, len);
             bufchain_add(&ps->inputdata, data, len);
+            ps->frozen = FROZEN;
 
 
             /*
             /*
              * And return a very large backlog, to prevent further
              * And return a very large backlog, to prevent further
@@ -108,6 +111,11 @@ static void sk_handle_close(Socket s)
 {
 {
     Handle_Socket ps = (Handle_Socket) s;
     Handle_Socket ps = (Handle_Socket) s;
 
 
+    if (ps->defer_close) {
+        ps->deferred_close = TRUE;
+        return;
+    }
+
     handle_free(ps->send_h);
     handle_free(ps->send_h);
     handle_free(ps->recv_h);
     handle_free(ps->recv_h);
     CloseHandle(ps->send_H);
     CloseHandle(ps->send_H);
@@ -168,9 +176,17 @@ static void handle_socket_unfreeze(void *psv)
     assert(len > 0);
     assert(len > 0);
 
 
     /*
     /*
-     * Hand it off to the plug.
+     * Hand it off to the plug. Be careful of re-entrance - that might
+     * have the effect of trying to close this socket.
      */
      */
+    ps->defer_close = TRUE;
     new_backlog = plug_receive(ps->plug, 0, data, len);
     new_backlog = plug_receive(ps->plug, 0, data, len);
+    bufchain_consume(&ps->inputdata, len);
+    ps->defer_close = FALSE;
+    if (ps->deferred_close) {
+        sk_handle_close(ps);
+        return;
+    }
 
 
     if (bufchain_size(&ps->inputdata) > 0) {
     if (bufchain_size(&ps->inputdata) > 0) {
         /*
         /*
@@ -308,5 +324,7 @@ Socket make_handle_socket(HANDLE send_H, HANDLE recv_H, HANDLE stderr_H,
         ret->stderr_h = handle_input_new(ret->stderr_H, handle_stderr,
         ret->stderr_h = handle_input_new(ret->stderr_H, handle_stderr,
                                          ret, flags);
                                          ret, flags);
 
 
+    ret->defer_close = ret->deferred_close = FALSE;
+
     return (Socket) ret;
     return (Socket) ret;
 }
 }

+ 9 - 1
source/putty/WINDOWS/winsecur.c

@@ -94,9 +94,17 @@ PSID get_user_sid(void)
 
 
 int getsids(char **error)
 int getsids(char **error)
 {
 {
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wmissing-braces"
+#endif
     SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
     SID_IDENTIFIER_AUTHORITY world_auth = SECURITY_WORLD_SID_AUTHORITY;
     SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;
     SID_IDENTIFIER_AUTHORITY nt_auth = SECURITY_NT_AUTHORITY;
-    int ret;
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+    int ret = FALSE;
 
 
     *error = NULL;
     *error = NULL;
 
 

+ 1 - 1
source/putty/doc/blurb.but

@@ -19,7 +19,7 @@ page</a>.</p>}
 \cfg{winhelp-filename}{putty.hlp}
 \cfg{winhelp-filename}{putty.hlp}
 \cfg{info-filename}{putty.info}
 \cfg{info-filename}{putty.info}
 
 
-PuTTY is a free (MIT-licensed) Win32 Telnet and SSH client. This
+PuTTY is a free (MIT-licensed) Windows Telnet and SSH client. This
 manual documents PuTTY, and its companion utilities PSCP, PSFTP,
 manual documents PuTTY, and its companion utilities PSCP, PSFTP,
 Plink, Pageant and PuTTYgen.
 Plink, Pageant and PuTTYgen.
 
 

+ 22 - 0
source/putty/doc/config.but

@@ -1955,6 +1955,9 @@ If you want your local proxy command to make a secondary SSH
 connection to a proxy host and then tunnel the primary connection
 connection to a proxy host and then tunnel the primary connection
 over that, you might well want the \c{-nc} command-line option in
 over that, you might well want the \c{-nc} command-line option in
 Plink. See \k{using-cmdline-ncmode} for more information.
 Plink. See \k{using-cmdline-ncmode} for more information.
+
+You can also enable this mode on the command line; see
+\k{using-cmdline-proxycmd}.
 }
 }
 
 
 \S{config-proxy-exclude} Excluding parts of the network from proxying
 \S{config-proxy-exclude} Excluding parts of the network from proxying
@@ -2100,6 +2103,25 @@ port. Note that if you do not include the \c{%user} or \c{%pass}
 tokens in the Telnet command, then the \q{Username} and \q{Password}
 tokens in the Telnet command, then the \q{Username} and \q{Password}
 configuration fields will be ignored.
 configuration fields will be ignored.
 
 
+\S{config-proxy-logging} Controlling \i{proxy logging}
+
+\cfg{winhelp-topic}{proxy.logging}
+
+Often the proxy interaction has its own diagnostic output; this is
+particularly the case for local proxy commands.
+
+The setting \q{Print proxy diagnostics in the terminal window} lets
+you control how much of the proxy's diagnostics are printed to the main
+terminal window, along with output from your main session.
+
+By default (\q{No}), proxy diagnostics are only sent to the Event Log;
+with \q{Yes} they are also printed to the terminal, where they may get
+mixed up with your main session. \q{Only until session starts} is a
+compromise; proxy messages will go to the terminal window until the main
+session is deemed to have started (in a protocol-dependent way), which
+is when they're most likely to be interesting; any further proxy-related
+messages during the session will only go to the Event Log.
+
 \H{config-telnet} The \i{Telnet} panel
 \H{config-telnet} The \i{Telnet} panel
 
 
 The Telnet panel allows you to configure options that only apply to
 The Telnet panel allows you to configure options that only apply to

+ 5 - 5
source/putty/doc/errors.but

@@ -69,11 +69,11 @@ change the \q{SSH protocol version} setting (see \k{config-ssh-prot}),
 or use the \c{-1} command-line option; in any case, you should not
 or use the \c{-1} command-line option; in any case, you should not
 treat the resulting connection as secure.
 treat the resulting connection as secure.
 
 
-You might start seeing this message with new versions of PuTTY
-\#{XXX-REVIEW-BEFORE-RELEASE: (from 0.XX onwards)}
-where you didn't before, because it used to be possible to configure
-PuTTY to automatically fall back from SSH-2 to SSH-1. This is no
-longer supported, to prevent the possibility of a downgrade attack.
+You might start seeing this message with new versions of PuTTY (from
+0.68 onwards) where you didn't before, because it used to be possible
+to configure PuTTY to automatically fall back from SSH-2 to SSH-1.
+This is no longer supported, to prevent the possibility of a downgrade
+attack.
 
 
 \H{errors-cipher-warning} \q{The first cipher supported by the server is
 \H{errors-cipher-warning} \q{The first cipher supported by the server is
 ... below the configured warning threshold}
 ... below the configured warning threshold}

+ 33 - 24
source/putty/doc/faq.but

@@ -66,9 +66,8 @@ Yes. SSH-1 support has always been available in PuTTY.
 However, the SSH-1 protocol has many weaknesses and is no longer
 However, the SSH-1 protocol has many weaknesses and is no longer
 considered secure; you should use SSH-2 instead if at all possible.
 considered secure; you should use SSH-2 instead if at all possible.
 
 
-\#{XXX-REVIEW-BEFORE-RELEASE:
 As of 0.68, PuTTY will no longer fall back to SSH-1 if the server
 As of 0.68, PuTTY will no longer fall back to SSH-1 if the server
-doesn't appear to support SSH-2; you must explicitly ask for SSH-1. }
+doesn't appear to support SSH-2; you must explicitly ask for SSH-1.
 
 
 \S{faq-localecho}{Question} Does PuTTY support \i{local echo}?
 \S{faq-localecho}{Question} Does PuTTY support \i{local echo}?
 
 
@@ -167,7 +166,7 @@ the wrong solution and we will not do it.
 
 
 If you have host keys available in the common \i\c{known_hosts} format,
 If you have host keys available in the common \i\c{known_hosts} format,
 we have a script called 
 we have a script called 
-\W{http://tartarus.org/~simon-git/gitweb/?p=putty.git;a=blob;f=contrib/kh2reg.py;hb=HEAD}\c{kh2reg.py}
+\W{https://git.tartarus.org/?p=simon/putty.git;a=blob;f=contrib/kh2reg.py;hb=HEAD}\c{kh2reg.py}
 to convert them to a Windows .REG file, which can be installed ahead of
 to convert them to a Windows .REG file, which can be installed ahead of
 time by double-clicking or using \c{REGEDIT}.
 time by double-clicking or using \c{REGEDIT}.
 
 
@@ -213,16 +212,21 @@ seems to be working so far.
 
 
 \S{faq-ports-general}{Question} What ports of PuTTY exist?
 \S{faq-ports-general}{Question} What ports of PuTTY exist?
 
 
-Currently, release versions of PuTTY tools only run on full Win32
-systems and Unix. \q{\i{Win32}} includes versions of Windows from
-Windows 95 onwards (as opposed to the 16-bit Windows 3.1; see
-\k{faq-win31}), up to and including Windows 7; and we know of no
-reason why PuTTY should not continue to work on future versions
-of Windows.
+Currently, release versions of PuTTY tools only run on Windows
+systems and Unix.
+
+As of 0.68, the supplied PuTTY executables run on versions of
+Windows from XP onwards, up to and including Windows 10; and we
+know of no reason why PuTTY should not continue to work on
+future versions of Windows.
+
+The 32-bit Windows executables we provide for the \q{\i{x86}}
+processor architecture should also work fine on 64-bit processors
+that are backward-compatible with that architecture. The 64-bit
+executables will only work on 64-bit versions of Windows. They
+will run somewhat faster than 32-bit executables would on the
+same processor, but will consume slightly more memory.
 
 
-The Windows executables we provide are for the 32-bit \q{\i{x86}}
-processor architecture, but they should work fine on 64-bit
-processors that are backward-compatible with that architecture.
 (We used to also provide executables for Windows for the Alpha
 (We used to also provide executables for Windows for the Alpha
 processor, but stopped after 0.58 due to lack of interest.)
 processor, but stopped after 0.58 due to lack of interest.)
 
 
@@ -248,10 +252,9 @@ If you look at the source release, you should find a \c{unix}
 subdirectory. There are a couple of ways of building it,
 subdirectory. There are a couple of ways of building it,
 including the usual \c{configure}/\c{make}; see the file \c{README}
 including the usual \c{configure}/\c{make}; see the file \c{README}
 in the source distribution. This should build you Unix
 in the source distribution. This should build you Unix
-ports of Plink, PuTTY itself, PuTTYgen, PSCP, PSFTP, and also
+ports of Plink, PuTTY itself, PuTTYgen, PSCP, PSFTP, Pageant, and also
 \i\c{pterm} - an \cw{xterm}-type program which supports the same
 \i\c{pterm} - an \cw{xterm}-type program which supports the same
-terminal emulation as PuTTY. \#{XXX-REVIEW-BEFORE-RELEASE:}
-We do not yet have a Unix port of Pageant.
+terminal emulation as PuTTY.
 
 
 If you don't have \i{Gtk}, you should still be able to build the
 If you don't have \i{Gtk}, you should still be able to build the
 command-line tools.
 command-line tools.
@@ -1045,7 +1048,7 @@ is triggered by PuTTY 0.58. This was fixed in 0.59. The
 \W{http://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/xp-wont-run}{\q{xp-wont-run}}
 \W{http://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/xp-wont-run}{\q{xp-wont-run}}
 entry in PuTTY's wishlist has more details.
 entry in PuTTY's wishlist has more details.
 
 
-\S{faq-system32}{Question} When I put PuTTY in
+\S{faq-system32}{Question} When I put 32-bit PuTTY in
 \cw{C:\\WINDOWS\\\i{SYSTEM32}} on my \i{64-bit Windows} system,
 \cw{C:\\WINDOWS\\\i{SYSTEM32}} on my \i{64-bit Windows} system,
 \i{\q{Duplicate Session}} doesn't work.
 \i{\q{Duplicate Session}} doesn't work.
 
 
@@ -1053,7 +1056,7 @@ The short answer is not to put the PuTTY executables in that location.
 
 
 On 64-bit systems, \cw{C:\\WINDOWS\\SYSTEM32} is intended to contain
 On 64-bit systems, \cw{C:\\WINDOWS\\SYSTEM32} is intended to contain
 only 64-bit binaries; Windows' 32-bit binaries live in
 only 64-bit binaries; Windows' 32-bit binaries live in
-\cw{C:\\WINDOWS\\SYSWOW64}. When a 32-bit program such as PuTTY runs
+\cw{C:\\WINDOWS\\SYSWOW64}. When a 32-bit PuTTY executable runs
 on a 64-bit system, it cannot by default see the \q{real}
 on a 64-bit system, it cannot by default see the \q{real}
 \cw{C:\\WINDOWS\\SYSTEM32} at all, because the
 \cw{C:\\WINDOWS\\SYSTEM32} at all, because the
 \W{http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx}{File
 \W{http://msdn.microsoft.com/en-us/library/aa384187(v=vs.85).aspx}{File
@@ -1083,15 +1086,21 @@ USB stick).
 I \i{clean up} after it?
 I \i{clean up} after it?
 
 
 PuTTY will leave some Registry entries, and a random seed file, on
 PuTTY will leave some Registry entries, and a random seed file, on
-the PC (see \k{faq-settings}). If you are using PuTTY on a public
-PC, or somebody else's PC, you might want to clean these up when you
-leave. You can do that automatically, by running the command
-\c{putty -cleanup}. (Note that this only removes settings for
-the currently logged-in user on \i{multi-user systems}.)
+the PC (see \k{faq-settings}). Windows 7 and up also remember some
+information about recently launched sessions for the \q{jump list}
+feature.
+
+If you are using PuTTY on a public PC, or somebody else's PC, you
+might want to clean this information up when you leave. You can do
+that automatically, by running the command \c{putty -cleanup}. See
+\k{using-cleanup} in the documentation for more detail. (Note that
+this only removes settings for the currently logged-in user on
+\i{multi-user systems}.)
 
 
 If PuTTY was installed from the installer package, it will also
 If PuTTY was installed from the installer package, it will also
-appear in \q{Add/Remove Programs}. Older versions of the uninstaller
-do not remove the above-mentioned registry entries and file.
+appear in \q{Add/Remove Programs}. Current versions of the installer
+do not offer to remove the above-mentioned items, so if you want them
+removed you should run \c{putty -cleanup} before uninstalling.
 
 
 \S{faq-dsa}{Question} How come PuTTY now supports \i{DSA}, when the
 \S{faq-dsa}{Question} How come PuTTY now supports \i{DSA}, when the
 website used to say how insecure it was?
 website used to say how insecure it was?

+ 9 - 0
source/putty/doc/index.but

@@ -863,3 +863,12 @@ saved sessions from
 
 
 \IM{64-bit Windows} 64-bit Windows
 \IM{64-bit Windows} 64-bit Windows
 \IM{64-bit Windows} Windows, 64-bit
 \IM{64-bit Windows} Windows, 64-bit
+
+\IM{Windows process ACL} Windows process ACL
+\IM{Windows process ACL} process ACL (Windows)
+\IM{Windows process ACL} ACL, process (Windows)
+
+\IM{proxy logging} proxy logging
+\IM{proxy logging} logging, proxy
+\IM{proxy logging} diagnostic, proxy
+\IM{proxy logging} standard error, proxy

+ 1 - 1
source/putty/doc/intro.but

@@ -1,6 +1,6 @@
 \C{intro} Introduction to PuTTY
 \C{intro} Introduction to PuTTY
 
 
-PuTTY is a free SSH, Telnet and Rlogin client for 32-bit Windows
+PuTTY is a free SSH, Telnet and Rlogin client for Windows
 systems.
 systems.
 
 
 \H{you-what} What are SSH, Telnet and Rlogin?
 \H{you-what} What are SSH, Telnet and Rlogin?

+ 23 - 9
source/putty/doc/man-pg.but

@@ -21,8 +21,7 @@
 
 
 \c{puttygen} is a tool to generate and manipulate SSH public and
 \c{puttygen} is a tool to generate and manipulate SSH public and
 private key pairs. It is part of the PuTTY suite, although it can
 private key pairs. It is part of the PuTTY suite, although it can
-also interoperate with the private key formats used by some other
-SSH clients.
+also interoperate with the key formats used by some other SSH clients.
 
 
 When you run \c{puttygen}, it does three things. Firstly, it either
 When you run \c{puttygen}, it does three things. Firstly, it either
 loads an existing key file (if you specified \e{keyfile}), or
 loads an existing key file (if you specified \e{keyfile}), or
@@ -37,18 +36,29 @@ the following section.
 \S{puttygen-manpage-options} OPTIONS
 \S{puttygen-manpage-options} OPTIONS
 
 
 In the first phase, \c{puttygen} either loads or generates a key.
 In the first phase, \c{puttygen} either loads or generates a key.
-Note that generating a key requires random data (from
-\c{/dev/random}), which can cause \c{puttygen} to pause, possibly for
-some time if your system does not have much randomness available.
+Note that generating a key requires random data, which can cause
+\c{puttygen} to pause, possibly for some time if your system does
+not have much randomness available.
 
 
 The options to control this phase are:
 The options to control this phase are:
 
 
 \dt \e{keyfile}
 \dt \e{keyfile}
 
 
-\dd Specify a private key file to be loaded. This private key file can
-be in the (de facto standard) SSH-1 key format, or in PuTTY's SSH-2
-key format, or in either of the SSH-2 private key formats used by
-OpenSSH and ssh.com's implementation.
+\dd Specify a key file to be loaded.
+
+\lcont{
+
+Usually this will be a private key, which can be in the (de facto
+standard) SSH-1 key format, or in PuTTY's SSH-2 key format, or in
+either of the SSH-2 private key formats used by OpenSSH and
+ssh.com's implementation.
+
+You can also specify a file containing only a \e{public} key here.
+The operations you can do are limited to outputting another public
+key format or a fingerprint. Public keys can be in RFC 4716 or
+OpenSSH format, or the standard SSH-1 format.
+
+}
 
 
 \dt \cw{\-t} \e{keytype}
 \dt \cw{\-t} \e{keytype}
 
 
@@ -71,6 +81,10 @@ and \c{rsa1} (to generate SSH-1 keys).
 \s{CAUTION:} If the passphrase is important, the file should be stored
 \s{CAUTION:} If the passphrase is important, the file should be stored
 on a temporary filesystem or else securely erased after use.
 on a temporary filesystem or else securely erased after use.
 
 
+\dt \cw{\-\-random\-device} \e{device}
+
+\dd Specify device to read entropy from (default \c{/dev/random}).
+
 In the second phase, \c{puttygen} optionally alters properties of
 In the second phase, \c{puttygen} optionally alters properties of
 the key it has loaded or generated. The options to control this are:
 the key it has loaded or generated. The options to control this are:
 
 

+ 51 - 0
source/putty/doc/man-pl.but

@@ -56,6 +56,27 @@ to aid in verifying new files released by the PuTTY team.
 
 
 \dd Force serial mode.
 \dd Force serial mode.
 
 
+\dt \cw{\-proxycmd} \e{command}
+
+\dd Instead of making a TCP connection, use \e{command} as a proxy;
+network traffic will be redirected to the standard input and output
+of \e{command}. \e{command} must be a single word, so is likely to
+need quoting by the shell.
+
+\lcont{
+The special strings \cw{%host} and \cw{%port} in \e{command} will be
+replaced by the hostname and port number you want to connect to; to get
+a literal \c{%} sign, enter \c{%%}.
+
+Backslash escapes are also supported, such as sequences like \c{\\n}
+being replaced by a literal newline; to get a literal backslash,
+enter \c{\\\\}. (Further escaping may be required by the shell.)
+
+(See the main PuTTY manual for full details of the supported \cw{%}-
+and backslash-delimited tokens, although most of them are probably not
+very useful in this context.)
+}
+
 \dt \cw{-P} \e{port}
 \dt \cw{-P} \e{port}
 
 
 \dd Connect to port \e{port}.
 \dd Connect to port \e{port}.
@@ -133,6 +154,10 @@ tunnel all their connections. Only works in SSH.
 
 
 \dd Force use of SSH protocol version 2.
 \dd Force use of SSH protocol version 2.
 
 
+\dt \cw{-4}, \cw{-6}
+
+\dd Force use of IPv4 or IPv6 for network connections.
+
 \dt \cw{-C}
 \dt \cw{-C}
 
 
 \dd Enable SSH compression.
 \dd Enable SSH compression.
@@ -147,6 +172,16 @@ else's.
 a \e{public} key here (in RFC 4716 or OpenSSH format), to identify
 a \e{public} key here (in RFC 4716 or OpenSSH format), to identify
 which of the agent's keys to use. }
 which of the agent's keys to use. }
 
 
+\dt \cw{\-noagent}
+
+\dd Don't try to use an authentication agent for local authentication.
+(This doesn't affect agent forwarding.)
+
+\dt \cw{\-agent}
+
+\dd Allow use of an authentication agent. (This option is only necessary
+to override a setting in a saved session.)
+
 \dt \cw{\-hostkey} \e{key}
 \dt \cw{\-hostkey} \e{key}
 
 
 \dd Specify an acceptable host public key. This option may be specified
 \dd Specify an acceptable host public key. This option may be specified
@@ -167,6 +202,11 @@ written. }
 
 
 \dd Don't start a remote command or shell at all (SSH-2 only).
 \dd Don't start a remote command or shell at all (SSH-2 only).
 
 
+\dt \cw{\-nc} \e{host}:\e{port}
+
+\dd Make a remote network connection from the server instead of
+starting a shell or command.
+
 \dt \cw{\-sercfg} \e{configuration-string}
 \dt \cw{\-sercfg} \e{configuration-string}
 
 
 \dd Specify the configuration parameters for the serial port, in
 \dd Specify the configuration parameters for the serial port, in
@@ -204,6 +244,17 @@ an effort is made to suppress obvious passwords.)
 encrypted packet data.
 encrypted packet data.
 }
 }
 
 
+\dt \cw{\-shareexists}
+
+\dd Instead of making a new connection, test for the presence of an
+existing connection that can be shared. The desired session can be
+specified in any of the usual ways.
+
+\lcont{
+Returns immediately with a zero exit status if a suitable \q{upstream}
+exists, nonzero otherwise.
+}
+
 \S{plink-manpage-more-information} MORE INFORMATION
 \S{plink-manpage-more-information} MORE INFORMATION
 
 
 For more information on plink, it's probably best to go and look at
 For more information on plink, it's probably best to go and look at

+ 34 - 0
source/putty/doc/man-pscp.but

@@ -65,6 +65,27 @@ to aid in verifying new files released by the PuTTY team.
 
 
 \dd Connect to port \e{port}.
 \dd Connect to port \e{port}.
 
 
+\dt \cw{\-proxycmd} \e{command}
+
+\dd Instead of making a TCP connection, use \e{command} as a proxy;
+network traffic will be redirected to the standard input and output
+of \e{command}. \e{command} must be a single word, so is likely to
+need quoting by the shell.
+
+\lcont{
+The special strings \cw{%host} and \cw{%port} in \e{command} will be
+replaced by the hostname and port number you want to connect to; to get
+a literal \c{%} sign, enter \c{%%}.
+
+Backslash escapes are also supported, such as sequences like \c{\\n}
+being replaced by a literal newline; to get a literal backslash,
+enter \c{\\\\}. (Further escaping may be required by the shell.)
+
+(See the main PuTTY manual for full details of the supported \cw{%}-
+and backslash-delimited tokens, although most of them are probably not
+very useful in this context.)
+}
+
 \dt \cw{-l} \e{user}
 \dt \cw{-l} \e{user}
 
 
 \dd Set remote username to \e{user}.
 \dd Set remote username to \e{user}.
@@ -87,6 +108,10 @@ commands such as \q{\c{w}}).
 
 
 \dd Force use of SSH protocol version 2.
 \dd Force use of SSH protocol version 2.
 
 
+\dt \cw{-4}, \cw{-6}
+
+\dd Force use of IPv4 or IPv6 for network connections.
+
 \dt \cw{-C}
 \dt \cw{-C}
 
 
 \dd Enable SSH compression.
 \dd Enable SSH compression.
@@ -101,6 +126,15 @@ else's.
 a \e{public} key here (in RFC 4716 or OpenSSH format), to identify
 a \e{public} key here (in RFC 4716 or OpenSSH format), to identify
 which of the agent's keys to use. }
 which of the agent's keys to use. }
 
 
+\dt \cw{\-noagent}
+
+\dd Don't try to use an authentication agent.
+
+\dt \cw{\-agent}
+
+\dd Allow use of an authentication agent. (This option is only necessary
+to override a setting in a saved session.)
+
 \dt \cw{\-hostkey} \e{key}
 \dt \cw{\-hostkey} \e{key}
 
 
 \dd Specify an acceptable host public key. This option may be specified
 \dd Specify an acceptable host public key. This option may be specified

+ 34 - 0
source/putty/doc/man-psft.but

@@ -53,6 +53,27 @@ to aid in verifying new files released by the PuTTY team.
 
 
 \dd Connect to port \e{port}.
 \dd Connect to port \e{port}.
 
 
+\dt \cw{\-proxycmd} \e{command}
+
+\dd Instead of making a TCP connection, use \e{command} as a proxy;
+network traffic will be redirected to the standard input and output
+of \e{command}. \e{command} must be a single word, so is likely to
+need quoting by the shell.
+
+\lcont{
+The special strings \cw{%host} and \cw{%port} in \e{command} will be
+replaced by the hostname and port number you want to connect to; to get
+a literal \c{%} sign, enter \c{%%}.
+
+Backslash escapes are also supported, such as sequences like \c{\\n}
+being replaced by a literal newline; to get a literal backslash,
+enter \c{\\\\}. (Further escaping may be required by the shell.)
+
+(See the main PuTTY manual for full details of the supported \cw{%}-
+and backslash-delimited tokens, although most of them are probably not
+very useful in this context.)
+}
+
 \dt \cw{-l} \e{user}
 \dt \cw{-l} \e{user}
 
 
 \dd Set remote username to \e{user}.
 \dd Set remote username to \e{user}.
@@ -75,6 +96,10 @@ commands such as \q{\c{w}}).
 
 
 \dd Force use of SSH protocol version 2.
 \dd Force use of SSH protocol version 2.
 
 
+\dt \cw{-4}, \cw{-6}
+
+\dd Force use of IPv4 or IPv6 for network connections.
+
 \dt \cw{-C}
 \dt \cw{-C}
 
 
 \dd Enable SSH compression.
 \dd Enable SSH compression.
@@ -89,6 +114,15 @@ else's.
 a \e{public} key here (in RFC 4716 or OpenSSH format), to identify
 a \e{public} key here (in RFC 4716 or OpenSSH format), to identify
 which of the agent's keys to use. }
 which of the agent's keys to use. }
 
 
+\dt \cw{\-noagent}
+
+\dd Don't try to use an authentication agent.
+
+\dt \cw{\-agent}
+
+\dd Allow use of an authentication agent. (This option is only necessary
+to override a setting in a saved session.)
+
 \dt \cw{\-hostkey} \e{key}
 \dt \cw{\-hostkey} \e{key}
 
 
 \dd Specify an acceptable host public key. This option may be specified
 \dd Specify an acceptable host public key. This option may be specified

+ 25 - 0
source/putty/doc/man-ptel.but

@@ -165,6 +165,27 @@ configuration box first.
 
 
 \dd Select the protocol \cw{puttytel} will use to make the connection.
 \dd Select the protocol \cw{puttytel} will use to make the connection.
 
 
+\dt \cw{\-proxycmd} \e{command}
+
+\dd Instead of making a TCP connection, use \e{command} as a proxy;
+network traffic will be redirected to the standard input and output
+of \e{command}. \e{command} must be a single word, so is likely to
+need quoting by the shell.
+
+\lcont{
+The special strings \cw{%host} and \cw{%port} in \e{command} will be
+replaced by the hostname and port number you want to connect to; to get
+a literal \c{%} sign, enter \c{%%}.
+
+Backslash escapes are also supported, such as sequences like \c{\\n}
+being replaced by a literal newline; to get a literal backslash,
+enter \c{\\\\}. (Further escaping may be required by the shell.)
+
+(See the main PuTTY manual for full details of the supported \cw{%}-
+and backslash-delimited tokens, although most of them are probably not
+very useful in this context.)
+}
+
 \dt \cw{\-l} \e{username}
 \dt \cw{\-l} \e{username}
 
 
 \dd Specify the username to use when logging in to the server.
 \dd Specify the username to use when logging in to the server.
@@ -173,6 +194,10 @@ configuration box first.
 
 
 \dd Specify the port to connect to the server on.
 \dd Specify the port to connect to the server on.
 
 
+\dt \cw{-4}, \cw{-6}
+
+\dd Force use of IPv4 or IPv6 for network connections.
+
 \S{puttytel-manpage-saved-sessions} SAVED SESSIONS
 \S{puttytel-manpage-saved-sessions} SAVED SESSIONS
 
 
 Saved sessions are stored in a \cw{.putty/sessions} subdirectory in
 Saved sessions are stored in a \cw{.putty/sessions} subdirectory in

+ 35 - 0
source/putty/doc/man-putt.but

@@ -178,6 +178,27 @@ configuration box first.
 
 
 \dd Select the protocol \cw{putty} will use to make the connection.
 \dd Select the protocol \cw{putty} will use to make the connection.
 
 
+\dt \cw{\-proxycmd} \e{command}
+
+\dd Instead of making a TCP connection, use \e{command} as a proxy;
+network traffic will be redirected to the standard input and output
+of \e{command}. \e{command} must be a single word, so is likely to
+need quoting by the shell.
+
+\lcont{
+The special strings \cw{%host} and \cw{%port} in \e{command} will be
+replaced by the hostname and port number you want to connect to; to get
+a literal \c{%} sign, enter \c{%%}.
+
+Backslash escapes are also supported, such as sequences like \c{\\n}
+being replaced by a literal newline; to get a literal backslash,
+enter \c{\\\\}. (Further escaping may be required by the shell.)
+
+(See the main PuTTY manual for full details of the supported \cw{%}-
+and backslash-delimited tokens, although most of them are probably not
+very useful in this context.)
+}
+
 \dt \cw{\-l} \e{username}
 \dt \cw{\-l} \e{username}
 
 
 \dd Specify the username to use when logging in to the server.
 \dd Specify the username to use when logging in to the server.
@@ -231,6 +252,10 @@ pseudo-terminal at the server end.
 
 
 \dd Select SSH protocol version 1 or 2.
 \dd Select SSH protocol version 1 or 2.
 
 
+\dt \cw{-4}, \cw{-6}
+
+\dd Force use of IPv4 or IPv6 for network connections.
+
 \dt \cw{\-i} \e{keyfile}
 \dt \cw{\-i} \e{keyfile}
 
 
 \dd Private key file for user authentication. For SSH-2 keys, this key
 \dd Private key file for user authentication. For SSH-2 keys, this key
@@ -241,6 +266,16 @@ else's.
 a \e{public} key here (in RFC 4716 or OpenSSH format), to identify
 a \e{public} key here (in RFC 4716 or OpenSSH format), to identify
 which of the agent's keys to use. }
 which of the agent's keys to use. }
 
 
+\dt \cw{\-noagent}
+
+\dd Don't try to use an authentication agent for local authentication.
+(This doesn't affect agent forwarding.)
+
+\dt \cw{\-agent}
+
+\dd Allow use of an authentication agent. (This option is only necessary
+to override a setting in a saved session.)
+
 \dt \cw{\-hostkey} \e{key}
 \dt \cw{\-hostkey} \e{key}
 
 
 \dd Specify an acceptable host public key. This option may be specified
 \dd Specify an acceptable host public key. This option may be specified

+ 5 - 1
source/putty/doc/plink.but

@@ -41,7 +41,7 @@ use Plink:
 
 
 \c Z:\sysosd>plink
 \c Z:\sysosd>plink
 \c Plink: command-line connection utility
 \c Plink: command-line connection utility
-\c Release 0.67
+\c Release 0.68
 \c Usage: plink [options] [user@]host [command]
 \c Usage: plink [options] [user@]host [command]
 \c        ("host" can also be a PuTTY saved session name)
 \c        ("host" can also be a PuTTY saved session name)
 \c Options:
 \c Options:
@@ -54,6 +54,8 @@ use Plink:
 \c   -P port   connect to specified port
 \c   -P port   connect to specified port
 \c   -l user   connect with specified username
 \c   -l user   connect with specified username
 \c   -batch    disable all interactive prompts
 \c   -batch    disable all interactive prompts
+\c   -proxycmd command
+\c             use 'command' as local proxy
 \c   -sercfg configuration-string (e.g. 19200,8,n,1,X)
 \c   -sercfg configuration-string (e.g. 19200,8,n,1,X)
 \c             Specify the serial configuration (serial only)
 \c             Specify the serial configuration (serial only)
 \c The following options only apply to SSH connections:
 \c The following options only apply to SSH connections:
@@ -83,6 +85,8 @@ use Plink:
 \c   -sshlog file
 \c   -sshlog file
 \c   -sshrawlog file
 \c   -sshrawlog file
 \c             log protocol details to a file
 \c             log protocol details to a file
+\c   -shareexists
+\c             test whether a connection-sharing upstream exists
 
 
 Once this works, you are ready to use Plink.
 Once this works, you are ready to use Plink.
 
 

+ 3 - 1
source/putty/doc/pscp.but

@@ -39,7 +39,7 @@ use PSCP:
 
 
 \c Z:\owendadmin>pscp
 \c Z:\owendadmin>pscp
 \c PuTTY Secure Copy client
 \c PuTTY Secure Copy client
-\c Release 0.67
+\c Release 0.68
 \c Usage: pscp [options] [user@]host:source target
 \c Usage: pscp [options] [user@]host:source target
 \c        pscp [options] source [source...] [user@]host:target
 \c        pscp [options] source [source...] [user@]host:target
 \c        pscp [options] -ls [user@]host:filespec
 \c        pscp [options] -ls [user@]host:filespec
@@ -63,6 +63,8 @@ use PSCP:
 \c   -hostkey aa:bb:cc:...
 \c   -hostkey aa:bb:cc:...
 \c             manually specify a host key (may be repeated)
 \c             manually specify a host key (may be repeated)
 \c   -batch    disable all interactive prompts
 \c   -batch    disable all interactive prompts
+\c   -proxycmd command
+\c             use 'command' as local proxy
 \c   -unsafe   allow server-side wildcards (DANGEROUS)
 \c   -unsafe   allow server-side wildcards (DANGEROUS)
 \c   -sftp     force use of SFTP protocol
 \c   -sftp     force use of SFTP protocol
 \c   -scp      force use of SCP protocol
 \c   -scp      force use of SCP protocol

+ 21 - 10
source/putty/doc/using.but

@@ -607,7 +607,9 @@ use the \c{-load} option (described in \k{using-cmdline-load}).
 If invoked with the \c{-cleanup} option, rather than running as
 If invoked with the \c{-cleanup} option, rather than running as
 normal, PuTTY will remove its \I{removing registry entries}registry
 normal, PuTTY will remove its \I{removing registry entries}registry
 entries and \i{random seed file} from the local machine (after
 entries and \i{random seed file} from the local machine (after
-confirming with the user).
+confirming with the user). It will also attempt to remove information
+about recently launched sessions stored in the \q{jump list} on
+Windows 7 and up.
 
 
 Note that on \i{multi-user systems}, \c{-cleanup} only removes
 Note that on \i{multi-user systems}, \c{-cleanup} only removes
 registry entries and files associated with the currently logged-in
 registry entries and files associated with the currently logged-in
@@ -1009,18 +1011,21 @@ on the local machine and using it as a proxy for the network
 connection. It expects a shell command string as an argument.
 connection. It expects a shell command string as an argument.
 
 
 See \k{config-proxy-type} for more information on this, and on other
 See \k{config-proxy-type} for more information on this, and on other
-proxy settings.
+proxy settings. In particular, note that since the special sequences
+described there are understood in the argument string, literal
+backslashes must be doubled (if you want \c{\\} in your command, you
+must put \c{\\\\} on the command line).
 
 
 \S2{using-cmdline-restrict-acl} \i\c{-restrict-acl}: restrict the
 \S2{using-cmdline-restrict-acl} \i\c{-restrict-acl}: restrict the
-Windows process ACL
+\i{Windows process ACL}
 
 
-This option (on Windows only) causes PuTTY to try to lock down the
-operating system's access control on its own process. If this
-succeeds, it should present an extra obstacle to malware that has
-managed to run under the same user id as the PuTTY process, by
-preventing it from attaching to PuTTY using the same interfaces
-debuggers use and either reading sensitive information out of its
-memory or hijacking its network session.
+This option (on Windows only) causes PuTTY (or another PuTTY tool) to
+try to lock down the operating system's access control on its own
+process. If this succeeds, it should present an extra obstacle to
+malware that has managed to run under the same user id as the PuTTY
+process, by preventing it from attaching to PuTTY using the same
+interfaces debuggers use and either reading sensitive information out
+of its memory or hijacking its network session.
 
 
 This option is not enabled by default, because this form of
 This option is not enabled by default, because this form of
 interaction between Windows programs has many legitimate uses,
 interaction between Windows programs has many legitimate uses,
@@ -1031,3 +1036,9 @@ up, and malware could still get in if it attacks the process between
 startup and lockdown. So it trades away noticeable convenience, and
 startup and lockdown. So it trades away noticeable convenience, and
 delivers less real security than you might want. However, if you do
 delivers less real security than you might want. However, if you do
 want to make that tradeoff anyway, the option is available.
 want to make that tradeoff anyway, the option is available.
+
+A PuTTY process started with \c{-restrict-acl} will pass that on to
+any processes started with Duplicate Session, New Session etc.
+(However, if you're invoking PuTTY tools explicitly, for instance as a
+proxy command, you'll need to arrange to pass them the
+\c{-restrict-acl} option yourself, if that's what you want.)

+ 11 - 10
source/putty/import.c

@@ -1543,18 +1543,14 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
                                       const char **errmsg_p)
                                       const char **errmsg_p)
 {
 {
     struct openssh_new_key *key = load_openssh_new_key(filename, errmsg_p);
     struct openssh_new_key *key = load_openssh_new_key(filename, errmsg_p);
-    struct ssh2_userkey *retkey;
+    struct ssh2_userkey *retkey = NULL;
     int i;
     int i;
     struct ssh2_userkey *retval = NULL;
     struct ssh2_userkey *retval = NULL;
     const char *errmsg;
     const char *errmsg;
-    unsigned char *blob;
-    int blobsize = 0;
     unsigned checkint0, checkint1;
     unsigned checkint0, checkint1;
     const void *priv, *string;
     const void *priv, *string;
     int privlen, stringlen, key_index;
     int privlen, stringlen, key_index;
-    const struct ssh_signkey *alg;
-
-    blob = NULL;
+    const struct ssh_signkey *alg = NULL;
 
 
     if (!key)
     if (!key)
 	return NULL;
 	return NULL;
@@ -1678,10 +1674,10 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
                            (const unsigned char *)thiskey);
                            (const unsigned char *)thiskey);
         if (key_index == key->key_wanted) {
         if (key_index == key->key_wanted) {
             retkey = snew(struct ssh2_userkey);
             retkey = snew(struct ssh2_userkey);
+            retkey->comment = NULL;
             retkey->alg = alg;
             retkey->alg = alg;
             retkey->data = alg->openssh_createkey(alg, &thiskey, &thiskeylen);
             retkey->data = alg->openssh_createkey(alg, &thiskey, &thiskeylen);
             if (!retkey->data) {
             if (!retkey->data) {
-                sfree(retkey);
                 errmsg = "unable to create key data structure";
                 errmsg = "unable to create key data structure";
                 goto error;
                 goto error;
             }
             }
@@ -1718,11 +1714,16 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
 
 
     errmsg = NULL;                     /* no error */
     errmsg = NULL;                     /* no error */
     retval = retkey;
     retval = retkey;
+    retkey = NULL;                     /* prevent the free */
 
 
     error:
     error:
-    if (blob) {
-        smemclr(blob, blobsize);
-        sfree(blob);
+    if (retkey) {
+        sfree(retkey->comment);
+        if (retkey->data) {
+            assert(alg);
+            alg->freekey(retkey->data);
+        }
+        sfree(retkey);
     }
     }
     smemclr(key->keyblob, key->keyblob_size);
     smemclr(key->keyblob, key->keyblob_size);
     sfree(key->keyblob);
     sfree(key->keyblob);

+ 12 - 1
source/putty/misc.c

@@ -406,7 +406,7 @@ static char *dupvprintf_inner(char *buf, int oldlen, int oldsize,
     }
     }
 
 
     while (1) {
     while (1) {
-#if defined _WINDOWS && _MSC_VER < 1900 /* 1900 == VS2015 has real snprintf */
+#if defined _WINDOWS && !defined __WINE__ && _MSC_VER < 1900 /* 1900 == VS2015 has real snprintf */
 #define vsnprintf _vsnprintf
 #define vsnprintf _vsnprintf
 #endif
 #endif
 #ifdef va_copy
 #ifdef va_copy
@@ -1183,6 +1183,17 @@ char *buildinfo(const char *newline)
     strbuf_catf(buf, " (_MSC_VER=%d)", (int)_MSC_VER);
     strbuf_catf(buf, " (_MSC_VER=%d)", (int)_MSC_VER);
 #endif
 #endif
 
 
+#ifdef BUILDINFO_GTK
+    {
+        char *gtk_buildinfo = buildinfo_gtk_version();
+        if (gtk_buildinfo) {
+            strbuf_catf(buf, "%sCompiled against GTK version %s",
+                        newline, gtk_buildinfo);
+            sfree(gtk_buildinfo);
+        }
+    }
+#endif
+
 #ifdef NO_SECURITY
 #ifdef NO_SECURITY
     strbuf_catf(buf, "%sBuild option: NO_SECURITY", newline);
     strbuf_catf(buf, "%sBuild option: NO_SECURITY", newline);
 #endif
 #endif

+ 1 - 1
source/putty/proxy.c

@@ -518,7 +518,7 @@ Socket new_connection(SockAddr addr, const char *hostname,
 
 
         {
         {
             char addrbuf[256], *logmsg;
             char addrbuf[256], *logmsg;
-            sk_getaddr(addr, addrbuf, lenof(addrbuf));
+            sk_getaddr(proxy_addr, addrbuf, lenof(addrbuf));
             logmsg = dupprintf("Connecting to %s proxy at %s port %d",
             logmsg = dupprintf("Connecting to %s proxy at %s port %d",
                                proxy_type, addrbuf,
                                proxy_type, addrbuf,
                                conf_get_int(conf, CONF_proxy_port));
                                conf_get_int(conf, CONF_proxy_port));

+ 1 - 0
source/putty/putty.h

@@ -671,6 +671,7 @@ enum {
     BUSY_CPU	    /* Locally busy (e.g. crypto); user interaction suspended */
     BUSY_CPU	    /* Locally busy (e.g. crypto); user interaction suspended */
 };
 };
 void set_busy_status(void *frontend, int status);
 void set_busy_status(void *frontend, int status);
+int frontend_is_utf8(void *frontend);
 
 
 void cleanup_exit(int);
 void cleanup_exit(int);
 
 

+ 9 - 4
source/putty/ssh.c

@@ -3954,6 +3954,7 @@ static void ssh_agentf_try_forward(struct ssh_channel *c)
          * straight on and go round this loop again.
          * straight on and go round this loop again.
          */
          */
         ssh_agentf_got_response(c, reply, replylen);
         ssh_agentf_got_response(c, reply, replylen);
+        sfree(reply);
     }
     }
 
 
     /*
     /*
@@ -9444,21 +9445,25 @@ static void do_ssh2_authconn(Ssh ssh, const unsigned char *in, int inlen,
                             goto done_agent_query;
                             goto done_agent_query;
                         }
                         }
                         bloblen = toint(GET_32BIT(q));
                         bloblen = toint(GET_32BIT(q));
+                        lenleft -= 4;
+                        q += 4;
                         if (bloblen < 0 || bloblen > lenleft) {
                         if (bloblen < 0 || bloblen > lenleft) {
                             logeventf(ssh, "Pageant response was truncated");
                             logeventf(ssh, "Pageant response was truncated");
                             s->nkeys = 0;
                             s->nkeys = 0;
                             goto done_agent_query;
                             goto done_agent_query;
                         }
                         }
-                        lenleft -= 4 + bloblen;
-                        q += 4 + bloblen;
+                        lenleft -= bloblen;
+                        q += bloblen;
                         commentlen = toint(GET_32BIT(q));
                         commentlen = toint(GET_32BIT(q));
+                        lenleft -= 4;
+                        q += 4;
                         if (commentlen < 0 || commentlen > lenleft) {
                         if (commentlen < 0 || commentlen > lenleft) {
                             logeventf(ssh, "Pageant response was truncated");
                             logeventf(ssh, "Pageant response was truncated");
                             s->nkeys = 0;
                             s->nkeys = 0;
                             goto done_agent_query;
                             goto done_agent_query;
                         }
                         }
-                        lenleft -= 4 + commentlen;
-                        q += 4 + commentlen;
+                        lenleft -= commentlen;
+                        q += commentlen;
                     }
                     }
                 }
                 }
 
 

+ 6 - 6
source/putty/ssh.h

@@ -156,12 +156,12 @@ const struct ssh_signkey *ec_alg_by_oid(int len, const void *oid,
                                         const struct ec_curve **curve);
                                         const struct ec_curve **curve);
 const unsigned char *ec_alg_oid(const struct ssh_signkey *alg, int *oidlen);
 const unsigned char *ec_alg_oid(const struct ssh_signkey *alg, int *oidlen);
 extern const int ec_nist_curve_lengths[], n_ec_nist_curve_lengths;
 extern const int ec_nist_curve_lengths[], n_ec_nist_curve_lengths;
-const int ec_nist_alg_and_curve_by_bits(int bits,
-                                        const struct ec_curve **curve,
-                                        const struct ssh_signkey **alg);
-const int ec_ed_alg_and_curve_by_bits(int bits,
-                                      const struct ec_curve **curve,
-                                      const struct ssh_signkey **alg);
+int ec_nist_alg_and_curve_by_bits(int bits,
+                                  const struct ec_curve **curve,
+                                  const struct ssh_signkey **alg);
+int ec_ed_alg_and_curve_by_bits(int bits,
+                                const struct ec_curve **curve,
+                                const struct ssh_signkey **alg);
 
 
 struct ssh_signkey;
 struct ssh_signkey;
 
 

+ 6 - 6
source/putty/sshecc.c

@@ -2940,9 +2940,9 @@ const unsigned char *ec_alg_oid(const struct ssh_signkey *alg,
 const int ec_nist_curve_lengths[] = { 256, 384, 521 };
 const int ec_nist_curve_lengths[] = { 256, 384, 521 };
 const int n_ec_nist_curve_lengths = lenof(ec_nist_curve_lengths);
 const int n_ec_nist_curve_lengths = lenof(ec_nist_curve_lengths);
 
 
-const int ec_nist_alg_and_curve_by_bits(int bits,
-                                        const struct ec_curve **curve,
-                                        const struct ssh_signkey **alg)
+int ec_nist_alg_and_curve_by_bits(int bits,
+                                  const struct ec_curve **curve,
+                                  const struct ssh_signkey **alg)
 {
 {
     switch (bits) {
     switch (bits) {
       case 256: *alg = &ssh_ecdsa_nistp256; break;
       case 256: *alg = &ssh_ecdsa_nistp256; break;
@@ -2954,9 +2954,9 @@ const int ec_nist_alg_and_curve_by_bits(int bits,
     return TRUE;
     return TRUE;
 }
 }
 
 
-const int ec_ed_alg_and_curve_by_bits(int bits,
-                                      const struct ec_curve **curve,
-                                      const struct ssh_signkey **alg)
+int ec_ed_alg_and_curve_by_bits(int bits,
+                                const struct ec_curve **curve,
+                                const struct ssh_signkey **alg)
 {
 {
     switch (bits) {
     switch (bits) {
       case 256: *alg = &ssh_ecdsa_ed25519; break;
       case 256: *alg = &ssh_ecdsa_ed25519; break;

+ 1 - 0
source/putty/sshpubk.c

@@ -946,6 +946,7 @@ unsigned char *rfc4716_loadpub(FILE *fp, char **algorithm,
             }
             }
 
 
             *q = '\0';
             *q = '\0';
+            sfree(comment);   /* *just* in case of multiple Comment headers */
             comment = dupstr(line);
             comment = dupstr(line);
         } else if (!strcmp(line, "Subject") ||
         } else if (!strcmp(line, "Subject") ||
                    !strncmp(line, "x-", 2)) {
                    !strncmp(line, "x-", 2)) {

+ 2 - 3
source/putty/sshzlib.c

@@ -201,7 +201,7 @@ static void lz77_compress(struct LZ77Context *ctx,
 			  unsigned char *data, int len, int compress)
 			  unsigned char *data, int len, int compress)
 {
 {
     struct LZ77InternalContext *st = ctx->ictx;
     struct LZ77InternalContext *st = ctx->ictx;
-    int i, hash, distance, off, nmatch, matchlen, advance;
+    int i, distance, off, nmatch, matchlen, advance;
     struct Match defermatch, matches[MAXMATCH];
     struct Match defermatch, matches[MAXMATCH];
     int deferchr;
     int deferchr;
 
 
@@ -242,7 +242,7 @@ static void lz77_compress(struct LZ77Context *ctx,
 	    /*
 	    /*
 	     * Hash the next few characters.
 	     * Hash the next few characters.
 	     */
 	     */
-	    hash = lz77_hash(data);
+	    int hash = lz77_hash(data);
 
 
 	    /*
 	    /*
 	     * Look the hash up in the corresponding hash chain and see
 	     * Look the hash up in the corresponding hash chain and see
@@ -267,7 +267,6 @@ static void lz77_compress(struct LZ77Context *ctx,
 	    }
 	    }
 	} else {
 	} else {
 	    nmatch = 0;
 	    nmatch = 0;
-	    hash = INVALID;
 	}
 	}
 
 
 	if (nmatch > 0) {
 	if (nmatch > 0) {

+ 5 - 5
source/putty/version.h

@@ -1,6 +1,6 @@
 /* Generated by automated build script */
 /* Generated by automated build script */
-#define SNAPSHOT
-#define TEXTVER "Development snapshot 2017-02-02.f6c1c88"
-#define SSHVER "PuTTY-Snapshot-2017-02-02.f6c1c88"
-#define BINARY_VERSION 0,67,1339,0
-#define SOURCE_COMMIT "f6c1c8819b5d90a97124b62ee07b0e06d6bbb6c3"
+#define RELEASE 0.68
+#define TEXTVER "Release 0.68"
+#define SSHVER "PuTTY-Release-0.68"
+#define BINARY_VERSION 0,68,0,0
+#define SOURCE_COMMIT "23fbc4f56b04ca5d387c16720caa05ddf2d63e2f"

+ 1 - 1
source/putty/windows/wingss.c

@@ -91,7 +91,7 @@ struct ssh_gss_liblist *ssh_gss_setup(Conf *conf)
 	if (ret == ERROR_SUCCESS && type == REG_SZ) {
 	if (ret == ERROR_SUCCESS && type == REG_SZ) {
 	    buffer = snewn(size + 20, char);
 	    buffer = snewn(size + 20, char);
 	    ret = RegQueryValueEx(regkey, "InstallDir", NULL,
 	    ret = RegQueryValueEx(regkey, "InstallDir", NULL,
-				  &type, buffer, &size);
+				  &type, (LPBYTE)buffer, &size);
 	    if (ret == ERROR_SUCCESS && type == REG_SZ) {
 	    if (ret == ERROR_SUCCESS && type == REG_SZ) {
 		strcat(buffer, "\\bin\\gssapi32.dll");
 		strcat(buffer, "\\bin\\gssapi32.dll");
 		module = LoadLibrary(buffer);
 		module = LoadLibrary(buffer);

+ 1 - 1
source/putty/windows/winhandl.c

@@ -533,7 +533,7 @@ void handle_write_eof(struct handle *h)
      * direction!
      * direction!
      */
      */
     assert(h->type == HT_OUTPUT);
     assert(h->type == HT_OUTPUT);
-    if (!h->u.o.outgoingeof == EOF_NO) {
+    if (h->u.o.outgoingeof == EOF_NO) {
         h->u.o.outgoingeof = EOF_PENDING;
         h->u.o.outgoingeof = EOF_PENDING;
         handle_try_output(&h->u.o);
         handle_try_output(&h->u.o);
     }
     }

+ 18 - 0
source/putty/windows/winnet.c

@@ -5,11 +5,15 @@
  * unfix.org.
  * unfix.org.
  */
  */
 
 
+#include <winsock2.h> /* need to put this first, for winelib builds */
+
 #include <stdio.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <assert.h>
 
 
 #define DEFINE_PLUG_METHOD_MACROS
 #define DEFINE_PLUG_METHOD_MACROS
+#define NEED_DECLARATION_OF_SELECT     /* in order to initialise it */
+
 #include "putty.h"
 #include "putty.h"
 #include "network.h"
 #include "network.h"
 #include "tree234.h"
 #include "tree234.h"
@@ -17,8 +21,15 @@
 #include <ws2tcpip.h>
 #include <ws2tcpip.h>
 
 
 #ifndef NO_IPV6
 #ifndef NO_IPV6
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wmissing-braces"
+#endif
 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
 const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
 const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
 #endif
 #endif
 
 
 #define ipv4_is_loopback(addr) \
 #define ipv4_is_loopback(addr) \
@@ -229,6 +240,13 @@ int sk_startup(int hi, int lo)
     return TRUE;
     return TRUE;
 }
 }
 
 
+/* Actually define this function pointer, which won't have been
+ * defined alongside all the others by PUTTY_DO_GLOBALS because of the
+ * annoying winelib header-ordering issue. (See comment in winstuff.h.) */
+DECL_WINDOWS_FUNCTION(/* empty */, int, select,
+		      (int, fd_set FAR *, fd_set FAR *,
+		       fd_set FAR *, const struct timeval FAR *));
+
 void sk_init(void)
 void sk_init(void)
 {
 {
 #ifndef NO_IPV6
 #ifndef NO_IPV6

+ 4 - 0
source/putty/windows/winproxy.c

@@ -77,6 +77,10 @@ Socket platform_new_connection(SockAddr addr, const char *hostname,
             Socket ret = new_error_socket
             Socket ret = new_error_socket
                 ("Unable to create pipes for proxy command", plug);
                 ("Unable to create pipes for proxy command", plug);
             sfree(cmd);
             sfree(cmd);
+            CloseHandle(us_from_cmd);
+            CloseHandle(cmd_to_us);
+            CloseHandle(us_to_cmd);
+            CloseHandle(cmd_from_us);
             return ret;
             return ret;
         }
         }
     }
     }

+ 11 - 10
source/putty/windows/winstore.c

@@ -110,7 +110,7 @@ void *open_settings_w(const char *sessionname, char **errmsg)
 void write_setting_s(void *handle, const char *key, const char *value)
 void write_setting_s(void *handle, const char *key, const char *value)
 {
 {
     if (handle)
     if (handle)
-	RegSetValueEx((HKEY) handle, key, 0, REG_SZ, value,
+	RegSetValueEx((HKEY) handle, key, 0, REG_SZ, (CONST BYTE *)value,
 		      1 + strlen(value));
 		      1 + strlen(value));
 }
 }
 
 
@@ -168,7 +168,7 @@ char *read_setting_s(void *handle, const char *key)
     allocsize = size+1;         /* allow for an extra NUL if needed */
     allocsize = size+1;         /* allow for an extra NUL if needed */
     ret = snewn(allocsize, char);
     ret = snewn(allocsize, char);
     if (RegQueryValueEx((HKEY) handle, key, 0,
     if (RegQueryValueEx((HKEY) handle, key, 0,
-			&type, ret, &size) != ERROR_SUCCESS ||
+			&type, (BYTE *)ret, &size) != ERROR_SUCCESS ||
 	type != REG_SZ) {
 	type != REG_SZ) {
         sfree(ret);
         sfree(ret);
         return NULL;
         return NULL;
@@ -372,7 +372,8 @@ int verify_host_key(const char *hostname, int port,
 
 
     readlen = len;
     readlen = len;
     otherstr = snewn(len, char);
     otherstr = snewn(len, char);
-    ret = RegQueryValueEx(rkey, regname, NULL, &type, otherstr, &readlen);
+    ret = RegQueryValueEx(rkey, regname, NULL,
+                          &type, (BYTE *)otherstr, &readlen);
 
 
     if (ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA &&
     if (ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA &&
 	!strcmp(keytype, "rsa")) {
 	!strcmp(keytype, "rsa")) {
@@ -385,7 +386,7 @@ int verify_host_key(const char *hostname, int port,
 	char *oldstyle = snewn(len + 10, char);	/* safety margin */
 	char *oldstyle = snewn(len + 10, char);	/* safety margin */
 	readlen = len;
 	readlen = len;
 	ret = RegQueryValueEx(rkey, justhost, NULL, &type,
 	ret = RegQueryValueEx(rkey, justhost, NULL, &type,
-			      oldstyle, &readlen);
+			      (BYTE *)oldstyle, &readlen);
 
 
 	if (ret == ERROR_SUCCESS && type == REG_SZ) {
 	if (ret == ERROR_SUCCESS && type == REG_SZ) {
 	    /*
 	    /*
@@ -431,7 +432,7 @@ int verify_host_key(const char *hostname, int port,
 	     * wrong, and hyper-cautiously do nothing.
 	     * wrong, and hyper-cautiously do nothing.
 	     */
 	     */
 	    if (!strcmp(otherstr, key))
 	    if (!strcmp(otherstr, key))
-		RegSetValueEx(rkey, regname, 0, REG_SZ, otherstr,
+		RegSetValueEx(rkey, regname, 0, REG_SZ, (BYTE *)otherstr,
 			      strlen(otherstr) + 1);
 			      strlen(otherstr) + 1);
 	}
 	}
 
 
@@ -476,7 +477,7 @@ void store_host_key(const char *hostname, int port,
 
 
     if (RegCreateKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys",
     if (RegCreateKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys",
 		     &rkey) == ERROR_SUCCESS) {
 		     &rkey) == ERROR_SUCCESS) {
-	RegSetValueEx(rkey, regname, 0, REG_SZ, key, strlen(key) + 1);
+	RegSetValueEx(rkey, regname, 0, REG_SZ, (BYTE *)key, strlen(key) + 1);
 	RegCloseKey(rkey);
 	RegCloseKey(rkey);
     } /* else key does not exist in registry */
     } /* else key does not exist in registry */
 
 
@@ -536,7 +537,7 @@ static HANDLE access_random_seed(int action)
     if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_POS, &rkey) ==
     if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_POS, &rkey) ==
 	ERROR_SUCCESS) {
 	ERROR_SUCCESS) {
 	int ret = RegQueryValueEx(rkey, "RandSeedFile",
 	int ret = RegQueryValueEx(rkey, "RandSeedFile",
-				  0, &type, seedpath, &size);
+				  0, &type, (BYTE *)seedpath, &size);
 	if (ret != ERROR_SUCCESS || type != REG_SZ)
 	if (ret != ERROR_SUCCESS || type != REG_SZ)
 	    seedpath[0] = '\0';
 	    seedpath[0] = '\0';
 	RegCloseKey(rkey);
 	RegCloseKey(rkey);
@@ -672,7 +673,7 @@ static int transform_jumplist_registry
     value_length = 200;
     value_length = 200;
     old_value = snewn(value_length, char);
     old_value = snewn(value_length, char);
     ret = RegQueryValueEx(pjumplist_key, reg_jumplist_value, NULL, &type,
     ret = RegQueryValueEx(pjumplist_key, reg_jumplist_value, NULL, &type,
-                          old_value, &value_length);
+                          (BYTE *)old_value, &value_length);
     /* When the passed buffer is too small, ERROR_MORE_DATA is
     /* When the passed buffer is too small, ERROR_MORE_DATA is
      * returned and the required size is returned in the length
      * returned and the required size is returned in the length
      * argument. */
      * argument. */
@@ -680,7 +681,7 @@ static int transform_jumplist_registry
         sfree(old_value);
         sfree(old_value);
         old_value = snewn(value_length, char);
         old_value = snewn(value_length, char);
         ret = RegQueryValueEx(pjumplist_key, reg_jumplist_value, NULL, &type,
         ret = RegQueryValueEx(pjumplist_key, reg_jumplist_value, NULL, &type,
-                              old_value, &value_length);
+                              (BYTE *)old_value, &value_length);
     }
     }
 
 
     if (ret == ERROR_FILE_NOT_FOUND) {
     if (ret == ERROR_FILE_NOT_FOUND) {
@@ -754,7 +755,7 @@ static int transform_jumplist_registry
 
 
         /* Save the new list to the registry. */
         /* Save the new list to the registry. */
         ret = RegSetValueEx(pjumplist_key, reg_jumplist_value, 0, REG_MULTI_SZ,
         ret = RegSetValueEx(pjumplist_key, reg_jumplist_value, 0, REG_MULTI_SZ,
-                            new_value, piterator_new - new_value);
+                            (BYTE *)new_value, piterator_new - new_value);
 
 
         sfree(old_value);
         sfree(old_value);
         old_value = new_value;
         old_value = new_value;

+ 29 - 3
source/putty/windows/winstuff.h

@@ -89,10 +89,26 @@ struct FontSpec *fontspec_new(const char *name,
 #define BOXRESULT (DLGWINDOWEXTRA + sizeof(LONG_PTR))
 #define BOXRESULT (DLGWINDOWEXTRA + sizeof(LONG_PTR))
 #define DF_END 0x0001
 #define DF_END 0x0001
 
 
+#ifdef __WINE__
+#define NO_SECUREZEROMEMORY            /* winelib doesn't have this */
+#endif
+
 #ifndef NO_SECUREZEROMEMORY
 #ifndef NO_SECUREZEROMEMORY
 #define PLATFORM_HAS_SMEMCLR /* inhibit cross-platform one in misc.c */
 #define PLATFORM_HAS_SMEMCLR /* inhibit cross-platform one in misc.c */
 #endif
 #endif
 
 
+#ifndef __WINE__
+/* Up-to-date Windows headers warn that the unprefixed versions of
+ * these names are deprecated. */
+#define stricmp _stricmp
+#define strnicmp _strnicmp
+#else
+/* Compiling with winegcc, _neither_ version of these functions
+ * exists. Use the POSIX names. */
+#define stricmp strcasecmp
+#define strnicmp strncasecmp
+#endif
+
 #define BROKEN_PIPE_ERROR_CODE ERROR_BROKEN_PIPE   /* used in sshshare.c */
 #define BROKEN_PIPE_ERROR_CODE ERROR_BROKEN_PIPE   /* used in sshshare.c */
 
 
 /*
 /*
@@ -271,12 +287,21 @@ DECL_WINDOWS_FUNCTION(GLOBAL, int, WSAAsyncSelect,
 		      (SOCKET, HWND, u_int, long));
 		      (SOCKET, HWND, u_int, long));
 DECL_WINDOWS_FUNCTION(GLOBAL, int, WSAEventSelect,
 DECL_WINDOWS_FUNCTION(GLOBAL, int, WSAEventSelect,
 		      (SOCKET, WSAEVENT, long));
 		      (SOCKET, WSAEVENT, long));
-DECL_WINDOWS_FUNCTION(GLOBAL, int, select,
-		      (int, fd_set FAR *, fd_set FAR *,
-		       fd_set FAR *, const struct timeval FAR *));
 DECL_WINDOWS_FUNCTION(GLOBAL, int, WSAGetLastError, (void));
 DECL_WINDOWS_FUNCTION(GLOBAL, int, WSAGetLastError, (void));
 DECL_WINDOWS_FUNCTION(GLOBAL, int, WSAEnumNetworkEvents,
 DECL_WINDOWS_FUNCTION(GLOBAL, int, WSAEnumNetworkEvents,
 		      (SOCKET, WSAEVENT, LPWSANETWORKEVENTS));
 		      (SOCKET, WSAEVENT, LPWSANETWORKEVENTS));
+#ifdef NEED_DECLARATION_OF_SELECT
+/* This declaration is protected by an ifdef for the sake of building
+ * against winelib, in which you have to include winsock2.h before
+ * stdlib.h so that the right fd_set type gets defined. It would be a
+ * pain to do that throughout this codebase, so instead I arrange that
+ * only a modules actually needing to use (or define, or initialise)
+ * this function pointer will see its declaration, and _those_ modules
+ * - which will be Windows-specific anyway - can take more care. */
+DECL_WINDOWS_FUNCTION(GLOBAL, int, select,
+		      (int, fd_set FAR *, fd_set FAR *,
+		       fd_set FAR *, const struct timeval FAR *));
+#endif
 
 
 extern int socket_writable(SOCKET skt);
 extern int socket_writable(SOCKET skt);
 
 
@@ -485,6 +510,7 @@ BOOL init_winver(void);
 HMODULE load_system32_dll(const char *libname);
 HMODULE load_system32_dll(const char *libname);
 const char *win_strerror(int error);
 const char *win_strerror(int error);
 void restrict_process_acl(void);
 void restrict_process_acl(void);
+GLOBAL int restricted_acl;
 
 
 /*
 /*
  * Exports from sizetip.c.
  * Exports from sizetip.c.

+ 2 - 0
source/putty/windows/wintime.c

@@ -10,6 +10,8 @@ struct tm ltime(void)
     SYSTEMTIME st;
     SYSTEMTIME st;
     struct tm tm;
     struct tm tm;
 
 
+    memset(&tm, 0, sizeof(tm));        /* in case there are any other fields */
+
     GetLocalTime(&st);
     GetLocalTime(&st);
     tm.tm_sec=st.wSecond;
     tm.tm_sec=st.wSecond;
     tm.tm_min=st.wMinute;
     tm.tm_min=st.wMinute;

+ 1 - 1
source/putty/x11fwd.c

@@ -934,7 +934,7 @@ int x11_send(struct X11Connection *xconn, char *data, int len)
          * Write a new connection header containing our replacement
          * Write a new connection header containing our replacement
          * auth data.
          * auth data.
 	 */
 	 */
-
+        socketdatalen = 0;             /* placate compiler warning */
         socketdata = sk_getxdmdata(xconn->s, &socketdatalen);
         socketdata = sk_getxdmdata(xconn->s, &socketdatalen);
         if (socketdata && socketdatalen==6) {
         if (socketdata && socketdatalen==6) {
             sprintf(new_peer_addr, "%d.%d.%d.%d", socketdata[0],
             sprintf(new_peer_addr, "%d.%d.%d.%d", socketdata[0],