diff --git a/scan_ldapaddrequest.c b/scan_ldapaddrequest.c index 3885039..f5e57ad 100644 --- a/scan_ldapaddrequest.c +++ b/scan_ldapaddrequest.c @@ -3,7 +3,16 @@ #include #include -#if 0 +#ifdef UNITTEST +size_t mallocfail=0; +static void* mymalloc(size_t n) { + if (--mallocfail == 0) return 0; + return malloc(n); +} +#define malloc mymalloc +#endif + +/* AddRequest ::= [APPLICATION 8] SEQUENCE { entry LDAPDN, attributes SEQUENCE OF SEQUENCE { @@ -13,23 +22,25 @@ AttributeList ::= SEQUENCE OF SEQUENCE { type AttributeDescription, vals SET OF AttributeValue } -#endif +*/ size_t scan_ldapaddrequest(const char* src,const char* max,struct AddRequest* a) { size_t res,tmp,oslen; struct Addition* last=0; byte_zero(a,sizeof(*a)); - if (!(res=scan_ldapstring(src,max,&a->entry))) goto error; - if (!(tmp=scan_asn1SEQUENCE(src+res,max,&oslen))) goto error; + if (!(res=scan_ldapstring(src,max,&a->entry))) // fail01 + goto error; + if (!(tmp=scan_asn1SEQUENCE(src+res,max,&oslen))) // fail02 + goto error; res+=tmp; - if (src+res+oslen>max) goto error; max=src+res+oslen; - if (src+res>=max) goto error; /* need at least one record */ + if (src+res>=max) // fail04 + goto error; /* need at least one record */ do { size_t islen; - if (last) { + if (last) { // case01 struct Addition* cur; - if (!(cur=malloc(sizeof(struct Addition)))) + if (!(cur=malloc(sizeof(struct Addition)))) // fail05 goto error; last->next=cur; last=cur; @@ -37,11 +48,12 @@ size_t scan_ldapaddrequest(const char* src,const char* max,struct AddRequest* a) last=&a->a; } byte_zero(last, sizeof(*last)); - if (!(tmp=scan_asn1SEQUENCE(src+res,max,&islen))) + if (!(tmp=scan_asn1SEQUENCE(src+res,max,&islen))) // fail06 goto error; res+=tmp; + const char* seq_max=src+res+islen; /* scan AttributeDescription: */ - if (!(tmp=scan_ldapstring(src+res,max,&last->AttributeDescription))) + if (!(tmp=scan_ldapstring(src+res,max,&last->AttributeDescription))) // fail07 goto error; res+=tmp; @@ -50,25 +62,26 @@ size_t scan_ldapaddrequest(const char* src,const char* max,struct AddRequest* a) size_t set_len; const char* set_max; struct AttributeDescriptionList* ilast=0; - if (!(tmp=scan_asn1SET(src+res,max,&set_len))) { + if (!(tmp=scan_asn1SET(src+res,max,&set_len))) { // fail08 goto error; } res+=tmp; set_max=src+res+set_len; - if (src+res+set_len!=set_max) { + if (seq_max!=set_max) { // fail09 goto error; } while (src+resnext=x; ilast = ilast->next; } else { ilast=&last->vals; } ilast->next=0; - if (!(tmp=scan_ldapstring(src+res,max,&ilast->a))) + if (!(tmp=scan_ldapstring(src+res,max,&ilast->a))) // fail11 goto error; res+=tmp; } @@ -84,6 +97,7 @@ error: static void free_add(struct Addition * a) { while (a) { struct Addition * tmp = a->next; + free_ldapadl(a->vals.next); free(a); a = tmp; } @@ -93,3 +107,86 @@ void free_ldapaddrequest(struct AddRequest * a) { free_ldapadl(a->a.vals.next); free_add(a->a.next); } + +#ifdef UNITTEST +#undef UNITTEST +#include +#include +#include + +#include "scan_ldapstring.c" +#include "scan_asn1STRING.c" +#include "scan_asn1tag.c" +#include "scan_asn1tagint.c" +#include "scan_asn1length.c" +#include "scan_asn1string.c" +#include "scan_asn1SEQUENCE.c" +#include "scan_asn1SET.c" +#include "free_ldapadl.c" + +void byte_zero(void* out,size_t n) { + memset(out,0,n); +} + +int main() { + static char buf[500]= + "\x04\x21""ts=1234567890,ou=blog,d=fefe,c=de" // 0: string(33) + "\x30\x82\x01\x64" // 35: sequence(356) + "\x30\x1a" // 39: sequence(26) + "\x04\x0b" // 41: string(11) + "objectClass" // 43 + "\x31\x0b" // 54: set(11) + "\x04\x09" // 56: string(9) + "blogentry" // 58 + "\x30\x12" // 67: sequence(18) + "\x04\x02" // 69: string(2) + "ts" // 71 + "\x31\x0c" // 73: set(12) + "\x04\x0a" // 75: string(10) + "1234567890" // 77 + "\x30\x82\x01\x30" // 87: sequence(304) + "\x04\x04" // 91: string(4) + "text" // 93 + "\x31\x82\x01\x26" // 97: set(294) + "\x04\x82\x01\x22" // 101: string(290) + "Ein Leser berichtet:
Gestern in einem Regionalzug der \303\226BB:

