From 7a8b09526fbb3c5a465b4f9e34ae8d412f349b82 Mon Sep 17 00:00:00 2001 From: "Alan T. DeKok" Date: Mon, 2 Aug 2010 15:54:46 +0200 Subject: [PATCH] Manual merge of aec08bce7f Better handle a "known" attribute with invalid length If we receive an "integer" attribute with length "10", don't leave the name as "Foo-Bar". Instead, make it clear that the attribute is unknown, and print it as "Attr-%d" --- src/include/libradius.h | 1 + src/lib/radius.c | 35 +++++++++++++++++++++++++++-------- src/lib/valuepair.c | 49 ++++++++++++++++++++++++++++++++++++------------- 3 files changed, 64 insertions(+), 21 deletions(-) diff --git a/src/include/libradius.h b/src/include/libradius.h index c8f7ce9..1d12fd7 100644 --- a/src/include/libradius.h +++ b/src/include/libradius.h @@ -331,6 +331,7 @@ int rad_vp2attr(const RADIUS_PACKET *packet, /* valuepair.c */ VALUE_PAIR *pairalloc(DICT_ATTR *da); +VALUE_PAIR *paircreate_raw(int attr, int vendor, int type, VALUE_PAIR *); VALUE_PAIR *paircreate(int attr, int vendor, int type); void pairfree(VALUE_PAIR **); void pairbasicfree(VALUE_PAIR *pair); diff --git a/src/lib/radius.c b/src/lib/radius.c index 84e88ef..112e35d 100644 --- a/src/lib/radius.c +++ b/src/lib/radius.c @@ -2437,16 +2437,35 @@ static VALUE_PAIR *data2vp(const RADIUS_PACKET *packet, default: raw: - vp->type = PW_TYPE_OCTETS; - vp->length = length; - memcpy(vp->vp_octets, data, length); - - /* - * Ensure there's no encryption or tag stuff, - * we just pass the attribute as-is. + * Change the name to show the user that the + * attribute is not of the correct format. */ - memset(&vp->flags, 0, sizeof(vp->flags)); + { + int attr = vp->attribute; + int vendor = vp->vendor; + VALUE_PAIR *vp2; + + vp2 = pairalloc(NULL); + if (!vp2) { + pairfree(&vp); + return NULL; + } + pairfree(&vp); + vp = vp2; + + /* + * This sets "vp->flags" appropriately, + * and vp->type. + */ + if (!paircreate_raw(attr, vendor, PW_TYPE_OCTETS, vp)) { + return NULL; + } + + vp->length = length; + memcpy(vp->vp_octets, data, length); + } + break; } return vp; diff --git a/src/lib/valuepair.c b/src/lib/valuepair.c index efe37db..a85ecc4 100644 --- a/src/lib/valuepair.c +++ b/src/lib/valuepair.c @@ -134,6 +134,34 @@ VALUE_PAIR *pairalloc(DICT_ATTR *da) return vp; } +/* + * Create a new valuepair. + */ +VALUE_PAIR *paircreate_raw(int attr, int vendor, int type, VALUE_PAIR *vp) +{ + char *p = (char *) (vp + 1); + + if (!vp->flags.unknown_attr) { + pairfree(&vp); + return NULL; + } + + vp->vendor = vendor; + vp->attribute = attr; + vp->operator = T_OP_EQ; + vp->name = p; + vp->type = type; + vp->length = 0; + memset(&vp->flags, 0, sizeof(vp->flags)); + vp->flags.unknown_attr = 1; + + if (!vp_print_name(p, FR_VP_NAME_LEN, vp->attribute, vp->vendor)) { + free(vp); + return NULL; + } + + return vp; +} /* * Create a new valuepair. @@ -153,19 +181,7 @@ VALUE_PAIR *paircreate(int attr, int vendor, int type) /* * It isn't in the dictionary: update the name. */ - if (!da) { - char *p = (char *) (vp + 1); - - vp->vendor = vendor; - vp->attribute = attr; - vp->name = p; - vp->type = type; /* be forgiving */ - - if (!vp_print_name(p, FR_VP_NAME_LEN, attr, vendor)) { - free(vp); - return NULL; - } - } + if (!da) return paircreate_raw(attr, vendor, type, vp); return vp; } @@ -326,6 +342,13 @@ VALUE_PAIR *paircopyvp(const VALUE_PAIR *vp) return NULL; } memcpy(n, vp, sizeof(*n) + name_len); + + /* + * Reset the name field to point to the NEW attribute, + * rather than to the OLD one. + */ + if (vp->flags.unknown_attr) n->name = (char *) (n + 1); + n->next = NULL; if ((n->type == PW_TYPE_TLV) && -- 2.1.4