From 1fde943e8c85a12562621aa0f46d96c3421bc520 Mon Sep 17 00:00:00 2001 From: markus Date: Fri, 14 Apr 2000 10:09:14 +0000 Subject: [PATCH] check payload for (illegal) extra data --- usr.bin/ssh/auth.c | 20 +++++++++++++++----- usr.bin/ssh/channels.c | 12 +++++++++++- usr.bin/ssh/clientloop.c | 3 ++- usr.bin/ssh/packet.c | 8 +++++++- usr.bin/ssh/packet.h | 15 ++++++++++++++- usr.bin/ssh/serverloop.c | 14 ++++++++------ usr.bin/ssh/session.c | 18 +++++++++++++----- usr.bin/ssh/sshconnect.c | 20 ++++++++++++++++---- 8 files changed, 86 insertions(+), 24 deletions(-) diff --git a/usr.bin/ssh/auth.c b/usr.bin/ssh/auth.c index f33790da06e..b5677bf059c 100644 --- a/usr.bin/ssh/auth.c +++ b/usr.bin/ssh/auth.c @@ -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(); diff --git a/usr.bin/ssh/channels.c b/usr.bin/ssh/channels.c index c32999a0586..3a634bfb9da 100644 --- a/usr.bin/ssh/channels.c +++ b/usr.bin/ssh/channels.c @@ -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; } diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c index cf6d3816445..0b21d519633 100644 --- a/usr.bin/ssh/clientloop.c +++ b/usr.bin/ssh/clientloop.c @@ -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 ? diff --git a/usr.bin/ssh/packet.c b/usr.bin/ssh/packet.c index c6a462c045e..af8824f3641 100644 --- a/usr.bin/ssh/packet.c +++ b/usr.bin/ssh/packet.c @@ -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 diff --git a/usr.bin/ssh/packet.h b/usr.bin/ssh/packet.h index 51d4882f756..70fc0ddcdf4 100644 --- a/usr.bin/ssh/packet.h +++ b/usr.bin/ssh/packet.h @@ -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 */ diff --git a/usr.bin/ssh/serverloop.c b/usr.bin/ssh/serverloop.c index 4cbb3ba39f5..72f6c2ac72a 100644 --- a/usr.bin/ssh/serverloop.c +++ b/usr.bin/ssh/serverloop.c @@ -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, diff --git a/usr.bin/ssh/session.c b/usr.bin/ssh/session.c index c98e65e3d58..3849dac6ee2 100644 --- a/usr.bin/ssh/session.c +++ b/usr.bin/ssh/session.c @@ -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) { diff --git a/usr.bin/ssh/sshconnect.c b/usr.bin/ssh/sshconnect.c index 18d1c593234..cecd304c348 100644 --- a/usr.bin/ssh/sshconnect.c +++ b/usr.bin/ssh/sshconnect.c @@ -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 #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"); } -- 2.20.1