Browse Source

Merge branch 'master' into dev

# Conflicts:
#	source/putty/WINDOWS/winhsock.c
#	source/putty/WINDOWS/winnet.c

Source commit: a66d8544dbce33e8e07a1d1a790b8d8f93cd6cad
Martin Prikryl 8 years ago
parent
commit
21c46e44d7

+ 2 - 6
source/core/SecureShell.cpp

@@ -1851,12 +1851,8 @@ void __fastcall TSecureShell::HandleNetworkEvents(SOCKET Socket, WSANETWORKEVENT
       #pragma option push -w-prc
       LPARAM SelectEvent = WSAMAKESELECTREPLY(EventTypes[Event].Mask, Err);
       #pragma option pop
-      if (!select_result((WPARAM)Socket, SelectEvent))
-      {
-        // note that connection was closed definitely,
-        // so "check" is actually not required
-        CheckConnection();
-      }
+      select_result((WPARAM)Socket, SelectEvent);
+      CheckConnection();
     }
   }
 }

+ 2 - 1
source/putty/import.c

@@ -445,7 +445,7 @@ static struct openssh_pem_key *load_openssh_pem_key(const Filename *filename,
 		if (!strcmp(p, "ENCRYPTED"))
 		    ret->encrypted = TRUE;
 	    } else if (!strcmp(line, "DEK-Info")) {
-		int i, j, ivlen;
+		int i, ivlen;
 
 		if (!strncmp(p, "DES-EDE3-CBC,", 13)) {
 		    ret->encryption = OP_E_3DES;
@@ -459,6 +459,7 @@ static struct openssh_pem_key *load_openssh_pem_key(const Filename *filename,
 		}
 		p = strchr(p, ',') + 1;/* always non-NULL, by above checks */
 		for (i = 0; i < ivlen; i++) {
+                    unsigned j;
 		    if (1 != sscanf(p, "%2x", &j)) {
 			errmsg = "expected more iv data in DEK-Info";
 			goto error;

+ 22 - 6
source/putty/misc.c

@@ -157,7 +157,8 @@ int main(void)
             passes++;                                                   \
         } else {                                                        \
             printf("fail: %s(%s,%s)%s = %u, expected %u\n",             \
-                   #func, #string, #arg2, #suffix, ret, result);        \
+                   #func, #string, #arg2, #suffix, ret,                 \
+                   (unsigned)result);                                   \
             fails++;                                                    \
         }                                                               \
 } while (0)
@@ -1168,11 +1169,21 @@ char *buildinfo(const char *newline)
                 BUILDINFO_PLATFORM);
 
 #ifdef __clang_version__
+#define FOUND_COMPILER
     strbuf_catf(buf, "%sCompiler: clang %s", newline, __clang_version__);
 #elif defined __GNUC__ && defined __VERSION__
+#define FOUND_COMPILER
     strbuf_catf(buf, "%sCompiler: gcc %s", newline, __VERSION__);
-#elif defined _MSC_VER
-    strbuf_catf(buf, "%sCompiler: Visual Studio", newline);
+#endif
+
+#if defined _MSC_VER
+#ifndef FOUND_COMPILER
+#define FOUND_COMPILER
+    strbuf_catf(buf, "%sCompiler: ", newline);
+#else
+    strbuf_catf(buf, ", emulating ");
+#endif
+    strbuf_catf(buf, "Visual Studio", newline);
 #if _MSC_VER == 1900
     strbuf_catf(buf, " 2015 / MSVC++ 14.0");
 #elif _MSC_VER == 1800
@@ -1181,12 +1192,14 @@ char *buildinfo(const char *newline)
     strbuf_catf(buf, " 2012 / MSVC++ 11.0");
 #elif _MSC_VER == 1600
     strbuf_catf(buf, " 2010 / MSVC++ 10.0");
-#elif  _MSC_VER == 1500
+#elif _MSC_VER == 1500
     strbuf_catf(buf, " 2008 / MSVC++ 9.0");
-#elif  _MSC_VER == 1400
+#elif _MSC_VER == 1400
     strbuf_catf(buf, " 2005 / MSVC++ 8.0");
-#elif  _MSC_VER == 1310
+#elif _MSC_VER == 1310
     strbuf_catf(buf, " 2003 / MSVC++ 7.1");
+#elif _MSC_VER == 1300
+    strbuf_catf(buf, " 2003 / MSVC++ 7.0");
 #else
     strbuf_catf(buf, ", unrecognised version");
 #endif
@@ -1204,6 +1217,9 @@ char *buildinfo(const char *newline)
     }
 #endif
 
