From 52d8194d4ffb2bc499ebdd868d4a3ee5214d7d25 Mon Sep 17 00:00:00 2001 From: leitner Date: Mon, 14 Jan 2002 18:24:32 +0000 Subject: [PATCH] more work --- .cvsignore | 1 + Makefile | 6 ++- asn1.h | 5 +++ ldap.h | 66 +++++++++++++++++++++------------ scan_ldapbindrequest.c | 2 +- scan_ldapbindresponse.c | 6 +-- scan_ldapsearchfilter.c | 82 +++++++++++++++++++++++++++++++++++++++++ scan_ldapstring.c | 6 +++ 8 files changed, 144 insertions(+), 30 deletions(-) create mode 100644 scan_ldapsearchfilter.c create mode 100644 scan_ldapstring.c diff --git a/.cvsignore b/.cvsignore index a0f4c34..787e8f6 100644 --- a/.cvsignore +++ b/.cvsignore @@ -4,3 +4,4 @@ t t1 t2 tinyldap +exp.ldif diff --git a/Makefile b/Makefile index e0a8c3b..b7fce02 100644 --- a/Makefile +++ b/Makefile @@ -5,10 +5,12 @@ all: t t1 t2 bindrequest tinyldap ldapclient 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_asn1STRING.o scan_asn1SEQUENCE.o scan_asn1ENUMERATED.o \ +scan_asn1BOOLEAN.o ldap.a: scan_ldapmessage.o fmt_ldapmessage.o fmt_ldapbindrequest.o \ -scan_ldapbindrequest.o fmt_ldapbindresponse.o scan_ldapbindresponse.o +scan_ldapbindrequest.o fmt_ldapbindresponse.o scan_ldapbindresponse.o \ +scan_ldapstring.o scan_ldapsearchfilter.o DIET=diet -Os CC=gcc diff --git a/asn1.h b/asn1.h index ea3d6f4..545ba8e 100644 --- a/asn1.h +++ b/asn1.h @@ -11,6 +11,7 @@ enum asn1_tagtype { }; enum asn1_tag { + BOOLEAN=1, INTEGER=2, OCTET_STRING=4, ENUMERATED=10, @@ -52,6 +53,9 @@ int fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum as /* write ASN.1 INTEGER */ #define fmt_asn1INTEGER(dest,l) fmt_asn1int(dest,UNIVERSAL,PRIMITIVE,INTEGER,l); +/* write ASN.1 BOOLEAN */ +#define fmt_asn1BOOLEAN(dest,l) fmt_asn1int(dest,UNIVERSAL,PRIMITIVE,BOOLEAN,l); + /* write ASN.1 ENUMERATED */ #define fmt_asn1ENUMERATED(dest,l) fmt_asn1int(dest,UNIVERSAL,PRIMITIVE,ENUMERATED,l); @@ -69,6 +73,7 @@ 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_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); diff --git a/ldap.h b/ldap.h index f86f41e..a43c643 100644 --- a/ldap.h +++ b/ldap.h @@ -1,32 +1,45 @@ -struct attributevalueassertion { - unsigned char* desc,* value; - long dlen, vlen; -}; - -struct attributelist { - unsigned char* a; - long alen; - struct attributelist* next; -}; - -struct filter { - enum { - AND=0, OR=1, NOT=2, EQUAL=3, SUBSTRING=4, GREATEQUAL=5, LESSEQUAL=6, PRESENT=7, APPROX=8, EXTENSIBLE=9 - } type; - struct attributevalueassertion ava; - struct attributelist *a; - enum { - PREFIX=0, ANY=1, SUFFIX=2 - } substrtype; - struct filter* x,*next; -}; - struct string { long l; const char* s; }; +struct AttributeValueAssertion { + struct string desc, value; +}; + +struct AttributeList { + struct string a; + struct AttributeList *next; +}; + +struct Filter { + enum { + AND=0, OR=1, NOT=2, EQUAL=3, SUBSTRING=4, GREATEQUAL=5, LESSEQUAL=6, PRESENT=7, APPROX=8, EXTENSIBLE=9 + } type; + struct AttributeValueAssertion ava; + struct AttributeList *a; + enum { + PREFIX=0, ANY=1, SUFFIX=2 + } substrtype; + struct Filter* x,*next; +}; + +struct SearchRequest { + struct string LDAPDN; + enum { baseObject=0, singleLevel=1, wholeSubtree=2 } scope; + enum { + neverDerefAliases=0, + derefInSearching=1, + derefFindingBaseObj=2, + derefAlways=3 + } derefAliases; + unsigned long sizeLimit, timeLimit, typesOnly; + struct Filter* filter; + /* really an AttributeDescriptionList, but the types are equivalent: */ + struct AttributeList* attributes; +}; + enum ldapops { BindRequest=0, BindResponse=1, UnbindRequest=2, @@ -40,8 +53,9 @@ enum ldapops { ExtendedRequest=23 /* das ist doch kein Zufall?! */, ExtendedResponse=24 }; -void freefilter(struct filter* f); +void freefilter(struct Filter* f); +int scan_ldapstring(const char* src,const char* max,struct string* s); int scan_ldapmessage(const char* src,const char* max, long* messageid,long* op,long* len); int scan_ldapbindrequest(const char* src,const char* max, @@ -49,8 +63,12 @@ int scan_ldapbindrequest(const char* src,const char* max, int scan_ldapbindresponse(const char* src,const char* max, long* result,struct string* matcheddn, struct string* errormessage,struct string* referral); +int scan_ldapava(const char* src,const char* max,struct AttributeValueAssertion* a); +int scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f); +int scan_ldapsearchrequest(const char* src,const char* max,struct SearchRequest* s); int fmt_ldapmessage(char* dest,long messageid,long op,long len); int fmt_ldapbindrequest(char* dest,long version,char* name,char* simple); int fmt_ldapbindresponse(char* dest,long result,char* matcheddn, char* errormessage,char* referral); +int fmt_ldapsearchfilter(char* dest,struct Filter* f); diff --git a/scan_ldapbindrequest.c b/scan_ldapbindrequest.c index 1068bec..eff9862 100644 --- a/scan_ldapbindrequest.c +++ b/scan_ldapbindrequest.c @@ -5,7 +5,7 @@ int scan_ldapbindrequest(const char* src,const char* max, long* version,struct string* name,long* method) { int res,tmp; if (!(res=scan_asn1INTEGER(src,max,version))) return 0; - if (!(tmp=scan_asn1STRING(src+res,max,&name->s,&name->l))) return 0; + if (!(tmp=scan_ldapstring(src+res,max,name))) return 0; res+=tmp; { enum asn1_tagclass tc; diff --git a/scan_ldapbindresponse.c b/scan_ldapbindresponse.c index 488ad16..ab83f9b 100644 --- a/scan_ldapbindresponse.c +++ b/scan_ldapbindresponse.c @@ -6,16 +6,16 @@ int scan_ldapbindresponse(const char* src,const char* max, struct string* errormessage,struct string* referral) { int res,tmp; if (!(res=scan_asn1ENUMERATED(src,max,result))) return 0; - if (!(tmp=scan_asn1STRING(src+res,max,&matcheddn->s,&matcheddn->l))) return 0; + if (!(tmp=scan_ldapstring(src+res,max,matcheddn))) return 0; res+=tmp; if (src+ress,&errormessage->l))) return 0; + if (!(tmp=scan_ldapstring(src+res,max,errormessage))) return 0; res+=tmp; } else { errormessage->s=0; errormessage->l=0; } if (src+ress,&referral->l))) return 0; + if (!(tmp=scan_ldapstring(src+res,max,referral))) return 0; res+=tmp; } else { referral->s=0; referral->l=0; diff --git a/scan_ldapsearchfilter.c b/scan_ldapsearchfilter.c new file mode 100644 index 0000000..a4f073f --- /dev/null +++ b/scan_ldapsearchfilter.c @@ -0,0 +1,82 @@ +#include "asn1.h" +#include "ldap.h" +#include + +/* + Filter ::= CHOICE { + and [0] SET OF Filter, + or [1] SET OF Filter, + not [2] Filter, + equalityMatch [3] AttributeValueAssertion, + substrings [4] SubstringFilter, + greaterOrEqual [5] AttributeValueAssertion, + lessOrEqual [6] AttributeValueAssertion, + present [7] AttributeDescription, + approxMatch [8] AttributeValueAssertion, + extensibleMatch [9] MatchingRuleAssertion } + + SubstringFilter ::= SEQUENCE { + type AttributeDescription, + -- at least one must be present + substrings SEQUENCE OF CHOICE { + initial [0] LDAPString, + any [1] LDAPString, + final [2] LDAPString } } + + MatchingRuleAssertion ::= SEQUENCE { + matchingRule [1] MatchingRuleId OPTIONAL, + type [2] AttributeDescription OPTIONAL, + matchValue [3] AssertionValue, + dnAttributes [4] BOOLEAN DEFAULT FALSE } +*/ + +int scan_ldapsearchfilter(const char* src,const char* max,struct Filter** f) { + enum asn1_tagclass tc; + enum asn1_tagtype tt; + unsigned long tag,len; + int res,tmp; + *f=0; + if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) goto error; + if (tc!=CONTEXT_SPECIFIC || tt!=CONSTRUCTED || tag>9) goto error; + if (!(tmp=scan_asn1length(src+res,max,&len))) goto error; + res+=tmp; + if (src+res+len>max) goto error; + if (!(*f=malloc(sizeof(struct Filter)))) goto error; + switch ((*f)->type=tag) { + case 0: /* and [0] SET OF Filter, */ + goto error; + case 1: /* or [1] SET OF Filter, */ + goto error; + case 2: /* not [2] Filter, */ + { + if (!(tmp=scan_ldapsearchfilter(src+res,src+res+len,&(*f)->x))) goto error; + if (tmp!=len) goto error; + } + case 3: /* equalityMatch [3] AttributeValueAssertion, */ + goto error; + case 4: /* substrings [4] SubstringFilter, */ + { + const char* nmax=src+res+len; + long len2; + if (!(tmp=scan_ldapstring(src+res,nmax,&(*f)->ava.desc))) goto error; + res+=tmp; + if (!(tmp=scan_asn1SEQUENCE(src+res,nmax,&len2))) goto error; + if (src+tmp+len2!=nmax) goto error; + goto error; + } + case 5: /* greaterOrEqual [5] AttributeValueAssertion, */ + goto error; + case 6: /* lessOrEqual [6] AttributeValueAssertion, */ + goto error; + case 7: /* present [7] AttributeDescription, */ + goto error; + case 8: /* approxMatch [8] AttributeValueAssertion, */ + goto error; + case 9: /* extensibleMatch [9] MatchingRuleAssertion } */ + goto error; + } + return res; +error: + freefilter((*f)); + return 0; +} diff --git a/scan_ldapstring.c b/scan_ldapstring.c new file mode 100644 index 0000000..58ecb21 --- /dev/null +++ b/scan_ldapstring.c @@ -0,0 +1,6 @@ +#include +#include + +int scan_ldapstring(const char* src,const char* max,struct string* s) { + return scan_asn1STRING(src,max,&s->s,&s->l); +}