Security fixes, copied from ssh.c: check string length versus packet
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Tue, 6 Jun 2000 10:54:41 +0000 (10:54 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Tue, 6 Jun 2000 10:54:41 +0000 (10:54 +0000)
length on incoming SSH_SMSG_*_DATA, and check CRCs on all incoming
packets.

git-svn-id: svn://svn.tartarus.org/sgt/putty@498 cda61777-01e9-0310-a592-d414129be87e

scpssh.c

index 3d2c824..5bc12cd 100644 (file)
--- a/scpssh.c
+++ b/scpssh.c
@@ -93,6 +93,7 @@ static void get_packet(void)
     unsigned char buf[4];
     int ret;
     int len, pad, biglen;
+    unsigned long realcrc, gotcrc;
 
 next_packet:
 
@@ -145,6 +146,15 @@ next_packet:
     pktin.type = pktin.data[pad];
     pktin.body = pktin.data + pad + 1;
 
+    realcrc = crc32(pktin.data, biglen-4);
+    gotcrc = (pktin.data[biglen-4] << 24);
+    gotcrc |= (pktin.data[biglen-3] << 16);
+    gotcrc |= (pktin.data[biglen-2] <<  8);
+    gotcrc |= (pktin.data[biglen-1] <<  0);
+    if (gotcrc != realcrc) {
+        fatalbox("Incorrect CRC received on packet");
+    }
+
     if (pktin.type == SSH_MSG_DEBUG) {
        if (verbose) {
            int len = GET_32BIT(pktin.body);
@@ -425,7 +435,10 @@ int ssh_recv(unsigned char *buf, int len)
            return 0;
        if (pktin.type == SSH_SMSG_STDOUT_DATA) {
            int plen = GET_32BIT(pktin.body);
-           if (plen <= to_read) {
+            if (plen+4 != pktin.length) {
+                fprintf(stderr, "Received data packet with bogus string length"
+                        ", ignoring\n");
+            } else if (plen <= to_read) {
                memcpy(buf, pktin.body + 4, plen);
                buf += plen;
                to_read -= plen;
@@ -437,7 +450,11 @@ int ssh_recv(unsigned char *buf, int len)
            }
        } else if (pktin.type == SSH_SMSG_STDERR_DATA) {
            int plen = GET_32BIT(pktin.body);
-           fwrite(pktin.body + 4, plen, 1, stderr);
+            if (plen+4 != pktin.length) {
+                fprintf(stderr, "Received data packet with bogus string length"
+                        ", ignoring\n");
+            } else
+                fwrite(pktin.body + 4, plen, 1, stderr);
        } else if (pktin.type == SSH_MSG_DISCONNECT) {
        } else if (pktin.type == SSH_SMSG_SUCCESS ||
                   pktin.type == SSH_SMSG_FAILURE) {