+#if defined _WINDOWS && defined MINEFIELD
+    strbuf_catf(buf, "%sBuild option: MINEFIELD", newline);
+#endif
 #ifdef NO_SECURITY
     strbuf_catf(buf, "%sBuild option: NO_SECURITY", newline);
 #endif

+ 2 - 2
source/putty/network.h

@@ -64,12 +64,12 @@ struct plug_function_table {
      *    proxy command, so the receiver should probably prefix it to
      *    indicate this.
      */
-    int (*closing)
+    void (*closing)
      (Plug p, const char *error_msg, int error_code, int calling_back);
     /* error_msg is NULL iff it is not an error (ie it closed normally) */
     /* calling_back != 0 iff there is a Plug function */
     /* currently running (would cure the fixme in try_send()) */
-    int (*receive) (Plug p, int urgent, char *data, int len);
+    void (*receive) (Plug p, int urgent, char *data, int len);
     /*
      *  - urgent==0. `data' points to `len' bytes of perfectly
      *    ordinary data.

+ 11 - 15
source/putty/portfwd.c

@@ -117,8 +117,8 @@ static void pfl_log(Plug plug, int type, SockAddr addr, int port,
     /* we have to dump these since we have no interface to logging.c */
 }
 
-static int pfd_closing(Plug plug, const char *error_msg, int error_code,
-		       int calling_back)
+static void pfd_closing(Plug plug, const char *error_msg, int error_code,
+			int calling_back)
 {
     struct PortForwarding *pf = (struct PortForwarding *) plug;
 
@@ -145,16 +145,13 @@ static int pfd_closing(Plug plug, const char *error_msg, int error_code,
         if (pf->c)
             sshfwd_write_eof(pf->c);
     }
-
-    return 1;
 }
 
-static int pfl_closing(Plug plug, const char *error_msg, int error_code,
-		       int calling_back)
+static void pfl_closing(Plug plug, const char *error_msg, int error_code,
+			int calling_back)
 {
     struct PortListener *pl = (struct PortListener *) plug;
     pfl_terminate(pl);
-    return 1;
 }
 
 static void wrap_send_port_open(void *channel, const char *hostname, int port,
@@ -172,7 +169,7 @@ static void wrap_send_port_open(void *channel, const char *hostname, int port,
     sfree(description);
 }
 
-static int pfd_receive(Plug plug, int urgent, char *data, int len)
+static void pfd_receive(Plug plug, int urgent, char *data, int len)
 {
     struct PortForwarding *pf = (struct PortForwarding *) plug;
     if (pf->dynamic) {
@@ -204,7 +201,7 @@ static int pfd_receive(Plug plug, int urgent, char *data, int len)
 		    data[1] = 91;      /* generic `request rejected' */
 		    sk_write(pf->s, data, 8);
 		    pfd_close(pf);
-		    return 1;
+		    return;
 		}
 		if (pf->sockslen <= 8)
                     continue;      /* haven't started user/hostname */
@@ -320,7 +317,7 @@ static int pfd_receive(Plug plug, int urgent, char *data, int len)
 			reply[1] = 1;	/* generic failure */
 			sk_write(pf->s, (char *) reply, lenof(reply));
 			pfd_close(pf);
-			return 1;
+			return;
 		    }
 		    /*
 		     * Now we have a viable connect request. Switch
@@ -350,7 +347,7 @@ static int pfd_receive(Plug plug, int urgent, char *data, int len)
 			reply[1] = 8;	/* atype not supported */
 			sk_write(pf->s, (char *) reply, lenof(reply));
 			pfd_close(pf);
-			return 1;
+			return;
 		    }
 		}
 	    }
@@ -362,9 +359,9 @@ static int pfd_receive(Plug plug, int urgent, char *data, int len)
 	     * close the connection rudely.
 	     */
 	    pfd_close(pf);
-	    return 1;
+            break;
 	}
-	return 1;
+	return;
 
 	/*
 	 * We come here when we're ready to make an actual
@@ -383,7 +380,7 @@ static int pfd_receive(Plug plug, int urgent, char *data, int len)
 	pf->c = new_sock_channel(pf->backhandle, pf);
 	if (pf->c == NULL) {
 	    pfd_close(pf);
-	    return 1;
+	    return;
 	} else {
 	    /* asks to forward to the specified host/port for this */
 	    wrap_send_port_open(pf->c, pf->hostname, pf->port, pf->s);
@@ -406,7 +403,6 @@ static int pfd_receive(Plug plug, int urgent, char *data, int len)
 	    sk_set_frozen(pf->s, 1);
 	}
     }
-    return 1;
 }
 
 static void pfd_sent(Plug plug, int bufsize)