\"Sehr geehrte Fahrg\303\244ste, aufgrund eines Softwarefehlers muss ich das Fahrzeug neu starten. Das hei\303\237t es gehen kurz die Lichter aus, es wird finster, aber es ist alles in Ordnung.\"

Kann man nichts machen."; // 105 + struct AddRequest a = { 0 }; + assert(scan_ldapaddrequest(buf,buf+500,&a) == 395); + assert(a.entry.l==33 && a.entry.s==buf+2); // dn + struct Addition* b=&a.a; + assert(b->AttributeDescription.l==11 && b->AttributeDescription.s==buf+43); // "objectClass" + assert(b->vals.a.l==9 && b->vals.a.s==buf+58 && b->vals.next==0); // "blogentry" + b=b->next; assert(b); + assert(b->AttributeDescription.l==2 && b->AttributeDescription.s==buf+71); // "ts" + assert(b->vals.a.l==10 && b->vals.a.s==buf+77 && b->vals.next==0); // "1234567890" + b=b->next; assert(b); + assert(b->AttributeDescription.l==4 && b->AttributeDescription.s==buf+93); // "text" + assert(b->vals.a.l==290 && b->vals.a.s==buf+105 && b->vals.next==0); // "Ein..." + assert(b->next==0); + free_ldapaddrequest(&a); + mallocfail=1; assert(scan_ldapaddrequest(buf,buf+500,&a) == 0); // fail10 + + memcpy(buf+75,"\x04\x02xy\x04\x06zyxabc", 12); + mallocfail=0; assert(scan_ldapaddrequest(buf,buf+500,&a) == 395); // case01 + b=a.a.next; assert(b); + assert(b->vals.a.l==2 && b->vals.a.s==buf+77 && b->vals.next); // "xy" + assert(b->vals.next->a.l==6 && b->vals.next->a.s==buf+81 && b->vals.next->next==0); // "zyxabc" + free_ldapaddrequest(&a); + mallocfail=2; assert(scan_ldapaddrequest(buf,buf+500,&a) == 0); // fail05 + + buf[104]=0x23; assert(scan_ldapaddrequest(buf,buf+500,&a) == 0); // fail11 + buf[100]=0x27; assert(scan_ldapaddrequest(buf,buf+500,&a) == 0); // fail08 + buf[100]=0x25; assert(scan_ldapaddrequest(buf,buf+500,&a) == 0); // fail09 + buf[91]=0; assert(scan_ldapaddrequest(buf,buf+500,&a) == 0); // fail07 + buf[87]=0; assert(scan_ldapaddrequest(buf,buf+500,&a) == 0); // fail06 + + strcpy(buf,"\x04\x21""ts=1234567890,ou=blog,d=fefe,c=de" // 0: string(33) + "\x30"); // 35: sequence(0), 0 byte implicit because strcpy not memcpy + assert(scan_ldapaddrequest(buf,buf+500,&a) == 0); // fail04 + buf[35]=0; assert(scan_ldapaddrequest(buf,buf+500,&a) == 0); // fail02 + buf[0]=0; assert(scan_ldapaddrequest(buf,buf+500,&a) == 0); // fail01 + + return 0; +} + +#endif diff --git a/scan_ldapsearchfilter.c b/scan_ldapsearchfilter.c index eac0805..0b8b420 100644 --- a/scan_ldapsearchfilter.c +++ b/scan_ldapsearchfilter.c @@ -49,10 +49,6 @@ size_t scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f) goto error; res+=tmp; nmax=src+res+len; -#if 0 - if (nmax>max) // already caught by scan_asn1length - goto error; -#endif if (!(*f=calloc(1,sizeof(struct Filter)))) // fail04 goto error; switch ((*f)->type=tag) {