sprinkle some attributes
This commit is contained in:
33
asn1.h
33
asn1.h
@@ -6,6 +6,8 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
enum asn1_tagclass {
|
||||
UNIVERSAL=(0<<6),
|
||||
APPLICATION=(1<<6),
|
||||
@@ -34,34 +36,41 @@ enum asn1_tag {
|
||||
};
|
||||
|
||||
/* write variable length integer in the encoding used in tag and oid */
|
||||
att_write(1)
|
||||
size_t fmt_asn1tagint(char* dest,unsigned long val);
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 tag */
|
||||
att_write(1)
|
||||
size_t fmt_asn1tag(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||
unsigned long tag);
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 length */
|
||||
att_write(1)
|
||||
size_t fmt_asn1length(char* dest,size_t 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! */
|
||||
att_write(1)
|
||||
size_t fmt_asn1intpayload(char* dest,unsigned long val);
|
||||
|
||||
/* 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! */
|
||||
att_write(1)
|
||||
size_t fmt_asn1sintpayload(char* dest,signed long val);
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 INTEGER or ENUMERATED. */
|
||||
att_write(1)
|
||||
size_t fmt_asn1int(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||
enum asn1_tag tag,unsigned long val);
|
||||
|
||||
/* write int in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 INTEGER or ENUMERATED. */
|
||||
att_write(1)
|
||||
size_t fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||
enum asn1_tag tag,signed long val);
|
||||
|
||||
@@ -71,16 +80,19 @@ size_t fmt_asn1sint(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||
/* does not wrote the payload itself, just the header! First construct
|
||||
* the sequence/octet string so you know the length, then use
|
||||
* fmt_asn1transparent to write the header before it */
|
||||
att_write(1)
|
||||
size_t fmt_asn1transparent(char* dest,enum asn1_tagclass tc,
|
||||
enum asn1_tagtype tt,enum asn1_tag tag,size_t len);
|
||||
|
||||
/* write string in least amount of bytes, return number of bytes */
|
||||
/* as used in ASN.1 OCTET STRING. */
|
||||
att_write(1)
|
||||
size_t fmt_asn1string(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||
enum asn1_tag tag,const char* c,size_t l);
|
||||
|
||||
/* same but for bitstrings.
|
||||
* l in this case means the number of BITS in c, not bytes */
|
||||
att_write(1)
|
||||
size_t fmt_asn1bitstring(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||
enum asn1_tag tag,const char* c,size_t l);
|
||||
|
||||
@@ -102,6 +114,7 @@ size_t fmt_asn1bitstring(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,
|
||||
/* write ASN.1 SET */
|
||||
#define fmt_asn1SET(dest,l) fmt_asn1transparent(dest,UNIVERSAL,CONSTRUCTED,SET_OF,l)
|
||||
|
||||
att_write(1) __bufin(5,6)
|
||||
size_t fmt_asn1OID(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum asn1_tag tag,const size_t* array,size_t len);
|
||||
|
||||
|
||||
@@ -111,61 +124,78 @@ size_t fmt_asn1OID(char* dest,enum asn1_tagclass tc,enum asn1_tagtype tt,enum as
|
||||
* the return value is the number of bytes parsed or 0 for parse error */
|
||||
|
||||
/* parse ASN.1 variable length integer as used in tag and oid */
|
||||
att_read(1) att_write(3)
|
||||
size_t scan_asn1tagint(const char* src,const char* max,unsigned long* val);
|
||||
|
||||
/* parse ASN.1 tag into a tag class, tag type and tag number */
|
||||
att_read(1) att_write(3) att_write(4) att_write(5)
|
||||
size_t scan_asn1tag(const char* src,const char* max,
|
||||
enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag);
|
||||
|
||||
/* parse ASN.1 length */
|
||||
/* only return success if source buffer is large enough to hold length bytes */
|
||||
att_read(1) att_write(3)
|
||||
size_t scan_asn1length(const char* src,const char* max,size_t* length);
|
||||
|
||||
/* Same but does not check the source buffer is large enough to hold
|
||||
* length bytes. Useful to find out how many more bytes we need to read
|
||||
* from network */
|
||||
att_read(1) att_write(3)
|
||||
size_t scan_asn1length_nolengthcheck(const char* src,const char* max, size_t* length);
|
||||
|
||||
/* helper for scan_asn1INT, scan_asn1ENUMERATED and scan_asn1BOOLEAN */
|
||||
att_read(1) att_write(3) att_write(4) att_write(5) att_write(6)
|
||||
size_t scan_asn1int(const char* src,const char* max,
|
||||
enum asn1_tagclass* tc,enum asn1_tagtype* tt, unsigned long* tag,
|
||||
long* val);
|
||||
|
||||
/* parse raw integer (payload after tag and length); internal helper */
|
||||
/* internal helper; parse raw integer (payload after tag and length) */
|
||||
att_read(1) att_write(4)
|
||||
size_t scan_asn1rawint(const char* src,const char* max,size_t len,long* val);
|
||||
|
||||
/* parse string with tag and length.
|
||||
* Points s to the first byte in the string, and writes the length of
|
||||
* the string to l. */
|
||||
att_read(1) att_write(3) att_write(4) att_write(5) att_write(6) att_write(7)
|
||||
size_t scan_asn1string(const char* src,const char* max,
|
||||
enum asn1_tagclass* tc,enum asn1_tagtype* tt,unsigned long* tag,
|
||||
const char** s,size_t* l);
|
||||
|
||||
/* the following expect a specific universal type and return a parse
|
||||
* error if the tag does not match that type */
|
||||
att_read(1) att_write(3)
|
||||
size_t scan_asn1BOOLEAN(const char* src,const char* max,int* l);
|
||||
att_read(1) att_write(3)
|
||||
size_t scan_asn1INTEGER(const char* src,const char* max,signed long* l);
|
||||
att_read(1) att_write(3)
|
||||
size_t scan_asn1ENUMERATED(const char* src,const char* max,unsigned long* l);
|
||||
att_read(1) att_write(3) att_write(4)
|
||||
size_t scan_asn1STRING(const char* src,const char* max,const char** s,size_t* l);
|
||||
att_read(1) att_write(3) att_write(4)
|
||||
size_t scan_asn1BITSTRING(const char* src,const char* max,const char** s,size_t* l);
|
||||
/* note: these only parse the header. src + return value points to first element */
|
||||
att_read(1) att_write(3)
|
||||
size_t scan_asn1SEQUENCE(const char* src,const char* max,size_t* len);
|
||||
/* scan_asn1SEQUENCE will only return success if the header and the
|
||||
* whole contents fit into src..max; this function will only parse the
|
||||
* outer sequence header and return the number of bytes it say it wants.
|
||||
* For finding out how much more data you need to read from the socket. */
|
||||
att_read(1) att_write(3)
|
||||
size_t scan_asn1SEQUENCE_nolengthcheck(const char* src,const char* max,size_t* len);
|
||||
att_read(1) att_write(3)
|
||||
size_t scan_asn1SET(const char* src,const char* max,size_t* len);
|
||||
|
||||
/* scan an ASN.1 OID and put the numbers into array.
|
||||
* Return numbers of bytes parsed or 0 on error.
|
||||
* Put at most arraylen longs into array; if the OID is longer, or if array is NULL, return real number in arraylen and return 0
|
||||
* If 0 is returned and arraylen is also 0, there was a parse error */
|
||||
att_read(1) att_write(3) att_mangle(4)
|
||||
size_t scan_asn1oid(const char* src,const char* max,size_t* array,size_t* arraylen);
|
||||
/* internal helper, assumes you already read tag and length and max=src+length */
|
||||
/* call with *arraylen = sizeof(array)/sizeof(array[0]) */
|
||||
/* returns needed array size in *arraylen */
|
||||
/* rule of thumb: (number of bytes in input + 1) needed */
|
||||
att_read(1) att_write(3) att_mangle(4)
|
||||
size_t scan_asn1rawoid(const char* src,const char* max,size_t* array,size_t* arraylen);
|
||||
|
||||
struct string {
|
||||
@@ -217,6 +247,7 @@ extern const struct oidlookup {
|
||||
enum x509_oid id;
|
||||
} oid2string[];
|
||||
|
||||
__strin(1) att_pure
|
||||
size_t lookupoid(const char* oid,size_t l);
|
||||
|
||||
/* Generic parser and formatter routines: */
|
||||
|
||||
6
bstr.h
6
bstr.h
@@ -1,4 +1,5 @@
|
||||
#include <stddef.h>
|
||||
#include <libowfat/compiler.h>
|
||||
|
||||
/* The LDAP read-only data store is mmapped and trusted, because it
|
||||
* takes higher privileges than tinyldap has to modify it.
|
||||
@@ -12,13 +13,18 @@
|
||||
* This means we need small wrappers around strlen and strcmp.
|
||||
* These are those small wrappers. */
|
||||
|
||||
__strin(1) __strin(2) att_pure
|
||||
int bstr_diff(const char* a,const char* b);
|
||||
#define bstr_equal(s,t) (!bstr_diff((s),(t)))
|
||||
|
||||
__strin(1) __strnin(2,3) att_pure
|
||||
int bstr_diff2(const char* a,const char* b,size_t blen);
|
||||
#define bstr_equal2(s,t,l) (!bstr_diff2((s),(t),(l)))
|
||||
|
||||
__strin(1) att_pure
|
||||
size_t bstrlen(const char* a);
|
||||
__strin(1) att_pure
|
||||
size_t bstrstart(const char* a); /* offset of first byte of bstring */
|
||||
|
||||
__strin(1) att_pure
|
||||
const char* bstrfirst(const char* a); /* pointer to first byte of bstring */
|
||||
|
||||
18
ldap.h
18
ldap.h
@@ -4,16 +4,22 @@
|
||||
#include <stddef.h>
|
||||
#include <inttypes.h>
|
||||
#include "asn1.h"
|
||||
// asn1.h includes libowfat/compiler.h, so don't include it again here
|
||||
|
||||
/* return zero if same, otherwise nonzero */
|
||||
int matchstring(struct string* s,const char* c);
|
||||
int matchcasestring(struct string* s,const char* c);
|
||||
int matchprefix(struct string* s,const char* c);
|
||||
int matchcaseprefix(struct string* s,const char* c);
|
||||
att_read(1) __strin(2)
|
||||
int matchstring(const struct string* s,const char* c);
|
||||
att_read(1) __strin(2)
|
||||
int matchcasestring(const struct string* s,const char* c);
|
||||
att_read(1) __strin(2)
|
||||
int matchprefix(const struct string* s,const char* c);
|
||||
att_read(1) __strin(2)
|
||||
int matchcaseprefix(const struct string* s,const char* c);
|
||||
|
||||
/* "ou=fnord; O=fefe; c=de" -> "ou=fnord,o=fefe,c=de" */
|
||||
/* returns the length of the new string */
|
||||
size_t normalize_dn(char* dest,const char* src,int len);
|
||||
att_write(1) __strnin(2,3)
|
||||
size_t normalize_dn(char* dest,const char* src,size_t len);
|
||||
|
||||
struct AttributeValueAssertion {
|
||||
struct string desc, value;
|
||||
@@ -55,7 +61,7 @@ struct Filter {
|
||||
|
||||
struct SearchRequest {
|
||||
struct string baseObject;
|
||||
enum { baseObject=0, singleLevel=1, wholeSubtree=2 } scope;
|
||||
enum { baseObjectOnly=0, singleLevel=1, wholeSubtree=2 } scope;
|
||||
enum {
|
||||
neverDerefAliases=0,
|
||||
derefInSearching=1,
|
||||
|
||||
@@ -190,7 +190,7 @@ int ldap_match_mapped(uint32 ofs,struct SearchRequest* sr) {
|
||||
/* it is. If scope==wholeSubtree, the scope check is also done */
|
||||
switch (sr->scope) {
|
||||
case wholeSubtree: break;
|
||||
case baseObject: if (l==sr->baseObject.l) break; return 0;
|
||||
case baseObjectOnly: if (l==sr->baseObject.l) break; return 0;
|
||||
default:
|
||||
i=str_chr(map+k,',');
|
||||
if (i+2>=l-sr->baseObject.l) break;
|
||||
|
||||
@@ -154,7 +154,7 @@ int ldap_match_sre(struct SearchResultEntry* sre,struct SearchRequest* sr) {
|
||||
return 0;
|
||||
switch (sr->scope) {
|
||||
case wholeSubtree: break;
|
||||
case baseObject: if (sre->objectName.l==sr->baseObject.l) break; return 0;
|
||||
case baseObjectOnly: if (sre->objectName.l==sr->baseObject.l) break; return 0;
|
||||
default:
|
||||
for (i=0; i<sre->objectName.l; ++i)
|
||||
if (sre->objectName.s[i]==',')
|
||||
|
||||
@@ -267,7 +267,9 @@ lookagain:
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (!m) if (!(m=malloc(sizeof(struct ldaprec)))) return 2;
|
||||
if (!m)
|
||||
if (!(m=malloc(sizeof(struct ldaprec))))
|
||||
return 2;
|
||||
|
||||
(*l)->next=m;
|
||||
m->n=0; m->dn=-1; m->next=0;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
#include <libowfat/str.h>
|
||||
|
||||
/* behave like strcmp, but also return 0 if s is a prefix of c. */
|
||||
int matchcaseprefix(struct string* s,const char* c) {
|
||||
int matchcaseprefix(const struct string* s,const char* c) {
|
||||
unsigned int l,l1,i;
|
||||
if (!c) return -1;
|
||||
l1=l=str_len(c);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "ldif.h"
|
||||
|
||||
/* like matchstring, but case insensitively */
|
||||
int matchcasestring(struct string* s,const char* c) {
|
||||
int matchcasestring(const struct string* s,const char* c) {
|
||||
unsigned int l,l1,i;
|
||||
if (!c) return -1;
|
||||
l1=l=bstrlen(c);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "bstr.h"
|
||||
|
||||
/* behave like strcmp, but also return 0 if s is a prefix of c. */
|
||||
int matchprefix(struct string* s,const char* c) {
|
||||
int matchprefix(const struct string* s,const char* c) {
|
||||
unsigned int l,l1,i;
|
||||
if (!c) return -1;
|
||||
l1=l=bstrlen(c);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "ldif.h"
|
||||
|
||||
/* behave like strcmp */
|
||||
int matchstring(struct string* s,const char* c) {
|
||||
int matchstring(const struct string* s,const char* c) {
|
||||
unsigned int l,l1,i;
|
||||
if (!c) return -1;
|
||||
l1=l=bstrlen(c);
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
/* "ou=fnord; O=fefe; c=de" -> "ou=fnord,o=fefe,c=de" */
|
||||
/* returns the length of the new string */
|
||||
size_t normalize_dn(char* dest,const char* src,int len) {
|
||||
size_t normalize_dn(char* dest,const char* src,size_t len) {
|
||||
int makelower=1;
|
||||
char* orig=dest;
|
||||
while (len) {
|
||||
|
||||
Reference in New Issue
Block a user