+ 21 - 20
source/putty/proxy.c

@@ -201,8 +201,8 @@ static void plug_proxy_log(Plug plug, int type, SockAddr addr, int port,
     plug_log(ps->plug, type, addr, port, error_msg, error_code);
 }
 
-static int plug_proxy_closing (Plug p, const char *error_msg,
-			       int error_code, int calling_back)
+static void plug_proxy_closing (Plug p, const char *error_msg,
+				int error_code, int calling_back)
 {
     Proxy_Plug pp = (Proxy_Plug) p;
     Proxy_Socket ps = pp->proxy_socket;
@@ -211,13 +211,13 @@ static int plug_proxy_closing (Plug p, const char *error_msg,
 	ps->closing_error_msg = error_msg;
 	ps->closing_error_code = error_code;
 	ps->closing_calling_back = calling_back;
-	return ps->negotiate(ps, PROXY_CHANGE_CLOSING);
+	ps->negotiate(ps, PROXY_CHANGE_CLOSING);
+    } else {
+        plug_closing(ps->plug, error_msg, error_code, calling_back);
     }
-    return plug_closing(ps->plug, error_msg,
-			error_code, calling_back);
 }
 
-static int plug_proxy_receive (Plug p, int urgent, char *data, int len)
+static void plug_proxy_receive (Plug p, int urgent, char *data, int len)
 {
     Proxy_Plug pp = (Proxy_Plug) p;
     Proxy_Socket ps = pp->proxy_socket;
@@ -231,9 +231,10 @@ static int plug_proxy_receive (Plug p, int urgent, char *data, int len)
 	ps->receive_urgent = urgent;
 	ps->receive_data = data;
 	ps->receive_len = len;
-	return ps->negotiate(ps, PROXY_CHANGE_RECEIVE);
+	ps->negotiate(ps, PROXY_CHANGE_RECEIVE);
+    } else {
+        plug_receive(ps->plug, urgent, data, len);
     }
-    return plug_receive(ps->plug, urgent, data, len);
 }
 
 static void plug_proxy_sent (Plug p, int bufsize)
@@ -652,9 +653,9 @@ int proxy_http_negotiate (Proxy_Socket p, int change)
 	 * a socket close, then some error must have occurred. we'll
 	 * just pass those errors up to the backend.
 	 */
