diff options
-rw-r--r-- | usr.bin/ldap/aldap.c | 59 | ||||
-rw-r--r-- | usr.bin/ldap/aldap.h | 22 | ||||
-rw-r--r-- | usr.bin/ldap/ber.c | 24 | ||||
-rw-r--r-- | usr.bin/ldap/ber.h | 11 | ||||
-rw-r--r-- | usr.bin/ldap/ldapclient.c | 46 |
5 files changed, 104 insertions, 58 deletions
diff --git a/usr.bin/ldap/aldap.c b/usr.bin/ldap/aldap.c index 569286f2793..b75b491fa0b 100644 --- a/usr.bin/ldap/aldap.c +++ b/usr.bin/ldap/aldap.c @@ -1,5 +1,5 @@ -/* $Id: aldap.c,v 1.5 2018/08/12 22:04:09 rob Exp $ */ -/* $OpenBSD: aldap.c,v 1.5 2018/08/12 22:04:09 rob Exp $ */ +/* $Id: aldap.c,v 1.6 2018/11/27 12:04:57 martijn Exp $ */ +/* $OpenBSD: aldap.c,v 1.6 2018/11/27 12:04:57 martijn Exp $ */ /* * Copyright (c) 2008 Alexander Schrijver <aschrijver@openbsd.org> @@ -39,7 +39,7 @@ static struct ber_element *ldap_parse_search_filter(struct ber_element *, char *); static struct ber_element *ldap_do_parse_search_filter( struct ber_element *, char **); -char **aldap_get_stringset(struct ber_element *); +struct aldap_stringset *aldap_get_stringset(struct ber_element *); char *utoa(char *); static int isu8cont(unsigned char); char *parseval(char *, size_t); @@ -522,7 +522,7 @@ aldap_get_dn(struct aldap_message *msg) return utoa(dn); } -char ** +struct aldap_stringset * aldap_get_references(struct aldap_message *msg) { if (msg->references == NULL) @@ -576,11 +576,12 @@ aldap_count_attrs(struct aldap_message *msg) } int -aldap_first_attr(struct aldap_message *msg, char **outkey, char ***outvalues) +aldap_first_attr(struct aldap_message *msg, char **outkey, + struct aldap_stringset **outvalues) { struct ber_element *b, *c; char *key; - char **ret; + struct aldap_stringset *ret; if (msg->body.search.attrs == NULL) goto fail; @@ -605,11 +606,12 @@ fail: } int -aldap_next_attr(struct aldap_message *msg, char **outkey, char ***outvalues) +aldap_next_attr(struct aldap_message *msg, char **outkey, + struct aldap_stringset **outvalues) { struct ber_element *a, *b; char *key; - char **ret; + struct aldap_stringset *ret; if (msg->body.search.iter == NULL) goto notfound; @@ -640,11 +642,12 @@ notfound: } int -aldap_match_attr(struct aldap_message *msg, char *inkey, char ***outvalues) +aldap_match_attr(struct aldap_message *msg, char *inkey, + struct aldap_stringset **outvalues) { struct ber_element *a, *b; char *descr = NULL; - char **ret; + struct aldap_stringset *ret; if (msg->body.search.attrs == NULL) goto fail; @@ -677,16 +680,12 @@ notfound: } int -aldap_free_attr(char **values) +aldap_free_attr(struct aldap_stringset *values) { - int i; - if (values == NULL) return -1; - for (i = 0; values[i] != NULL; i++) - free(values[i]); - + free(values->str); free(values); return (1); @@ -836,33 +835,35 @@ fail: * internal functions */ -char ** +struct aldap_stringset * aldap_get_stringset(struct ber_element *elm) { struct ber_element *a; int i; - char **ret; - char *s; + struct aldap_stringset *ret; if (elm->be_type != BER_TYPE_OCTETSTRING) return NULL; - for (a = elm, i = 1; i > 0 && a != NULL && a->be_type == - BER_TYPE_OCTETSTRING; a = a->be_next, i++) + if ((ret = malloc(sizeof(*ret))) == NULL) + return NULL; + for (a = elm, ret->len = 0; a != NULL && a->be_type == + BER_TYPE_OCTETSTRING; a = a->be_next, ret->len++) ; - if (i == 1) + if (ret->len == 0) { + free(ret); return NULL; + } - if ((ret = calloc(i + 1, sizeof(char *))) == NULL) + if ((ret->str = reallocarray(NULL, ret->len, + sizeof(*(ret->str)))) == NULL) { + free(ret); return NULL; + } for (a = elm, i = 0; a != NULL && a->be_type == BER_TYPE_OCTETSTRING; - a = a->be_next, i++) { - - ber_get_string(a, &s); - ret[i] = utoa(s); - } - ret[i + 1] = NULL; + a = a->be_next, i++) + (void) ber_get_ostring(a, &(ret->str[i])); return ret; } diff --git a/usr.bin/ldap/aldap.h b/usr.bin/ldap/aldap.h index 755408458cb..1dc19de86fa 100644 --- a/usr.bin/ldap/aldap.h +++ b/usr.bin/ldap/aldap.h @@ -1,5 +1,5 @@ -/* $Id: aldap.h,v 1.1.1.1 2018/06/13 15:45:57 reyk Exp $ */ -/* $OpenBSD: aldap.h,v 1.1.1.1 2018/06/13 15:45:57 reyk Exp $ */ +/* $Id: aldap.h,v 1.2 2018/11/27 12:04:57 martijn Exp $ */ +/* $OpenBSD: aldap.h,v 1.2 2018/11/27 12:04:57 martijn Exp $ */ /* * Copyright (c) 2008 Alexander Schrijver <aschrijver@openbsd.org> @@ -88,6 +88,11 @@ enum aldap_protocol { LDAPI }; +struct aldap_stringset { + size_t len; + struct ber_octetstring *str; +}; + struct aldap_url { int protocol; char *host; @@ -226,7 +231,7 @@ int aldap_get_errno(struct aldap *, const char **); int aldap_get_resultcode(struct aldap_message *); char *aldap_get_dn(struct aldap_message *); char *aldap_get_diagmsg(struct aldap_message *); -char **aldap_get_references(struct aldap_message *); +struct aldap_stringset *aldap_get_references(struct aldap_message *); void aldap_free_references(char **values); int aldap_parse_url(const char *, struct aldap_url *); void aldap_free_url(struct aldap_url *); @@ -234,10 +239,13 @@ int aldap_search_url(struct aldap *, char *, int, int, int, struct aldap_page_control *); int aldap_count_attrs(struct aldap_message *); -int aldap_match_attr(struct aldap_message *, char *, char ***); -int aldap_first_attr(struct aldap_message *, char **, char ***); -int aldap_next_attr(struct aldap_message *, char **, char ***); -int aldap_free_attr(char **); +int aldap_match_attr(struct aldap_message *, char *, + struct aldap_stringset **); +int aldap_first_attr(struct aldap_message *, char **, struct + aldap_stringset **); +int aldap_next_attr(struct aldap_message *, char **, + struct aldap_stringset **); +int aldap_free_attr(struct aldap_stringset *); struct aldap_page_control *aldap_parse_page_control(struct ber_element *, size_t len); void aldap_freepage(struct aldap_page_control *); diff --git a/usr.bin/ldap/ber.c b/usr.bin/ldap/ber.c index a4e1e4ccd1d..a958e580453 100644 --- a/usr.bin/ldap/ber.c +++ b/usr.bin/ldap/ber.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ber.c,v 1.20 2018/11/20 07:20:21 martijn Exp $ */ +/* $OpenBSD: ber.c,v 1.21 2018/11/27 12:04:57 martijn Exp $ */ /* * Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org> @@ -282,11 +282,22 @@ ber_add_nstring(struct ber_element *prev, const char *string0, size_t len) return elm; } +struct ber_element * +ber_add_ostring(struct ber_element *prev, struct ber_octetstring *s) +{ + return ber_add_nstring(prev, s->ostr_val, s->ostr_len); +} + int ber_get_string(struct ber_element *elm, char **s) { if (elm->be_encoding != BER_TYPE_OCTETSTRING) return -1; + /* Some components use getstring on binary data containing \0 */ +#if 0 + if (memchr(elm->be_val, '\0', elm->be_len) != NULL) + return -1; +#endif *s = elm->be_val; return 0; @@ -303,6 +314,17 @@ ber_get_nstring(struct ber_element *elm, void **p, size_t *len) return 0; } +int +ber_get_ostring(struct ber_element *elm, struct ber_octetstring *s) +{ + if (elm->be_encoding != BER_TYPE_OCTETSTRING) + return -1; + + s->ostr_val = elm->be_val; + s->ostr_len = elm->be_len; + return 0; +} + struct ber_element * ber_add_bitstring(struct ber_element *prev, const void *v0, size_t len) { diff --git a/usr.bin/ldap/ber.h b/usr.bin/ldap/ber.h index 8cc989554da..962249f02cf 100644 --- a/usr.bin/ldap/ber.h +++ b/usr.bin/ldap/ber.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ber.h,v 1.7 2018/08/12 22:04:09 rob Exp $ */ +/* $OpenBSD: ber.h,v 1.8 2018/11/27 12:04:57 martijn Exp $ */ /* * Copyright (c) 2007, 2012 Reyk Floeter <reyk@openbsd.org> @@ -20,6 +20,11 @@ #ifndef _BER_H #define _BER_H +struct ber_octetstring { + size_t ostr_len; + const void *ostr_val; +}; + struct ber_element { struct ber_element *be_next; unsigned int be_type; @@ -104,9 +109,13 @@ int ber_get_boolean(struct ber_element *, int *); struct ber_element *ber_add_string(struct ber_element *, const char *); struct ber_element *ber_add_nstring(struct ber_element *, const char *, size_t); +struct ber_element *ber_add_ostring(struct ber_element *, + struct ber_octetstring *); int ber_get_string(struct ber_element *, char **); int ber_get_nstring(struct ber_element *, void **, size_t *); +int ber_get_ostring(struct ber_element *, + struct ber_octetstring *); struct ber_element *ber_add_bitstring(struct ber_element *, const void *, size_t); int ber_get_bitstring(struct ber_element *, void **, diff --git a/usr.bin/ldap/ldapclient.c b/usr.bin/ldap/ldapclient.c index 73248dab930..6bfd2b01afd 100644 --- a/usr.bin/ldap/ldapclient.c +++ b/usr.bin/ldap/ldapclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ldapclient.c,v 1.9 2018/11/07 13:58:51 martijn Exp $ */ +/* $OpenBSD: ldapclient.c,v 1.10 2018/11/27 12:04:57 martijn Exp $ */ /* * Copyright (c) 2018 Reyk Floeter <reyk@openbsd.org> @@ -82,7 +82,8 @@ struct ldapc_search { __dead void usage(void); int ldapc_connect(struct ldapc *); int ldapc_search(struct ldapc *, struct ldapc_search *); -int ldapc_printattr(struct ldapc *, const char *, const char *); +int ldapc_printattr(struct ldapc *, const char *, + const struct ber_octetstring *); void ldapc_disconnect(struct ldapc *); int ldapc_parseurl(struct ldapc *, struct ldapc_search *, const char *); @@ -297,8 +298,9 @@ ldapc_search(struct ldapc *ldap, struct ldapc_search *ls) const char *errstr; const char *searchdn, *dn = NULL; char *outkey; - char **outvalues; - int ret, i, code, fail = 0; + struct aldap_stringset *outvalues; + int ret, code, fail = 0; + size_t i; if (ldap->ldap_flags & F_LDIF) printf("version: 1\n"); @@ -359,10 +361,9 @@ ldapc_search(struct ldapc *ldap, struct ldapc_search *ls) for (ret = aldap_first_attr(m, &outkey, &outvalues); ret != -1; ret = aldap_next_attr(m, &outkey, &outvalues)) { - for (i = 0; outvalues != NULL && - outvalues[i] != NULL; i++) { + for (i = 0; i < outvalues->len; i++) { if (ldapc_printattr(ldap, outkey, - outvalues[i]) == -1) { + &(outvalues->str[i])) == -1) { fail = 1; break; } @@ -384,12 +385,13 @@ ldapc_search(struct ldapc *ldap, struct ldapc_search *ls) } int -ldapc_printattr(struct ldapc *ldap, const char *key, const char *value) +ldapc_printattr(struct ldapc *ldap, const char *key, + const struct ber_octetstring *value) { char *p = NULL, *out; const unsigned char *cp; int encode; - size_t inlen, outlen, left; + size_t i, inlen, outlen, left; if (ldap->ldap_flags & F_LDIF) { /* OpenLDAP encodes the userPassword by default */ @@ -403,32 +405,33 @@ ldapc_printattr(struct ldapc *ldap, const char *key, const char *value) * in SAFE-STRINGs. String value that do not match the * criteria must be encoded as Base64. */ - cp = (const unsigned char *)value; + cp = (const unsigned char *)value->ostr_val; /* !SAFE-INIT-CHAR: SAFE-CHAR minus %x20 %x3A %x3C */ if (*cp == ' ' || *cp == ':' || *cp == '<') encode = 1; - for (; encode == 0 &&*cp != '\0'; cp++) { + for (i = 0; encode == 0 && i < value->ostr_len - 1; i++) { /* !SAFE-CHAR %x01-09 / %x0B-0C / %x0E-7F */ - if (*cp > 127 || - *cp == '\0' || - *cp == '\n' || - *cp == '\r') + if (cp[i] > 127 || + cp[i] == '\0' || + cp[i] == '\n' || + cp[i] == '\r') encode = 1; } if (!encode) { - if (asprintf(&p, "%s: %s", key, value) == -1) { + if (asprintf(&p, "%s: %s", key, + (const char *)value->ostr_val) == -1) { log_warnx("asprintf"); return (-1); } } else { - inlen = strlen(value); - outlen = (((inlen + 2) / 3) * 4) + 1; + outlen = (((value->ostr_len + 2) / 3) * 4) + 1; if ((out = calloc(1, outlen)) == NULL || - b64_ntop(value, inlen, out, outlen) == -1) { + b64_ntop(value->ostr_val, value->ostr_len, out, + outlen) == -1) { log_warnx("Base64 encoding failed"); free(p); return (-1); @@ -466,12 +469,15 @@ ldapc_printattr(struct ldapc *ldap, const char *key, const char *value) * on all values no matter if they include non-printable * characters. */ - if (stravis(&p, value, VIS_SAFE|VIS_NL) == -1) { + p = calloc(1, 4 * value->ostr_len + 1); + if (strvisx(p, value->ostr_val, value->ostr_len, + VIS_SAFE|VIS_NL) == -1) { log_warn("visual encoding failed"); return (-1); } printf("%s: %s\n", key, p); + free(p); } free(p); |