Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
implement rewritevendorattribute
  • Loading branch information
Fabian Mauchle committed Apr 24, 2019
1 parent 3e6bd73 commit 51630d4
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 10 deletions.
1 change: 1 addition & 0 deletions radmsg.h
Expand Up @@ -52,6 +52,7 @@ struct list *radmsg_getalltype(const struct radmsg *msg, uint8_t type);
int radmsg_copy_attrs(struct radmsg *dst,
const struct radmsg *src,
uint8_t type);
uint8_t *tlv2buf(uint8_t *p, const struct tlv *tlv);
uint8_t *radmsg2buf(struct radmsg *msg, uint8_t *, int);
struct radmsg *buf2radmsg(uint8_t *, uint8_t *, int, uint8_t *);
uint8_t attrname2val(char *attrname);
Expand Down
83 changes: 74 additions & 9 deletions rewrite.c
Expand Up @@ -257,6 +257,7 @@ void addrewrite(char *value, uint8_t whitelist_mode, char **rmattrs, char **rmva
rewrite->removevendorattrs = rmva;
rewrite->addattrs = adda;
rewrite->modattrs = moda;
rewrite->modvattrs = NULL;
rewrite->supattrs = supa;
}

Expand Down Expand Up @@ -406,14 +407,78 @@ int dorewritemodattr(struct tlv *attr, struct modattr *modattr) {
return 1;
}