-	return plug_closing(p->plug, p->closing_error_msg,
-			    p->closing_error_code,
-			    p->closing_calling_back);
+	plug_closing(p->plug, p->closing_error_msg, p->closing_error_code,
+		     p->closing_calling_back);
+	return 0; /* ignored */
     }
 
     if (change == PROXY_CHANGE_SENT) {
@@ -855,9 +856,9 @@ int proxy_socks4_negotiate (Proxy_Socket p, int change)
 	 * a socket close, then some error must have occurred. we'll
 	 * just pass those errors up to the backend.
 	 */
-	return plug_closing(p->plug, p->closing_error_msg,
-			    p->closing_error_code,
-			    p->closing_calling_back);
+	plug_closing(p->plug, p->closing_error_msg, p->closing_error_code,
+		     p->closing_calling_back);
+	return 0; /* ignored */
     }
 
     if (change == PROXY_CHANGE_SENT) {
@@ -995,9 +996,9 @@ int proxy_socks5_negotiate (Proxy_Socket p, int change)
 	 * a socket close, then some error must have occurred. we'll
 	 * just pass those errors up to the backend.
 	 */
-	return plug_closing(p->plug, p->closing_error_msg,
-			    p->closing_error_code,
-			    p->closing_calling_back);
+        plug_closing(p->plug, p->closing_error_msg, p->closing_error_code,
+		     p->closing_calling_back);
+	return 0; /* ignored */
     }
 
     if (change == PROXY_CHANGE_SENT) {
@@ -1569,9 +1570,9 @@ int proxy_telnet_negotiate (Proxy_Socket p, int change)
 	 * a socket close, then some error must have occurred. we'll
 	 * just pass those errors up to the backend.
 	 */
-	return plug_closing(p->plug, p->closing_error_msg,
-			    p->closing_error_code,
-			    p->closing_calling_back);
+	plug_closing(p->plug, p->closing_error_msg, p->closing_error_code,
+		     p->closing_calling_back);
+	return 0; /* ignored */
     }
 
     if (change == PROXY_CHANGE_SENT) {

+ 1 - 1
source/putty/puttyexp.h

@@ -55,7 +55,7 @@ void putty_unmungestr(const char *in, char *out, int outlen);
 
 // from winnet.c
 
-int select_result(WPARAM wParam, LPARAM lParam);
+void select_result(WPARAM wParam, LPARAM lParam);
 
 // from sshzlib.c
 

+ 46 - 26
source/putty/ssh.c

@@ -303,7 +303,7 @@ enum {
  * macros look impenetrable to you, you might find it helpful to
  * read
  *
- *   http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
+ *   https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
  *
  * which explains the theory behind these macros.
  *
@@ -3570,8 +3570,8 @@ void ssh_connshare_log(Ssh ssh, int event, const char *logtext,
     }
 }
 
-static int ssh_closing(Plug plug, const char *error_msg, int error_code,
-		       int calling_back)
+static void ssh_closing(Plug plug, const char *error_msg, int error_code,
+			int calling_back)
 {
     Ssh ssh = (Ssh) plug;
     int need_notify = ssh_do_close(ssh, FALSE);
@@ -3593,18 +3593,15 @@ static int ssh_closing(Plug plug, const char *error_msg, int error_code,
 	logevent(error_msg);
     if (!ssh->close_expected || !ssh->clean_exit)
 	connection_fatal(ssh->frontend, "%s", error_msg);
-    return 0;
 }
 
-static int ssh_receive(Plug plug, int urgent, char *data, int len)
+static void ssh_receive(Plug plug, int urgent, char *data, int len)
 {
     Ssh ssh = (Ssh) plug;
     ssh_gotdata(ssh, (unsigned char *)data, len);
     if (ssh->state == SSH_STATE_CLOSED) {
 	ssh_do_close(ssh, TRUE);
-	return 0;
     }
-    return 1;
 }
 
 static void ssh_sent(Plug plug, int bufsize)
@@ -8524,18 +8521,37 @@ static void ssh2_msg_channel_open_confirmation(Ssh ssh, struct Packet *pktin)
         ssh_channel_try_eof(c);        /* in case we had a pending EOF */
 }
 
-static void ssh2_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
+static char *ssh2_channel_open_failure_error_text(struct Packet *pktin)
 {
     static const char *const reasons[] = {
-	"<unknown reason code>",
-	    "Administratively prohibited",
-	    "Connect failed",
-	    "Unknown channel type",
-	    "Resource shortage",
+        NULL,
+        "Administratively prohibited",
+        "Connect failed",
+        "Unknown channel type",
+        "Resource shortage",
     };
     unsigned reason_code;
+    const char *reason_code_string;
+    char reason_code_buf[256];
     char *reason_string;
     int reason_length;
+
+    reason_code = ssh_pkt_getuint32(pktin);
+    if (reason_code < lenof(reasons) && reasons[reason_code]) {
+        reason_code_string = reasons[reason_code];
+    } else {
+        reason_code_string = reason_code_buf;
+        sprintf(reason_code_buf, "unknown reason code %#x", reason_code);
+    }
+
+    ssh_pkt_getstring(pktin, &reason_string, &reason_length);
+
+    return dupprintf("%s [%.*s]", reason_code_string,
+                     reason_length, NULLTOEMPTY(reason_string));
+}
+
+static void ssh2_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
+{
     struct ssh_channel *c;
 
     c = ssh_channel_msg(ssh, pktin);
@@ -8544,14 +8560,9 @@ static void ssh2_msg_channel_open_failure(Ssh ssh, struct Packet *pktin)
     assert(c->halfopen); /* ssh_channel_msg will have enforced this */
 
     if (c->type == CHAN_SOCKDATA) {
-        reason_code = ssh_pkt_getuint32(pktin);
-        if (reason_code >= lenof(reasons))
-            reason_code = 0; /* ensure reasons[reason_code] in range */
-        ssh_pkt_getstring(pktin, &reason_string, &reason_length);
-        logeventf(ssh, "Forwarded connection refused by server: %s [%.*s]",
-                  reasons[reason_code], reason_length,
-                  NULLTOEMPTY(reason_string));
-
+        char *errtext = ssh2_channel_open_failure_error_text(pktin);
+        logeventf(ssh, "Forwarded connection refused by server: %s", errtext);
+        sfree(errtext);
         pfd_close(c->u.pfd.pf);
     } else if (c->type == CHAN_ZOMBIE) {
         /*
@@ -10818,15 +10829,24 @@ static void do_ssh2_authconn(Ssh ssh, const unsigned char *in, int inlen,
 	    ssh->ncmode = FALSE;
 	}
 	crWaitUntilV(pktin);
-	if (pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION) {
-	    bombout(("Server refused to open channel"));
+        if (pktin->type != SSH2_MSG_CHANNEL_OPEN_CONFIRMATION &&
+            pktin->type != SSH2_MSG_CHANNEL_OPEN_FAILURE) {
+            bombout(("Server sent strange packet %d in response to main "
+                     "channel open request", pktin->type));
 	    crStopV;
-	    /* FIXME: error data comes back in FAILURE packet */
-	}
+        }
 	if (ssh_pkt_getuint32(pktin) != ssh->mainchan->localid) {
-	    bombout(("Server's channel confirmation cited wrong channel"));
+	    bombout(("Server's response to main channel open cited wrong"
+                     " channel number"));
+	    crStopV;
+	}
+	if (pktin->type == SSH2_MSG_CHANNEL_OPEN_FAILURE) {
+            char *errtext = ssh2_channel_open_failure_error_text(pktin);
+            bombout(("Server refused to open main channel: %s", errtext));
+            sfree(errtext);
 	    crStopV;
 	}
+
 	ssh->mainchan->remoteid = ssh_pkt_getuint32(pktin);
 	ssh->mainchan->halfopen = FALSE;
 	ssh->mainchan->type = CHAN_MAINSESSION;

+ 11 - 14
source/putty/sshshare.c

@@ -911,8 +911,8 @@ static void share_disconnect(struct ssh_sharing_connstate *cs,
     share_begin_cleanup(cs);
 }
 
-static int share_closing(Plug plug, const char *error_msg, int error_code,
-                         int calling_back)
+static void share_closing(Plug plug, const char *error_msg, int error_code,
+			  int calling_back)
 {
     struct ssh_sharing_connstate *cs = (struct ssh_sharing_connstate *)plug;
 
@@ -935,7 +935,6 @@ static int share_closing(Plug plug, const char *error_msg, int error_code,
                              "Socket error: %s", error_msg);
     }
     share_begin_cleanup(cs);
-    return 1;
 }
 
 static int getstring_inner(const void *vdata, int datalen,
@@ -1775,17 +1774,17 @@ static void share_got_pkt_from_downstream(struct ssh_sharing_connstate *cs,
  * Coroutine macros similar to, but simplified from, those in ssh.c.
  */
 #define crBegin(v)	{ int *crLine = &v; switch(v) { case 0:;
-#define crFinish(z)	} *crLine = 0; return (z); }
+#define crFinishV	} *crLine = 0; return; }
 #define crGetChar(c) do                                         \
     {                                                           \
         while (len == 0) {                                      \
-            *crLine =__LINE__; return 1; case __LINE__:;        \
+            *crLine =__LINE__; return; case __LINE__:;          \
         }                                                       \
         len--;                                                  \
         (c) = (unsigned char)*data++;                           \
     } while (0)
 
-static int share_receive(Plug plug, int urgent, char *data, int len)
+static void share_receive(Plug plug, int urgent, char *data, int len)
 {
     struct ssh_sharing_connstate *cs = (struct ssh_sharing_connstate *)plug;
     static const char expected_verstring_prefix[] =
@@ -1858,7 +1857,7 @@ static int share_receive(Plug plug, int urgent, char *data, int len)
     }
 
   dead:;
-    crFinish(1);
+    crFinishV;
 }
 
 static void share_sent(Plug plug, int bufsize)
@@ -1875,8 +1874,8 @@ static void share_sent(Plug plug, int bufsize)
      */
 }
 
