This diff is a final synchronization of ber.c and ber.h. It basically takes (2012) ber additions to snmpd and adds them back to ldap, ldapd, and ypldap instances. See usr.sbin/snmpd/ber.c revision 1.24 commit log for a summary of those changes (e.g. SNMPv2 traps, User-based Security Model, callback for the USM HMAC calculations).
The ber code in this diff is not used by ldap, ldapd, or ypldap, but these changes will make maintenance easier going forward. The current (six) consumers of this ber implementation are as follows: - usr.bin/ldap - usr.sbin/ldapctl - usr.sbin/ldapd - usr.sbin/snmpctl - usr.sbin/snmpd - usr.sbin/ypldap Ok? Index: usr.bin/ldap/ber.c =================================================================== RCS file: /cvs/src/usr.bin/ldap/ber.c,v retrieving revision 1.6 diff -u -p -r1.6 ber.c --- usr.bin/ldap/ber.c 29 Jun 2018 18:28:41 -0000 1.6 +++ usr.bin/ldap/ber.c 29 Jun 2018 19:41:59 -0000 @@ -631,10 +631,11 @@ ber_scanf_elements(struct ber_element *b va_list ap; int *d, level = -1; unsigned long *t; - long long *i; + long long *i, l; void **ptr; size_t *len, ret = 0, n = strlen(fmt); char **s; + off_t *pos; struct ber_oid *o; struct ber_element *parent[_MAX_SEQ], **e; @@ -656,6 +657,13 @@ ber_scanf_elements(struct ber_element *b goto fail; ret++; break; + case 'd': + d = va_arg(ap, int *); + if (ber_get_integer(ber, &l) == -1) + goto fail; + *d = l; + ret++; + break; case 'e': e = va_arg(ap, struct ber_element **); *e = ber; @@ -712,6 +720,11 @@ ber_scanf_elements(struct ber_element *b goto fail; ret++; break; + case 'p': + pos = va_arg(ap, off_t *); + *pos = ber_getpos(ber); + ret++; + continue; case '{': case '(': if (ber->be_encoding != BER_TYPE_SEQUENCE && @@ -821,6 +834,12 @@ ber_read_elements(struct ber *ber, struc return root; } +off_t +ber_getpos(struct ber_element *elm) +{ + return elm->be_offs; +} + void ber_free_element(struct ber_element *root) { @@ -893,6 +912,8 @@ ber_dump_element(struct ber *ber, struct uint8_t u; ber_dump_header(ber, root); + if (root->be_cb) + root->be_cb(root->be_cbarg, ber->br_wptr - ber->br_wbuf); switch (root->be_encoding) { case BER_TYPE_BOOLEAN: @@ -1101,6 +1122,7 @@ ber_read_element(struct ber *ber, struct elm->be_type = type; elm->be_len = len; + elm->be_offs = ber->br_offs; /* element position within stream */ elm->be_class = class; if (elm->be_encoding == 0) { @@ -1232,6 +1254,15 @@ ber_set_application(struct ber *b, unsig } void +ber_set_writecallback(struct ber_element *elm, void (*cb)(void *, size_t), + void *arg) +{ + elm->be_cb = cb; + elm->be_cbarg = arg; +} + + +void ber_free(struct ber *b) { free(b->br_wbuf); @@ -1258,5 +1289,33 @@ ber_read(struct ber *ber, void *buf, siz b += r; remain -= r; } - return (b - (u_char *)buf); + r = b - (u_char *)buf; + ber->br_offs += r; + return r; +} + +int +ber_oid_cmp(struct ber_oid *a, struct ber_oid *b) +{ + size_t i; + for (i = 0; i < BER_MAX_OID_LEN; i++) { + if (a->bo_id[i] != 0) { + if (a->bo_id[i] == b->bo_id[i]) + continue; + else if (a->bo_id[i] < b->bo_id[i]) { + /* b is a successor of a */ + return (1); + } else { + /* b is a predecessor of a */ + return (-1); + } + } else if (b->bo_id[i] != 0) { + /* b is larger, but a child of a */ + return (2); + } else + break; + } + + /* b and a are identical */ + return (0); } Index: usr.bin/ldap/ber.h =================================================================== RCS file: /cvs/src/usr.bin/ldap/ber.h,v retrieving revision 1.3 diff -u -p -r1.3 ber.h --- usr.bin/ldap/ber.h 29 Jun 2018 18:28:41 -0000 1.3 +++ usr.bin/ldap/ber.h 29 Jun 2018 19:41:59 -0000 @@ -17,13 +17,19 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifndef _BER_H +#define _BER_H + struct ber_element { struct ber_element *be_next; unsigned long be_type; unsigned long be_encoding; size_t be_len; + off_t be_offs; int be_free; u_int8_t be_class; + void (*be_cb)(void *, size_t); + void *be_cbarg; union { struct ber_element *bv_sub; void *bv_val; @@ -35,6 +41,7 @@ struct ber_element { }; struct ber { + off_t br_offs; u_char *br_wbuf; u_char *br_wptr; u_char *br_wend; @@ -119,10 +126,17 @@ ssize_t ber_get_writebuf(struct ber * int ber_write_elements(struct ber *, struct ber_element *); void ber_set_readbuf(struct ber *, void *, size_t); struct ber_element *ber_read_elements(struct ber *, struct ber_element *); +off_t ber_getpos(struct ber_element *); void ber_free_element(struct ber_element *); void ber_free_elements(struct ber_element *); size_t ber_calc_len(struct ber_element *); void ber_set_application(struct ber *, unsigned long (*)(struct ber_element *)); +void ber_set_writecallback(struct ber_element *, + void (*)(void *, size_t), void *); void ber_free(struct ber *); +int ber_oid_cmp(struct ber_oid *, struct ber_oid *); + __END_DECLS + +#endif /* _BER_H */ Index: usr.sbin/ldapd/ber.c =================================================================== RCS file: /cvs/src/usr.sbin/ldapd/ber.c,v retrieving revision 1.16 diff -u -p -r1.16 ber.c --- usr.sbin/ldapd/ber.c 29 Jun 2018 18:28:42 -0000 1.16 +++ usr.sbin/ldapd/ber.c 29 Jun 2018 19:42:09 -0000 @@ -631,10 +631,11 @@ ber_scanf_elements(struct ber_element *b va_list ap; int *d, level = -1; unsigned long *t; - long long *i; + long long *i, l; void **ptr; size_t *len, ret = 0, n = strlen(fmt); char **s; + off_t *pos; struct ber_oid *o; struct ber_element *parent[_MAX_SEQ], **e; @@ -656,6 +657,13 @@ ber_scanf_elements(struct ber_element *b goto fail; ret++; break; + case 'd': + d = va_arg(ap, int *); + if (ber_get_integer(ber, &l) == -1) + goto fail; + *d = l; + ret++; + break; case 'e': e = va_arg(ap, struct ber_element **); *e = ber; @@ -712,6 +720,11 @@ ber_scanf_elements(struct ber_element *b goto fail; ret++; break; + case 'p': + pos = va_arg(ap, off_t *); + *pos = ber_getpos(ber); + ret++; + continue; case '{': case '(': if (ber->be_encoding != BER_TYPE_SEQUENCE && @@ -821,6 +834,12 @@ ber_read_elements(struct ber *ber, struc return root; } +off_t +ber_getpos(struct ber_element *elm) +{ + return elm->be_offs; +} + void ber_free_element(struct ber_element *root) { @@ -893,6 +912,8 @@ ber_dump_element(struct ber *ber, struct uint8_t u; ber_dump_header(ber, root); + if (root->be_cb) + root->be_cb(root->be_cbarg, ber->br_wptr - ber->br_wbuf); switch (root->be_encoding) { case BER_TYPE_BOOLEAN: @@ -1101,6 +1122,7 @@ ber_read_element(struct ber *ber, struct elm->be_type = type; elm->be_len = len; + elm->be_offs = ber->br_offs; /* element position within stream */ elm->be_class = class; if (elm->be_encoding == 0) { @@ -1232,6 +1254,15 @@ ber_set_application(struct ber *b, unsig } void +ber_set_writecallback(struct ber_element *elm, void (*cb)(void *, size_t), + void *arg) +{ + elm->be_cb = cb; + elm->be_cbarg = arg; +} + + +void ber_free(struct ber *b) { free(b->br_wbuf); @@ -1258,5 +1289,33 @@ ber_read(struct ber *ber, void *buf, siz b += r; remain -= r; } - return (b - (u_char *)buf); + r = b - (u_char *)buf; + ber->br_offs += r; + return r; +} + +int +ber_oid_cmp(struct ber_oid *a, struct ber_oid *b) +{ + size_t i; + for (i = 0; i < BER_MAX_OID_LEN; i++) { + if (a->bo_id[i] != 0) { + if (a->bo_id[i] == b->bo_id[i]) + continue; + else if (a->bo_id[i] < b->bo_id[i]) { + /* b is a successor of a */ + return (1); + } else { + /* b is a predecessor of a */ + return (-1); + } + } else if (b->bo_id[i] != 0) { + /* b is larger, but a child of a */ + return (2); + } else + break; + } + + /* b and a are identical */ + return (0); } Index: usr.sbin/ldapd/ber.h =================================================================== RCS file: /cvs/src/usr.sbin/ldapd/ber.h,v retrieving revision 1.4 diff -u -p -r1.4 ber.h --- usr.sbin/ldapd/ber.h 29 Jun 2018 18:28:42 -0000 1.4 +++ usr.sbin/ldapd/ber.h 29 Jun 2018 19:42:09 -0000 @@ -17,13 +17,19 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifndef _BER_H +#define _BER_H + struct ber_element { struct ber_element *be_next; unsigned long be_type; unsigned long be_encoding; size_t be_len; + off_t be_offs; int be_free; u_int8_t be_class; + void (*be_cb)(void *, size_t); + void *be_cbarg; union { struct ber_element *bv_sub; void *bv_val; @@ -35,6 +41,7 @@ struct ber_element { }; struct ber { + off_t br_offs; u_char *br_wbuf; u_char *br_wptr; u_char *br_wend; @@ -119,10 +126,17 @@ ssize_t ber_get_writebuf(struct ber * int ber_write_elements(struct ber *, struct ber_element *); void ber_set_readbuf(struct ber *, void *, size_t); struct ber_element *ber_read_elements(struct ber *, struct ber_element *); +off_t ber_getpos(struct ber_element *); void ber_free_element(struct ber_element *); void ber_free_elements(struct ber_element *); size_t ber_calc_len(struct ber_element *); void ber_set_application(struct ber *, unsigned long (*)(struct ber_element *)); +void ber_set_writecallback(struct ber_element *, + void (*)(void *, size_t), void *); void ber_free(struct ber *); +int ber_oid_cmp(struct ber_oid *, struct ber_oid *); + __END_DECLS + +#endif /* _BER_H */ Index: usr.sbin/ypldap/ber.c =================================================================== RCS file: /cvs/src/usr.sbin/ypldap/ber.c,v retrieving revision 1.18 diff -u -p -r1.18 ber.c --- usr.sbin/ypldap/ber.c 29 Jun 2018 18:28:42 -0000 1.18 +++ usr.sbin/ypldap/ber.c 29 Jun 2018 19:42:19 -0000 @@ -631,10 +631,11 @@ ber_scanf_elements(struct ber_element *b va_list ap; int *d, level = -1; unsigned long *t; - long long *i; + long long *i, l; void **ptr; size_t *len, ret = 0, n = strlen(fmt); char **s; + off_t *pos; struct ber_oid *o; struct ber_element *parent[_MAX_SEQ], **e; @@ -656,6 +657,13 @@ ber_scanf_elements(struct ber_element *b goto fail; ret++; break; + case 'd': + d = va_arg(ap, int *); + if (ber_get_integer(ber, &l) == -1) + goto fail; + *d = l; + ret++; + break; case 'e': e = va_arg(ap, struct ber_element **); *e = ber; @@ -712,6 +720,11 @@ ber_scanf_elements(struct ber_element *b goto fail; ret++; break; + case 'p': + pos = va_arg(ap, off_t *); + *pos = ber_getpos(ber); + ret++; + continue; case '{': case '(': if (ber->be_encoding != BER_TYPE_SEQUENCE && @@ -821,6 +834,12 @@ ber_read_elements(struct ber *ber, struc return root; } +off_t +ber_getpos(struct ber_element *elm) +{ + return elm->be_offs; +} + void ber_free_element(struct ber_element *root) { @@ -893,6 +912,8 @@ ber_dump_element(struct ber *ber, struct uint8_t u; ber_dump_header(ber, root); + if (root->be_cb) + root->be_cb(root->be_cbarg, ber->br_wptr - ber->br_wbuf); switch (root->be_encoding) { case BER_TYPE_BOOLEAN: @@ -1101,6 +1122,7 @@ ber_read_element(struct ber *ber, struct elm->be_type = type; elm->be_len = len; + elm->be_offs = ber->br_offs; /* element position within stream */ elm->be_class = class; if (elm->be_encoding == 0) { @@ -1232,6 +1254,15 @@ ber_set_application(struct ber *b, unsig } void +ber_set_writecallback(struct ber_element *elm, void (*cb)(void *, size_t), + void *arg) +{ + elm->be_cb = cb; + elm->be_cbarg = arg; +} + + +void ber_free(struct ber *b) { free(b->br_wbuf); @@ -1258,5 +1289,33 @@ ber_read(struct ber *ber, void *buf, siz b += r; remain -= r; } - return (b - (u_char *)buf); + r = b - (u_char *)buf; + ber->br_offs += r; + return r; +} + +int +ber_oid_cmp(struct ber_oid *a, struct ber_oid *b) +{ + size_t i; + for (i = 0; i < BER_MAX_OID_LEN; i++) { + if (a->bo_id[i] != 0) { + if (a->bo_id[i] == b->bo_id[i]) + continue; + else if (a->bo_id[i] < b->bo_id[i]) { + /* b is a successor of a */ + return (1); + } else { + /* b is a predecessor of a */ + return (-1); + } + } else if (b->bo_id[i] != 0) { + /* b is larger, but a child of a */ + return (2); + } else + break; + } + + /* b and a are identical */ + return (0); } Index: usr.sbin/ypldap/ber.h =================================================================== RCS file: /cvs/src/usr.sbin/ypldap/ber.h,v retrieving revision 1.5 diff -u -p -r1.5 ber.h --- usr.sbin/ypldap/ber.h 29 Jun 2018 18:28:42 -0000 1.5 +++ usr.sbin/ypldap/ber.h 29 Jun 2018 19:42:19 -0000 @@ -17,13 +17,19 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#ifndef _BER_H +#define _BER_H + struct ber_element { struct ber_element *be_next; unsigned long be_type; unsigned long be_encoding; size_t be_len; + off_t be_offs; int be_free; u_int8_t be_class; + void (*be_cb)(void *, size_t); + void *be_cbarg; union { struct ber_element *bv_sub; void *bv_val; @@ -35,6 +41,7 @@ struct ber_element { }; struct ber { + off_t br_offs; u_char *br_wbuf; u_char *br_wptr; u_char *br_wend; @@ -119,10 +126,17 @@ ssize_t ber_get_writebuf(struct ber * int ber_write_elements(struct ber *, struct ber_element *); void ber_set_readbuf(struct ber *, void *, size_t); struct ber_element *ber_read_elements(struct ber *, struct ber_element *); +off_t ber_getpos(struct ber_element *); void ber_free_element(struct ber_element *); void ber_free_elements(struct ber_element *); size_t ber_calc_len(struct ber_element *); void ber_set_application(struct ber *, unsigned long (*)(struct ber_element *)); +void ber_set_writecallback(struct ber_element *, + void (*)(void *, size_t), void *); void ber_free(struct ber *); +int ber_oid_cmp(struct ber_oid *, struct ber_oid *); + __END_DECLS + +#endif /* _BER_H */