add parser for SearchResultEntry
This commit is contained in:
4
Makefile
4
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
|
||||
|
||||
|
||||
4
asn1.h
4
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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
15
freepal.c
Normal file
15
freepal.c
Normal file
@@ -0,0 +1,15 @@
|
||||
#include <stdlib.h>
|
||||
#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;
|
||||
}
|
||||
}
|
||||
1
ldap.h
1
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,
|
||||
|
||||
15
scan_asn1SET.c
Normal file
15
scan_asn1SET.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
44
scan_ldapsearchresultentry.c
Normal file
44
scan_ldapsearchresultentry.c
Normal file
@@ -0,0 +1,44 @@
|
||||
#include <stdlib.h>
|
||||
#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+res<max) {
|
||||
struct string s;
|
||||
struct AttributeDescriptionList* x;
|
||||
long islen;
|
||||
const char* nmax;
|
||||
if (!(tmp=scan_asn1SEQUENCE(src+res,max,&islen))) goto error;
|
||||
res+=tmp; nmax=src+res+islen; if (nmax>max) 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+res<nmax) {
|
||||
if (!(tmp=scan_ldapstring(src+res,max,&s))) goto error;
|
||||
if (!(x=malloc(sizeof(struct AttributeDescriptionList)))) goto error;
|
||||
x->a=s;
|
||||
x->next=(*a)->values;
|
||||
(*a)->values=x;
|
||||
res+=tmp;
|
||||
}
|
||||
a=&(*a)->next;
|
||||
}
|
||||
*a=0;
|
||||
return res;
|
||||
error:
|
||||
freepal(sre->attributes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
55
t2.c
55
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<size) {
|
||||
@@ -95,7 +99,11 @@ int main(int argc,char* argv[]) {
|
||||
printf("scan_ldapbindrequest: %d\n",tmp=scan_ldapbindrequest(ldapsequence+done+res,ldapsequence+done+res+len,&version,&name,&method));
|
||||
printf("version %lu, name \"%.*s\", method %lu\n",version,(int)name.l,name.s,method);
|
||||
if (method==0) {
|
||||
if (scan_ldapstring(ldapsequence+done+res+tmp,ldapsequence+size,&name))
|
||||
enum asn1_tagclass tc;
|
||||
enum asn1_tagtype tt;
|
||||
long tag;
|
||||
if (scan_asn1string(ldapsequence+done+res+tmp,ldapsequence+size,&tc,&tt,&tag,&name.s,&name.l) &&
|
||||
tc==PRIVATE && tt==PRIMITIVE && tag==0)
|
||||
printf("simple \"%.*s\"\n",(int)name.l,name.s);
|
||||
else
|
||||
puts("method 0 but couldn't parse simple");
|
||||
@@ -103,6 +111,22 @@ int main(int argc,char* argv[]) {
|
||||
puts("unknown method!");
|
||||
break;
|
||||
}
|
||||
case BindResponse:
|
||||
puts(" >> 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;
|
||||
|
||||
Reference in New Issue
Block a user