-static int share_listen_closing(Plug plug, const char *error_msg,
-                                int error_code, int calling_back)
+static void share_listen_closing(Plug plug, const char *error_msg,
+				 int error_code, int calling_back)
 {
     struct ssh_sharing_state *sharestate = (struct ssh_sharing_state *)plug;
     if (error_msg)
@@ -1884,7 +1883,6 @@ static int share_listen_closing(Plug plug, const char *error_msg,
                          "listening socket: %s", error_msg);
     sk_close(sharestate->listensock);
     sharestate->listensock = NULL;
-    return 1;
 }
 
 static void share_send_verstring(struct ssh_sharing_connstate *cs)
@@ -2047,10 +2045,9 @@ char *ssh_share_sockname(const char *host, int port, Conf *conf)
 
 static void nullplug_socket_log(Plug plug, int type, SockAddr addr, int port,
                                 const char *error_msg, int error_code) {}
-static int nullplug_closing(Plug plug, const char *error_msg, int error_code,
-                            int calling_back) { return 0; }
-static int nullplug_receive(Plug plug, int urgent, char *data,
-                            int len) { return 0; }
+static void nullplug_closing(Plug plug, const char *error_msg, int error_code,
+			     int calling_back) {}
+static void nullplug_receive(Plug plug, int urgent, char *data, int len) {}
 static void nullplug_sent(Plug plug, int bufsize) {}
 
 int ssh_share_test_for_upstream(const char *host, int port, Conf *conf)

