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 91e968c..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>: ");
@@ -6473,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);