Skip to content

Commit

Permalink
Disallow "TLV" types to have any data
Browse files Browse the repository at this point in the history
If created as hex, they either get turned into unknowns
(when they have a bad format), or they get turned into
multiple sub-attrs (when they have a good format)
  • Loading branch information
alandekok committed Jun 15, 2015
1 parent 6dcd242 commit a12333b
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 35 deletions.
2 changes: 0 additions & 2 deletions src/include/libradius.h
Expand Up @@ -269,7 +269,6 @@ typedef union value_data {

uint8_t ipv4prefix[6]; //!< IPv4 prefix (should be struct?).

uint8_t *tlv; //!< Nested TLV (should go away).
void *ptr; //!< generic pointer.
} value_data_t;

Expand Down Expand Up @@ -364,7 +363,6 @@ typedef struct value_pair_raw {
#define vp_signed data.sinteger
#define vp_integer64 data.integer64
#define vp_ipv4prefix data.ipv4prefix
#define vp_tlv data.tlv
#define vp_length length

typedef struct fr_ipaddr_t {
Expand Down
60 changes: 52 additions & 8 deletions src/lib/pair.c
Expand Up @@ -652,7 +652,6 @@ VALUE_PAIR *paircopyvp(TALLOC_CTX *ctx, VALUE_PAIR const *vp)
}

switch (vp->da->type) {
case PW_TYPE_TLV:
case PW_TYPE_OCTETS:
n->vp_octets = NULL; /* else pairmemcpy will free vp's value */
pairmemcpy(n, vp->vp_octets, n->vp_length);
Expand Down Expand Up @@ -881,11 +880,6 @@ void pairmove(TALLOC_CTX *ctx, VALUE_PAIR **to, VALUE_PAIR **from)
found->next = j;
break;

case PW_TYPE_TLV:
pairmemsteal(found, i->vp_tlv);
i->vp_tlv = NULL;
break;

case PW_TYPE_OCTETS:
pairmemsteal(found, i->vp_octets);
i->vp_octets = NULL;
Expand Down Expand Up @@ -1433,6 +1427,57 @@ VALUE_PAIR *pairmake(TALLOC_CTX *ctx, VALUE_PAIR **vps,
break;
}

/*
* We allow this for stupidity, but it's really a bad idea.
*/
if (vp->da->type == PW_TYPE_TLV) {
ssize_t len;
DICT_ATTR const *unknown;
VALUE_PAIR *head = NULL;
VALUE_PAIR **tail = &head;

if (!value) {
talloc_free(vp);
return NULL;
}

unknown = dict_unknown_afrom_fields(vp, vp->da->attr, vp->da->vendor);
if (!unknown) {
talloc_free(vp);
return NULL;
}

vp->da = unknown;

/*
* Parse it as an unknown type, i.e. octets.
*/
if (pairparsevalue(vp, value, -1) < 0) {
talloc_free(vp);
return NULL;
}

/*
* It's badly formatted. Treat it as unknown.
*/
if (rad_tlv_ok(vp->vp_octets, vp->vp_length, 1, 1) < 0) {
goto do_add;
}

/*
* Decode the TLVs
*/
len = rad_data2vp_tlvs(ctx, NULL, NULL, NULL, da, vp->vp_octets,
vp->vp_length, tail);
if (len < 0) {
goto do_add;
}

talloc_free(vp);
vp = head;
goto do_add;
}

/*
* FIXME: if (strcasecmp(attribute, vp->da->name) != 0)
* then the user MAY have typed in the attribute name
Expand All @@ -1446,6 +1491,7 @@ VALUE_PAIR *pairmake(TALLOC_CTX *ctx, VALUE_PAIR **vps,
return NULL;
}

do_add:
if (vps) pairadd(vps, vp);
return vp;
}
Expand Down Expand Up @@ -1931,7 +1977,6 @@ static void pairtypeset(VALUE_PAIR *vp)

switch (vp->da->type) {
case PW_TYPE_OCTETS:
case PW_TYPE_TLV:
talloc_set_type(vp->data.ptr, uint8_t);
return;

Expand Down Expand Up @@ -2115,7 +2160,6 @@ inline void fr_pair_verify_vp(char const *file, int line, VALUE_PAIR const *vp)

if (vp->data.ptr) switch (vp->da->type) {
case PW_TYPE_OCTETS:
case PW_TYPE_TLV:
{
size_t len;
TALLOC_CTX *parent;
Expand Down
3 changes: 1 addition & 2 deletions src/lib/radius.c
Expand Up @@ -852,7 +852,6 @@ static ssize_t vp2data_any(RADIUS_PACKET const *packet,
switch (vp->da->type) {
case PW_TYPE_STRING:
case PW_TYPE_OCTETS:
case PW_TYPE_TLV:
data = vp->data.ptr;
if (!data) {
fr_strerror_printf("ERROR: Cannot encode NULL data");
Expand Down Expand Up @@ -3939,7 +3938,6 @@ ssize_t rad_vp2data(uint8_t const **out, VALUE_PAIR const *vp)
switch (vp->da->type) {
case PW_TYPE_STRING:
case PW_TYPE_OCTETS:
case PW_TYPE_TLV:
memcpy(out, &vp->data.ptr, sizeof(*out));
break;

Expand Down Expand Up @@ -4008,6 +4006,7 @@ ssize_t rad_vp2data(uint8_t const **out, VALUE_PAIR const *vp)
case PW_TYPE_LONG_EXTENDED:
case PW_TYPE_EVS:
case PW_TYPE_VSA:
case PW_TYPE_TLV:
case PW_TYPE_TIMEVAL:
case PW_TYPE_MAX:
fr_strerror_printf("Cannot get data for VALUE_PAIR type %i", vp->da->type);
Expand Down
25 changes: 2 additions & 23 deletions src/lib/value.c
Expand Up @@ -642,29 +642,8 @@ ssize_t value_data_from_str(TALLOC_CTX *ctx, value_data_t *dst,

/* don't use this! */
case PW_TYPE_TLV:
{
uint8_t *p;

if ((len < 2) || (len & 0x01) || (strncasecmp(src, "0x", 2) != 0)) {
fr_strerror_printf("Invalid TLV specification");
return -1;
}
len -= 2;

ret = len >> 1;
p = talloc_array(ctx, uint8_t, ret);
if (!p) {
fr_strerror_printf("No memory");
return -1;
}
if (fr_hex2bin(p, ret, src + 2, len) != (size_t)ret) {
fr_strerror_printf("Invalid hex data in TLV");
return -1;
}

dst->tlv = p;
}
goto finish;
fr_strerror_printf("Cannot parse TLV");
return -1;

case PW_TYPE_IPV4_ADDR:
{
Expand Down
6 changes: 6 additions & 0 deletions src/tests/unit/wimax.txt
Expand Up @@ -137,3 +137,9 @@ data 55 06 00 00 0e 10 1a 25 00 00 60 b5 1c 1f 00 01 04 00 20 02 04 00 20 03 06

encode WiMAX-Packet-Data-Flow-Id := 32, WiMAX-Service-Data-Flow-ID := 32, WiMAX-Service-Profile-ID := 32, Session-Timeout := 7200, WiMAX-Packet-Data-Flow-Id := 33, WiMAX-Service-Data-Flow-ID := 33, WiMAX-Service-Profile-ID := 33
data 1a 17 00 00 60 b5 1c 11 00 01 04 00 20 02 04 00 20 03 06 00 00 00 20 1b 06 00 00 1c 20 1a 17 00 00 60 b5 1c 11 00 01 04 00 21 02 04 00 21 03 06 00 00 00 21

encode WiMAX-Capability = 0x01ff45454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545040301
data 1a ff 00 00 60 b5 01 f9 80 01 ff 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 45 1a 15 00 00 60 b5 01 0f 00 45 45 45 45 45 45 45 45 45 04 03 01

decode -
data WiMAX-Release = 'EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE', WiMAX-Idle-Mode-Notification-Cap = Supported

0 comments on commit a12333b

Please sign in to comment.