summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvenaas <venaas>2008-09-08 12:23:17 +0000
committervenaas <venaas@e88ac4ed-0b26-0410-9574-a7f39faa03bf>2008-09-08 12:23:17 +0000
commit74ba8cbc3a91ba4fe3e73da9bb27959f73380265 (patch)
treed6a7391e8947f1c0e89996f9f451b175c5e301a8
parent03f17173b68a6a84f4020c96905fe7af13633339 (diff)
added addattribute support to rewrite
git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@368 e88ac4ed-0b26-0410-9574-a7f39faa03bf
-rw-r--r--radsecproxy.c176
-rw-r--r--radsecproxy.h7
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 {