diff options
| -rw-r--r-- | radsecproxy.c | 98 | 
1 files changed, 79 insertions, 19 deletions
| diff --git a/radsecproxy.c b/radsecproxy.c index c058ac7..09adf63 100644 --- a/radsecproxy.c +++ b/radsecproxy.c @@ -1092,15 +1092,21 @@ int dorewritemod(struct radmsg *msg, struct list *modattrs) {  }  int dorewrite(struct radmsg *msg, struct rewrite *rewrite) { -    if (!rewrite) +    int rv = 1;			/* Success.  */ + +    if (rewrite)  	return 1; +      if (rewrite->removeattrs || rewrite->removevendorattrs)  	dorewriterm(msg, rewrite->removeattrs, rewrite->removevendorattrs); -    if (rewrite->addattrs && !dorewriteadd(msg, rewrite->addattrs)) -	return 0; -    if (rewrite->modattrs && !dorewritemod(msg, rewrite->modattrs)) -	return 0; -    return 1; +    if (rewrite->modattrs) +	if (!dorewritemod(msg, rewrite->modattrs)) +	    rv = 0; +    if (rewrite->addattrs) +	if (!dorewriteadd(msg, rewrite->addattrs)) +	    rv = 0; + +    return rv;  }  int rewriteusername(struct request *rq, struct tlv *attr) { @@ -1116,23 +1122,37 @@ int rewriteusername(struct request *rq, struct tlv *attr) {      return 1;  } -int addvendorattr(struct radmsg *msg, uint32_t vendor, struct tlv *attr) { -    struct tlv *vattr; +static struct tlv * +makevendortlv(uint32_t vendor, const struct tlv *attr) +{ +    struct tlv *newtlv = NULL;      uint8_t l, *v;      l = attr->l + 6;      v = malloc(l);      if (v) { -	vendor = htonl(vendor); +	vendor = htonl(vendor & 0x00ffffff); /* MSB=0 according to RFC 2865. */  	memcpy(v, &vendor, 4);  	tlv2buf(v + 4, attr);  	v[5] += 2; -	vattr = maketlv(RAD_Attr_Vendor_Specific, l, v); -	if (vattr && radmsg_add(msg, vattr)) -	    return 1; +	newtlv = maketlv(RAD_Attr_Vendor_Specific, l, v); +	if (newtlv == NULL) +	    free(v); +    } +    return newtlv; +} + +int addvendorattr(struct radmsg *msg, uint32_t vendor, struct tlv *attr) { +    struct tlv *vattr; + +    vattr = makevendortlv(vendor, attr); +    if (!vattr) +	return 0; +    if (!radmsg_add(msg, vattr)) {  	freetlv(vattr); +	return 0;      } -    return 0; +    return 1;  }  void addttlattr(struct radmsg *msg, uint32_t *attrtype, uint8_t addttl) { @@ -2281,13 +2301,18 @@ uint8_t attrname2val(char *attrname) {      return val > 0 && val < 256 ? val : 0;  } +/* ATTRNAME is on the form vendor[:type]. +   If only vendor is found, TYPE is set to 256 and 1 is returned. +   If type is >= 256, 1 is returned. +   Otherwise, 0 is returned. +*/  /* should accept both names and numeric values, only numeric right now */  int vattrname2val(char *attrname, uint32_t *vendor, uint32_t *type) {      char *s;      *vendor = atoi(attrname);      s = strchr(attrname, ':'); -    if (!s) { +    if (!s) {			/* Only vendor was found.  */  	*type = 256;  	return 1;      } @@ -2298,19 +2323,31 @@ int vattrname2val(char *attrname, uint32_t *vendor, uint32_t *type) {  /* should accept both names and numeric values, only numeric right now */  struct tlv *extractattr(char *nameval) {      int len, name = 0; -    char *s; +    int vendor = 0;	    /* Vendor 0 is reserved, see RFC 1700.  */ +    char *s, *s2;      struct tlv *a;      s = strchr(nameval, ':');      name = atoi(nameval); -    if (!s || name < 1 || name > 255) +    if (!s)  	return NULL;      len = strlen(s + 1);      if (len > 253)  	return NULL; + +    s2 = strchr(s + 1, ':'); +    if (s2) {		 /* Two ':' means we have vendor:name:val.  */ +	vendor = name; +	name = atoi(s2 + 1); +	s = s2; +    } + +    if (name < 1 || name > 255) +	return NULL;      a = malloc(sizeof(struct tlv));      if (!a)  	return NULL; +      a->v = (uint8_t *)stringcopy(s + 1, 0);      if (!a->v) {  	free(a); @@ -2318,6 +2355,10 @@ struct tlv *extractattr(char *nameval) {      }      a->t = name;      a->l = len; + +    if (vendor) + 	a = makevendortlv(vendor, a); +      return a;  } @@ -2390,7 +2431,8 @@ struct rewrite *getrewrite(char *alt1, char *alt2) {      return NULL;  } -void addrewrite(char *value, char **rmattrs, char **rmvattrs, char **addattrs, char **modattrs) { +void addrewrite(char *value, char **rmattrs, char **rmvattrs, char **addattrs, char **addvattrs, char **modattrs) +{      struct rewrite *rewrite = NULL;      int i, n;      uint8_t *rma = NULL; @@ -2439,6 +2481,21 @@ void addrewrite(char *value, char **rmattrs, char **rmvattrs, char **addattrs, c  	freegconfmstr(addattrs);      } +    if (addvattrs) { +	if (!adda) +	    adda = list_create(); +	if (!adda) +	    debugx(1, DBG_ERR, "malloc failed"); +	for (i = 0; addvattrs[i]; i++) { +	    a = extractattr(addvattrs[i]); +	    if (!a) +		debugx(1, DBG_ERR, "addrewrite: invalid attribute %s", addvattrs[i]); +	    if (!list_push(adda, a)) +		debugx(1, DBG_ERR, "malloc failed"); +	} +	freegconfmstr(addvattrs); +    } +      if (modattrs) {  	moda = list_create();  	if (!moda) @@ -2917,7 +2974,9 @@ int confrealm_cb(struct gconffile **cf, void *arg, char *block, char *opt, char  }  int confrewrite_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) { -    char **rmattrs = NULL, **rmvattrs = NULL, **addattrs = NULL, **modattrs = NULL; +    char **rmattrs = NULL, **rmvattrs = NULL; +    char **addattrs = NULL, **addvattrs = NULL; +    char **modattrs = NULL;      debug(DBG_DBG, "confrewrite_cb called for %s", block); @@ -2925,11 +2984,12 @@ int confrewrite_cb(struct gconffile **cf, void *arg, char *block, char *opt, cha  			  "removeAttribute", CONF_MSTR, &rmattrs,  			  "removeVendorAttribute", CONF_MSTR, &rmvattrs,  			  "addAttribute", CONF_MSTR, &addattrs, +			  "addVendorAttribute", CONF_MSTR, &addvattrs,  			  "modifyAttribute", CONF_MSTR, &modattrs,  			  NULL  	    ))  	debugx(1, DBG_ERR, "configuration error"); -    addrewrite(val, rmattrs, rmvattrs, addattrs, modattrs); +    addrewrite(val, rmattrs, rmvattrs, addattrs, addvattrs, modattrs);      return 1;  } | 
