瀏覽代碼

Merge branch 'master' into dev

Source commit: 8f066459fa99121db346a390d116cca7dd74d7bd
Martin Prikryl 8 年之前
父節點
當前提交
1951d03cdf

+ 11 - 10
source/putty/import.c

@@ -1543,18 +1543,14 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
                                       const char **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;
     struct ssh2_userkey *retval = NULL;
     const char *errmsg;
-    unsigned char *blob;
-    int blobsize = 0;
     unsigned checkint0, checkint1;
     const void *priv, *string;
     int privlen, stringlen, key_index;
-    const struct ssh_signkey *alg;
-
-    blob = NULL;
+    const struct ssh_signkey *alg = NULL;
 
     if (!key)
 	return NULL;
@@ -1678,10 +1674,10 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
                            (const unsigned char *)thiskey);
         if (key_index == key->key_wanted) {
             retkey = snew(struct ssh2_userkey);
+            retkey->comment = NULL;
             retkey->alg = alg;
             retkey->data = alg->openssh_createkey(alg, &thiskey, &thiskeylen);
             if (!retkey->data) {
-                sfree(retkey);
                 errmsg = "unable to create key data structure";
                 goto error;
             }
@@ -1718,11 +1714,16 @@ struct ssh2_userkey *openssh_new_read(const Filename *filename,
 
     errmsg = NULL;                     /* no error */
     retval = retkey;
+    retkey = NULL;                     /* prevent the free */
 
     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);
     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) {
-#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
 #endif
 #ifdef va_copy
@@ -1186,6 +1186,17 @@ char *buildinfo(const char *newline)
     strbuf_catf(buf, " (_MSC_VER=%d)", (int)_MSC_VER);
 #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
     strbuf_catf(buf, "%sBuild option: NO_SECURITY", newline);
 #endif

+ 1 - 1
source/putty/proxy.c

@@ -518,7 +518,7 @@ Socket new_connection(SockAddr addr, const char *hostname,
 
         {
             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",
                                proxy_type, addrbuf,
                                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 */
 };
 void set_busy_status(void *frontend, int status);
+int frontend_is_utf8(void *frontend);
 
 void cleanup_exit(int);
 

+ 9 - 4
source/putty/ssh.c

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

+ 6 - 6
source/putty/ssh.h

@@ -157,12 +157,12 @@ const struct ssh_signkey *ec_alg_by_oid(int len, const void *oid,
                                         const struct ec_curve **curve);
 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;
-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;
 

+ 6 - 6
source/putty/sshecc.c

@@ -3024,9 +3024,9 @@ const unsigned char *ec_alg_oid(const struct ssh_signkey *alg,
 const int ec_nist_curve_lengths[] = { 256, 384, 521 };
 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) {
       case 256: *alg = &ssh_ecdsa_nistp256; break;
@@ -3038,9 +3038,9 @@ const int ec_nist_alg_and_curve_by_bits(int bits,
     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) {
       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';
+            sfree(comment);   /* *just* in case of multiple Comment headers */
             comment = dupstr(line);
         } else if (!strcmp(line, "Subject") ||
                    !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)
 {
     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];
     int deferchr;
 
@@ -242,7 +242,7 @@ static void lz77_compress(struct LZ77Context *ctx,
 	    /*
 	     * 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
@@ -267,7 +267,6 @@ static void lz77_compress(struct LZ77Context *ctx,
 	    }
 	} else {
 	    nmatch = 0;
-	    hash = INVALID;
 	}
 
 	if (nmatch > 0) {

+ 5 - 5
source/putty/version.h

@@ -1,6 +1,6 @@
 /* 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

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

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

@@ -533,7 +533,7 @@ void handle_write_eof(struct handle *h)
      * direction!
      */
     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;
         handle_try_output(&h->u.o);
     }

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

@@ -46,6 +46,8 @@ struct Socket_handle_tag {
     /* Data received from stderr_H, if we have one. */
     bufchain stderrdata;
 
+    int defer_close, deferred_close;   /* in case of re-entrance */
+
     char *error;
 
     Plug plug;
@@ -61,7 +63,7 @@ static int handle_gotdata(struct handle *h, void *data, int len)
     } else if (len == 0) {
 	return plug_closing(ps->plug, NULL, 0, 0);
     } else {
-        assert(ps->frozen != FREEZING && ps->frozen != THAWING);
+        assert(ps->frozen != FROZEN && ps->frozen != THAWING);
         if (ps->frozen == FREEZING) {
             /*
              * If we've received data while this socket is supposed to
@@ -70,6 +72,7 @@ static int handle_gotdata(struct handle *h, void *data, int len)
              * the data for when we unfreeze.
              */
             bufchain_add(&ps->inputdata, data, len);
+            ps->frozen = FROZEN;
 
             /*
              * And return a very large backlog, to prevent further
@@ -112,6 +115,11 @@ static void sk_handle_close(Socket s)
 {
     Handle_Socket ps = (Handle_Socket) s;
 
+    if (ps->defer_close) {
+        ps->deferred_close = TRUE;
+        return;
+    }
+
     #ifdef MPEXT
     // WinSCP core uses do_select as signalization of connection up/down
     do_select(ps->plug, INVALID_SOCKET, 0);
@@ -177,9 +185,17 @@ static void handle_socket_unfreeze(void *psv)
     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);
+    bufchain_consume(&ps->inputdata, len);
+    ps->defer_close = FALSE;
+    if (ps->deferred_close) {
+        sk_handle_close(ps);
+        return;
+    }
 
     if (bufchain_size(&ps->inputdata) > 0) {
         /*
@@ -317,6 +333,8 @@ 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, flags);
 
+    ret->defer_close = ret->deferred_close = FALSE;
+
     #ifdef MPEXT
     // WinSCP core uses do_select as signalization of connection up/down
     do_select(plug, INVALID_SOCKET, 1);

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

@@ -5,11 +5,15 @@
  * unfix.org.
  */
 
+#include <winsock2.h> /* need to put this first, for winelib builds */
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
 
 #define DEFINE_PLUG_METHOD_MACROS
+#define NEED_DECLARATION_OF_SELECT     /* in order to initialise it */
+
 #include "putty.h"
 #include "network.h"
 #include "tree234.h"
@@ -21,8 +25,15 @@
 #include <ws2tcpip.h>
 
 #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_loopback = IN6ADDR_LOOPBACK_INIT;
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
 #endif
 
 #define ipv4_is_loopback(addr) \
@@ -237,6 +248,13 @@ int sk_startup(int hi, int lo)
     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)
 {
 #ifndef NO_IPV6

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

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

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

@@ -104,9 +104,17 @@ PSID get_user_sid(void)
 
 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 nt_auth = SECURITY_NT_AUTHORITY;
-    int ret;
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+    int ret = FALSE;
 
     *error = NULL;
 

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

@@ -125,7 +125,7 @@ void *open_settings_w(const char *sessionname, char **errmsg)
 void write_setting_s(void *handle, const char *key, const char *value)
 {
     if (handle)
-	RegSetValueEx((HKEY) handle, key, 0, REG_SZ, value,
+	RegSetValueEx((HKEY) handle, key, 0, REG_SZ, (CONST BYTE *)value,
 		      1 + strlen(value));
 }
 
@@ -183,7 +183,7 @@ char *read_setting_s(void *handle, const char *key)
     allocsize = size+1;         /* allow for an extra NUL if needed */
     ret = snewn(allocsize, char);
     if (RegQueryValueEx((HKEY) handle, key, 0,
-			&type, ret, &size) != ERROR_SUCCESS ||
+			&type, (BYTE *)ret, &size) != ERROR_SUCCESS ||
 	type != REG_SZ) {
         sfree(ret);
         return NULL;
@@ -396,7 +396,8 @@ int verify_host_key(const char *hostname, int port,
 
     readlen = len;
     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 &&
 	!strcmp(keytype, "rsa")) {
@@ -409,7 +410,7 @@ int verify_host_key(const char *hostname, int port,
 	char *oldstyle = snewn(len + 10, char);	/* safety margin */
 	readlen = len;
 	ret = RegQueryValueEx(rkey, justhost, NULL, &type,
-			      oldstyle, &readlen);
+			      (BYTE *)oldstyle, &readlen);
 
 	if (ret == ERROR_SUCCESS && type == REG_SZ) {
 	    /*
@@ -455,7 +456,7 @@ int verify_host_key(const char *hostname, int port,
 	     * wrong, and hyper-cautiously do nothing.
 	     */
 	    if (!strcmp(otherstr, key))
-		RegSetValueEx(rkey, regname, 0, REG_SZ, otherstr,
+		RegSetValueEx(rkey, regname, 0, REG_SZ, (BYTE *)otherstr,
 			      strlen(otherstr) + 1);
 	}
 
@@ -515,7 +516,7 @@ void store_host_key(const char *hostname, int port,
 
     if (RegCreateKey(HKEY_CURRENT_USER, PUTTY_REG_POS "\\SshHostKeys",
 		     &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);
     } /* else key does not exist in registry */
 
@@ -575,7 +576,7 @@ static HANDLE access_random_seed(int action)
     if (RegOpenKey(HKEY_CURRENT_USER, PUTTY_REG_POS, &rkey) ==
 	ERROR_SUCCESS) {
 	int ret = RegQueryValueEx(rkey, "RandSeedFile",
-				  0, &type, seedpath, &size);
+				  0, &type, (BYTE *)seedpath, &size);
 	if (ret != ERROR_SUCCESS || type != REG_SZ)
 	    seedpath[0] = '\0';
 	RegCloseKey(rkey);
@@ -711,7 +712,7 @@ static int transform_jumplist_registry
     value_length = 200;
     old_value = snewn(value_length, char);
     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
      * returned and the required size is returned in the length
      * argument. */
@@ -719,7 +720,7 @@ static int transform_jumplist_registry
         sfree(old_value);
         old_value = snewn(value_length, char);
         ret = RegQueryValueEx(pjumplist_key, reg_jumplist_value, NULL, &type,
-                              old_value, &value_length);
+                              (BYTE *)old_value, &value_length);
     }
 
     if (ret == ERROR_FILE_NOT_FOUND) {
@@ -793,7 +794,7 @@ static int transform_jumplist_registry
 
         /* Save the new list to the registry. */
         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);
         old_value = new_value;

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

@@ -96,10 +96,30 @@ struct FontSpec *fontspec_new(const char *name,
 #define BOXRESULT (DLGWINDOWEXTRA + sizeof(LONG_PTR))
 #define DF_END 0x0001
 
+#ifdef __WINE__
+#define NO_SECUREZEROMEMORY            /* winelib doesn't have this */
+#endif
+
 #ifndef NO_SECUREZEROMEMORY
 #define PLATFORM_HAS_SMEMCLR /* inhibit cross-platform one in misc.c */
 #endif
 
+#ifndef __WINE__
+#ifdef MPEXT
+/* use them as is in bcb */
+#else
+/* Up-to-date Windows headers warn that the unprefixed versions of
+ * these names are deprecated. */
+#define stricmp _stricmp
+#define strnicmp _strnicmp
+#endif
+#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 */
 
 /*
@@ -278,12 +298,21 @@ DECL_WINDOWS_FUNCTION(GLOBAL, int, WSAAsyncSelect,
 		      (SOCKET, HWND, u_int, long));
 DECL_WINDOWS_FUNCTION(GLOBAL, int, WSAEventSelect,
 		      (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, WSAEnumNetworkEvents,
 		      (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);
 
@@ -492,6 +521,7 @@ BOOL init_winver(void);
 HMODULE load_system32_dll(const char *libname);
 const char *win_strerror(int error);
 void restrict_process_acl(void);
+GLOBAL int restricted_acl;
 
 /*
  * Exports from sizetip.c.

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

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

+ 1 - 1
source/putty/x11fwd.c

@@ -938,7 +938,7 @@ int x11_send(struct X11Connection *xconn, char *data, int len)
          * Write a new connection header containing our replacement
          * auth data.
 	 */
-
+        socketdatalen = 0;             /* placate compiler warning */
         #ifdef MPEXT
         // placate compiler warning
         socketdatalen = 0;