+ 1 - 1
source/putty/tree234.c

@@ -681,7 +681,7 @@ static void *delpos234_internal(tree234 * t, int index)
 	    LOG(("  moving to subtree %d\n", ki));
 	    sub = n->kids[ki];
 	    if (!sub->elems[1]) {
-		LOG(("  subtree has only one element!\n", ki));
+		LOG(("  subtree has only one element!\n"));
 		if (ki > 0 && n->kids[ki - 1]->elems[1]) {
 		    /*
 		     * Case 3a, left-handed variant. Child ki has

+ 5 - 5
source/putty/version.h

@@ -1,6 +1,6 @@
 /* Generated by automated build script */
-#define RELEASE 0.69
-#define TEXTVER "Release 0.69"
-#define SSHVER "PuTTY-Release-0.69"
-#define BINARY_VERSION 0,69,0,0
-#define SOURCE_COMMIT "b1829b81b5c0d12dcc91f6b50b0b4d83c3df6a8e"
+#define RELEASE 0.70
+#define TEXTVER "Release 0.70"
+#define SSHVER "PuTTY-Release-0.70"
+#define BINARY_VERSION 0,70,0,0
+#define SOURCE_COMMIT "3cd10509a51edf5a21cdc80aabf7e6a934522d47"

+ 12 - 9
source/putty/windows/winhsock.c

@@ -58,10 +58,11 @@ static int handle_gotdata(struct handle *h, void *data, int len)
     Handle_Socket ps = (Handle_Socket) handle_get_privdata(h);
 
     if (len < 0) {
-	return plug_closing(ps->plug, "Read error from handle",
-			    0, 0);
+	plug_closing(ps->plug, "Read error from handle", 0, 0);
+	return 0;
     } else if (len == 0) {
-	return plug_closing(ps->plug, NULL, 0, 0);
+	plug_closing(ps->plug, NULL, 0, 0);
+	return 0;
     } else {
         assert(ps->frozen != FROZEN && ps->frozen != THAWING);
         if (ps->frozen == FREEZING) {
@@ -80,7 +81,8 @@ static int handle_gotdata(struct handle *h, void *data, int len)
              */
             return INT_MAX;
         } else {
-            return plug_receive(ps->plug, 0, data, len);
+            plug_receive(ps->plug, 0, data, len);
+	    return 0;
         }
     }
 }
@@ -177,7 +179,7 @@ static void handle_socket_unfreeze(void *psv)
 {
     Handle_Socket ps = (Handle_Socket) psv;
     void *data;
-    int len, new_backlog;
+    int len;
 
     /*
      * If we've been put into a state other than THAWING since the
@@ -197,7 +199,7 @@ static void handle_socket_unfreeze(void *psv)
      * have the effect of trying to close this socket.
      */
     ps->defer_close = TRUE;
-    new_backlog = plug_receive(ps->plug, 0, data, len);
+    plug_receive(ps->plug, 0, data, len);
     bufchain_consume(&ps->inputdata, len);
     ps->defer_close = FALSE;
     if (ps->deferred_close) {
@@ -216,7 +218,7 @@ static void handle_socket_unfreeze(void *psv)
          * Otherwise, we've successfully thawed!
          */
         ps->frozen = UNFROZEN;
-        handle_unthrottle(ps->recv_h, new_backlog);
+        handle_unthrottle(ps->recv_h, 0);
     }
 }
 
@@ -291,10 +293,11 @@ static char *sk_handle_peer_info(Socket s)
 
     if (!kernel32_module) {
         kernel32_module = load_system32_dll("kernel32.dll");
-#if (defined _MSC_VER && _MSC_VER < 1900) || defined __MINGW32__
+#if (defined _MSC_VER && _MSC_VER < 1900) || defined __MINGW32__ || defined COVERITY
         /* For older Visual Studio, and MinGW too (at least as of
          * Ubuntu 16.04), this function isn't available in the header
-         * files to type-check */
+         * files to type-check. Ditto the toolchain I use for
+         * Coveritying the Windows code. */
         GET_WINDOWS_FUNCTION_NO_TYPECHECK(
             kernel32_module, GetNamedPipeClientProcessId);
 #else

+ 5 - 3
source/putty/windows/winmisc.c

@@ -214,9 +214,11 @@ void dll_hijacking_protection(void)
 
     if (!kernel32_module) {
         kernel32_module = load_system32_dll("kernel32.dll");
-#if (defined _MSC_VER && _MSC_VER < 1900) || defined MPEXT
-        /* For older Visual Studio, this function isn't available in
-         * the header files to type-check */
+#if (defined _MSC_VER && _MSC_VER < 1900) || defined COVERITY || defined MPEXT
+        /* For older Visual Studio, and also for the system I
+         * currently use for Coveritying the Windows code, this
+         * function isn't available in the header files to
+         * type-check */
         GET_WINDOWS_FUNCTION_NO_TYPECHECK(
             kernel32_module, SetDefaultDllDirectories);
 #else

+ 25 - 21
source/putty/windows/winnet.c

@@ -319,11 +319,21 @@ void sk_init(void)
     GET_WINDOWS_FUNCTION(winsock_module, WSAStartup);
     GET_WINDOWS_FUNCTION(winsock_module, WSACleanup);
     GET_WINDOWS_FUNCTION(winsock_module, closesocket);
+#ifndef COVERITY
     GET_WINDOWS_FUNCTION(winsock_module, ntohl);
     GET_WINDOWS_FUNCTION(winsock_module, htonl);
     GET_WINDOWS_FUNCTION(winsock_module, htons);
     GET_WINDOWS_FUNCTION(winsock_module, ntohs);
     GET_WINDOWS_FUNCTION(winsock_module, gethostname);
+#else
+    /* The toolchain I use for Windows Coverity builds doesn't know
+     * the type signatures of these */
+    GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, ntohl);
+    GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, htonl);
+    GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, htons);
+    GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, ntohs);
+    GET_WINDOWS_FUNCTION_NO_TYPECHECK(winsock_module, gethostname);
+#endif
     GET_WINDOWS_FUNCTION(winsock_module, gethostbyname);
     GET_WINDOWS_FUNCTION(winsock_module, getservbyname);
     GET_WINDOWS_FUNCTION(winsock_module, inet_addr);
