From 74ba8cbc3a91ba4fe3e73da9bb27959f73380265 Mon Sep 17 00:00:00 2001 From: venaas Date: Mon, 8 Sep 2008 12:23:17 +0000 Subject: added addattribute support to rewrite git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@368 e88ac4ed-0b26-0410-9574-a7f39faa03bf --- radsecproxy.c | 176 +++++++++++++++++++++++++++++++++++++++++++--------------- radsecproxy.h | 7 +++ 2 files changed, 139 insertions(+), 44 deletions(-) diff --git a/radsecproxy.c b/radsecproxy.c index 35b0caa..948541e 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -1458,7 +1458,7 @@ int findvendorsubattr(uint32_t *attrs, uint32_t vendor, uint8_t subattr) { return 0; } -int dovendorrewrite(uint8_t *attrs, uint16_t length, uint32_t *removevendorattrs) { +int dovendorrewriterm(uint8_t *attrs, uint16_t length, uint32_t *removevendorattrs) { uint8_t alen, sublen, rmlen = 0; uint32_t vendor = *(uint32_t *)ATTRVAL(attrs); uint8_t *subattrs; @@ -1503,23 +1503,20 @@ int dovendorrewrite(uint8_t *attrs, uint16_t length, uint32_t *removevendorattrs return rmlen; } -void dorewrite(uint8_t *buf, struct rewrite *rewrite) { +void dorewriterm(uint8_t *buf, uint8_t *rmattrs, uint32_t *rmvattrs) { uint8_t *attrs, alen; uint16_t len, rmlen = 0; - if (!rewrite || (!rewrite->removeattrs && !rewrite->removevendorattrs)) - return; - len = RADLEN(buf) - 20; attrs = buf + 20; while (len > 1) { alen = ATTRLEN(attrs); len -= alen; - if (rewrite->removeattrs && strchr((char *)rewrite->removeattrs, ATTRTYPE(attrs))) { + if (rmattrs && strchr((char *)rmattrs, ATTRTYPE(attrs))) { memmove(attrs, attrs + alen, len); rmlen += alen; - } else if (ATTRTYPE(attrs) == RAD_Attr_Vendor_Specific && rewrite->removevendorattrs) - rmlen += dovendorrewrite(attrs, len, rewrite->removevendorattrs); + } else if (ATTRTYPE(attrs) == RAD_Attr_Vendor_Specific && rmvattrs) + rmlen += dovendorrewriterm(attrs, len, rmvattrs); else attrs += alen; } @@ -1527,6 +1524,43 @@ void dorewrite(uint8_t *buf, struct rewrite *rewrite) { ((uint16_t *)buf)[1] = htons(RADLEN(buf) - rmlen); } +int dorewriteadd(uint8_t **buf, struct list *addattrs) { + struct list_node *n; + struct attribute *a; + uint16_t i, addlen = 0; + uint8_t *newbuf; + + for (n = list_first(addattrs); n; n = list_next(n)) + addlen += 2 + ((struct attribute *)n->data)->l; + if (!addlen) + return 1; + newbuf = realloc(*buf, RADLEN(*buf) + addlen); + if (!newbuf) + return 0; + + i = RADLEN(newbuf); + for (n = list_first(addattrs); n; n = list_next(n)) { + a = (struct attribute *)n->data; + newbuf[i++] = a->t; + newbuf[i++] = a->l + 2; + memcpy(newbuf + i, a->v, a->l); + i += a->l; + } + ((uint16_t *)newbuf)[1] = htons(RADLEN(newbuf) + addlen); + *buf = newbuf; + return 1; +} + +int dorewrite(uint8_t **buf, struct rewrite *rewrite) { + if (!rewrite) + return 1; + if (rewrite->removeattrs || rewrite->removevendorattrs) + dorewriterm(*buf, rewrite->removeattrs, rewrite->removevendorattrs); + if (rewrite->addattrs) + return dorewriteadd(buf, rewrite->addattrs); + return 1; +} + /* returns a pointer to the resized attribute value */ uint8_t *resizeattr(uint8_t **buf, uint8_t newvallen, uint8_t type) { uint8_t *attrs, *attr, vallen; @@ -1826,8 +1860,11 @@ int radsrv(struct request *rq) { } if (rq->from->conf->rewritein) { - dorewrite(rq->buf, rq->from->conf->rewritein); + if (!dorewrite(&rq->buf, rq->from->conf->rewritein)) + goto exit; len = RADLEN(rq->buf) - 20; + auth = (uint8_t *)(rq->buf + 4); + attrs = rq->buf + 20; } attr = attrget(attrs, len, RAD_Attr_User_Name); @@ -1913,7 +1950,9 @@ int radsrv(struct request *rq) { memcpy(auth, newauth, 16); if (to->conf->rewriteout) - dorewrite(rq->buf, to->conf->rewriteout); + if (!dorewrite(&rq->buf, to->conf->rewriteout)) + goto exit; + sendrq(to, rq); return 1; @@ -2014,8 +2053,12 @@ int replyh(struct server *server, unsigned char *buf) { } if (server->conf->rewritein) { - dorewrite(buf, server->conf->rewritein); + if (!dorewrite(&buf, server->conf->rewritein)) + return 0; len = RADLEN(buf) - 20; + attrs = buf + 20; + if (messageauth) + messageauth = attrget(attrs, len, RAD_Attr_Message_Authenticator); } /* MS MPPE */ @@ -2076,8 +2119,10 @@ int replyh(struct server *server, unsigned char *buf) { } if (from->conf->rewriteout) { - dorewrite(buf, from->conf->rewriteout); + if (!dorewrite(&buf, from->conf->rewriteout)) + return 0; len = RADLEN(buf) - 20; + attrs = buf + 20; if (messageauth) messageauth = attrget(attrs, len, RAD_Attr_Message_Authenticator); } @@ -2368,7 +2413,7 @@ SSL_CTX *tlscreatectx(uint8_t type, struct tls *conf) { unsigned long error; if (!ssl_locks) { - ssl_locks = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); + ssl_locks = calloc(CRYPTO_num_locks(), sizeof(pthread_mutex_t)); ssl_lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); for (i = 0; i < CRYPTO_num_locks(); i++) { ssl_lock_count[i] = 0; @@ -2878,6 +2923,32 @@ int vattrname2val(char *attrname, uint32_t *vendor, uint32_t *type) { return *type >= 0 && *type < 256; } +/* should accept both names and numeric values, only numeric right now */ +struct attribute *extractattr(char *nameval) { + int len, name = 0; + char *s; + struct attribute *a; + + s = strchr(nameval, ':'); + name = atoi(nameval); + if (!s || name < 1 || name > 255) + return NULL; + len = strlen(s + 1); + if (len > 253) + return NULL; + a = malloc(sizeof(struct attribute)); + if (!a) + return NULL; + a->v = (uint8_t *)stringcopy(s + 1, 0); + if (!a->v) { + free(a); + return NULL; + } + a->t = name; + a->l = len; + return a; +} + struct rewrite *getrewrite(char *alt1, char *alt2) { struct rewrite *r; @@ -2888,50 +2959,66 @@ struct rewrite *getrewrite(char *alt1, char *alt2) { return NULL; } -void addrewrite(char *value, char **attrs, char **vattrs) { +void addrewrite(char *value, char **rmattrs, char **rmvattrs, char **addattrs) { struct rewrite *rewrite = NULL; int i, n; - uint8_t *a = NULL; - uint32_t *p, *va = NULL; - - if (attrs) { - n = 0; - for (; attrs[n]; n++); - a = malloc((n + 1) * sizeof(uint8_t)); - if (!a) + uint8_t *rma = NULL; + uint32_t *p, *rmva = NULL; + struct list *adda = NULL; + struct attribute *a; + + if (rmattrs) { + for (n = 0; rmattrs[n]; n++); + rma = calloc(n + 1, sizeof(uint8_t)); + if (!rma) debugx(1, DBG_ERR, "malloc failed"); for (i = 0; i < n; i++) { - if (!(a[i] = attrname2val(attrs[i]))) - debugx(1, DBG_ERR, "addrewrite: invalid attribute %s", attrs[i]); - free(attrs[i]); + if (!(rma[i] = attrname2val(rmattrs[i]))) + debugx(1, DBG_ERR, "addrewrite: invalid attribute %s", rmattrs[i]); + free(rmattrs[i]); } - free(attrs); - a[i] = 0; + free(rmattrs); + rma[i] = 0; } - if (vattrs) { - n = 0; - for (; vattrs[n]; n++); - va = malloc((2 * n + 1) * sizeof(uint32_t)); - if (!va) + if (rmvattrs) { + for (n = 0; rmvattrs[n]; n++); + rmva = calloc(2 * n + 1, sizeof(uint32_t)); + if (!rmva) debugx(1, DBG_ERR, "malloc failed"); - for (p = va, i = 0; i < n; i++, p += 2) { - if (!vattrname2val(vattrs[i], p, p + 1)) - debugx(1, DBG_ERR, "addrewrite: invalid vendor attribute %s", vattrs[i]); - free(vattrs[i]); + for (p = rmva, i = 0; i < n; i++, p += 2) { + if (!vattrname2val(rmvattrs[i], p, p + 1)) + debugx(1, DBG_ERR, "addrewrite: invalid vendor attribute %s", rmvattrs[i]); + free(rmvattrs[i]); } - free(vattrs); + free(rmvattrs); *p = 0; } - if (a || va) { + if (addattrs) { + adda = list_create(); + if (!adda) + debugx(1, DBG_ERR, "malloc failed"); + for (i = 0; addattrs[i]; i++) { + a = extractattr(addattrs[i]); + if (!a) + debugx(1, DBG_ERR, "addrewrite: invalid attribute %s", addattrs[i]); + free(addattrs[i]); + if (!list_push(adda, a)) + debugx(1, DBG_ERR, "malloc failed"); + } + free(addattrs); + } + + if (rma || rmva || adda) { rewrite = malloc(sizeof(struct rewrite)); if (!rewrite) debugx(1, DBG_ERR, "malloc failed"); - rewrite->removeattrs = a; - rewrite->removevendorattrs = va; + rewrite->removeattrs = rma; + rewrite->removevendorattrs = rmva; + rewrite->addattrs = adda; } if (!hash_insert(rewriteconfs, value, strlen(value), rewrite)) @@ -3329,17 +3416,18 @@ int conftls_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *v } int confrewrite_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) { - char **attrs = NULL, **vattrs = NULL; + char **rmattrs = NULL, **rmvattrs = NULL, **addattrs = NULL; debug(DBG_DBG, "confrewrite_cb called for %s", block); if (!getgenericconfig(cf, block, - "removeAttribute", CONF_MSTR, &attrs, - "removeVendorAttribute", CONF_MSTR, &vattrs, + "removeAttribute", CONF_MSTR, &rmattrs, + "removeVendorAttribute", CONF_MSTR, &rmvattrs, + "addAttribute", CONF_MSTR, &addattrs, NULL )) debugx(1, DBG_ERR, "configuration error"); - addrewrite(val, attrs, vattrs); + addrewrite(val, rmattrs, rmvattrs, addattrs); return 1; } diff --git a/radsecproxy.h b/radsecproxy.h index ea154f2..11eebf8 100644 --- a/radsecproxy.h +++ b/radsecproxy.h @@ -167,9 +167,16 @@ struct tls { SSL_CTX *dtlsctx; }; +struct attribute { + uint8_t t; + uint8_t l; + uint8_t *v; +}; + struct rewrite { uint8_t *removeattrs; uint32_t *removevendorattrs; + struct list *addattrs; }; struct protodefs { -- cgit v1.2.3