diff --git a/Makefile b/Makefile index 6aeba84..26b563b 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -#DEBUG=1 +DEBUG=1 all: t t1 t2 bindrequest tinyldap ldapclient diff --git a/THANKS b/THANKS index 4ec23e7..4075626 100644 --- a/THANKS +++ b/THANKS @@ -1 +1,3 @@ Trevor Harrison found a bug in fmt_asn1tag for the multibyte encoding. + +David Lichteblau found lots of problems in the ASN.1 code. diff --git a/fmt_asn1int.c b/fmt_asn1int.c index caed0d3..d28f34e 100644 --- a/fmt_asn1int.c +++ b/fmt_asn1int.c @@ -3,7 +3,7 @@ int fmt_asn1int(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,unsigned long l) { int len,tmp; /* first the tag */ - if (!dest) return 2+fmt_asn1intpayload(0,l); + if (!dest) return fmt_asn1tag(0,tc,tt,tag)+1+fmt_asn1intpayload(0,l); len=fmt_asn1tag(dest,tc,tt,tag); tmp=fmt_asn1intpayload(dest+len+1,l); if (fmt_asn1length(dest+len,tmp)!=1) return 0; diff --git a/fmt_asn1intpayload.c b/fmt_asn1intpayload.c index 57f6b25..317ae79 100644 --- a/fmt_asn1intpayload.c +++ b/fmt_asn1intpayload.c @@ -3,17 +3,20 @@ int fmt_asn1intpayload(char* dest,unsigned long l) { int needed=sizeof l; int i; + int fixup; for (i=1; i>(i*8))) break; } + fixup=(l>>((i-1)*8))&0x80 ? 1 : 0; if (dest) { int j=i; + if (fixup) *dest++=0; while (j) { --j; *dest=(l>>(j*8))&0xff; ++dest; } } - return i; + return i+fixup; } diff --git a/fmt_asn1tag.c b/fmt_asn1tag.c index aa569dc..a08b3c2 100644 --- a/fmt_asn1tag.c +++ b/fmt_asn1tag.c @@ -3,8 +3,8 @@ /* write int in least amount of bytes, return number of bytes */ /* as used in ASN.1 tags */ int fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,unsigned long l) { - /* encoding is either l%128 or (0x80+number of bytes,bytes) */ - int needed=(sizeof l)+1; + /* encoding is either l%128 or (0x1f,...) */ + int needed=(sizeof l)*7/8; int i; if (l<0x1f) { if (dest) *dest=(int)tc+(int)tt+(l&0x1f); diff --git a/ldapclient.c b/ldapclient.c index d0703e2..7f9880e 100644 --- a/ldapclient.c +++ b/ldapclient.c @@ -82,6 +82,10 @@ usage: for (;;) { long slen,mid,op; tmp=read(sock,buf+len,sizeof(buf)-len); + if (tmp<=0) { + buffer_putsflush(buffer_2,"read error.\n"); + return 0; + } len+=tmp; if ((tmp2=scan_ldapmessage(buf,buf+len,&mid,&op,&slen))) { max=buf+slen+tmp2; diff --git a/scan_asn1BOOLEAN.c b/scan_asn1BOOLEAN.c index e918bc6..853a596 100644 --- a/scan_asn1BOOLEAN.c +++ b/scan_asn1BOOLEAN.c @@ -6,7 +6,7 @@ int scan_asn1BOOLEAN(const char* src,const char* max,unsigned long* l) { enum asn1_tagclass tc; enum asn1_tagtype tt; if ((tmp=scan_asn1int(src,max,&tc,&tt,&tag,l))) - if (tc==UNIVERSAL || tt==PRIMITIVE || tag==BOOLEAN) + if (tc==UNIVERSAL && tt==PRIMITIVE && tag==BOOLEAN) return tmp; return 0; } diff --git a/scan_asn1ENUMERATED.c b/scan_asn1ENUMERATED.c index b9a4710..539cd6f 100644 --- a/scan_asn1ENUMERATED.c +++ b/scan_asn1ENUMERATED.c @@ -6,7 +6,7 @@ int scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* l) { enum asn1_tagclass tc; enum asn1_tagtype tt; if ((tmp=scan_asn1int(src,max,&tc,&tt,&tag,l))) - if (tc==UNIVERSAL || tt==PRIMITIVE || tag==ENUMERATED) + if (tc==UNIVERSAL && tt==PRIMITIVE && tag==ENUMERATED) return tmp; return 0; } diff --git a/scan_asn1INTEGER.c b/scan_asn1INTEGER.c index f5bfbb4..e943861 100644 --- a/scan_asn1INTEGER.c +++ b/scan_asn1INTEGER.c @@ -6,7 +6,7 @@ int scan_asn1INTEGER(const char* src,const char* max,unsigned long* l) { enum asn1_tagclass tc; enum asn1_tagtype tt; if ((tmp=scan_asn1int(src,max,&tc,&tt,&tag,l))) - if (tc==UNIVERSAL || tt==PRIMITIVE || tag==INTEGER) + if (tc==UNIVERSAL && tt==PRIMITIVE && tag==INTEGER) return tmp; return 0; } diff --git a/scan_asn1SEQUENCE.c b/scan_asn1SEQUENCE.c index 0b5c2a4..545e450 100644 --- a/scan_asn1SEQUENCE.c +++ b/scan_asn1SEQUENCE.c @@ -8,8 +8,7 @@ int scan_asn1SEQUENCE(const char* src,const char* max,unsigned long* len) { if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) return 0; if (!(tmp=scan_asn1length(src+res,max,len))) return 0; res+=tmp; - if (src+res+*len>max) return 0; - if (tc==UNIVERSAL || tt==CONSTRUCTED || tag==SEQUENCE_OF) + if (tc==UNIVERSAL && tt==CONSTRUCTED && tag==SEQUENCE_OF) return res; return 0; } diff --git a/scan_asn1SET.c b/scan_asn1SET.c index cde7bda..01624f6 100644 --- a/scan_asn1SET.c +++ b/scan_asn1SET.c @@ -8,8 +8,7 @@ int scan_asn1SET(const char* src,const char* max,unsigned long* len) { if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) return 0; if (!(tmp=scan_asn1length(src+res,max,len))) return 0; res+=tmp; - if (src+res+*len>max) return 0; - if (tc==UNIVERSAL || tt==CONSTRUCTED || tag==SET_OF) + if (tc==UNIVERSAL && tt==CONSTRUCTED && tag==SET_OF) return res; return 0; } diff --git a/scan_asn1int.c b/scan_asn1int.c index 0847286..08b637e 100644 --- a/scan_asn1int.c +++ b/scan_asn1int.c @@ -15,7 +15,6 @@ int scan_asn1int(const char* src,const char* max,enum asn1_tagclass* tc,enum asn if (!(len=scan_asn1tag(src,max,tc,tt,tag))) return 0; if (!(tmp=scan_asn1length(src+len,max,&tlen))) return 0; len+=tmp; - if (src+len+tlen>max) return 0; *l=handleint(src+len,tlen); return len+tlen; } diff --git a/scan_asn1length.c b/scan_asn1length.c index 573dad9..6aa2ad1 100644 --- a/scan_asn1length.c +++ b/scan_asn1length.c @@ -14,5 +14,8 @@ int scan_asn1length(const char* src,const char* max,unsigned long* length) { *length=l; } else *length=*src&0x7f; - return src-orig+1; + src++; + if (src+*length>max) return 0; + if (src+*lengthmax) return 0; *s=src+len; return len+*l; } diff --git a/scan_asn1tag.c b/scan_asn1tag.c index 3057a34..5287fd1 100644 --- a/scan_asn1tag.c +++ b/scan_asn1tag.c @@ -7,6 +7,7 @@ int scan_asn1tag(const char* src,const char* max,enum asn1_tagclass* tc,enum asn if (maxmax) return 0; *tag=*tag*128+(*src&0x7F); if (!(*src&0x80)) break; diff --git a/scan_ldapsearchrequest.c b/scan_ldapsearchrequest.c index 312fcb2..bc0c014 100644 --- a/scan_ldapsearchrequest.c +++ b/scan_ldapsearchrequest.c @@ -20,7 +20,7 @@ int scan_ldapsearchrequest(const char* src,const char* max, if (!(tmp=scan_ldapsearchfilter(src+res,max,&s->filter))) goto error; res+=tmp; /* now for the attributelist */ - if (!(tmp=scan_asn1SEQUENCE(src+res,max,&etmp))) goto error; + if (!(tmp=scan_asn1SET(src+res,max,&etmp))) goto error; res+=tmp; { const char* nmax=src+res+etmp; diff --git a/tinyldap.c b/tinyldap.c index 6e0598e..cbc68ff 100644 --- a/tinyldap.c +++ b/tinyldap.c @@ -4,6 +4,7 @@ #include "buffer.h" #include "ldap.h" #include "ldif.h" +#include "open.h" #define BUFSIZE 8192 @@ -61,6 +62,11 @@ int main() { { struct SearchRequest sr; int tmp; + { + int fd=open_write("request"); + write(fd,buf,res+len); + close(fd); + } if ((tmp=scan_ldapsearchrequest(buf+res,buf+res+len,&sr))) { struct ldaprec* r=first; #if 0