@@ -567,7 +577,7 @@ SockAddr sk_namelookup(const char *host, char **canonicalname,
 
     if ((a = p_inet_addr(host)) == (unsigned long) INADDR_NONE) {
 	struct hostent *h = NULL;
-	int err;
+	int err = 0;
 #ifndef NO_IPV6
 	/*
 	 * Use getaddrinfo when it's available
@@ -1742,9 +1752,9 @@ static void sk_tcp_write_eof(Socket sock)
 	try_send(s);
 }
 
-int select_result(WPARAM wParam, LPARAM lParam)
+void select_result(WPARAM wParam, LPARAM lParam)
 {
-    int ret, open;
+    int ret;
     DWORD err;
     char buf[20480];		       /* nice big buffer for plenty of speed */
     Actual_Socket s;
@@ -1753,11 +1763,11 @@ int select_result(WPARAM wParam, LPARAM lParam)
     /* wParam is the socket itself */
 
     if (wParam == 0)
-	return 1;		       /* boggle */
+	return;		       /* boggle */
 
     s = find234(sktree, (void *) wParam, cmpforsearch);
     if (!s)
-	return 1;		       /* boggle */
+	return;		       /* boggle */
 
     if ((err = WSAGETSELECTERROR(lParam)) != 0) {
 	/*
@@ -1779,10 +1789,9 @@ int select_result(WPARAM wParam, LPARAM lParam)
 	}
 	if (err != 0)
 	{
-	    return plug_closing(s->plug, winsock_error_string(err), err, 0);
+	    plug_closing(s->plug, winsock_error_string(err), err, 0);
+	    return;
 	}
-	else
-	    return 1;
     }
 
     noise_ultralight(lParam);
@@ -1835,12 +1844,11 @@ int select_result(WPARAM wParam, LPARAM lParam)
 	    }
 	}
 	if (ret < 0) {
-	    return plug_closing(s->plug, winsock_error_string(err), err,
-				0);
+	    plug_closing(s->plug, winsock_error_string(err), err, 0);
 	} else if (0 == ret) {
-	    return plug_closing(s->plug, NULL, 0, 0);
+	    plug_closing(s->plug, NULL, 0, 0);
 	} else {
-	    return plug_receive(s->plug, atmark ? 0 : 1, buf, ret);
+	    plug_receive(s->plug, atmark ? 0 : 1, buf, ret);
 	}
 	break;
       case FD_OOB:
@@ -1860,7 +1868,7 @@ int select_result(WPARAM wParam, LPARAM lParam)
 	    logevent(NULL, str);
 	    fatalbox("%s", str);
 	} else {
-	    return plug_receive(s->plug, 2, buf, ret);
+	    plug_receive(s->plug, 2, buf, ret);
 	}
 	break;
       case FD_WRITE:
@@ -1876,25 +1884,23 @@ int select_result(WPARAM wParam, LPARAM lParam)
 	break;
       case FD_CLOSE:
 	/* Signal a close on the socket. First read any outstanding data. */
-	open = 1;
 	do {
 	    ret = p_recv(s->s, buf, sizeof(buf), 0);
 	    if (ret < 0) {
 		err = p_WSAGetLastError();
 		if (err == WSAEWOULDBLOCK)
 		    break;
-		return plug_closing(s->plug, winsock_error_string(err),
-				    err, 0);
+		plug_closing(s->plug, winsock_error_string(err), err, 0);
 	    } else {
 		if (ret)
-		    open &= plug_receive(s->plug, 0, buf, ret);
+		    plug_receive(s->plug, 0, buf, ret);
 		else
 		{
-		    open &= plug_closing(s->plug, NULL, 0, 0);
+		    plug_closing(s->plug, NULL, 0, 0);
 		}
 	    }
 	} while (ret > 0);
-	return open;
+	return;
        case FD_ACCEPT:
 	{
 #ifdef NO_IPV6
@@ -1932,8 +1938,6 @@ int select_result(WPARAM wParam, LPARAM lParam)
 	    }
 	}
     }
-
-    return 1;
 }
 
 /*

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

@@ -19,7 +19,7 @@
  * stddef.h. So here we try to make sure _some_ standard header is
  * included which defines uintptr_t. */
 #include <stddef.h>
