Browse Source

Merge branch 'thirdparty_dev' into dev

Conflicts:
	source/putty/WINDOWS/winmisc.c

Source commit: 4b6b991e6b041adb028f5711edd7bcde14473329
Martin Prikryl 10 years ago
parent
commit
896787318d

+ 49 - 11
source/putty/logging.c

@@ -22,7 +22,8 @@ struct LogContext {
     int logtype;		       /* cached out of conf */
 };
 
-static Filename *xlatlognam(Filename *s, char *hostname, struct tm *tm);
+static Filename *xlatlognam(Filename *s, char *hostname, int port,
+                            struct tm *tm);
 
 /*
  * Internal wrapper function which must be called for _all_ output
@@ -87,16 +88,19 @@ static void logfopen_callback(void *handle, int mode)
     char buf[256], *event;
     struct tm tm;
     const char *fmode;
+    int shout = FALSE;
 
     if (mode == 0) {
 	ctx->state = L_ERROR;	       /* disable logging */
     } else {
 	fmode = (mode == 1 ? "ab" : "wb");
 	ctx->lgfp = f_open(ctx->currlogfilename, fmode, FALSE);
-	if (ctx->lgfp)
+	if (ctx->lgfp) {
 	    ctx->state = L_OPEN;
-	else
+        } else {
 	    ctx->state = L_ERROR;
+            shout = TRUE;
+        }
     }
 
     if (ctx->state == L_OPEN) {
@@ -118,6 +122,23 @@ static void logfopen_callback(void *handle, int mode)
 		       "unknown"),
 		      filename_to_str(ctx->currlogfilename));
     logevent(ctx->frontend, event);
+    if (shout) {
+        /*
+         * If we failed to open the log file due to filesystem error
+         * (as opposed to user action such as clicking Cancel in the
+         * askappend box), we should log it more prominently. We do
+         * this by sending it to the same place that stderr output
+         * from the main session goes (so, either a console tool's
+         * actual stderr, or a terminal window).
+         *
+         * Of course this is one case in which that policy won't cause
+         * it to turn up embarrassingly in a log file of real server
+         * output, because the whole point is that we haven't managed
+         * to open any such log file :-)
+         */
+        from_backend(ctx->frontend, 1, event, strlen(event));
+        from_backend(ctx->frontend, 1, "\r\n", 2);
+    }
     sfree(event);
 
     /*
@@ -143,6 +164,7 @@ void logfopen(void *handle)
 {
     struct LogContext *ctx = (struct LogContext *)handle;
     struct tm tm;
+    FILE *fp;
     int mode;
 
     /* Prevent repeat calls */
@@ -159,12 +181,13 @@ void logfopen(void *handle)
         filename_free(ctx->currlogfilename);
     ctx->currlogfilename = 
         xlatlognam(conf_get_filename(ctx->conf, CONF_logfilename),
-                   conf_get_str(ctx->conf, CONF_host), &tm);
+                   conf_get_str(ctx->conf, CONF_host),
+                   conf_get_int(ctx->conf, CONF_port), &tm);
 
