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",
446VALUE_PAIR *rc_avpair_gen(rc_handle
const *rh, VALUE_PAIR *pair,
447 unsigned char const *ptr,
int length,
451 VALUE_PAIR *out = NULL;
454 pb_init_read(&pb, (
void *)ptr, (
size_t)length, (
size_t)length);
455 if (rc_avpair_gen2(rh, pair, &pb, vendorspec, &out) < 0)
467VALUE_PAIR *
rc_avpair_get (VALUE_PAIR *vp, uint32_t attrid, uint32_t vendorspec)
469 uint64_t attr = RADCLI_VENDOR_ATTR_SET(attrid, vendorspec);
471 for (; vp != NULL && !(attr == vp->
attribute); vp = vp->next)
486 VALUE_PAIR *vp, *fp = NULL, *lp = NULL;
489 vp = malloc(
sizeof(VALUE_PAIR));
521 VALUE_PAIR *this_node = NULL;
526 rc_log(LOG_CRIT,
"rc_avpair_insert: value pair (0x%p) next ptr. (0x%p) not NULL", b, b->next);
549 while (this_node != NULL)
555 this_node = this_node->next;
560 b->next = this_node->next;
593static void rc_fieldcpy(
char *
string,
char const **uptr,
char const *stopat,
size_t len)
595 char const *ptr, *estring;
598 estring =
string + len - 1;
602 while (*ptr !=
'"' && *ptr !=
'\0' && *ptr !=
'\n')
604 if (
string < estring)
617 while (*ptr !=
'\0' && strchr(stopat, *ptr) == NULL)
619 if (
string < estring)
638 char attrstr[AUTH_ID_LEN];
639 char valstr[AUTH_STRING_LEN + 1], *p;
640 DICT_ATTR *attr = NULL;
647 mode = PARSE_MODE_NAME;
648 while (*buffer !=
'\n' && *buffer !=
'\0')
650 if (*buffer ==
' ' || *buffer ==
'\t')
658 case PARSE_MODE_NAME:
659 rc_fieldcpy (attrstr, &buffer,
" \t\n=,",
sizeof(attrstr));
663 rc_log(LOG_ERR,
"rc_avpair_parse: unknown attribute");
670 mode = PARSE_MODE_EQUAL;
673 case PARSE_MODE_EQUAL:
676 mode = PARSE_MODE_VALUE;
681 rc_log(LOG_ERR,
"rc_avpair_parse: missing or misplaced equal sign");
690 case PARSE_MODE_VALUE:
691 rc_fieldcpy (valstr, &buffer,
" \t\n,",
sizeof(valstr));
693 if ((pair = malloc (
sizeof (VALUE_PAIR))) == NULL)
695 rc_log(LOG_CRIT,
"rc_avpair_parse: out of memory");
711 rc_log(LOG_ERR,
"rc_avpair_parse: string value too long");
718 if (isdigit (*valstr))
720 pair->
lvalue = atoi (valstr);
727 rc_log(LOG_ERR,
"rc_avpair_parse: unknown attribute value: %s", valstr);
737 pair->
lvalue = dval->value;
743 if (inet_pton(AF_INET, valstr, &pair->
lvalue) == 0) {
744 rc_log(LOG_ERR,
"rc_avpair_parse: invalid IPv4 address %s", valstr);
753 if (inet_pton(AF_INET6, valstr, pair->
strvalue) == 0) {
754 rc_log(LOG_ERR,
"rc_avpair_parse: invalid IPv6 address %s", valstr);
762 p = strchr(valstr,
'/');
764 rc_log(LOG_ERR,
"rc_avpair_parse: invalid IPv6 prefix %s", valstr);
773 if (inet_pton(AF_INET6, valstr, pair->
strvalue+2) == 0) {
774 rc_log(LOG_ERR,
"rc_avpair_parse: invalid IPv6 prefix %s", valstr);
783 tm = localtime_r (&timeval, &_tm);
787 rc_str2tm (valstr, tm);
788 pair->
lvalue = (uint32_t) mktime (tm);
792 rc_log(LOG_ERR,
"rc_avpair_parse: unknown attribute type %d", pair->
type);
814 if (pair->
lvalue > AUTH_STRING_LEN - 2)
815 pair->
lvalue = AUTH_STRING_LEN - 2;
829 if (*first_pair == NULL)
836 while (link->next != NULL)
843 mode = PARSE_MODE_NAME;
847 mode = PARSE_MODE_NAME;
864int rc_avpair_tostr (rc_handle
const *rh, VALUE_PAIR *pair,
char *name,
int ln,
char *value,
int lv)
872 *name = *value =
'\0';
874 if (!pair || pair->
name[0] ==
'\0') {
875 rc_log(LOG_ERR,
"rc_avpair_tostr: pair is NULL or empty");
879 strlcpy(name, pair->
name, (
size_t) ln);
886 ptr = (
unsigned char *) pair->
strvalue;
895 if (!(isprint (*ptr)))
898 snprintf (&value[pos], lv,
"\\%03o", *ptr);
923 strlcpy(value, dval->name, (
size_t) lv);
927 snprintf(value, lv,
"%ld", (
long int)pair->
lvalue);
932 inad.s_addr = htonl(pair->
lvalue);
933 strlcpy (value, inet_ntoa (inad), (
size_t) lv);
937 if (inet_ntop(AF_INET6, pair->
strvalue, value, lv) == NULL)
947 memset(ip, 0,
sizeof(ip));
950 if (inet_ntop(AF_INET6, ip, (
void*)txt,
sizeof(txt)) == NULL)
952 snprintf(value, lv,
"%s/%u", txt, (
unsigned)pair->
strvalue[1]);
958 struct tm *ptm = gmtime_r((time_t *) & pair->
lvalue, &_tm);
962 strftime (value, lv,
"%m/%d/%y %H:%M:%S", ptm);
967 rc_log(LOG_ERR,
"rc_avpair_tostr: unknown attribute type %d", pair->
type);
985char *
rc_avpair_log(rc_handle
const *rh, VALUE_PAIR *pair,
char *buf,
size_t buf_len)
989 char name[RC_NAME_LENGTH + 1], value[256];
992 for (vp = pair; vp != NULL; vp = vp->next) {
994 sizeof(value)) == -1)
996 nlen = len + 32 + 3 + strlen(value) + 2 + 2;
998 sprintf(buf + len,
"%-32s = '%s'\n", name, value);
1051 *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)
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.