provide some infrastructure for signed ints
This commit is contained in:
11
Makefile
11
Makefile
@@ -1,12 +1,13 @@
|
||||
DEBUG=1
|
||||
#DEBUG=1
|
||||
|
||||
all: t t1 t2 bindrequest tinyldap ldapclient ldapclient_str
|
||||
all: t1 t2 bindrequest tinyldap ldapclient ldapclient_str # t
|
||||
|
||||
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_asn1SET.o
|
||||
scan_asn1BOOLEAN.o scan_asn1rawint.o scan_asn1SET.o fmt_asn1sint.o \
|
||||
fmt_asn1sintpayload.o
|
||||
|
||||
ldap.a: scan_ldapmessage.o fmt_ldapmessage.o fmt_ldapbindrequest.o \
|
||||
scan_ldapbindrequest.o scan_ldapbindresponse.o scan_ldapresult.o \
|
||||
@@ -20,10 +21,10 @@ ldif.a: ldif_parse.o ldap_match.o strduptab.o strstorage.o
|
||||
|
||||
DIET=diet -Os
|
||||
CC=gcc
|
||||
CFLAGS=-pipe -I. -Wall
|
||||
CFLAGS=-pipe -I. -Wall -W
|
||||
ifneq ($(DEBUG),)
|
||||
DIET=diet
|
||||
CFLAGS=-pipe -I. -Wall -g
|
||||
CFLAGS=-pipe -I. -Wall -W -g
|
||||
endif
|
||||
|
||||
%.o: %.c
|
||||
|
||||
35
asn1.h
35
asn1.h
@@ -1,3 +1,6 @@
|
||||
/* parser and formatter for ASN.1 DER encoding.
|
||||
* The parser can read BER encoding, too. */
|
||||
|
||||
enum asn1_tagclass {
|
||||
UNIVERSAL=(0<<6),
|
||||
APPLICATION=(1<<6),
|
||||
@@ -32,10 +35,19 @@ int fmt_asn1length(char* dest,unsigned long l);
|
||||
* and length headers! */
|
||||
int fmt_asn1intpayload(char* dest,unsigned long l);
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 INTEGER. This only does the payload, not the tag
|
||||
* and length headers! */
|
||||
int fmt_asn1sintpayload(char* dest,signed long l);
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 INTEGER or ENUMERATED. */
|
||||
int fmt_asn1int(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,unsigned long l);
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 INTEGER or ENUMERATED. */
|
||||
int fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,signed long l);
|
||||
|
||||
/* write any data type that does not require transformation in the least
|
||||
* amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 OCTET STRING, SEQUENCE etc. */
|
||||
@@ -66,19 +78,38 @@ int fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum as
|
||||
/* write ASN.1 SET */
|
||||
#define fmt_asn1SET(dest,l) fmt_asn1transparent(dest,UNIVERSAL,CONSTRUCTED,SET_OF,l);
|
||||
|
||||
|
||||
/* conventions for the parser routines:
|
||||
* src points to the first byte to parse
|
||||
* max points to the first byte behind the buffer
|
||||
* the return value is the number of bytes parsed or 0 for parse error */
|
||||
|
||||
/* parse ASN.1 tag into a tag class, tag type and tag number */
|
||||
int scan_asn1tag(const char* src,const char* max,
|
||||
enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag);
|
||||
|
||||
/* parse ASN.1 length */
|
||||
int scan_asn1length(const char* src,const char* max,unsigned long* length);
|
||||
|
||||
/* parse ASN.1 integer with tag and length */
|
||||
int scan_asn1int(const char* src,const char* max,
|
||||
enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag,
|
||||
unsigned long* l);
|
||||
long* l);
|
||||
|
||||
/* parse raw integer (payload after tag and length); internal helper */
|
||||
int scan_asn1rawint(const char* src,const char* max,unsigned int len,long* i);
|
||||
|
||||
/* parse string with tag and length.
|
||||
* Points s to the first byte in the string, and writes the length of
|
||||
* the string to l. */
|
||||
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);
|
||||
|
||||
/* the following expect a specific universal type and return a parse
|
||||
* error if the tag does not match that type */
|
||||
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_asn1INTEGER(const char* src,const char* max,signed 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);
|
||||
|
||||
11
fmt_asn1sint.c
Normal file
11
fmt_asn1sint.c
Normal file
@@ -0,0 +1,11 @@
|
||||
#include <asn1.h>
|
||||
|
||||
int fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,signed long l) {
|
||||
int len,tmp;
|
||||
/* first the tag */
|
||||
if (!dest) return fmt_asn1tag(0,tc,tt,tag)+1+fmt_asn1intpayload(0,l);
|
||||
len=fmt_asn1tag(dest,tc,tt,tag);
|
||||
tmp=fmt_asn1sintpayload(dest+len+1,l);
|
||||
if (fmt_asn1length(dest+len,tmp)!=1) return 0;
|
||||
return len+tmp+1;
|
||||
}
|
||||
23
fmt_asn1sintpayload.c
Normal file
23
fmt_asn1sintpayload.c
Normal file
@@ -0,0 +1,23 @@
|
||||
#include <asn1.h>
|
||||
|
||||
int fmt_asn1sintpayload(char* dest,signed long l) {
|
||||
int needed=sizeof l;
|
||||
int i;
|
||||
signed long tmp=0x7f;
|
||||
if (l>=0) return fmt_asn1intpayload(dest,l);
|
||||
for (i=1; i<needed; ++i) {
|
||||
/* assumes two's complement */
|
||||
if ((l|tmp) == -1)
|
||||
break;
|
||||
tmp=(tmp<<8)|0xff;
|
||||
}
|
||||
if (dest) {
|
||||
int j=i;
|
||||
while (j) {
|
||||
--j;
|
||||
*dest=(l>>(j*8))&0xff;
|
||||
++dest;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
@@ -43,7 +43,7 @@ int fmt_ldapsearchfilter(char* dest,struct Filter* f) {
|
||||
l=fmt_ldapstring(nd,&f->ava.desc);
|
||||
l+=fmt_asn1SEQUENCE(nd+l,tmp);
|
||||
l+=fmt_ldapsubstring(nd+l,f->substrings);
|
||||
sum+=l;
|
||||
sum=l;
|
||||
}
|
||||
break;
|
||||
case PRESENT:
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include "byte.h"
|
||||
#include "ldif.h"
|
||||
|
||||
/* behave like strcmp */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "asn1.h"
|
||||
|
||||
int scan_asn1INTEGER(const char* src,const char* max,unsigned long* l) {
|
||||
int scan_asn1INTEGER(const char* src,const char* max,signed long* l) {
|
||||
int tmp;
|
||||
long tag;
|
||||
enum asn1_tagclass tc;
|
||||
|
||||
@@ -1,20 +1,11 @@
|
||||
#include "asn1.h"
|
||||
|
||||
static long int handleint(const unsigned char* c,int len) {
|
||||
long l=0;
|
||||
while (len) {
|
||||
l=l*256+*c;
|
||||
--len; ++c;
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
int scan_asn1int(const char* src,const char* max,enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag,unsigned long* l) {
|
||||
int scan_asn1int(const char* src,const char* max,enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag,signed long* l) {
|
||||
int len,tmp;
|
||||
long tlen;
|
||||
if (!(len=scan_asn1tag(src,max,tc,tt,tag))) return 0;
|
||||
if (!(tmp=scan_asn1length(src+len,max,&tlen))) return 0;
|
||||
len+=tmp;
|
||||
*l=handleint(src+len,tlen);
|
||||
if (!(scan_asn1rawint(src+len,max,tlen,l))) return 0;
|
||||
return len+tlen;
|
||||
}
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
#include "asn1.h"
|
||||
|
||||
int scan_asn1rawint(const char* src,const char* max,unsigned int len,long* l) {
|
||||
int i;
|
||||
*l=0;
|
||||
for (i=0; i<len; ++i) {
|
||||
*l=*l*256+*src;
|
||||
unsigned int i,j;
|
||||
long m;
|
||||
if (*src<0) m=-1; else m=0;
|
||||
for (i=j=0; i<len; ++i,++j) {
|
||||
if ((m==0 && *src==0) || (m==-1 && *src==-1)) --j;
|
||||
m=(m<<8)|(unsigned char)*src;
|
||||
++src;
|
||||
if (src>max) return 0;
|
||||
}
|
||||
if (j>sizeof(long)) return 0;
|
||||
*l=m;
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -10,8 +10,7 @@ int scan_ldapbindrequest(const char* src,const char* max,
|
||||
{
|
||||
enum asn1_tagclass tc;
|
||||
enum asn1_tagtype tt;
|
||||
long method;
|
||||
if (!(tmp=scan_asn1tag(src+res,max,&tc,&tt,&method))) return 0;
|
||||
if (!(tmp=scan_asn1tag(src+res,max,&tc,&tt,method))) return 0;
|
||||
if (tc!=PRIVATE || tt!=PRIMITIVE) return 0;
|
||||
}
|
||||
return res;
|
||||
|
||||
@@ -34,7 +34,8 @@ 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;
|
||||
int res;
|
||||
unsigned int tmp;
|
||||
const char* nmax;
|
||||
*f=0;
|
||||
if (!(res=scan_asn1tag(src,max,&tc,&tt,&tag))) goto error;
|
||||
|
||||
5
t2.c
5
t2.c
@@ -87,7 +87,8 @@ int main(int argc,char* argv[]) {
|
||||
// char* ldapsequence=mmap_read("req",&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;
|
||||
int res;
|
||||
unsigned long done=0;
|
||||
while (done<size) {
|
||||
printf("scan_ldapmessage: %d\n",res=scan_ldapmessage(ldapsequence+done,ldapsequence+size,&messageid,&op,&len));
|
||||
if (!res) { puts("punt!"); break; }
|
||||
@@ -151,7 +152,7 @@ int main(int argc,char* argv[]) {
|
||||
case 2: printf("derefFindingBaseObj"); break;
|
||||
case 3: printf("derefAlways"); break;
|
||||
}
|
||||
printf(", size limit %d, time limit %d\n",br.sizeLimit,br.timeLimit);
|
||||
printf(", size limit %ld, time limit %ld\n",br.sizeLimit,br.timeLimit);
|
||||
printfilter(br.filter); printf("\n");
|
||||
}
|
||||
printal(br.attributes);
|
||||
|
||||
Reference in New Issue
Block a user