Radcli library 1.4.0
A simple radius library
Loading...
Searching...
No Matches
avpair.c
1/*
2 * Copyright (C) 2015 Nikos Mavrogiannopoulos
3 * Copyright (C) 1995 Lars Fenneberg
4 *
5 * Copyright 1992 Livingston Enterprises, Inc.
6 *
7 * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
8 * and Merit Network, Inc. All Rights Reserved
9 *
10 * See the file COPYRIGHT for the respective terms and conditions.
11 * If the file is missing contact me at lf@elemental.net
12 * and I'll send you a copy.
13 *
14 */
15#include <config.h>
16#include <includes.h>
17#include <radcli/radcli.h>
18#include "util.h"
19
20#define PARSE_MODE_NAME 0
21#define PARSE_MODE_EQUAL 1
22#define PARSE_MODE_VALUE 2
23#define PARSE_MODE_INVALID 3
24
46VALUE_PAIR *rc_avpair_add (rc_handle const *rh, VALUE_PAIR **list, uint32_t attrid, void const *pval, int len, uint32_t vendorspec)
47{
48 VALUE_PAIR *vp;
49
50 vp = rc_avpair_new (rh, attrid, pval, len, vendorspec);
51
52 if (vp != NULL)
53 {
54 rc_avpair_insert (list, NULL, vp);
55 }
56
57 return vp;
58
59}
60
69void rc_avpair_remove (VALUE_PAIR **list, uint32_t attrid, uint32_t vendorspec)
70{
71 VALUE_PAIR *vp, *prev, *tmp;
72 uint64_t vattrid;
73
74 if(vendorspec != VENDOR_NONE)
75 vattrid = RADCLI_VENDOR_ATTR_SET(attrid, vendorspec);
76 else
77 vattrid = attrid;
78
79 prev = NULL;
80 vp = *list;
81 while(vp != NULL) {
82 if (vp->attribute == vattrid) {
83 /* found */
84 if (prev == NULL) { /* first one */
85 tmp = vp;
86 vp = tmp->next;
87 free(tmp);
88 *list = vp;
89 } else { /* somewhere in the middle */
90 prev->next = vp->next;
91 free(vp);
92 }
93 break;
94 }
95
96 prev = vp;
97 vp = vp->next;
98 };
99
100 return;
101}
102
113{
114 return t->next;
115}
116
135int rc_avpair_assign (VALUE_PAIR *vp, void const *pval, int len)
136{
137
138 switch (vp->type)
139 {
140 case PW_TYPE_STRING:
141 if (len == -1)
142 len = (uint32_t)strlen((char const *)pval);
143 if (len > AUTH_STRING_LEN) {
144 rc_log(LOG_ERR, "rc_avpair_assign: bad attribute length");
145 return -1;
146 }
147 memcpy(vp->strvalue, (char const *)pval, len);
148 vp->strvalue[len] = '\0';
149 vp->lvalue = len;
150 break;
151
152 case PW_TYPE_DATE:
153 case PW_TYPE_INTEGER:
154 case PW_TYPE_IPADDR:
155 vp->lvalue = * (uint32_t *) pval;
156 break;
157 case PW_TYPE_IPV6ADDR:
158 if (len != 16) {
159 rc_log(LOG_ERR, "rc_avpair_assign: bad IPv6 length");
160 return -1;
161 }
162 memcpy(vp->strvalue, (char const *)pval, len);
163 vp->lvalue = len;
164 break;
165
167 if (len < 2 || len > 18) {
168 rc_log(LOG_ERR, "rc_avpair_assign: bad IPv6 prefix length");
169 return -1;
170 }
171 memcpy(vp->strvalue, (char const *)pval, len);
172 vp->lvalue = len;
173 break;
174
175 default:
176 rc_log(LOG_ERR, "rc_avpair_assign: no attribute %d in dictionary", vp->type);
177 return -1;
178 }
179 return 0;
180}
181
193VALUE_PAIR *rc_avpair_new (rc_handle const *rh, uint32_t attrid, void const *pval, int len, uint32_t vendorspec)
194{
195 VALUE_PAIR *vp = NULL;
196 DICT_ATTR *pda;
197 uint64_t vattrid;
198
199 if(vendorspec != VENDOR_NONE) {
200 vattrid = RADCLI_VENDOR_ATTR_SET(attrid, vendorspec);
201 } else {
202 vattrid = attrid;
203 }
204
205 if ((pda = rc_dict_getattr (rh, vattrid)) == NULL)
206 {
207 rc_log(LOG_ERR,"rc_avpair_new: no attribute %d/%u in dictionary", vendorspec, attrid);
208 return NULL;
209 }
210 if (vendorspec != 0 && rc_dict_getvend(rh, vendorspec) == NULL)
211 {
212 rc_log(LOG_ERR,"rc_avpair_new: no Vendor-Id %d in dictionary", vendorspec);
213 return NULL;
214 }
215 if ((vp = malloc (sizeof (VALUE_PAIR))) != NULL)
216 {
217 strlcpy (vp->name, pda->name, sizeof (vp->name));
218 vp->attribute = vattrid;
219 vp->next = NULL;
220 vp->type = pda->type;
221 if (rc_avpair_assign (vp, pval, len) == 0)
222 {
223 /* XXX: Fix up Digest-Attributes */
224 switch (vp->attribute) {
225 case PW_DIGEST_REALM:
226 case PW_DIGEST_NONCE:
227 case PW_DIGEST_METHOD:
228 case PW_DIGEST_URI:
229 case PW_DIGEST_QOP:
232 case PW_DIGEST_CNONCE:
235 /* overlapping! */
236 if (vp->lvalue > AUTH_STRING_LEN - 2)
237 vp->lvalue = AUTH_STRING_LEN - 2;
238 memmove(&vp->strvalue[2], &vp->strvalue[0], vp->lvalue);
239 vp->strvalue[0] = vp->attribute - PW_DIGEST_REALM + 1;
240 vp->lvalue += 2;
241 vp->strvalue[1] = vp->lvalue;
242 vp->strvalue[vp->lvalue] = '\0';
244 default:
245 break;
246 }
247 return vp;
248 }
249 free (vp);
250 vp = NULL;
251 }
252 else
253 {
254 rc_log(LOG_CRIT,"rc_avpair_new: out of memory");
255 }
256
257 return vp;
258}
259
271VALUE_PAIR *rc_avpair_gen(rc_handle const *rh, VALUE_PAIR *pair, unsigned char const *ptr,
272 int length, uint32_t vendorspec)
273{
274 uint64_t attribute;
275 int attrlen, x_len;
276 unsigned char const *x_ptr;
277 uint32_t lvalue;
278 DICT_ATTR *attr;
279 VALUE_PAIR *rpair;
280 char buffer[(AUTH_STRING_LEN * 2) + 1];
281 /* For hex string conversion. */
282 char hex[3];
283
284 if (length < 2) {
285 rc_log(LOG_ERR, "rc_avpair_gen: received attribute with "
286 "invalid length");
287 goto shithappens;
288 }
289 attrlen = ptr[1];
290 if (length < attrlen || attrlen < 2) {
291 rc_log(LOG_ERR, "rc_avpair_gen: received attribute with "
292 "invalid length");
293 goto shithappens;
294 }
295
296 /* Advance to the next attribute and process recursively */
297 if (length != attrlen) {
298 pair = rc_avpair_gen(rh, pair, ptr + attrlen, length - attrlen,
299 vendorspec);
300 }
301
302 /* Actual processing */
303 attribute = RADCLI_VENDOR_ATTR_SET(ptr[0], vendorspec);
304 ptr += 2;
305 attrlen -= 2;
306
307 /* VSA */
308 if (attribute == PW_VENDOR_SPECIFIC) {
309 if (attrlen < 4) {
310 rc_log(LOG_ERR, "rc_avpair_gen: received VSA "
311 "attribute with invalid length");
312 goto skipit;
313 }
314 memcpy(&lvalue, ptr, 4);
315 vendorspec = ntohl(lvalue);
316 if (rc_dict_getvend(rh, vendorspec) == NULL) {
317 /* Warn and skip over the unknown VSA */
318 rc_log(LOG_WARNING, "rc_avpair_gen: received VSA "
319 "attribute with unknown Vendor-Id %d", vendorspec);
320 goto skipit;
321 }
322 /* Process recursively */
323 return rc_avpair_gen(rh, pair, ptr + 4, attrlen - 4,
324 vendorspec);
325 }
326
327 /* Normal */
328 attr = rc_dict_getattr(rh, attribute);
329 if (attr == NULL) {
330 buffer[0] = '\0'; /* Initial length. */
331 x_ptr = ptr;
332 for (x_len = attrlen; x_len > 0; x_len--, x_ptr++) {
333 snprintf(hex, sizeof(hex), "%2.2X", x_ptr[0]);
334 strcat(buffer, hex);
335 }
336 if (vendorspec == 0) {
337 rc_log(LOG_WARNING, "rc_avpair_gen: received "
338 "unknown attribute %d of length %d: 0x%s",
339 (unsigned)attribute, attrlen + 2, buffer);
340 } else {
341 rc_log(LOG_WARNING, "rc_avpair_gen: received "
342 "unknown VSA attribute %u, vendor %u of "
343 "length %d: 0x%s", (unsigned)ATTRID(attribute),
344 (unsigned)VENDOR(attribute), attrlen + 2, buffer);
345 }
346 goto skipit;
347 }
348 rpair = calloc(1, sizeof(*rpair));
349 if (rpair == NULL) {
350 rc_log(LOG_CRIT, "rc_avpair_gen: out of memory");
351 goto shithappens;
352 }
353
354 /* Insert this new pair at the beginning of the list */
355 rpair->next = pair;
356 pair = rpair;
357 strlcpy(pair->name, attr->name, sizeof(pair->name));
358 pair->attribute = attr->value;
359 pair->type = attr->type;
360
361 switch (attr->type) {
362 case PW_TYPE_STRING:
363 memcpy(pair->strvalue, (char *)ptr, (size_t)attrlen);
364 pair->strvalue[attrlen] = '\0';
365 pair->lvalue = attrlen;
366 break;
367
368 case PW_TYPE_INTEGER:
369 if (attrlen != 4) {
370 rc_log(LOG_ERR, "rc_avpair_gen: received INT "
371 "attribute with invalid length");
372 goto skipit;
373 }
374 case PW_TYPE_IPADDR:
375 if (attrlen != 4) {
376 rc_log(LOG_ERR, "rc_avpair_gen: received IPADDR"
377 " attribute with invalid length");
378 goto skipit;
379 }
380 memcpy((char *)&lvalue, (char *)ptr, 4);
381 pair->lvalue = ntohl(lvalue);
382 break;
383 case PW_TYPE_IPV6ADDR:
384 if (attrlen != 16) {
385 rc_log(LOG_ERR, "rc_avpair_gen: received IPV6ADDR"
386 " attribute with invalid length");
387 goto skipit;
388 }
389 memcpy(pair->strvalue, (char *)ptr, 16);
390 pair->lvalue = attrlen;
391 break;
393 if (attrlen > 18 || attrlen < 2) {
394 rc_log(LOG_ERR, "rc_avpair_gen: received IPV6PREFIX"
395 " attribute with invalid length: %d", attrlen);
396 goto skipit;
397 }
398 memcpy(pair->strvalue, (char *)ptr, attrlen);
399 pair->lvalue = attrlen;
400 break;
401 case PW_TYPE_DATE:
402 if (attrlen != 4) {
403 rc_log(LOG_ERR, "rc_avpair_gen: received DATE "
404 "attribute with invalid length");
405 goto skipit;
406 }
407
408 default:
409 rc_log(LOG_WARNING, "rc_avpair_gen: %s has unknown type",
410 attr->name);
411 goto skipit;
412 }
413
414skipit:
415 return pair;
416
417shithappens:
418 while (pair != NULL) {
419 rpair = pair->next;
420 free(pair);
421 pair = rpair;
422 }
423 return NULL;
424}
425
433VALUE_PAIR *rc_avpair_get (VALUE_PAIR *vp, uint32_t attrid, uint32_t vendorspec)
434{
435 uint64_t attr = RADCLI_VENDOR_ATTR_SET(attrid, vendorspec);
436
437 for (; vp != NULL && !(attr == vp->attribute); vp = vp->next)
438 {
439 continue;
440 }
441 return vp;
442}
443
451{
452 VALUE_PAIR *vp, *fp = NULL, *lp = NULL;
453
454 while (p) {
455 vp = malloc(sizeof(VALUE_PAIR));
456 if (!vp) {
457 while(fp) { /* free allocated memory */
458 vp = fp;
459 fp = fp->next;
460 free(vp);
461 }
462 return NULL;
463 }
464 *vp = *p;
465 if (!fp)
466 fp = vp;
467 if (lp)
468 lp->next = vp;
469 lp = vp;
470 p = p->next;
471 }
472
473 return fp;
474}
475
486{
487 VALUE_PAIR *this_node = NULL;
488 VALUE_PAIR *vp;
489
490 if (b->next != NULL)
491 {
492 rc_log(LOG_CRIT, "rc_avpair_insert: value pair (0x%p) next ptr. (0x%p) not NULL", b, b->next);
493 abort ();
494 }
495
496 if (*a == NULL)
497 {
498 *a = b;
499 return;
500 }
501
502 vp = *a;
503
504 if ( p == NULL) /* run to end of "a" list */
505 {
506 while (vp != NULL)
507 {
508 this_node = vp;
509 vp = vp->next;
510 }
511 }
512 else /* look for the "p" entry in the "a" list */
513 {
514 this_node = *a;
515 while (this_node != NULL)
516 {
517 if (this_node == p)
518 {
519 break;
520 }
521 this_node = this_node->next;
522 }
523 }
524
525 if (this_node) {
526 b->next = this_node->next;
527 this_node->next = b;
528 }
529
530 return;
531}
532
538{
539 VALUE_PAIR *next;
540
541 while (pair != NULL)
542 {
543 next = pair->next;
544 free (pair);
545 pair = next;
546 }
547}
548
559static void rc_fieldcpy(char *string, char const **uptr, char const *stopat, size_t len)
560{
561 char const *ptr, *estring;
562
563 ptr = *uptr;
564 estring = string + len - 1;
565 if (*ptr == '"')
566 {
567 ptr++;
568 while (*ptr != '"' && *ptr != '\0' && *ptr != '\n')
569 {
570 if (string < estring)
571 *string++ = *ptr;
572 ptr++;
573 }
574 if (*ptr == '"')
575 {
576 ptr++;
577 }
578 *string = '\0';
579 *uptr = ptr;
580 return;
581 }
582
583 while (*ptr != '\0' && strchr(stopat, *ptr) == NULL)
584 {
585 if (string < estring)
586 *string++ = *ptr;
587 ptr++;
588 }
589 *string = '\0';
590 *uptr = ptr;
591 return;
592}
593
601int rc_avpair_parse (rc_handle const *rh, char const *buffer, VALUE_PAIR **first_pair)
602{
603 int mode;
604 char attrstr[AUTH_ID_LEN];
605 char valstr[AUTH_STRING_LEN + 1], *p;
606 DICT_ATTR *attr = NULL;
607 DICT_VALUE *dval;
608 VALUE_PAIR *pair;
609 VALUE_PAIR *link;
610 struct tm *tm, _tm;
611 time_t timeval;
612
613 mode = PARSE_MODE_NAME;
614 while (*buffer != '\n' && *buffer != '\0')
615 {
616 if (*buffer == ' ' || *buffer == '\t')
617 {
618 buffer++;
619 continue;
620 }
621
622 switch (mode)
623 {
624 case PARSE_MODE_NAME: /* Attribute Name */
625 rc_fieldcpy (attrstr, &buffer, " \t\n=,", sizeof(attrstr));
626 if ((attr =
627 rc_dict_findattr (rh, attrstr)) == NULL)
628 {
629 rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute");
630 if (*first_pair) {
631 rc_avpair_free(*first_pair);
632 *first_pair = NULL;
633 }
634 return -1;
635 }
636 mode = PARSE_MODE_EQUAL;
637 break;
638
639 case PARSE_MODE_EQUAL: /* Equal sign */
640 if (*buffer == '=')
641 {
642 mode = PARSE_MODE_VALUE;
643 buffer++;
644 }
645 else
646 {
647 rc_log(LOG_ERR, "rc_avpair_parse: missing or misplaced equal sign");
648 if (*first_pair) {
649 rc_avpair_free(*first_pair);
650 *first_pair = NULL;
651 }
652 return -1;
653 }
654 break;
655
656 case PARSE_MODE_VALUE: /* Value */
657 rc_fieldcpy (valstr, &buffer, " \t\n,", sizeof(valstr));
658
659 if ((pair = malloc (sizeof (VALUE_PAIR))) == NULL)
660 {
661 rc_log(LOG_CRIT, "rc_avpair_parse: out of memory");
662 if (*first_pair) {
663 rc_avpair_free(*first_pair);
664 *first_pair = NULL;
665 }
666 return -1;
667 }
668 strcpy (pair->name, attr->name);
669 pair->attribute = attr->value;
670 pair->type = attr->type;
671
672 switch (pair->type)
673 {
674
675 case PW_TYPE_STRING:
676 strcpy (pair->strvalue, valstr);
677 pair->lvalue = (uint32_t)strlen(valstr);
678 break;
679
680 case PW_TYPE_INTEGER:
681 if (isdigit (*valstr))
682 {
683 pair->lvalue = atoi (valstr);
684 }
685 else
686 {
687 if ((dval = rc_dict_findval (rh, valstr))
688 == NULL)
689 {
690 rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute value: %s", valstr);
691 if (*first_pair) {
692 rc_avpair_free(*first_pair);
693 *first_pair = NULL;
694 }
695 free (pair);
696 return -1;
697 }
698 else
699 {
700 pair->lvalue = dval->value;
701 }
702 }
703 break;
704
705 case PW_TYPE_IPADDR:
706 if (inet_pton(AF_INET, valstr, &pair->lvalue) == 0) {
707 rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv4 address %s", valstr);
708 free(pair);
709 return -1;
710 }
711
712 pair->lvalue = ntohl(pair->lvalue);
713 break;
714
715 case PW_TYPE_IPV6ADDR:
716 if (inet_pton(AF_INET6, valstr, pair->strvalue) == 0) {
717 rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 address %s", valstr);
718 free(pair);
719 return -1;
720 }
721 pair->lvalue = 16;
722 break;
723
725 p = strchr(valstr, '/');
726 if (p == NULL) {
727 rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 prefix %s", valstr);
728 free(pair);
729 return -1;
730 }
731 *p = 0;
732 p++;
733 pair->strvalue[0] = 0;
734 pair->strvalue[1] = atoi(p);
735
736 if (inet_pton(AF_INET6, valstr, pair->strvalue+2) == 0) {
737 rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 prefix %s", valstr);
738 free(pair);
739 return -1;
740 }
741 pair->lvalue = 2+16;
742 break;
743
744 case PW_TYPE_DATE:
745 timeval = time (0);
746 tm = localtime_r (&timeval, &_tm);
747 tm->tm_hour = 0;
748 tm->tm_min = 0;
749 tm->tm_sec = 0;
750 rc_str2tm (valstr, tm);
751#ifdef TIMELOCAL
752 pair->lvalue = (uint32_t) timelocal (tm);
753#else /* TIMELOCAL */
754 pair->lvalue = (uint32_t) mktime (tm);
755#endif /* TIMELOCAL */
756 break;
757
758 default:
759 rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute type %d", pair->type);
760 if (*first_pair) {
761 rc_avpair_free(*first_pair);
762 *first_pair = NULL;
763 }
764 free (pair);
765 return -1;
766 }
767
768 /* XXX: Fix up Digest-Attributes */
769 switch (pair->attribute) {
770 case PW_DIGEST_REALM:
771 case PW_DIGEST_NONCE:
772 case PW_DIGEST_METHOD:
773 case PW_DIGEST_URI:
774 case PW_DIGEST_QOP:
777 case PW_DIGEST_CNONCE:
780 /* overlapping! */
781 if (pair->lvalue > AUTH_STRING_LEN - 2)
782 pair->lvalue = AUTH_STRING_LEN - 2;
783 memmove(&pair->strvalue[2], &pair->strvalue[0], pair->lvalue);
784 pair->strvalue[0] = pair->attribute - PW_DIGEST_REALM + 1;
785 pair->lvalue += 2;
786 pair->strvalue[1] = pair->lvalue;
787 pair->strvalue[pair->lvalue] = '\0';
789 break;
790 default:
791 break;
792 }
793
794 pair->next = NULL;
795
796 if (*first_pair == NULL)
797 {
798 *first_pair = pair;
799 }
800 else
801 {
802 link = *first_pair;
803 while (link->next != NULL)
804 {
805 link = link->next;
806 }
807 link->next = pair;
808 }
809
810 mode = PARSE_MODE_NAME;
811 break;
812
813 default:
814 mode = PARSE_MODE_NAME;
815 break;
816 }
817 }
818 return 0;
819}
820
831int rc_avpair_tostr (rc_handle const *rh, VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
832{
833 DICT_VALUE *dval;
834 struct in_addr inad;
835 unsigned char *ptr;
836 unsigned int pos;
837 unsigned int slen;
838
839 *name = *value = '\0';
840
841 if (!pair || pair->name[0] == '\0') {
842 rc_log(LOG_ERR, "rc_avpair_tostr: pair is NULL or empty");
843 return -1;
844 }
845
846 strlcpy(name, pair->name, (size_t) ln);
847
848 switch (pair->type)
849 {
850 case PW_TYPE_STRING:
851 lv--;
852 pos = 0;
853 ptr = (unsigned char *) pair->strvalue;
854 if (pair->attribute == PW_DIGEST_ATTRIBUTES) {
855 slen = ptr[1] - 2;
856 ptr += 2;
857 } else {
858 slen = pair->lvalue;
859 }
860 while (slen-- > 0)
861 {
862 if (!(isprint (*ptr)))
863 {
864 if (lv >= 4) {
865 snprintf (&value[pos], lv, "\\%03o", *ptr);
866 pos += 4;
867 lv -= 4;
868 } else {
869 break;
870 }
871 }
872 else
873 {
874 if (lv > 0) {
875 value[pos++] = *ptr;
876 lv--;
877 } else {
878 break;
879 }
880 }
881 ptr++;
882 }
883 value[pos] = 0;
884 break;
885
886 case PW_TYPE_INTEGER:
887 dval = rc_dict_getval (rh, pair->lvalue, pair->name);
888 if (dval != NULL)
889 {
890 strlcpy(value, dval->name, (size_t) lv);
891 }
892 else
893 {
894 snprintf(value, lv, "%ld", (long int)pair->lvalue);
895 }
896 break;
897
898 case PW_TYPE_IPADDR:
899 inad.s_addr = htonl(pair->lvalue);
900 strlcpy (value, inet_ntoa (inad), (size_t) lv);
901 break;
902
903 case PW_TYPE_IPV6ADDR:
904 if (inet_ntop(AF_INET6, pair->strvalue, value, lv) == NULL)
905 return -1;
906 break;
907
908 case PW_TYPE_IPV6PREFIX: {
909 uint8_t ip[16];
910 uint8_t txt[48];
911 if (pair->lvalue < 2)
912 return -1;
913
914 memset(ip, 0, sizeof(ip));
915 memcpy(ip, pair->strvalue+2, pair->lvalue-2);
916
917 if (inet_ntop(AF_INET6, ip, (void*)txt, sizeof(txt)) == NULL)
918 return -1;
919 snprintf(value, lv, "%s/%u", txt, (unsigned)pair->strvalue[1]);
920
921 break;
922 }
923 case PW_TYPE_DATE: {
924 struct tm _tm;
925 struct tm *ptm = gmtime_r((time_t *) & pair->lvalue, &_tm);
926 if (ptm == NULL)
927 return -1;
928
929 strftime (value, lv, "%m/%d/%y %H:%M:%S", ptm);
930 break;
931 }
932
933 default:
934 rc_log(LOG_ERR, "rc_avpair_tostr: unknown attribute type %d", pair->type);
935 return -1;
936 break;
937 }
938
939 return 0;
940}
941
952char *rc_avpair_log(rc_handle const *rh, VALUE_PAIR *pair, char *buf, size_t buf_len)
953{
954 size_t len, nlen;
955 VALUE_PAIR *vp;
956 char name[33], value[256];
957
958 len = 0;
959 for (vp = pair; vp != NULL; vp = vp->next) {
960 if (rc_avpair_tostr(rh, vp, name, sizeof(name), value,
961 sizeof(value)) == -1)
962 return NULL;
963 nlen = len + 32 + 3 + strlen(value) + 2 + 2;
964 if(nlen<buf_len-1) {
965 sprintf(buf + len, "%-32s = '%s'\n", name, value);
966 } else return buf;
967 len = nlen - 1;
968 }
969 return buf;
970}
971
982int rc_avpair_get_uint32 (VALUE_PAIR *vp, uint32_t *res)
983{
984 if (vp->type == PW_TYPE_DATE || vp->type == PW_TYPE_IPADDR ||
985 vp->type == PW_TYPE_INTEGER) {
986 if (res)
987 *res = vp->lvalue;
988 return 0;
989 } else {
990 return -1;
991 }
992}
993
1003int rc_avpair_get_in6 (VALUE_PAIR *vp, struct in6_addr *res, unsigned *prefix)
1004{
1005 if (vp->type == PW_TYPE_IPV6ADDR) {
1006 memcpy(res, vp->strvalue, 16);
1007 return 0;
1008 } else if (vp->type == PW_TYPE_IPV6PREFIX) {
1009 if (vp->lvalue < 2 || vp->lvalue > 18)
1010 return -1;
1011
1012 if (res) {
1013 memset(res, 0, 16);
1014 memcpy(res, vp->strvalue+2, vp->lvalue-2);
1015 }
1016
1017 if (prefix)
1018 *prefix = (unsigned char)vp->strvalue[1];
1019 return 0;
1020 }
1021
1022 return -1;
1023}
1024
1035int rc_avpair_get_raw (VALUE_PAIR *vp, char **res, unsigned *res_size)
1036{
1037 if (vp->type == PW_TYPE_STRING || vp->type == PW_TYPE_IPV6ADDR ||
1038 vp->type == PW_TYPE_IPV6PREFIX) {
1039 if (res)
1040 *res = vp->strvalue;
1041 if (res_size)
1042 *res_size = vp->lvalue;
1043 return 0;
1044 } else {
1045 return -1;
1046 }
1047}
1048
1055void rc_avpair_get_attr (VALUE_PAIR *vp, unsigned *type, unsigned *id)
1056{
1057 if (type)
1058 *type = vp->type;
1059 if (id)
1060 *id = vp->attribute;
1061}
1062
1064/*
1065 * Local Variables:
1066 * c-basic-offset:8
1067 * c-style: whitesmith
1068 * End:
1069 */
void rc_avpair_remove(VALUE_PAIR **list, uint32_t attrid, uint32_t vendorspec)
Definition avpair.c:69
DICT_VALUE * rc_dict_getval(rc_handle const *rh, uint32_t value, char const *attrname)
Definition dict.c:632
int rc_avpair_get_raw(VALUE_PAIR *vp, char **res, unsigned *res_size)
Definition avpair.c:1035
char * rc_avpair_log(rc_handle const *rh, VALUE_PAIR *pair, char *buf, size_t buf_len)
Definition avpair.c:952
VALUE_PAIR * rc_avpair_next(VALUE_PAIR *t)
Definition avpair.c:112
int rc_avpair_get_uint32(VALUE_PAIR *vp, uint32_t *res)
Definition avpair.c:982
int rc_avpair_get_in6(VALUE_PAIR *vp, struct in6_addr *res, unsigned *prefix)
Definition avpair.c:1003
void rc_avpair_get_attr(VALUE_PAIR *vp, unsigned *type, unsigned *id)
Definition avpair.c:1055
VALUE_PAIR * rc_avpair_gen(rc_handle const *rh, VALUE_PAIR *pair, unsigned char const *ptr, int length, uint32_t vendorspec)
Definition avpair.c:271
void rc_avpair_free(VALUE_PAIR *pair)
Definition avpair.c:537
VALUE_PAIR * rc_avpair_copy(VALUE_PAIR *p)
Definition avpair.c:450
int rc_avpair_tostr(rc_handle const *rh, VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
Definition avpair.c:831
int rc_avpair_assign(VALUE_PAIR *vp, void const *pval, int len)
Definition avpair.c:135
DICT_VALUE * rc_dict_findval(rc_handle const *rh, char const *valname)
Definition dict.c:578
int rc_avpair_parse(rc_handle const *rh, char const *buffer, VALUE_PAIR **first_pair)
Definition avpair.c:601
DICT_VENDOR * rc_dict_getvend(rc_handle const *rh, uint32_t vendorspec)
Definition dict.c:615
DICT_ATTR * rc_dict_getattr(rc_handle const *rh, uint64_t attribute)
Definition dict.c:532
VALUE_PAIR * rc_avpair_add(rc_handle const *rh, VALUE_PAIR **list, uint32_t attrid, void const *pval, int len, uint32_t vendorspec)
Definition avpair.c:46
void rc_avpair_insert(VALUE_PAIR **a, VALUE_PAIR *p, VALUE_PAIR *b)
Definition avpair.c:485
VALUE_PAIR * rc_avpair_get(VALUE_PAIR *vp, uint32_t attrid, uint32_t vendorspec)
Definition avpair.c:433
DICT_ATTR * rc_dict_findattr(rc_handle const *rh, char const *attrname)
Definition dict.c:555
VALUE_PAIR * rc_avpair_new(rc_handle const *rh, uint32_t attrid, void const *pval, int len, uint32_t vendorspec)
Definition avpair.c:193
@ PW_DIGEST_NONCE
Its type is string.
Definition radcli.h:258
@ PW_DIGEST_REALM
Its type is string.
Definition radcli.h:257
@ PW_DIGEST_USER_NAME
Its type is string.
Definition radcli.h:266
@ PW_DIGEST_URI
Its type is string.
Definition radcli.h:260
@ PW_DIGEST_QOP
Its type is string.
Definition radcli.h:261
@ PW_DIGEST_BODY_DIGEST
Its type is string.
Definition radcli.h:263
@ PW_DIGEST_ATTRIBUTES
Its type is string.
Definition radcli.h:256
@ PW_DIGEST_NONCE_COUNT
Its type is string.
Definition radcli.h:265
@ PW_DIGEST_ALGORITHM
Its type is string.
Definition radcli.h:262
@ PW_DIGEST_CNONCE
Its type is string.
Definition radcli.h:264
@ PW_DIGEST_METHOD
Its type is string.
Definition radcli.h:259
@ PW_VENDOR_SPECIFIC
Its type is string.
Definition radcli.h:171
@ PW_TYPE_IPADDR
The attribute is an IPv4 address in host-byte order.
Definition radcli.h:118
@ PW_TYPE_IPV6ADDR
The attribute is an 128-bit IPv6 address.
Definition radcli.h:120
@ PW_TYPE_IPV6PREFIX
The attribute is an IPv6 prefix; the lvalue will indicate its size.
Definition radcli.h:121
@ PW_TYPE_INTEGER
The attribute is a 32-bit integer.
Definition radcli.h:117
@ PW_TYPE_DATE
The attribute contains a 32-bit number indicating the seconds since epoch.
Definition radcli.h:119
@ PW_TYPE_STRING
The attribute is a printable string.
Definition radcli.h:116
rc_attr_type type
string, int, etc..
Definition radcli.h:437
uint64_t value
attribute index and vendor number; use VENDOR() and ATTRID() to separate.
Definition radcli.h:436
char name[RC_NAME_LENGTH+1]
attribute name.
Definition radcli.h:435
rc_attr_type type
attribute type.
Definition radcli.h:482
uint64_t attribute
attribute numeric value of type rc_attr_id including vendor; use VENDOR() and ATTRID() to separate.
Definition radcli.h:481
uint32_t lvalue
attribute value if type is PW_TYPE_INTEGER, PW_TYPE_DATE or PW_TYPE_IPADDR.
Definition radcli.h:483
char strvalue[AUTH_STRING_LEN+1]
contains attribute value in other cases.
Definition radcli.h:484
char name[RC_NAME_LENGTH+1]
attribute name if known.
Definition radcli.h:480