-#if !defined _MSC_VER || _MSC_VER >= 1600
+#if !defined _MSC_VER || _MSC_VER >= 1600 || defined __clang__
 #include <stdint.h>
 #endif
 
@@ -295,7 +295,7 @@ GLOBAL void *logctx;
 /*
  * Exports from winnet.c.
  */
-extern int select_result(WPARAM, LPARAM);
+extern void select_result(WPARAM, LPARAM);
 
 /*
  * winnet.c dynamically loads WinSock 2 or WinSock 1 depending on
@@ -544,8 +544,9 @@ GLOBAL int restricted_acl;
 #ifndef LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR
 #define LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR 0x00000100
 #endif
-#if _MSC_VER < 1400
+#ifndef DLL_DIRECTORY_COOKIE
 typedef PVOID DLL_DIRECTORY_COOKIE;
+DECLSPEC_IMPORT DLL_DIRECTORY_COOKIE WINAPI AddDllDirectory (PCWSTR NewDirectory);
 #endif
 
 /*

+ 6 - 12
source/putty/x11fwd.c

@@ -58,11 +58,9 @@ static int xdmseen_cmp(void *a, void *b)
  *      independent network.c or something */
 static void dummy_plug_log(Plug p, int type, SockAddr addr, int port,
 			   const char *error_msg, int error_code) { }
-static int dummy_plug_closing
-     (Plug p, const char *error_msg, int error_code, int calling_back)
-{ return 1; }
-static int dummy_plug_receive(Plug p, int urgent, char *data, int len)
-{ return 1; }
+static void dummy_plug_closing
+     (Plug p, const char *error_msg, int error_code, int calling_back) { }
+static void dummy_plug_receive(Plug p, int urgent, char *data, int len) { }
 static void dummy_plug_sent(Plug p, int bufsize) { }
 static int dummy_plug_accepting(Plug p, accept_fn_t constructor, accept_ctx_t ctx) { return 1; }
 static const struct plug_function_table dummy_plug = {
@@ -620,8 +618,8 @@ static void x11_log(Plug p, int type, SockAddr addr, int port,
 static void x11_send_init_error(struct X11Connection *conn,
                                 const char *err_message);
 
-static int x11_closing(Plug plug, const char *error_msg, int error_code,
-		       int calling_back)
+static void x11_closing(Plug plug, const char *error_msg, int error_code,
+			int calling_back)
 {
     struct X11Connection *xconn = (struct X11Connection *) plug;
 
@@ -650,11 +648,9 @@ static int x11_closing(Plug plug, const char *error_msg, int error_code,
         if (xconn->c)
             sshfwd_write_eof(xconn->c);
     }
-
-    return 1;
 }
 
-static int x11_receive(Plug plug, int urgent, char *data, int len)
+static void x11_receive(Plug plug, int urgent, char *data, int len)
 {
     struct X11Connection *xconn = (struct X11Connection *) plug;
 
@@ -663,8 +659,6 @@ static int x11_receive(Plug plug, int urgent, char *data, int len)
         xconn->no_data_sent_to_x_client = FALSE;
 	sk_set_frozen(xconn->s, 1);
     }
-
-    return 1;
 }
 
 static void x11_sent(Plug plug, int bufsize)