From 91f809d60313762f274aad34893b8de142f8634b Mon Sep 17 00:00:00 2001 From: leitner Date: Mon, 14 Jan 2002 23:22:28 +0000 Subject: [PATCH] add parser for SearchResultEntry --- Makefile | 4 +-- asn1.h | 4 ++- freefilter.c | 5 ++++ freepal.c | 15 ++++++++++ ldap.h | 1 + scan_asn1SET.c | 15 ++++++++++ scan_asn1STRING.c | 2 +- scan_asn1length.c | 2 +- scan_ldapsearchfilter.c | 3 +- scan_ldapsearchresultentry.c | 44 +++++++++++++++++++++++++++++ t2.c | 55 ++++++++++++++++++++++++++++++++++-- 11 files changed, 142 insertions(+), 8 deletions(-) create mode 100644 freepal.c create mode 100644 scan_asn1SET.c create mode 100644 scan_ldapsearchresultentry.c diff --git a/Makefile b/Makefile index fcaeece..eacf71b 100644 --- a/Makefile +++ b/Makefile @@ -6,13 +6,13 @@ asn1.a: fmt_asn1intpayload.o fmt_asn1length.o fmt_asn1tag.o \ fmt_asn1int.o fmt_asn1string.o fmt_asn1transparent.o scan_asn1tag.o \ scan_asn1length.o scan_asn1int.o scan_asn1string.o scan_asn1INTEGER.o \ scan_asn1STRING.o scan_asn1SEQUENCE.o scan_asn1ENUMERATED.o \ -scan_asn1BOOLEAN.o scan_asn1rawint.o +scan_asn1BOOLEAN.o scan_asn1rawint.o scan_asn1SET.o ldap.a: scan_ldapmessage.o fmt_ldapmessage.o fmt_ldapbindrequest.o \ scan_ldapbindrequest.o fmt_ldapbindresponse.o scan_ldapbindresponse.o \ scan_ldapstring.o scan_ldapsearchfilter.o scan_ldapsearchrequest.o \ freefilter.o freeava.o scan_ldapava.o fmt_ldapsearchresultentry.o \ -fmt_ldapstring.o +fmt_ldapstring.o freepal.o scan_ldapsearchresultentry.o ldif.a: ldif_parse.o diff --git a/asn1.h b/asn1.h index 1d2d858..a84d451 100644 --- a/asn1.h +++ b/asn1.h @@ -16,6 +16,7 @@ enum asn1_tag { OCTET_STRING=4, ENUMERATED=10, SEQUENCE_OF=16, + SET_OF=17, }; /* write int in least amount of bytes, return number of bytes */ @@ -73,8 +74,9 @@ int scan_asn1string(const char* src,const char* max, enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag, const char** s,unsigned long* l); -int scan_asn1SEQUENCE(const char* src,const char* max,unsigned long* len); int scan_asn1BOOLEAN(const char* src,const char* max,unsigned long* l); int scan_asn1INTEGER(const char* src,const char* max,unsigned long* l); int scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* l); int scan_asn1STRING(const char* src,const char* max,const char** s,unsigned long* l); +int scan_asn1SEQUENCE(const char* src,const char* max,unsigned long* len); +int scan_asn1SET(const char* src,const char* max,unsigned long* len); diff --git a/freefilter.c b/freefilter.c index a57e08b..442dfd1 100644 --- a/freefilter.c +++ b/freefilter.c @@ -6,6 +6,11 @@ void freefilter(struct Filter* f) { freeava(f->a); if (f->x) freefilter(f->x); if (f->next) freefilter(f->next); + while (f->substrings) { + struct Substring* s=f->substrings->next; + free(f->substrings); + f->substrings=s; + } free(f); } } diff --git a/freepal.c b/freepal.c new file mode 100644 index 0000000..9992a09 --- /dev/null +++ b/freepal.c @@ -0,0 +1,15 @@ +#include +#include "ldap.h" + +void freepal(struct PartialAttributeList* l) { + while (l) { + struct PartialAttributeList* x=l->next; + while (l->values) { + struct AttributeDescriptionList* y=l->values->next; + free(l->values); + l->values=y; + } + free(l); + l=x; + } +} diff --git a/ldap.h b/ldap.h index 57849b2..930afd4 100644 --- a/ldap.h +++ b/ldap.h @@ -73,6 +73,7 @@ enum ldapops { void freefilter(struct Filter* f); void freeava(struct AttributeDescriptionList* a); +void freepal(struct PartialAttributeList* a); int scan_ldapstring(const char* src,const char* max,struct string* s); int scan_ldapmessage(const char* src,const char* max, diff --git a/scan_asn1SET.c b/scan_asn1SET.c new file mode 100644 index 0000000..cde7bda --- /dev/null +++ b/scan_asn1SET.c @@ -0,0 +1,15 @@ +#include "asn1.h" + +int scan_asn1SET(const char* src,const char* max,unsigned long* len) { + int res,tmp; + long tag; + enum asn1_tagclass tc; + enum asn1_tagtype tt; + 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) + return res; + return 0; +} diff --git a/scan_asn1STRING.c b/scan_asn1STRING.c index b91cc46..eaa5101 100644 --- a/scan_asn1STRING.c +++ b/scan_asn1STRING.c @@ -6,7 +6,7 @@ int scan_asn1STRING(const char* src,const char* max,const char** s,unsigned long enum asn1_tagclass tc; enum asn1_tagtype tt; if ((tmp=scan_asn1string(src,max,&tc,&tt,&tag,s,l))) - if (tc==UNIVERSAL || tt==PRIMITIVE || tag==OCTET_STRING) + if (tc==UNIVERSAL && tt==PRIMITIVE && tag==OCTET_STRING) return tmp; return 0; } diff --git a/scan_asn1length.c b/scan_asn1length.c index 478f5c1..573dad9 100644 --- a/scan_asn1length.c +++ b/scan_asn1length.c @@ -8,7 +8,7 @@ int scan_asn1length(const char* src,const char* max,unsigned long* length) { long l=0; while (chars>0) { if (++src>=max) return 0; - l=l*256+*src; + l=l*256+(unsigned char)*src; --chars; } *length=l; diff --git a/scan_ldapsearchfilter.c b/scan_ldapsearchfilter.c index e2955a2..39962ac 100644 --- a/scan_ldapsearchfilter.c +++ b/scan_ldapsearchfilter.c @@ -43,6 +43,7 @@ int scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f) { res+=tmp; if (src+res+len>max) goto error; if (!(*f=malloc(sizeof(struct Filter)))) goto error; + (*f)->substrings=0; nmax=src+res+len; switch ((*f)->type=tag) { case 0: /* and [0] SET OF Filter, */ @@ -87,7 +88,7 @@ int scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f) { enum asn1_tagtype tt; enum asn1_tagclass tc; if (!s) goto error; - if (!(tmp=scan_asn1string(src+res,nmax,&tc,&tt,&x,&s->s.s,&s->s.l))) goto error; + if (!(tmp=scan_asn1string(src+res,nmax,&tc,&tt,&x,&s->s.s,&s->s.l))) { free(s); goto error; } if (x>2) goto error; s->substrtype=x; res+=tmp; diff --git a/scan_ldapsearchresultentry.c b/scan_ldapsearchresultentry.c new file mode 100644 index 0000000..72bef24 --- /dev/null +++ b/scan_ldapsearchresultentry.c @@ -0,0 +1,44 @@ +#include +#include "asn1.h" +#include "ldap.h" + +int scan_ldapsearchresultentry(const char* src,const char* max,struct SearchResultEntry* sre) { + int res,tmp; + long oslen; /* outer sequence length */ + struct PartialAttributeList** a=&sre->attributes; + *a=0; + if (!(res=scan_ldapstring(src,max,&sre->objectName))) goto error; + if (!(tmp=scan_asn1SEQUENCE(src+res,max,&oslen))) goto error; + res+=tmp; + if (src+res+oslen>max) goto error; + max=src+res+oslen; /* we now may have a stronger limit */ + while (src+resmax) goto error; + if (!(tmp=scan_ldapstring(src+res,nmax,&s))) goto error; + if (!(*a=malloc(sizeof(struct PartialAttributeList)))) goto error; + (*a)->next=0; (*a)->values=0; (*a)->type=s; + res+=tmp; + if (!(tmp=scan_asn1SET(src+res,max,&islen))) goto error; + res+=tmp; if (src+res+islen!=nmax) goto error; + while (src+resa=s; + x->next=(*a)->values; + (*a)->values=x; + res+=tmp; + } + a=&(*a)->next; + } + *a=0; + return res; +error: + freepal(sre->attributes); + return 0; +} + diff --git a/t2.c b/t2.c index d6f70cc..16eae60 100644 --- a/t2.c +++ b/t2.c @@ -4,6 +4,10 @@ #include "asn1.h" #include "ldap.h" +/* this is some sort of protocol analyzer. You give it a file name with + * a network dump of an LDAP correspondence, and it will try to parse it + * and display it in human readable form */ + void printava(struct AttributeValueAssertion* a,const char* rel) { printf("[%.*s %s %.*s]",(int)a->desc.l,a->desc.s,rel,(int)a->value.l,a->value.s); } @@ -78,7 +82,7 @@ int main(int argc,char* argv[]) { #if 1 unsigned long size; // char* ldapsequence=mmap_read("req",&size); - char* ldapsequence=mmap_read(argc>1?argv[1]:"capture/127.000.000.001.38433-127.000.000.001.00389",&size); + char* ldapsequence=mmap_read(argc>1?argv[1]:"/tmp/ldap/127.000.000.001.00389-127.000.000.001.38433",&size); long messageid, op, len; int res,done=0; while (done> BindResponse <<"); + { + long result; + struct string matcheddn,errormessage,referral; + int tmp; + printf("scan_ldapbindresponse: %d\n", + tmp=scan_ldapbindresponse(ldapsequence+done+res,ldapsequence+done+res+len, + &result,&matcheddn,&errormessage,&referral)); + printf("result %lu, matcheddn \"%.*s\", errormessage \"%.*s\", referral \"%.*s\"\n", + result,(int)matcheddn.l,matcheddn.s, + (int)errormessage.l,errormessage.s, + (int)referral.l,referral.s); + break; + } + break; case SearchRequest: puts(" >> SearchRequest <<"); { @@ -116,6 +140,33 @@ int main(int argc,char* argv[]) { printal(br.attributes); break; } + case SearchResultEntry: + puts(" >> SearchResultEntry <<"); + { + struct SearchResultEntry sre; + int tmp; + if ((tmp=scan_ldapsearchresultentry(ldapsequence+done+res,ldapsequence+done+res+len,&sre))) { + struct PartialAttributeList* pal=sre.attributes; + printf("objectName \"%.*s\"\n",(int)sre.objectName.l,sre.objectName.s); + while (pal) { + struct AttributeDescriptionList* adl=pal->values; + printf(" %.*s:",(int)pal->type.l,pal->type.s); + while (adl) { + printf("%.*s",(int)adl->a.l,adl->a.s); + if (adl->next) printf(", "); + adl=adl->next; + } + printf("\n"); + pal=pal->next; + } + } else + puts("punt!"); + } + break; + case SearchResultDone: + puts(" >> SearchResultDone <<"); + puts("to be done"); + break; case UnbindRequest: puts(" >> UnbindRequest <<"); break;