int dorewritemod(struct radmsg *msg, struct list *modattrs) {
struct list_node *n, *m;
int replacesubtlv(struct tlv *vendortlv, uint8_t *p, struct tlv *newtlv) {
int size_diff;
uint8_t rem_size, *next_attr;

size_diff = newtlv->l - ATTRLEN(p);
next_attr = p+ATTRLEN(p);
rem_size = (vendortlv->v + vendortlv->l) - next_attr;

if (size_diff < 0)
memmove(next_attr + size_diff, next_attr, rem_size);
if (!resizeattr(vendortlv, vendortlv->l+size_diff))
return 0;
if (size_diff > 0)
memmove(next_attr + size_diff, next_attr, rem_size);

tlv2buf(p, newtlv);
return 1;
}

for (n = list_first(msg->attrs); n; n = list_next(n))
for (m = list_first(modattrs); m; m = list_next(m))
if (((struct tlv *)n->data)->t == ((struct modattr *)m->data)->t &&
!dorewritemodattr((struct tlv *)n->data, (struct modattr *)m->data))
int dorewritemodvattr(struct tlv *vendortlv, struct modattr *modvattr) {
uint8_t *p;
struct tlv *tmpattr;

if (vendortlv->l <= 4 || !attrvalidate(vendortlv->v+4, vendortlv->l-4))
return 0;
for (p = vendortlv->v+4; p < (vendortlv->v + vendortlv->l); p = p+ATTRLEN(p)) {
if (ATTRTYPE(p) == modvattr->t) {
tmpattr = maketlv(ATTRTYPE(p), ATTRVALLEN(p), ATTRVAL(p));
if (dorewritemodattr(tmpattr, modvattr)) {
int size_diff = tmpattr->l - ATTRVALLEN(p);
uint8_t *next_attr = p+ATTRLEN(p);
uint8_t rem_size = (vendortlv->v + vendortlv->l) - next_attr;

if (size_diff < 0)
memmove(next_attr + size_diff, next_attr, rem_size);
if (!resizeattr(vendortlv, vendortlv->l+size_diff))
return 0;
if (size_diff > 0)
memmove(next_attr + size_diff, next_attr, rem_size);

tlv2buf(p, tmpattr);
} else {
freetlv(tmpattr);
return 0;
}
freetlv(tmpattr);
}
}
return 1;
}

int dorewritemod(struct radmsg *msg, struct list *modattrs, struct list *modvattrs) {
struct list_node *n, *m;
uint32_t vendor;

for (n = list_first(msg->attrs); n; n = list_next(n)) {
struct tlv *attr = (struct tlv *)n->data;
if (attr->t == RAD_Attr_Vendor_Specific) {
memcpy(&vendor, attr->v, 4);
vendor = ntohl(vendor);
for (m = list_first(modvattrs); m; m = list_next(m)) {
if (vendor == ((struct modattr *)m->data)->vendor &&
!dorewritemodvattr(attr, (struct modattr*)m->data))
return 0;
}
} else {
for (m = list_first(modattrs); m; m = list_next(m))
if (((struct tlv *)n->data)->t == ((struct modattr *)m->data)->t &&
!dorewritemodattr((struct tlv *)n->data, (struct modattr *)m->data))
return 0;
}
}
return 1;
}

Expand Down Expand Up @@ -480,9 +545,9 @@ int dorewrite(struct radmsg *msg, struct rewrite *rewrite) {

if (rewrite) {
if (rewrite->removeattrs || rewrite->removevendorattrs)
dorewriterm(msg, rewrite->removeattrs, rewrite->removevendorattrs, rewrite->whitelist_mode);
if (rewrite->modattrs)
if (!dorewritemod(msg, rewrite->modattrs))
dorewriterm(msg, rewrite->removeattrs, rewrite->removevendorattrs, rewrite->whitelist_mode);
if (rewrite->modattrs || rewrite->modvattrs)
if (!dorewritemod(msg, rewrite->modattrs, rewrite->modvattrs))
rv = 0;
if (rewrite->supattrs)
if (!dorewritesup(msg, rewrite->supattrs))
Expand Down
2 changes: 2 additions & 0 deletions rewrite.h
Expand Up @@ -10,6 +10,7 @@

struct modattr {
uint8_t t;
uint32_t vendor;
char *replacement;
regex_t *regex;
};
Expand All @@ -20,6 +21,7 @@ struct rewrite {
uint32_t *removevendorattrs; /*NULL terminated*/
struct list *addattrs; /*struct tlv*/
struct list *modattrs; /*struct modattr*/
struct list *modvattrs; /*struct modattr*/
struct list *supattrs; /*struct tlv*/
};

Expand Down
62 changes: 61 additions & 1 deletion tests/t_rewrite.c
Expand Up @@ -52,13 +52,14 @@ void _reset_rewrite(struct rewrite *rewrite) {
rewrite->removevendorattrs = NULL;
_list_clear(rewrite->addattrs);
_list_clear(rewrite->modattrs);
_list_clear(rewrite->modvattrs);
_list_clear(rewrite->supattrs);
}

int
main (int argc, char *argv[])
{
int testcount = 23;
int testcount = 25;
struct list *origattrs, *expectedattrs;
struct rewrite rewrite;
char *username = "user@realm";
Expand All @@ -73,6 +74,7 @@ main (int argc, char *argv[])
rewrite.removevendorattrs = NULL;
rewrite.addattrs = list_create();
rewrite.modattrs = list_create();
rewrite.modvattrs = list_create();
rewrite.supattrs = list_create();

printf("1..%d\n", testcount);
Expand Down Expand Up @@ -471,6 +473,64 @@ main (int argc, char *argv[])
_reset_rewrite(&rewrite);
}

/* test modify vendor*/
{
struct modattr *mod = malloc(sizeof(struct modattr));
regex_t regex;
uint8_t vendorattrin[] = {0,0,0,42,1,3,'b',1,3,'a',2,3,0,1,3,'a'};
uint8_t vendorattrout[] = {0,0,0,42,1,3,'b',1,4,'b','b',2,3,0,1,4,'b','b'};

mod->t = 1;
mod->vendor = 42;
mod->regex = &regex;
mod->replacement = "bb";
regcomp(mod->regex, "a", REG_ICASE | REG_EXTENDED);

list_push(rewrite.modvattrs, mod);
list_push(origattrs, maketlv(RAD_Attr_Vendor_Specific,sizeof(vendorattrin), vendorattrin));
list_push(expectedattrs, maketlv(RAD_Attr_Vendor_Specific,sizeof(vendorattrout), vendorattrout));

if (_check_rewrite(origattrs, &rewrite, expectedattrs, 0))
printf("not ");
printf("ok %d - modify vendor\n", testcount++);

_list_clear(origattrs);
_list_clear(expectedattrs);
_reset_rewrite(&rewrite);
}

/* test modify vendor too long (total vendor attribute too long) */
{
struct modattr *mod = malloc(sizeof(struct modattr));
regex_t regex;
uint8_t vendorattrin[RAD_Max_Attr_Value_Length];

memset(vendorattrin, 0, RAD_Max_Attr_Value_Length);
vendorattrin[3] = 42;
vendorattrin[4] = 1;
vendorattrin[5] = 3;
vendorattrin[6] = 'a';
vendorattrin[7] = 2;
vendorattrin[8] = RAD_Max_Attr_Value_Length - 7;

mod->t = 1;
mod->vendor = 42;
mod->regex = &regex;
mod->replacement = "bb";
regcomp(mod->regex, "a", REG_ICASE | REG_EXTENDED);

list_push(rewrite.modvattrs, mod);
list_push(origattrs, maketlv(RAD_Attr_Vendor_Specific,sizeof(vendorattrin), vendorattrin));

if (_check_rewrite(origattrs, &rewrite, origattrs, 1))
printf("not ");
printf("ok %d - modify vendor too long\n", testcount++);

_list_clear(origattrs);
_list_clear(expectedattrs);
_reset_rewrite(&rewrite);
}

/* test whitelist rewrite */
{
uint8_t whitelistattrs[] = {1,0};
Expand Down

0 comments on commit 51630d4

Please sign in to comment.