17#include <radcli/radcli.h>
20#define PARSE_MODE_NAME 0
21#define PARSE_MODE_EQUAL 1
22#define PARSE_MODE_VALUE 2
23#define PARSE_MODE_INVALID 3
46VALUE_PAIR *
rc_avpair_add (rc_handle
const *rh, VALUE_PAIR **list, uint32_t attrid,
void const *pval,
int len, uint32_t vendorspec)
71 VALUE_PAIR *vp, *prev, *tmp;
74 if(vendorspec != VENDOR_NONE)
75 vattrid = RADCLI_VENDOR_ATTR_SET(attrid, vendorspec);
90 prev->next = vp->next;
142 len = (uint32_t)strlen((
char const *)pval);
146 if (len > (
int)(VENDOR(vp->
attribute) ? (AUTH_STRING_LEN - VSA_HDR_LEN) : (AUTH_STRING_LEN))) {
147 rc_log(LOG_ERR,
"rc_avpair_assign: bad attribute length");
150 memcpy(vp->
strvalue, (
char const *)pval, len);
158 vp->
lvalue = * (uint32_t *) pval;
162 rc_log(LOG_ERR,
"rc_avpair_assign: bad IPv6 length");
165 memcpy(vp->
strvalue, (
char const *)pval, len);
170 if (len < 2 || len > 18) {
171 rc_log(LOG_ERR,
"rc_avpair_assign: bad IPv6 prefix length");
174 memcpy(vp->
strvalue, (
char const *)pval, len);
179 rc_log(LOG_ERR,
"rc_avpair_assign: no attribute %d in dictionary", vp->
type);
196VALUE_PAIR *
rc_avpair_new (rc_handle
const *rh, uint32_t attrid,
void const *pval,
int len, uint32_t vendorspec)
198 VALUE_PAIR *vp = NULL;
202 if(vendorspec != VENDOR_NONE) {
203 vattrid = RADCLI_VENDOR_ATTR_SET(attrid, vendorspec);
210 rc_log(LOG_ERR,
"rc_avpair_new: no attribute %d/%u in dictionary", vendorspec, attrid);
215 rc_log(LOG_ERR,
"rc_avpair_new: no Vendor-Id %d in dictionary", vendorspec);
218 if ((vp = malloc (
sizeof (VALUE_PAIR))) != NULL)
239 if (vp->
lvalue > AUTH_STRING_LEN - 2)
240 vp->
lvalue = AUTH_STRING_LEN - 2;
257 rc_log(LOG_CRIT,
"rc_avpair_new: out of memory");
276static int rc_avpair_gen2(rc_handle
const *rh, VALUE_PAIR *pair,
277 pkt_buf *pb, uint32_t vendorspec,
280 VALUE_PAIR *head = pair;
281 VALUE_PAIR **tail = &head;
282 const uint8_t *attr_data, *ptr;
288 char buffer[(AUTH_STRING_LEN * 2) + 1];
291 while (*tail != NULL)
292 tail = &(*tail)->next;
294 while (pb_len(pb) > 0) {
295 if (pb_len(pb) < 2) {
296 rc_log(LOG_ERR,
"rc_avpair_gen: received attribute with "
300 attrlen = pb->data[1];
301 if (attrlen < 2 || (
size_t)attrlen > pb_len(pb)) {
302 rc_log(LOG_ERR,
"rc_avpair_gen: received attribute with "
307 attr_data = pb->data;
308 assert(pb_pull(pb, attrlen) == 0);
310 attribute = RADCLI_VENDOR_ATTR_SET(attr_data[0], vendorspec);
317 rc_log(LOG_ERR,
"rc_avpair_gen: received VSA "
318 "attribute with invalid length");
321 memcpy(&lvalue, ptr, 4);
322 lvalue = ntohl(lvalue);
324 rc_log(LOG_WARNING,
"rc_avpair_gen: received VSA "
325 "attribute with unknown Vendor-Id %d", lvalue);
331 VALUE_PAIR *vsa_list = NULL;
332 pb_init_read(&vsa_pb,
333 (
void *)(uintptr_t)(ptr + 4),
334 attrlen - 4, attrlen - 4);
335 if (rc_avpair_gen2(rh, NULL, &vsa_pb, lvalue,
339 if (vsa_list != NULL) {
341 while (*tail != NULL)
342 tail = &(*tail)->next;
351 rc_bin2hex(buffer,
sizeof(buffer), ptr, (
size_t)attrlen);
352 if (vendorspec == 0) {
353 rc_log(LOG_WARNING,
"rc_avpair_gen: received "
354 "unknown attribute %d of length %d: 0x%s",
355 (
unsigned)attribute, attrlen + 2, buffer);
357 rc_log(LOG_WARNING,
"rc_avpair_gen: received "
358 "unknown VSA attribute %u, vendor %u of "
359 "length %d: 0x%s", (
unsigned)ATTRID(attribute),
360 (
unsigned)VENDOR(attribute), attrlen + 2, buffer);
365 rpair = calloc(1,
sizeof(*rpair));
367 rc_log(LOG_CRIT,
"rc_avpair_gen: out of memory");
375 switch (attr->
type) {
377 if (attrlen > AUTH_STRING_LEN) {
378 rc_log(LOG_ERR,
"rc_avpair_gen: string attribute too long: %d", attrlen);
382 memcpy(rpair->
strvalue, (
char *)ptr, (
size_t)attrlen);
389 rc_log(LOG_ERR,
"rc_avpair_gen: received "
390 "INTEGER/IPADDR attribute with invalid length");
394 memcpy((
char *)&lvalue, (
char *)ptr, 4);
395 rpair->
lvalue = ntohl(lvalue);
399 rc_log(LOG_ERR,
"rc_avpair_gen: received IPV6ADDR"
400 " attribute with invalid length");
404 memcpy(rpair->
strvalue, (
char *)ptr, 16);
408 if (attrlen > 18 || attrlen < 2) {
409 rc_log(LOG_ERR,
"rc_avpair_gen: received IPV6PREFIX"
410 " attribute with invalid length: %d", attrlen);
414 memcpy(rpair->
strvalue, (
char *)ptr, attrlen);
419 rc_log(LOG_ERR,
"rc_avpair_gen: received DATE "
420 "attribute with invalid length");
424 memcpy((
char *)&lvalue, (
char *)ptr, 4);
425 rpair->
lvalue = ntohl(lvalue);
428 rc_log(LOG_WARNING,
"rc_avpair_gen: %s has unknown type",
469 unsigned char const *ptr,
int length,
473 VALUE_PAIR *out = NULL;
476 pb_init_read(&pb, (
void *)ptr, (
size_t)length, (
size_t)length);
477 if (rc_avpair_gen2(rh, pair, &pb, vendorspec, &out) < 0)
489VALUE_PAIR *
rc_avpair_get (VALUE_PAIR *vp, uint32_t attrid, uint32_t vendorspec)
491 uint64_t attr = RADCLI_VENDOR_ATTR_SET(attrid, vendorspec);
493 for (; vp != NULL && !(attr == vp->
attribute); vp = vp->next)
508 VALUE_PAIR *vp, *fp = NULL, *lp = NULL;
511 vp = malloc(
sizeof(VALUE_PAIR));
543 VALUE_PAIR *this_node = NULL;
548 rc_log(LOG_CRIT,
"rc_avpair_insert: value pair (0x%p) next ptr. (0x%p) not NULL", b, b->next);
571 while (this_node != NULL)
577 this_node = this_node->next;
582 b->next = this_node->next;
615static void rc_fieldcpy(
char *
string,
char const **uptr,
char const *stopat,
size_t len)
617 char const *ptr, *estring;
620 estring =
string + len - 1;
624 while (*ptr !=
'"' && *ptr !=
'\0' && *ptr !=
'\n')
626 if (
string < estring)
639 while (*ptr !=
'\0' && strchr(stopat, *ptr) == NULL)
641 if (
string < estring)
660 char attrstr[AUTH_ID_LEN];
661 char valstr[AUTH_STRING_LEN + 1], *p;
662 DICT_ATTR *attr = NULL;
669 mode = PARSE_MODE_NAME;
670 while (*buffer !=
'\n' && *buffer !=
'\0')
672 if (*buffer ==
' ' || *buffer ==
'\t')
680 case PARSE_MODE_NAME:
681 rc_fieldcpy (attrstr, &buffer,
" \t\n=,",
sizeof(attrstr));
685 rc_log(LOG_ERR,
"rc_avpair_parse: unknown attribute");
692 mode = PARSE_MODE_EQUAL;
695 case PARSE_MODE_EQUAL:
698 mode = PARSE_MODE_VALUE;
703 rc_log(LOG_ERR,
"rc_avpair_parse: missing or misplaced equal sign");
712 case PARSE_MODE_VALUE:
713 rc_fieldcpy (valstr, &buffer,
" \t\n,",
sizeof(valstr));
715 if ((pair = malloc (
sizeof (VALUE_PAIR))) == NULL)
717 rc_log(LOG_CRIT,
"rc_avpair_parse: out of memory");
733 rc_log(LOG_ERR,
"rc_avpair_parse: string value too long");
740 if (isdigit (*valstr))
742 pair->
lvalue = atoi (valstr);
749 rc_log(LOG_ERR,
"rc_avpair_parse: unknown attribute value: %s", valstr);
759 pair->
lvalue = dval->value;
765 if (inet_pton(AF_INET, valstr, &pair->
lvalue) == 0) {
766 rc_log(LOG_ERR,
"rc_avpair_parse: invalid IPv4 address %s", valstr);
775 if (inet_pton(AF_INET6, valstr, pair->
strvalue) == 0) {
776 rc_log(LOG_ERR,
"rc_avpair_parse: invalid IPv6 address %s", valstr);
784 p = strchr(valstr,
'/');
786 rc_log(LOG_ERR,
"rc_avpair_parse: invalid IPv6 prefix %s", valstr);
795 if (inet_pton(AF_INET6, valstr, pair->
strvalue+2) == 0) {
796 rc_log(LOG_ERR,
"rc_avpair_parse: invalid IPv6 prefix %s", valstr);
805 tm = localtime_r (&timeval, &_tm);
809 rc_str2tm (valstr, tm);
810 pair->
lvalue = (uint32_t) mktime (tm);
814 rc_log(LOG_ERR,
"rc_avpair_parse: unknown attribute type %d", pair->
type);
836 if (pair->
lvalue > AUTH_STRING_LEN - 2)
837 pair->
lvalue = AUTH_STRING_LEN - 2;
851 if (*first_pair == NULL)
858 while (link->next != NULL)
865 mode = PARSE_MODE_NAME;
869 mode = PARSE_MODE_NAME;
886int rc_avpair_tostr (rc_handle
const *rh, VALUE_PAIR *pair,
char *name,
int ln,
char *value,
int lv)
894 *name = *value =
'\0';
896 if (!pair || pair->
name[0] ==
'\0') {
897 rc_log(LOG_ERR,
"rc_avpair_tostr: pair is NULL or empty");
901 strlcpy(name, pair->
name, (
size_t) ln);
908 ptr = (
unsigned char *) pair->
strvalue;
917 if (!(isprint (*ptr)))
920 snprintf (&value[pos], lv,
"\\%03o", *ptr);
945 strlcpy(value, dval->name, (
size_t) lv);
949 snprintf(value, lv,
"%ld", (
long int)pair->
lvalue);
954 inad.s_addr = htonl(pair->
lvalue);
955 strlcpy (value, inet_ntoa (inad), (
size_t) lv);
959 if (inet_ntop(AF_INET6, pair->
strvalue, value, lv) == NULL)
969 memset(ip, 0,
sizeof(ip));
972 if (inet_ntop(AF_INET6, ip, (
void*)txt,
sizeof(txt)) == NULL)
974 snprintf(value, lv,
"%s/%u", txt, (
unsigned)pair->
strvalue[1]);
980 struct tm *ptm = gmtime_r((time_t *) & pair->
lvalue, &_tm);
984 strftime (value, lv,
"%m/%d/%y %H:%M:%S", ptm);
989 rc_log(LOG_ERR,
"rc_avpair_tostr: unknown attribute type %d", pair->
type);
1007char *
rc_avpair_log(rc_handle
const *rh, VALUE_PAIR *pair,
char *buf,
size_t buf_len)
1011 char name[RC_NAME_LENGTH + 1], value[256];
1014 for (vp = pair; vp != NULL; vp = vp->next) {
1016 sizeof(value)) == -1)
1018 nlen = len + 32 + 3 + strlen(value) + 2 + 2;
1019 if(nlen<buf_len-1) {
1020 sprintf(buf + len,
"%-32s = '%s'\n", name, value);
1073 *prefix = (
unsigned char)vp->
strvalue[1];
void rc_avpair_remove(VALUE_PAIR **list, uint32_t attrid, uint32_t vendorspec)
DICT_VALUE * rc_dict_getval(rc_handle const *rh, uint32_t value, char const *attrname)
int rc_avpair_get_raw(VALUE_PAIR *vp, char **res, unsigned *res_size)
char * rc_avpair_log(rc_handle const *rh, VALUE_PAIR *pair, char *buf, size_t buf_len)
VALUE_PAIR * rc_avpair_next(VALUE_PAIR *t)
int rc_avpair_get_uint32(VALUE_PAIR *vp, uint32_t *res)
int rc_avpair_get_in6(VALUE_PAIR *vp, struct in6_addr *res, unsigned *prefix)
void rc_avpair_get_attr(VALUE_PAIR *vp, unsigned *type, unsigned *id)
VALUE_PAIR * rc_avpair_gen(rc_handle const *rh, VALUE_PAIR *pair, unsigned char const *ptr, int length, uint32_t vendorspec)
void rc_avpair_free(VALUE_PAIR *pair)
VALUE_PAIR * rc_avpair_copy(VALUE_PAIR *p)
int rc_avpair_tostr(rc_handle const *rh, VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
int rc_avpair_assign(VALUE_PAIR *vp, void const *pval, int len)
DICT_VALUE * rc_dict_findval(rc_handle const *rh, char const *valname)
int rc_avpair_parse(rc_handle const *rh, char const *buffer, VALUE_PAIR **first_pair)
DICT_VENDOR * rc_dict_getvend(rc_handle const *rh, uint32_t vendorspec)
DICT_ATTR * rc_dict_getattr(rc_handle const *rh, uint64_t attribute)
VALUE_PAIR * rc_avpair_add(rc_handle const *rh, VALUE_PAIR **list, uint32_t attrid, void const *pval, int len, uint32_t vendorspec)
void rc_avpair_insert(VALUE_PAIR **a, VALUE_PAIR *p, VALUE_PAIR *b)
VALUE_PAIR * rc_avpair_get(VALUE_PAIR *vp, uint32_t attrid, uint32_t vendorspec)
DICT_ATTR * rc_dict_findattr(rc_handle const *rh, char const *attrname)
VALUE_PAIR * rc_avpair_new(rc_handle const *rh, uint32_t attrid, void const *pval, int len, uint32_t vendorspec)
@ PW_DIGEST_NONCE
Its type is string.
@ PW_DIGEST_REALM
Its type is string.
@ PW_DIGEST_USER_NAME
Its type is string.
@ PW_DIGEST_URI
Its type is string.
@ PW_DIGEST_QOP
Its type is string.
@ PW_DIGEST_BODY_DIGEST
Its type is string.
@ PW_DIGEST_ATTRIBUTES
Its type is string.
@ PW_DIGEST_NONCE_COUNT
Its type is string.
@ PW_DIGEST_ALGORITHM
Its type is string.
@ PW_DIGEST_CNONCE
Its type is string.
@ PW_DIGEST_METHOD
Its type is string.
@ PW_VENDOR_SPECIFIC
Its type is string.
@ PW_TYPE_IPADDR
The attribute is an IPv4 address in host-byte order.
@ PW_TYPE_IPV6ADDR
The attribute is an 128-bit IPv6 address.
@ PW_TYPE_IPV6PREFIX
The attribute is an IPv6 prefix; the lvalue will indicate its size.
@ PW_TYPE_INTEGER
The attribute is a 32-bit integer.
@ PW_TYPE_DATE
The attribute contains a 32-bit number indicating the seconds since epoch.
@ PW_TYPE_STRING
The attribute is a printable string.
rc_attr_type type
string, int, etc..
uint64_t value
attribute index and vendor number; use VENDOR() and ATTRID() to separate.
char name[RC_NAME_LENGTH+1]
attribute name.
rc_attr_type type
attribute type.
uint64_t attribute
attribute numeric value of type rc_attr_id including vendor; use VENDOR() and ATTRID() to separate.
uint32_t lvalue
attribute value if type is PW_TYPE_INTEGER, PW_TYPE_DATE or PW_TYPE_IPADDR.
char strvalue[AUTH_STRING_LEN+1]
contains attribute value in other cases.
char name[RC_NAME_LENGTH+1]
attribute name if known.