Skip to content

Commit

Permalink
implement whitelist mode for attribute rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
Fabian Mauchle committed Apr 18, 2019
1 parent c49d8cb commit c0c1ea4
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 8 deletions.
15 changes: 8 additions & 7 deletions rewrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ int findvendorsubattr(uint32_t *attrs, uint32_t vendor, uint32_t subattr) {
}

/* returns 1 if entire element is to be removed, else 0 */
int dovendorrewriterm(struct tlv *attr, uint32_t *removevendorattrs) {
int dovendorrewriterm(struct tlv *attr, uint32_t *removevendorattrs, int inverted) {
uint8_t alen, sublen;
uint32_t vendor;
uint8_t *subattrs;
Expand Down Expand Up @@ -318,27 +318,28 @@ int dovendorrewriterm(struct tlv *attr, uint32_t *removevendorattrs) {
while (sublen > 1) {
alen = ATTRLEN(subattrs);
sublen -= alen;
if (findvendorsubattr(removevendorattrs, vendor, ATTRTYPE(subattrs))) {
if (!!findvendorsubattr(removevendorattrs, vendor, ATTRTYPE(subattrs)) != !!inverted) {
memmove(subattrs, subattrs + alen, sublen);
attr->l -= alen;
} else
subattrs += alen;
}
if (attr->l <= 4)
if ((attr->l <= 4) != !!inverted)
return 1;
return 0;
}

void dorewriterm(struct radmsg *msg, uint8_t *rmattrs, uint32_t *rmvattrs) {
/*if inverted is true, remove all attributes except those listed */
void dorewriterm(struct radmsg *msg, uint8_t *rmattrs, uint32_t *rmvattrs, int inverted) {
struct list_node *n, *p;
struct tlv *attr;

p = NULL;
n = list_first(msg->attrs);
while (n) {
attr = (struct tlv *)n->data;
if ((rmattrs && strchr((char *)rmattrs, attr->t)) ||
(rmvattrs && attr->t == RAD_Attr_Vendor_Specific && dovendorrewriterm(attr, rmvattrs))) {
if (((rmattrs && strchr((char *)rmattrs, attr->t)) ||
(rmvattrs && attr->t == RAD_Attr_Vendor_Specific && dovendorrewriterm(attr, rmvattrs, inverted))) != !!inverted) {
list_removedata(msg->attrs, attr);
freetlv(attr);
n = p ? list_next(p) : list_first(msg->attrs);
Expand Down Expand Up @@ -478,7 +479,7 @@ int dorewrite(struct radmsg *msg, struct rewrite *rewrite) {

if (rewrite) {
if (rewrite->removeattrs || rewrite->removevendorattrs)
dorewriterm(msg, rewrite->removeattrs, rewrite->removevendorattrs);
dorewriterm(msg, rewrite->removeattrs, rewrite->removevendorattrs, rewrite->whitelist_mode);
if (rewrite->modattrs)
if (!dorewritemod(msg, rewrite->modattrs))
rv = 0;
Expand Down
1 change: 1 addition & 0 deletions rewrite.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ struct modattr {
};

struct rewrite {
uint8_t whitelist_mode;
uint8_t *removeattrs; /*NULL terminated*/
uint32_t *removevendorattrs; /*NULL terminated*/
struct list *addattrs; /*struct tlv*/
Expand Down
101 changes: 100 additions & 1 deletion tests/t_rewrite.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ void _list_clear(struct list *list) {
}

void _reset_rewrite(struct rewrite *rewrite) {
rewrite->whitelist_mode = 0;
rewrite->removeattrs = NULL;
rewrite->removevendorattrs = NULL;
_list_clear(rewrite->addattrs);
Expand All @@ -57,7 +58,7 @@ void _reset_rewrite(struct rewrite *rewrite) {
int
main (int argc, char *argv[])
{
int testcount = 18;
int testcount = 22;
struct list *origattrs, *expectedattrs;
struct rewrite rewrite;
char *username = "user@realm";
Expand All @@ -67,6 +68,7 @@ main (int argc, char *argv[])
origattrs=list_create();
expectedattrs=list_create();

rewrite.whitelist_mode=0;
rewrite.removeattrs = NULL;
rewrite.removevendorattrs = NULL;
rewrite.addattrs = list_create();
Expand Down Expand Up @@ -449,6 +451,103 @@ main (int argc, char *argv[])
_reset_rewrite(&rewrite);
}

/* test whitelist rewrite */
{
uint8_t whitelistattrs[] = {1,0};
rewrite.whitelist_mode=1;
rewrite.removeattrs = whitelistattrs;

list_push(origattrs, maketlv(1, strlen(username), username));
list_push(origattrs, maketlv(3, strlen(username), username));
list_push(origattrs, makevendortlv(42, maketlv(1, strlen(username), username)));

list_push(expectedattrs, maketlv(1, strlen(username), username));

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

}

/* test whitelist vendor rewrite */
{
uint32_t whitelistvendorattrs[] = {42,256,0};
uint8_t value = 42;
uint8_t vendor_nonrfc_in[] = {0,0,0,42,1,2,3,4};

rewrite.whitelist_mode=1;
rewrite.removevendorattrs = whitelistvendorattrs;
list_push(origattrs, maketlv(1, strlen(username), username));
list_push(origattrs, makevendortlv(42, maketlv(1, 1, &value)));
list_push(origattrs, makevendortlv(43, maketlv(1, 1, &value)));
list_push(origattrs, maketlv(26, sizeof(vendor_nonrfc_in), vendor_nonrfc_in));

list_push(expectedattrs, makevendortlv(42, maketlv(1, 1, &value)));
list_push(expectedattrs, maketlv(26, sizeof(vendor_nonrfc_in), vendor_nonrfc_in));

if (_check_rewrite(origattrs, &rewrite, expectedattrs, 0))
printf("not ");
printf("ok %d - whitelistvendorattrs\n", testcount++);
_list_clear(origattrs);
_list_clear(expectedattrs);
_reset_rewrite(&rewrite);
}

/* test whitelist vendor rewrite subattribute*/
{
uint32_t whitelistvendorattrs[] = {42,1,0};
uint8_t value = 42;
uint8_t vendor_long1_in[] = {0,0,0,42,2,3,0,1,3,0};
uint8_t vendor_long1_out[] = {0,0,0,42,1,3,0};
uint8_t vendor_nonrfc_in[] = {0,0,0,42,1,2,3,4};

rewrite.whitelist_mode=1;
rewrite.removevendorattrs = whitelistvendorattrs;
list_push(origattrs, makevendortlv(42, maketlv(1, 1, &value)));
list_push(origattrs, makevendortlv(43, maketlv(1, 1, &value)));
list_push(origattrs, makevendortlv(42, maketlv(2, 1, &value)));
list_push(origattrs, maketlv(26, sizeof(vendor_long1_in), vendor_long1_in));
list_push(origattrs, maketlv(26, sizeof(vendor_nonrfc_in), vendor_nonrfc_in));

list_push(expectedattrs, makevendortlv(42, maketlv(1, 1, &value)));
list_push(expectedattrs, maketlv(26, sizeof(vendor_long1_out), vendor_long1_out));

if (_check_rewrite(origattrs, &rewrite, expectedattrs, 0))
printf("not ");
printf("ok %d - whitelistvendorattrs\n", testcount++);
_list_clear(origattrs);
_list_clear(expectedattrs);
_reset_rewrite(&rewrite);
}

/* test whitelist vendor rewrite combined*/
{
uint32_t whitelistvendorattrs[] = {42,1,0};
uint8_t whitelistattrs[] = {1,0};
uint8_t value = 42;

rewrite.whitelist_mode=1;
rewrite.removeattrs = whitelistattrs;
rewrite.removevendorattrs = whitelistvendorattrs;
list_push(origattrs, maketlv(1, strlen(username), username));
list_push(origattrs, maketlv(3, strlen(username), username));
list_push(origattrs, makevendortlv(42, maketlv(1, 1, &value)));
list_push(origattrs, makevendortlv(43, maketlv(1, 1, &value)));
list_push(origattrs, makevendortlv(43, maketlv(2, 1, &value)));

list_push(expectedattrs, maketlv(1, strlen(username), username));
list_push(expectedattrs, makevendortlv(42, maketlv(1, 1, &value)));

if (_check_rewrite(origattrs, &rewrite, expectedattrs, 0))
printf("not ");
printf("ok %d - whitelistvendorattrs\n", testcount++);
_list_clear(origattrs);
_list_clear(expectedattrs);
_reset_rewrite(&rewrite);
}


return 0;
Expand Down

0 comments on commit c0c1ea4

Please sign in to comment.