X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/48345fa3a4a29fb3002f34162550347123de916b..2b0c9995e4df8440f72b7522b14c838c83b814b5:/smbutil.c diff --git a/smbutil.c b/smbutil.c index 11de719c..1af60106 100644 --- a/smbutil.c +++ b/smbutil.c @@ -5,24 +5,33 @@ BSD-style license that accompanies tcpdump or the GNU GPL version 2 or later */ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#ifndef lint +static const char rcsid[] = + "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.12 2000-12-04 00:35:45 guy Exp $"; +#endif + #include #include #include #include -#include #include -#include #include #include #include #include +#include +#include "interface.h" #include "smb.h" -extern uchar *startbuf; +extern const uchar *startbuf; /******************************************************************* interpret a 32 bit dos packed date/time to some parameters @@ -45,7 +54,7 @@ static void interpret_dos_date(uint32 date,int *year,int *month,int *day,int *ho /******************************************************************* create a unix date from a dos date ********************************************************************/ -time_t make_unix_date(void *date_ptr) +static time_t make_unix_date(const void *date_ptr) { uint32 dos_date=0; struct tm t; @@ -66,7 +75,7 @@ time_t make_unix_date(void *date_ptr) /******************************************************************* create a unix date from a dos date ********************************************************************/ -time_t make_unix_date2(void *date_ptr) +static time_t make_unix_date2(const void *date_ptr) { uint32 x,x2; @@ -81,7 +90,7 @@ time_t make_unix_date2(void *date_ptr) interpret an 8 byte "filetime" structure to a time_t It's originally in "100ns units since jan 1st 1601" ****************************************************************************/ -time_t interpret_long_date(char *p) +static time_t interpret_long_date(const char *p) { double d; time_t ret; @@ -105,12 +114,18 @@ time_t interpret_long_date(char *p) /**************************************************************************** -interpret the weird netbios "name". Return the name type +interpret the weird netbios "name". Return the name type, or -1 if +we run past the end of the buffer ****************************************************************************/ -static int name_interpret(char *in,char *out) +static int name_interpret(const uchar *in,const uchar *maxbuf,char *out) { int ret; - int len = (*in++) / 2; + int len; + + if (in >= maxbuf) + return(-1); /* name goes past the end of the buffer */ + TCHECK2(*in, 1); + len = (*in++) / 2; *out=0; @@ -118,6 +133,9 @@ static int name_interpret(char *in,char *out) while (len--) { + if (in + 1 >= maxbuf) + return(-1); /* name goes past the end of the buffer */ + TCHECK2(*in, 2); if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { *out = 0; return(0); @@ -130,50 +148,89 @@ static int name_interpret(char *in,char *out) ret = out[-1]; return(ret); + +trunc: + return(-1); } /**************************************************************************** find a pointer to a netbios name ****************************************************************************/ -static char *name_ptr(char *buf,int ofs) +static const uchar *name_ptr(const uchar *buf,int ofs,const uchar *maxbuf) { - unsigned char c = *(unsigned char *)(buf+ofs); + const uchar *p; + uchar c; + p = buf+ofs; + if (p >= maxbuf) + return(NULL); /* name goes past the end of the buffer */ + TCHECK2(*p, 1); + + c = *p; + + /* XXX - this should use the same code that the DNS dissector does */ if ((c & 0xC0) == 0xC0) { uint16 l = RSVAL(buf, ofs) & 0x3FFF; + if (l == 0) + { + /* We have a pointer that points to itself. */ + return(NULL); + } + p = buf + l; + if (p >= maxbuf) + return(NULL); /* name goes past the end of the buffer */ + TCHECK2(*p, 1); return(buf + l); } else return(buf+ofs); + +trunc: + return(NULL); /* name goes past the end of the buffer */ } /**************************************************************************** extract a netbios name from a buf ****************************************************************************/ -static int name_extract(char *buf,int ofs,char *name) +static int name_extract(const uchar *buf,int ofs,const uchar *maxbuf,char *name) { - char *p = name_ptr(buf,ofs); - int d = PTR_DIFF(p,buf+ofs); + const uchar *p = name_ptr(buf,ofs,maxbuf); + if (p == NULL) + return(-1); /* error (probably name going past end of buffer) */ strcpy(name,""); - return(name_interpret(p,name)); + return(name_interpret(p,maxbuf,name)); } /**************************************************************************** return the total storage length of a mangled name ****************************************************************************/ -static int name_len(unsigned char *s) +static int name_len(const unsigned char *s, const unsigned char *maxbuf) { - char *s0 = s; - unsigned char c = *(unsigned char *)s; + const unsigned char *s0 = s; + unsigned char c; + + if (s >= maxbuf) + return(-1); /* name goes past the end of the buffer */ + TCHECK2(*s, 1); + c = *s; if ((c & 0xC0) == 0xC0) - return(2); - while (*s) s += (*s)+1; + return(2); + while (*s) + { + if (s >= maxbuf) + return(-1); /* name goes past the end of the buffer */ + TCHECK2(*s, 1); + s += (*s)+1; + } return(PTR_DIFF(s,s0)+1); + +trunc: + return(-1); /* name goes past the end of the buffer */ } -void print_asc(unsigned char *buf,int len) +static void print_asc(const unsigned char *buf,int len) { int i; for (i=0;i=maxbuf) return(buf); - bzero(s,sizeof(s)); + memset(s, 0, sizeof(s)); p = strchr(fmt,']'); strncpy(s,fmt,p-fmt); fmt = p+1; buf = fdata1(buf,s,maxbuf); + if (buf == NULL) + return(NULL); break; default: @@ -671,19 +742,16 @@ char *smb_errstr(int class,int num) for (j=0;err[j].name;j++) if (num == err[j].code) { - sprintf(ret,"%s - %s (%s)",err_classes[i].class, + snprintf(ret,sizeof(ret),"%s - %s (%s)",err_classes[i].class, err[j].name,err[j].message); return ret; } } - sprintf(ret,"%s - %d",err_classes[i].class,num); + snprintf(ret,sizeof(ret),"%s - %d",err_classes[i].class,num); return ret; } - sprintf(ret,"ERROR: Unknown error (%d,%d)",class,num); + snprintf(ret,sizeof(ret),"ERROR: Unknown error (%d,%d)",class,num); return(ret); } - - -