summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrob <rob@cvs.openbsd.org>2018-07-03 18:49:11 +0000
committerrob <rob@cvs.openbsd.org>2018-07-03 18:49:11 +0000
commit279159d5975f61840d0d3cca5b790edd6f9e145e (patch)
tree23ebe4f08474d8407151729e2d702ed983ffa905
parentf1e56339a425270bd2f8c5ab55a70d903416d413 (diff)
Synchronize ber changes from the snmpd instance to ldap, ldapd, and ypldap.
See usr.sbin/snmpd/ber.c revision 1.24 commit log for a summary of these changes (e.g. SNMPv2 traps, User-based Security Model, callback for USM HMAC calculations). There is one final ber piece to copy from the snmpd instance related to ber_getc() which will be done in a separate diff. "looks good to me" deraadt@
-rw-r--r--usr.bin/ldap/ber.c65
-rw-r--r--usr.bin/ldap/ber.h16
-rw-r--r--usr.sbin/ldapd/ber.c65
-rw-r--r--usr.sbin/ldapd/ber.h16
-rw-r--r--usr.sbin/ypldap/ber.c65
-rw-r--r--usr.sbin/ypldap/ber.h16
6 files changed, 231 insertions, 12 deletions
diff --git a/usr.bin/ldap/ber.c b/usr.bin/ldap/ber.c
index 151ae34739c..264fd4e5410 100644
--- a/usr.bin/ldap/ber.c
+++ b/usr.bin/ldap/ber.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ber.c,v 1.7 2018/07/01 20:03:48 rob Exp $ */
+/* $OpenBSD: ber.c,v 1.8 2018/07/03 18:49:10 rob Exp $ */
/*
* Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -631,10 +631,11 @@ ber_scanf_elements(struct ber_element *ber, char *fmt, ...)
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 *ber, char *fmt, ...)
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 *ber, char *fmt, ...)
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, struct ber_element *elm)
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 ber_element *root)
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 ber_element *elm)
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, unsigned long (*cb)(struct ber_element *))
}
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, size_t len)
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);
}
diff --git a/usr.bin/ldap/ber.h b/usr.bin/ldap/ber.h
index 398a3597e27..ad0f6d9023a 100644
--- a/usr.bin/ldap/ber.h
+++ b/usr.bin/ldap/ber.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ber.h,v 1.3 2018/06/29 18:28:41 rob Exp $ */
+/* $OpenBSD: ber.h,v 1.4 2018/07/03 18:49:10 rob Exp $ */
/*
* Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -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 *, void **);
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 */
diff --git a/usr.sbin/ldapd/ber.c b/usr.sbin/ldapd/ber.c
index 0353b06c7bb..94babe9693e 100644
--- a/usr.sbin/ldapd/ber.c
+++ b/usr.sbin/ldapd/ber.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ber.c,v 1.17 2018/07/01 20:03:48 rob Exp $ */
+/* $OpenBSD: ber.c,v 1.18 2018/07/03 18:49:10 rob Exp $ */
/*
* Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -631,10 +631,11 @@ ber_scanf_elements(struct ber_element *ber, char *fmt, ...)
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 *ber, char *fmt, ...)
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 *ber, char *fmt, ...)
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, struct ber_element *elm)
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 ber_element *root)
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 ber_element *elm)
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, unsigned long (*cb)(struct ber_element *))
}
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, size_t len)
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);
}
diff --git a/usr.sbin/ldapd/ber.h b/usr.sbin/ldapd/ber.h
index 81984cb3062..a97b1b756dd 100644
--- a/usr.sbin/ldapd/ber.h
+++ b/usr.sbin/ldapd/ber.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ber.h,v 1.4 2018/06/29 18:28:42 rob Exp $ */
+/* $OpenBSD: ber.h,v 1.5 2018/07/03 18:49:10 rob Exp $ */
/*
* Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -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 *, void **);
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 */
diff --git a/usr.sbin/ypldap/ber.c b/usr.sbin/ypldap/ber.c
index 227f5f1e594..7d6b10e6565 100644
--- a/usr.sbin/ypldap/ber.c
+++ b/usr.sbin/ypldap/ber.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ber.c,v 1.19 2018/07/01 20:03:48 rob Exp $ */
+/* $OpenBSD: ber.c,v 1.20 2018/07/03 18:49:10 rob Exp $ */
/*
* Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -631,10 +631,11 @@ ber_scanf_elements(struct ber_element *ber, char *fmt, ...)
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 *ber, char *fmt, ...)
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 *ber, char *fmt, ...)
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, struct ber_element *elm)
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 ber_element *root)
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 ber_element *elm)
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, unsigned long (*cb)(struct ber_element *))
}
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, size_t len)
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);
}
diff --git a/usr.sbin/ypldap/ber.h b/usr.sbin/ypldap/ber.h
index b599add0e1b..95932649f1e 100644
--- a/usr.sbin/ypldap/ber.h
+++ b/usr.sbin/ypldap/ber.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ber.h,v 1.5 2018/06/29 18:28:42 rob Exp $ */
+/* $OpenBSD: ber.h,v 1.6 2018/07/03 18:49:10 rob Exp $ */
/*
* Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org>
@@ -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 *, void **);
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 */