- fix potential buffer overflow problems.
[obnox/wireshark/wip.git] / packet-rlogin.c
index edb53b39a6035a608a4bdd35346bcde71952cf86..99878045d22e8a1d5039fc68a152828272df909d 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for unix rlogin packet dissection
  * Copyright 2000, Jeffrey C. Foster <jfoste@woodward.com>
  *
- * $Id: packet-rlogin.c,v 1.5 2000/08/06 07:22:37 guy Exp $
+ * $Id: packet-rlogin.c,v 1.9 2000/08/13 14:08:37 deniel Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
 #include <stdio.h>
 #include <string.h>
 #include <glib.h>
+
+#ifdef NEED_SNPRINTF_H
+# include "snprintf.h"
+#endif
+
 #include "packet.h"
 #include "resolv.h"
 #include "globals.h"
 
 #include "packet-tcp.h"
 
-#ifdef NEED_SNPRINTF_H
-# ifdef HAVE_STDARG_H
-#  include <stdarg.h>
-# else
-#  include <varargs.h>
-# endif
-# include "snprintf.h"
-#endif
 
-#define CHECK_PACKET_LENGTH(X) if ((offset+X) > pi.captured_len){  \
+#define CHECK_PACKET_LENGTH(X) if (!BYTES_ARE_IN_FRAME(offset, X)){  \
         proto_tree_add_text(tree, NullTVB, offset, 0, "*** FRAME TOO SHORT ***"); \
         return; }
 
@@ -116,6 +113,23 @@ static GMemChunk *rlogin_vals = NULL;
 static guint32 last_abs_sec = 0;
 static guint32 last_abs_usec= 0;
 
+/* Find the length of a '\0'-terminated string, *INCLUDING* the terminating
+   '\0', but don't run past the end of the packet doing so. */
+static int
+string_len(const char *str, int maxlen)
+{
+       const char *str_end;
+
+       str_end = memchr(str, '\0', maxlen);
+       if (str_end == NULL) {
+               /* No '\0' found - return the length as of when we stopped,
+                  plus one to force the length to be too long and and
+                  CHECK_PACKET_LENGTH to fail. */
+               return maxlen + 1;
+       }
+       return str_end - str + 1;
+}
+
 static void
 rlogin_init( void){
 
@@ -203,6 +217,7 @@ static void rlogin_display( rlogin_hash_entry_t *hash_info, const u_char *pd,
        proto_item      *ti;
        guint8 *Ptr;
        const char *str;
+       int str_len;
        proto_item      *user_info_item,  *window_info_item;
 
        ti = proto_tree_add_item( tree, proto_rlogin, NullTVB, offset,
@@ -210,7 +225,7 @@ static void rlogin_display( rlogin_hash_entry_t *hash_info, const u_char *pd,
 
        rlogin_tree = proto_item_add_subtree(ti, ett_rlogin);
 
-       if ( !END_OF_FRAME)                     /* exit if no data */
+       if ( !IS_DATA_IN_FRAME(offset))         /* exit if no data */
                return;
 
        if ( tcp_urgent_pointer &&              /* if control message */
@@ -244,37 +259,44 @@ static void rlogin_display( rlogin_hash_entry_t *hash_info, const u_char *pd,
                ++offset;
        }
                
-       if ( hash_info->info_framenum == fd->num){              /* user info ?*/
+        if (!IS_DATA_IN_FRAME(offset))
+               return; /* No more data to check */
 
+       if ( hash_info->info_framenum == fd->num){              /* user info ?*/
                user_info_item = proto_tree_add_item( rlogin_tree, hf_user_info, NullTVB,
                        offset, END_OF_FRAME, FALSE);
 
                str = &pd[ offset];             /* do server user name */
-
-               CHECK_PACKET_LENGTH( strlen( str));
-               
+               str_len = string_len( str, END_OF_FRAME);
+               CHECK_PACKET_LENGTH( str_len);
                user_info_tree = proto_item_add_subtree( user_info_item,
                        ett_rlogin_user_info);
-                       
-               proto_tree_add_text(  user_info_tree, NullTVB, offset, strlen( str) + 1, 
-                               "Server User Name:  %s", str);
-                               
-               offset += strlen( str) + 1;
+               proto_tree_add_text(  user_info_tree, NullTVB, offset, str_len,
+                               "Server User Name:  %.*s", str_len, str);
+               offset += str_len;
+
+               if (!IS_DATA_IN_FRAME(offset))
+                       return; /* No more data to check */
                str = &pd[ offset];             /* do client user name */
-               CHECK_PACKET_LENGTH( strlen( str));
-               proto_tree_add_text(  user_info_tree, NullTVB, offset, strlen( str) + 1, 
-                               "Client User Name:  %s", str);
-                               
-               offset += strlen( str) + 1;
+               str_len = string_len( str, END_OF_FRAME);
+               CHECK_PACKET_LENGTH( str_len);
+               proto_tree_add_text(  user_info_tree, NullTVB, offset, str_len,
+                               "Client User Name:  %.*s", str_len, str);
+               offset += str_len;
                
+               if (!IS_DATA_IN_FRAME(offset))
+                       return; /* No more data to check */
                str = &pd[ offset];             /* do terminal type/speed */
-               CHECK_PACKET_LENGTH( strlen( str));
-               proto_tree_add_text(  user_info_tree, NullTVB, offset, strlen( str) + 1, 
-                               "Terminal Type/Speed:  %s", str);
-
-               offset += strlen( str) + 1;
+               str_len = string_len( str, END_OF_FRAME);
+               CHECK_PACKET_LENGTH( str_len);
+               proto_tree_add_text(  user_info_tree, NullTVB, offset, str_len,
+                               "Terminal Type/Speed:  %.*s", str_len, str);
+               offset += str_len;
        }
   
+        if (!IS_DATA_IN_FRAME(offset))
+               return; /* No more data to check */
+
 /* test for terminal information, the data will have 2 0xff bytes */
   
                                                /* look for first 0xff byte */
@@ -343,6 +365,8 @@ dissect_rlogin(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
        rlogin_hash_entry_t *hash_info = 0;
        conversation_t *conversation;
 
+       OLD_CHECK_DISPLAY_AS_DATA(proto_rlogin, pd, offset, fd, tree);
+
                                                /* Lookup this connection*/
        conversation = find_conversation( &pi.src, &pi.dst, pi.ptype,
                pi.srcport, pi.destport);
@@ -471,5 +495,5 @@ proto_reg_handoff_rlogin(void) {
 
        /* dissector install routine */ 
  
-       dissector_add("tcp.port", TCP_PORT_RLOGIN, dissect_rlogin);
+       old_dissector_add("tcp.port", TCP_PORT_RLOGIN, dissect_rlogin);
 }