More sensible error handling when we receive an SSH1 public key
[u/mdw/putty] / ssh.c
diff --git a/ssh.c b/ssh.c
index 3616d21..3e051f9 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -827,6 +827,12 @@ static int ssh1_rdpkt(Ssh ssh, unsigned char **data, int *datalen)
     st->biglen = st->len + st->pad;
     ssh->pktin.length = st->len - 5;
 
+    if (st->biglen < 0) {
+        bombout(("Extremely large packet length from server suggests"
+                " data stream corruption"));
+        crStop(0);
+    }
+
     if (ssh->pktin.maxlen < st->biglen) {
        ssh->pktin.maxlen = st->biglen;
        ssh->pktin.data = sresize(ssh->pktin.data, st->biglen + APIEXTRA,
@@ -2435,7 +2441,7 @@ static int do_ssh1_login(Ssh ssh, unsigned char *in, int inlen, int ispkt)
 
     if (!ssh1_pkt_getrsakey(ssh, &servkey, &s->keystr1) ||
        !ssh1_pkt_getrsakey(ssh, &hostkey, &s->keystr2)) {      
-       bombout(("SSH1 public key packet stopped before public keys"));
+       bombout(("Failed to read SSH1 public keys from public key packet"));
        crStop(0);
     }
 
@@ -4610,7 +4616,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
        int num_prompts, curr_prompt, echo;
        char username[100];
        int got_username;
-       char pwprompt[200];
+       char pwprompt[512];
        char password[100];
        void *publickey_blob;
        int publickey_bloblen;
@@ -5189,9 +5195,16 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
 
                    ssh_pkt_getstring(ssh, &prompt, &prompt_len);
                    if (prompt_len > 0) {
-                       strncpy(s->pwprompt, prompt, sizeof(s->pwprompt));
-                       s->pwprompt[prompt_len < sizeof(s->pwprompt) ?
-                                   prompt_len : sizeof(s->pwprompt)-1] = '\0';
+                       static const char trunc[] = "<prompt truncated>: ";
+                       static const int prlen = sizeof(s->pwprompt) -
+                                                lenof(trunc);
+                       if (prompt_len > prlen) {
+                           memcpy(s->pwprompt, prompt, prlen);
+                           strcpy(s->pwprompt + prlen, trunc);
+                       } else {
+                           memcpy(s->pwprompt, prompt, prompt_len);
+                           s->pwprompt[prompt_len] = '\0';
+                       }
                    } else {
                        strcpy(s->pwprompt,
                               "<server failed to send prompt>: ");
@@ -6160,9 +6173,12 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
                     ssh_pkt_getstring(ssh, &peeraddr, &peeraddrlen);
                    addrstr = snewn(peeraddrlen+1, char);
                    memcpy(addrstr, peeraddr, peeraddrlen);
-                   peeraddr[peeraddrlen] = '\0';
+                   addrstr[peeraddrlen] = '\0';
                     peerport = ssh_pkt_getuint32(ssh);
 
+                   logeventf(ssh, "Received X11 connect request from %s:%d",
+                             addrstr, peerport);
+
                    if (!ssh->X11_fwd_enabled)
                        error = "X11 forwarding is not enabled";
                    else if (x11_init(&c->u.x11.s, ssh->cfg.x11_display, c,
@@ -6170,6 +6186,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
                                      &ssh->cfg) != NULL) {
                        error = "Unable to open an X11 connection";
                    } else {
+                       logevent("Opening X11 forward connection succeeded");
                        c->type = CHAN_X11;
                    }
 
@@ -6184,6 +6201,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
                     ssh_pkt_getstring(ssh, &peeraddr, &peeraddrlen);
                     peerport = ssh_pkt_getuint32(ssh);
                    realpf = find234(ssh->rportfwds, &pf, NULL);
+                   logeventf(ssh, "Received remote port %d open request "
+                             "from %s:%d", pf.sport, peeraddr, peerport);
                    if (realpf == NULL) {
                        error = "Remote port is not recognised";
                    } else {
@@ -6191,8 +6210,8 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
                                                       realpf->dhost,
                                                       realpf->dport, c,
                                                       &ssh->cfg);
-                       logeventf(ssh, "Received remote port open request"
-                                 " for %s:%d", realpf->dhost, realpf->dport);
+                       logeventf(ssh, "Attempting to forward remote port to "
+                                 "%s:%d", realpf->dhost, realpf->dport);
                        if (e != NULL) {
                            logeventf(ssh, "Port open failed: %s", e);
                            error = "Port open failed";
@@ -6221,6 +6240,7 @@ static void do_ssh2_authconn(Ssh ssh, unsigned char *in, int inlen, int ispkt)
                    ssh2_pkt_addstring(ssh, error);
                    ssh2_pkt_addstring(ssh, "en");      /* language tag */
                    ssh2_pkt_send(ssh);
+                   logeventf(ssh, "Rejected channel open: %s", error);
                    sfree(c);
                } else {
                    c->localid = alloc_channel_id(ssh);
@@ -6466,10 +6486,6 @@ static void ssh_free(void *handle)
        crcda_free_context(ssh->crcda_ctx);
        ssh->crcda_ctx = NULL;
     }
-    if (ssh->logctx) {
-       log_free(ssh->logctx);
-       ssh->logctx = NULL;
-    }
     if (ssh->s)
        ssh_do_close(ssh);
     sfree(ssh);