-    ctx->lgfp = f_open(ctx->currlogfilename, "r", FALSE);  /* file already present? */
-    if (ctx->lgfp) {
+    fp = f_open(ctx->currlogfilename, "r", FALSE);  /* file already present? */
+    if (fp) {
 	int logxfovr = conf_get_int(ctx->conf, CONF_logxfovr);
-	fclose(ctx->lgfp);
+	fclose(fp);
 	if (logxfovr != LGXF_ASK) {
 	    mode = ((logxfovr == LGXF_OVR) ? 2 : 1);
 	} else
@@ -408,9 +431,10 @@ void log_reconfig(void *handle, Conf *conf)
  *
  * "&Y":YYYY   "&m":MM   "&d":DD   "&T":hhmmss   "&h":<hostname>   "&&":&
  */
-static Filename *xlatlognam(Filename *src, char *hostname, struct tm *tm)
+static Filename *xlatlognam(Filename *src, char *hostname, int port,
+                            struct tm *tm)
 {
-    char buf[10], *bufp;
+    char buf[32], *bufp;
     int size;
     char *buffer;
     int buflen, bufsize;
@@ -423,6 +447,7 @@ static Filename *xlatlognam(Filename *src, char *hostname, struct tm *tm)
     s = filename_to_str(src);
 
     while (*s) {
+        int sanitise = FALSE;
 	/* Let (bufp, len) be the string to append. */
 	bufp = buf;		       /* don't usually override this */
 	if (*s == '&') {
@@ -446,12 +471,21 @@ static Filename *xlatlognam(Filename *src, char *hostname, struct tm *tm)
 		bufp = hostname;
 		size = strlen(bufp);
 		break;
+	      case 'p':
+                size = sprintf(buf, "%d", port);
+		break;
 	      default:
 		buf[0] = '&';
 		size = 1;
 		if (c != '&')
 		    buf[size++] = c;
 	    }
+            /* Never allow path separators - or any other illegal
+             * filename character - to come out of any of these
+             * auto-format directives. E.g. 'hostname' can contain
+             * colons, if it's an IPv6 address, and colons aren't
+             * legal in filenames on Windows. */
+            sanitise = TRUE;
 	} else {
 	    buf[0] = *s++;
 	    size = 1;
@@ -460,8 +494,12 @@ static Filename *xlatlognam(Filename *src, char *hostname, struct tm *tm)
             bufsize = (buflen + size) * 5 / 4 + 512;
             buffer = sresize(buffer, bufsize, char);
         }
-	memcpy(buffer + buflen, bufp, size);
-	buflen += size;
+        while (size-- > 0) {
+            char c = *bufp++;
+            if (sanitise)
+                c = filename_char_sanitise(c);
+            buffer[buflen++] = c;
+        }
     }
     buffer[buflen] = '\0';
 

+ 2 - 2
source/putty/misc.c

@@ -744,7 +744,7 @@ void *safemalloc(size_t n, size_t size)
 #else
 	strcpy(str, "Out of memory!");
 #endif
-	modalfatalbox(str);
+	modalfatalbox("%s", str);
     }
 #ifdef MALLOC_LOG
     if (fp)
@@ -786,7 +786,7 @@ void *saferealloc(void *ptr, size_t n, size_t size)
 #else
 	strcpy(str, "Out of memory!");
 #endif
-	modalfatalbox(str);
+	modalfatalbox("%s", str);
     }
 #ifdef MALLOC_LOG
     if (fp)

+ 9 - 0
source/putty/misc.h

@@ -42,6 +42,15 @@ char *dupprintf(const char *fmt, ...)
 char *dupvprintf(const char *fmt, va_list ap);
 void burnstr(char *string);
 
+/* String-to-Unicode converters that auto-allocate the destination and
+ * work around the rather deficient interface of mb_to_wc.
+ *
+ * These actually live in miscucs.c, not misc.c (the distinction being
+ * that the former is only linked into tools that also have the main
+ * Unicode support). */
+wchar_t *dup_mb_to_wc_c(int codepage, int flags, const char *string, int len);
+wchar_t *dup_mb_to_wc(int codepage, int flags, const char *string);
+
 int toint(unsigned);
 
 char *fgetline(FILE *fp);

+ 3 - 0
source/putty/putty.h

@@ -31,6 +31,8 @@ typedef struct terminal_tag Terminal;
  * Fingerprints of the PGP master keys that can be used to establish a trust
  * path between an executable and other files.
  */
+#define PGP_MASTER_KEY_FP \
+    "440D E3B5 B7A1 CA85 B3CC  1718 AB58 5DC6 0467 6F7C"
 #define PGP_RSA_MASTER_KEY_FP \
     "8F 15 97 DA 25 30 AB 0D  88 D1 92 54 11 CF 0C 4C"
 #define PGP_DSA_MASTER_KEY_FP \
@@ -1311,6 +1313,7 @@ int filename_serialise(const Filename *f, void *data);
 Filename *filename_deserialise(void *data, int maxsize, int *used);
 char *get_username(void);	       /* return value needs freeing */
 char *get_random_data(int bytes);      /* used in cmdgen.c */
