check payload for (illegal) extra data
authormarkus <markus@openbsd.org>
Fri, 14 Apr 2000 10:09:14 +0000 (10:09 +0000)
committermarkus <markus@openbsd.org>
Fri, 14 Apr 2000 10:09:14 +0000 (10:09 +0000)
usr.bin/ssh/auth.c
usr.bin/ssh/channels.c
usr.bin/ssh/clientloop.c
usr.bin/ssh/packet.c
usr.bin/ssh/packet.h
usr.bin/ssh/serverloop.c
usr.bin/ssh/session.c
usr.bin/ssh/sshconnect.c

index f33790d..b5677bf 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: auth.c,v 1.2 2000/04/06 08:55:22 markus Exp $");
+RCSID("$OpenBSD: auth.c,v 1.3 2000/04/14 10:09:14 markus Exp $");
 
 #include "xmalloc.h"
 #include "rsa.h"
@@ -630,6 +630,7 @@ input_service_request(int type, int plen)
        unsigned int len;
        int accept = 0;
        char *service = packet_get_string(&len);
+       packet_done();
 
        if (strcmp(service, "ssh-userauth") == 0) {
                if (!userauth_success) {
@@ -672,6 +673,7 @@ input_userauth_request(int type, int plen)
        pw = auth_set_user(user, service);
        if (pw && strcmp(service, "ssh-connection")==0) {
                if (strcmp(method, "none") == 0 && try == 1) {
+                       packet_done();
                        authenticated = auth_password(pw, "");
                } else if (strcmp(method, "password") == 0) {
                        char *password;
@@ -679,16 +681,25 @@ input_userauth_request(int type, int plen)
                        if (c)
                                debug("password change not supported");
                        password = packet_get_string(&len);
+                       packet_done();
                        authenticated = auth_password(pw, password);
                        memset(password, 0, len);
                        xfree(password);
                } else if (strcmp(method, "publickey") == 0) {
                        /* XXX TODO */
-                       char *pkalg;
-                       char *pkblob;
-                       c = packet_get_char();
+                       char *pkalg, *pkblob, *sig;
+                       int have_sig = packet_get_char();
                        pkalg = packet_get_string(&len);
                        pkblob = packet_get_string(&len);
+                       if (have_sig) {
+                               sig = packet_get_string(&len);
+                               /* test for correct signature */
+                               packet_done();
+                               xfree(sig);
+                       } else {
+                               packet_done();
+                               /* test whether pkalg/pkblob are acceptable */
+                       }
                        xfree(pkalg);
                        xfree(pkblob);
                }
@@ -697,7 +708,6 @@ input_userauth_request(int type, int plen)
        if (authenticated) {
                /* turn off userauth */
                dispatch_set(SSH2_MSG_USERAUTH_REQUEST, &protocol_error);
-               /* success! */
                packet_start(SSH2_MSG_USERAUTH_SUCCESS);
                packet_send();
                packet_write_wait();
index c32999a..3a634bf 100644 (file)
@@ -17,7 +17,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: channels.c,v 1.47 2000/04/10 15:19:43 markus Exp $");
+RCSID("$Id: channels.c,v 1.48 2000/04/14 10:09:14 markus Exp $");
 
 #include "ssh.h"
 #include "packet.h"
@@ -540,8 +540,10 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset)
                        packet_put_int(newch);
                        packet_put_int(c->local_window_max);
                        packet_put_int(c->local_maxpacket);
+                       /* target host and port */
                        packet_put_string(c->path, strlen(c->path));
                        packet_put_int(c->host_port);
+                       /* originator host and port */
                        packet_put_cstring(remote_hostname);
                        packet_put_int(remote_port);
                        packet_send();
@@ -934,6 +936,7 @@ channel_input_data(int type, int plen)
 
        /* Get the data. */
        data = packet_get_string(&data_len);
+       packet_done();
 
        if (compat20){
                if (data_len > c->local_maxpacket) {
@@ -980,6 +983,7 @@ channel_input_extended_data(int type, int plen)
                return;
        }
        data = packet_get_string(&data_len);
+       packet_done();
        if (data_len > c->local_window) {
                log("channel %d: rcvd too much extended_data %d, win %d",
                    c->self, data_len, c->local_window);
@@ -1093,6 +1097,7 @@ channel_input_close_confirmation(int type, int plen)
        int id = packet_get_int();
        Channel *c = channel_lookup(id);
 
+       packet_done();
        if (c == NULL)
                packet_disconnect("Received close confirmation for "
                    "out-of-range channel %d.", id);
@@ -1125,6 +1130,7 @@ channel_input_open_confirmation(int type, int plen)
        if (compat20) {
                c->remote_window = packet_get_int();
                c->remote_maxpacket = packet_get_int();
+               packet_done();
                if (c->cb_fn != NULL && c->cb_event == type) {
                        debug("callback start");
                        c->cb_fn(c->self, c->cb_arg);
@@ -1153,8 +1159,11 @@ channel_input_open_failure(int type, int plen)
        if (compat20) {
                int reason = packet_get_int();
                char *msg  = packet_get_string(NULL);
+               char *lang  = packet_get_string(NULL);
                log("channel_open_failure: %d: reason %d: %s", id, reason, msg);
+               packet_done();
                xfree(msg);
+               xfree(lang);
        }
        /* Free the channel.  This will also close the socket. */
        channel_free(id);
@@ -1204,6 +1213,7 @@ channel_input_window_adjust(int type, int plen)
                return;
        }
        adjust = packet_get_int();
+       packet_done();
        debug("channel %d: rcvd adjust %d", id, adjust);
        c->remote_window += adjust;
 }
index cf6d381..0b21d51 100644 (file)
@@ -16,7 +16,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: clientloop.c,v 1.18 2000/04/12 06:37:02 markus Exp $");
+RCSID("$Id: clientloop.c,v 1.19 2000/04/14 10:09:15 markus Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -1027,6 +1027,7 @@ client_input_channel_req(int id, void *arg)
        } else if (strcmp(rtype, "exit-status") == 0) {
                success = 1;
                exit_status = packet_get_int();
+               packet_done();
        }
        if (reply) {
                packet_start(success ?
index c6a462c..af8824f 100644 (file)
@@ -17,7 +17,7 @@
  */
 
 #include "includes.h"
-RCSID("$Id: packet.c,v 1.27 2000/04/12 09:39:10 markus Exp $");
+RCSID("$Id: packet.c,v 1.28 2000/04/14 10:09:15 markus Exp $");
 
 #include "xmalloc.h"
 #include "buffer.h"
@@ -1055,6 +1055,12 @@ packet_get_raw(int *length_ptr)
        return buffer_ptr(&incoming_packet);
 }
 
+int
+packet_remaining(void)
+{
+       return buffer_len(&incoming_packet);
+}
+
 /*
  * Returns a string from the packet data.  The string is allocated using
  * xmalloc; it is the responsibility of the calling program to free it when
index 51d4882..70fc0dd 100644 (file)
@@ -13,7 +13,7 @@
  * 
  */
 
-/* RCSID("$Id: packet.h,v 1.13 2000/04/12 09:39:10 markus Exp $"); */
+/* RCSID("$Id: packet.h,v 1.14 2000/04/14 10:09:15 markus Exp $"); */
 
 #ifndef PACKET_H
 #define PACKET_H
@@ -196,6 +196,16 @@ do { \
   } \
 } while (0)
 
+#define packet_done() \
+do { \
+       int _len = packet_remaining(); \
+       if (_len > 0) { \
+               log("Packet integrity error (%d bytes remaining) at %s:%d", \
+                   _len ,__FILE__, __LINE__); \
+               packet_disconnect("Packet integrity error."); \
+       } \
+} while (0)
+
 /* remote host is connected via a socket/ipv4 */
 int    packet_connection_is_on_socket(void);
 int    packet_connection_is_ipv4(void);
@@ -203,4 +213,7 @@ int packet_connection_is_ipv4(void);
 /* enable SSH2 packet format */
 void   packet_set_ssh2_format(void);
 
+/* returns remaining payload bytes */
+int    packet_remaining(void);
+
 #endif                         /* PACKET_H */
index 4cbb3ba..72f6c2a 100644 (file)
@@ -684,16 +684,17 @@ int
 input_direct_tcpip(void)
 {
        int sock;
-       char *host, *originator;
-       int host_port, originator_port;
+       char *target, *originator;
+       int target_port, originator_port;
 
-       host = packet_get_string(NULL);
-       host_port = packet_get_int();
+       target = packet_get_string(NULL);
+       target_port = packet_get_int();
        originator = packet_get_string(NULL);
        originator_port = packet_get_int();
+       packet_done();
        /* XXX check permission */
-       sock = channel_connect_to(host, host_port);
-       xfree(host);
+       sock = channel_connect_to(target, target_port);
+       xfree(target);
        xfree(originator);
        if (sock < 0)
                return -1;
@@ -722,6 +723,7 @@ server_input_channel_open(int type, int plen)
 
        if (strcmp(ctype, "session") == 0) {
                debug("open session");
+               packet_done();
                /*
                 * A server session has no fd to read or write
                 * until a CHANNEL_REQUEST for a shell is made,
index c98e65e..3849dac 100644 (file)
@@ -8,7 +8,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: session.c,v 1.2 2000/04/06 08:55:22 markus Exp $");
+RCSID("$OpenBSD: session.c,v 1.3 2000/04/14 10:09:16 markus Exp $");
 
 #include "xmalloc.h"
 #include "ssh.h"
@@ -1134,6 +1134,7 @@ session_window_change_req(Session *s)
        s->row = packet_get_int();
        s->xpixel = packet_get_int();
        s->ypixel = packet_get_int();
+       packet_done();
        pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
        return 1;
 }
@@ -1142,14 +1143,17 @@ int
 session_pty_req(Session *s)
 {
        unsigned int len;
+       char *term_modes;       /* encoded terminal modes */
 
        if (s->ttyfd != -1)
-               return -1;
+               return 0;
        s->term = packet_get_string(&len);
        s->col = packet_get_int();
        s->row = packet_get_int();
        s->xpixel = packet_get_int();
        s->ypixel = packet_get_int();
+       term_modes = packet_get_string(&len);
+       packet_done();
 
        if (strcmp(s->term, "") == 0) {
                xfree(s->term);
@@ -1162,7 +1166,8 @@ session_pty_req(Session *s)
                s->ptyfd = -1;
                s->ttyfd = -1;
                error("session_pty_req: session %d alloc failed", s->self);
-               return -1;
+               xfree(term_modes);
+               return 0;
        }
        debug("session_pty_req: session %d alloc %s", s->self, s->tty);
        /*
@@ -1174,6 +1179,8 @@ session_pty_req(Session *s)
        /* Get window size from the packet. */
        pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
 
+       /* XXX parse and set terminal modes */
+       xfree(term_modes);
        return 1;
 }
 
@@ -1206,6 +1213,7 @@ session_input_channel_req(int id, void *arg)
         */
        if (c->type == SSH_CHANNEL_LARVAL) {
                if (strcmp(rtype, "shell") == 0) {
+                       packet_done();
                        if (s->ttyfd == -1)
                                do_exec_no_pty(s, NULL, s->pw);
                        else
@@ -1213,6 +1221,7 @@ session_input_channel_req(int id, void *arg)
                        success = 1;
                } else if (strcmp(rtype, "exec") == 0) {
                        char *command = packet_get_string(&len);
+                       packet_done();
                        if (s->ttyfd == -1)
                                do_exec_no_pty(s, command, s->pw);
                        else
@@ -1220,8 +1229,7 @@ session_input_channel_req(int id, void *arg)
                        xfree(command);
                        success = 1;
                } else if (strcmp(rtype, "pty-req") == 0) {
-                       if (session_pty_req(s) > 0)
-                               success = 1;
+                       success =  session_pty_req(s);
                }
        }
        if (strcmp(rtype, "window-change") == 0) {
index 18d1c59..cecd304 100644 (file)
@@ -10,7 +10,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: sshconnect.c,v 1.66 2000/04/12 09:39:10 markus Exp $");
+RCSID("$OpenBSD: sshconnect.c,v 1.67 2000/04/14 10:09:16 markus Exp $");
 
 #include <openssl/bn.h>
 #include "xmalloc.h"
@@ -1400,6 +1400,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
        debug("first kex follow == %d", i);
        i = packet_get_int();
        debug("reserved == %d", i);
+       packet_done();
 
        debug("done read kexinit");
        kex = kex_choose_conf(cprop, sprop, 0);
@@ -1455,6 +1456,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
 
        /* signed H */
        signature = packet_get_string(&slen);
+       packet_done();
 
        if (!dh_pub_is_valid(dh, dh_server_pub))
                packet_disconnect("bad server public DH value");
@@ -1507,6 +1509,7 @@ ssh_kex2(char *host, struct sockaddr *hostaddr)
 
        debug("Wait SSH2_MSG_NEWKEYS.");
        packet_read_expect(&payload_len, SSH2_MSG_NEWKEYS);
+       packet_done();
        debug("GOT SSH2_MSG_NEWKEYS.");
 
        debug("send SSH2_MSG_NEWKEYS.");
@@ -1540,7 +1543,7 @@ ssh_userauth2(int host_key_valid, RSA *own_host_key,
        char *server_user, *local_user;
        char *auths;
        char *password;
-       char *service = "ssh-connection";               // service name
+       char *service = "ssh-connection";               /* service name */
 
        debug("send SSH2_MSG_SERVICE_REQUEST");
        packet_start(SSH2_MSG_SERVICE_REQUEST);
@@ -1552,8 +1555,15 @@ ssh_userauth2(int host_key_valid, RSA *own_host_key,
        if (type != SSH2_MSG_SERVICE_ACCEPT) {
                fatal("denied SSH2_MSG_SERVICE_ACCEPT: %d", type);
        }
-       /* payload empty for ssh-2.0.13 ?? */
-       /* reply = packet_get_string(&payload_len); */
+       if (packet_remaining() > 0) {
+               char *reply = packet_get_string(&plen);
+               debug("service_accept: %s", reply);
+               xfree(reply);
+       } else {
+               /* payload empty for ssh-2.0.13 ?? */
+               log("buggy server: service_accept w/o service");
+       }
+       packet_done();
        debug("got SSH2_MSG_SERVICE_ACCEPT");
 
        /*XX COMMONCODE: */
@@ -1582,6 +1592,7 @@ ssh_userauth2(int host_key_valid, RSA *own_host_key,
                auths = packet_get_string(&dlen);
                debug("authentications that can continue: %s", auths);
                partial = packet_get_char();
+               packet_done();
                if (partial)
                        debug("partial success");
                if (strstr(auths, "password") == NULL)
@@ -1602,6 +1613,7 @@ ssh_userauth2(int host_key_valid, RSA *own_host_key,
                packet_send();
                packet_write_wait();
        }
+       packet_done();
        debug("ssh-userauth2 successfull");
 }