+char filename_char_sanitise(char c);   /* rewrite special pathname chars */
 
 /*
  * Exports and imports from timing.c.

+ 24 - 5
source/putty/ssh.c

@@ -360,6 +360,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
 			     struct Packet *pktin);
 static void ssh2_channel_check_close(struct ssh_channel *c);
 static void ssh_channel_destroy(struct ssh_channel *c);
+static void ssh2_msg_something_unimplemented(Ssh ssh, struct Packet *pktin);
 
 /*
  * Buffer management constants. There are several of these for
@@ -1746,6 +1747,15 @@ static struct Packet *ssh2_rdpkt(Ssh ssh, unsigned char **data, int *datalen)
 	}
     }
 
+    /*
+     * RFC 4253 doesn't explicitly say that completely empty packets
+     * with no type byte are forbidden, so treat them as deserving
+     * an SSH_MSG_UNIMPLEMENTED.
+     */
+    if (st->pktin->length <= 5) { /* == 5 we hope, but robustness */
+        ssh2_msg_something_unimplemented(ssh, st->pktin);
+        crStop(NULL);
+    }
     /*
      * pktin->body and pktin->length should identify the semantic
      * content of the packet, excluding the initial type byte.
@@ -9184,11 +9194,20 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen,
 		s->can_keyb_inter = conf_get_int(ssh->conf, CONF_try_ki_auth) &&
 		    in_commasep_string("keyboard-interactive", methods, methlen);
 #ifndef NO_GSSAPI
-		if (!ssh->gsslibs)
-		    ssh->gsslibs = ssh_gss_setup(ssh->conf);
-		s->can_gssapi = conf_get_int(ssh->conf, CONF_try_gssapi_auth) &&
-		    in_commasep_string("gssapi-with-mic", methods, methlen) &&
-		    ssh->gsslibs->nlibraries > 0;
+                if (conf_get_int(ssh->conf, CONF_try_gssapi_auth) &&
+		    in_commasep_string("gssapi-with-mic", methods, methlen)) {
+                    /* Try loading the GSS libraries and see if we
+                     * have any. */
+                    if (!ssh->gsslibs)
+                        ssh->gsslibs = ssh_gss_setup(ssh->conf);
+                    s->can_gssapi = (ssh->gsslibs->nlibraries > 0);
+                } else {
+                    /* No point in even bothering to try to load the
+                     * GSS libraries, if the user configuration and
+                     * server aren't both prepared to attempt GSSAPI
+                     * auth in the first place. */
+                    s->can_gssapi = FALSE;
+                }
 #endif
 	    }
 

+ 2 - 0
source/putty/sshrsa.c

@@ -767,6 +767,8 @@ static int rsa2_pubkey_bits(void *blob, int len)
     int ret;
 
     rsa = rsa2_newkey((char *) blob, len);
+    if (!rsa)
+	return -1;
     ret = bignum_bitcount(rsa->modulus);
     rsa2_freekey(rsa);
 

+ 4 - 4
source/putty/version.h

@@ -1,5 +1,5 @@
 /* Generated by automated build script */
-#define RELEASE 0.65
-#define TEXTVER "Release 0.65"
-#define SSHVER "PuTTY-Release-0.65"
-#define BINARY_VERSION 0,65,0,0
+#define RELEASE 0.66
+#define TEXTVER "Release 0.66"
+#define SSHVER "PuTTY-Release-0.66"
+#define BINARY_VERSION 0,66,0,0

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

@@ -579,17 +579,18 @@ static void handle_destroy(struct handle *h)
 
 void handle_free(struct handle *h)
 {
-    /*
-     * If the handle is currently busy, we cannot immediately free
-     * it. Instead we must wait until it's finished its current
-     * operation, because otherwise the subthread will write to
-     * invalid memory after we free its context from under it.
-     */
     assert(h && !h->u.g.moribund);
-    if (h->u.g.busy) {
-	/*
-	 * Just set the moribund flag, which will be noticed next
-	 * time an operation completes.
+    if (h->u.g.busy && h->type != HT_FOREIGN) {
+        /*
+         * If the handle is currently busy, we cannot immediately free
+         * it, because its subthread is in the middle of something.
+         * (Exception: foreign handles don't have a subthread.)
+         *
+         * Instead we must wait until it's finished its current
+         * operation, because otherwise the subthread will write to
+         * invalid memory after we free its context from under it. So
+         * we set the moribund flag, which will be noticed next time
+         * an operation completes.
 	 */
 	h->u.g.moribund = TRUE;
     } else if (h->u.g.defunct) {

+ 7 - 0
source/putty/windows/winmisc.c

@@ -72,6 +72,13 @@ Filename *filename_deserialise(void *vdata, int maxsize, int *used)
     return filename_from_str(data);
 }
 
+char filename_char_sanitise(char c)
+{
+    if (strchr("<>:\"/\\|?*", c))
+        return '.';
+    return c;
+}
+
 #ifdef MPEXT
 
 FILE * mp_wfopen(const char *filename, const char *mode)