avpair.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894
  1. /*
  2. * $Id: avpair.c,v 1.26 2010/06/15 09:22:52 aland Exp $
  3. *
  4. * Copyright (C) 1995 Lars Fenneberg
  5. *
  6. * Copyright 1992 Livingston Enterprises, Inc.
  7. *
  8. * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
  9. * and Merit Network, Inc. All Rights Reserved
  10. *
  11. * See the file COPYRIGHT for the respective terms and conditions.
  12. * If the file is missing contact me at lf@elemental.net
  13. * and I'll send you a copy.
  14. *
  15. */
  16. #include <radius_config.h>
  17. #include <includes.h>
  18. #include <freeradius-client.h>
  19. #include "util.h"
  20. #include "def.h"
  21. /** Adds an attribute-value pair to the given list
  22. *
  23. * @note Always appends the new pair to the end of the list.
  24. *
  25. * @param rh a handle to parsed configuration.
  26. * @param list a #VALUE_PAIR array of values; initially must be %NULL.
  27. * @param attrid The attribute of the pair to add (e.g., %PW_USER_NAME).
  28. * @param pval the value (e.g., the actual username).
  29. * @param len the length of @pval, or -1 if to calculate (in case of strings).
  30. * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
  31. * @return pointer to added a/v pair upon success, NULL pointer upon failure.
  32. */
  33. VALUE_PAIR *rc_avpair_add (rc_handle const *rh, VALUE_PAIR **list, int attrid, void const *pval, int len, int vendorpec)
  34. {
  35. VALUE_PAIR *vp;
  36. vp = rc_avpair_new (rh, attrid, pval, len, vendorpec);
  37. if (vp != NULL)
  38. {
  39. rc_avpair_insert (list, NULL, vp);
  40. }
  41. return vp;
  42. }
  43. /** Assigns the given value to an attribute-value pair
  44. *
  45. * @param vp a pointer to a #VALUE_PAIR structure.
  46. * @param pval the value (e.g., the actual username).
  47. * @param len the length of @pval, or -1 if to calculate (in case of strings).
  48. * @return 0 on success or -1 on failure.
  49. */
  50. int rc_avpair_assign (VALUE_PAIR *vp, void const *pval, int len)
  51. {
  52. #if 1
  53. switch (vp->type)
  54. {
  55. case PW_TYPE_STRING:
  56. if (len == -1)
  57. len = (uint32_t)strlen((char const *)pval);
  58. if (len > AUTH_STRING_LEN) {
  59. rc_log(LOG_ERR, "rc_avpair_assign: bad attribute length");
  60. return -1;
  61. }
  62. memcpy(vp->strvalue, (char const *)pval, len);
  63. vp->strvalue[len] = '\0';
  64. vp->lvalue = len;
  65. break;
  66. case PW_TYPE_DATE:
  67. case PW_TYPE_INTEGER:
  68. case PW_TYPE_IPADDR:
  69. vp->lvalue = * (uint32_t *) pval;
  70. break;
  71. case PW_TYPE_IPV6ADDR:
  72. if (len != 16) {
  73. rc_log(LOG_ERR, "rc_avpair_assign: bad IPv6 length");
  74. return -1;
  75. }
  76. memcpy(vp->strvalue, (char const *)pval, len);
  77. vp->lvalue = len;
  78. break;
  79. case PW_TYPE_IPV6PREFIX:
  80. if (len < 2 || len > 18) {
  81. rc_log(LOG_ERR, "rc_avpair_assign: bad IPv6 prefix length");
  82. return -1;
  83. }
  84. memcpy(vp->strvalue, (char const *)pval, len);
  85. vp->lvalue = len;
  86. break;
  87. default:
  88. rc_log(LOG_ERR, "rc_avpair_assign: unknown attribute %d", vp->type);
  89. return -1;
  90. }
  91. #endif
  92. return 0;
  93. }
  94. /** Make a new attribute-value pair with given parameters
  95. *
  96. * @param rh a handle to parsed configuration.
  97. * @param attrid The attribute of the pair to add (e.g., %PW_USER_NAME).
  98. * @param pval the value (e.g., the actual username).
  99. * @param len the length of pval, or -1 if to calculate (in case of strings).
  100. * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
  101. * @return pointer to generated a/v pair when successful, NULL when failure.
  102. */
  103. VALUE_PAIR *rc_avpair_new (rc_handle const *rh, int attrid, void const *pval, int len, int vendorpec)
  104. {
  105. VALUE_PAIR *vp = NULL;
  106. DICT_ATTR *pda;
  107. attrid = attrid | (vendorpec << 16);
  108. if ((pda = rc_dict_getattr (rh, attrid)) == NULL)
  109. {
  110. rc_log(LOG_ERR,"rc_avpair_new: unknown attribute %d", attrid);
  111. return NULL;
  112. }
  113. if (vendorpec != 0 && rc_dict_getvend(rh, vendorpec) == NULL)
  114. {
  115. rc_log(LOG_ERR,"rc_avpair_new: unknown Vendor-Id %d", vendorpec);
  116. return NULL;
  117. }
  118. if ((vp = malloc (sizeof (VALUE_PAIR))) != NULL)
  119. {
  120. strlcpy (vp->name, pda->name, sizeof (vp->name));
  121. vp->attribute = attrid;
  122. vp->next = NULL;
  123. vp->type = pda->type;
  124. if (rc_avpair_assign (vp, pval, len) == 0)
  125. {
  126. /* XXX: Fix up Digest-Attributes */
  127. switch (vp->attribute) {
  128. case PW_DIGEST_REALM:
  129. case PW_DIGEST_NONCE:
  130. case PW_DIGEST_METHOD:
  131. case PW_DIGEST_URI:
  132. case PW_DIGEST_QOP:
  133. case PW_DIGEST_ALGORITHM:
  134. case PW_DIGEST_BODY_DIGEST:
  135. case PW_DIGEST_CNONCE:
  136. case PW_DIGEST_NONCE_COUNT:
  137. case PW_DIGEST_USER_NAME:
  138. /* overlapping! */
  139. if (vp->lvalue > AUTH_STRING_LEN - 2)
  140. vp->lvalue = AUTH_STRING_LEN - 2;
  141. memmove(&vp->strvalue[2], &vp->strvalue[0], vp->lvalue);
  142. vp->strvalue[0] = vp->attribute - PW_DIGEST_REALM + 1;
  143. vp->lvalue += 2;
  144. vp->strvalue[1] = vp->lvalue;
  145. vp->strvalue[vp->lvalue] = '\0';
  146. vp->attribute = PW_DIGEST_ATTRIBUTES;
  147. default:
  148. break;
  149. }
  150. return vp;
  151. }
  152. free (vp);
  153. vp = NULL;
  154. }
  155. else
  156. {
  157. rc_log(LOG_CRIT,"rc_avpair_new: out of memory");
  158. }
  159. return vp;
  160. }
  161. /** Takes attribute/value pairs from buffer and builds a value_pair list using allocated memory
  162. *
  163. * @note Uses recursion.
  164. *
  165. * @param rh a handle to parsed configuration.
  166. * @param pair a pointer to a #VALUE_PAIR structure.
  167. * @param ptr the value (e.g., the actual username).
  168. * @param length the length of ptr, or -1 if to calculate (in case of strings).
  169. * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
  170. * @return value_pair list or %NULL on failure.
  171. */
  172. VALUE_PAIR *rc_avpair_gen(rc_handle const *rh, VALUE_PAIR *pair, unsigned char const *ptr,
  173. int length, int vendorpec)
  174. {
  175. #if 1
  176. int attribute, attrlen, x_len;
  177. unsigned char const *x_ptr;
  178. uint32_t lvalue;
  179. DICT_ATTR *attr;
  180. VALUE_PAIR *rpair;
  181. char buffer[(AUTH_STRING_LEN * 2) + 1];
  182. /* For hex string conversion. */
  183. char hex[3];
  184. if (length < 2) {
  185. rc_log(LOG_ERR, "rc_avpair_gen: received attribute with "
  186. "invalid length");
  187. goto shithappens;
  188. }
  189. attrlen = ptr[1];
  190. if (length < attrlen || attrlen < 2) {
  191. rc_log(LOG_ERR, "rc_avpair_gen: received attribute with "
  192. "invalid length");
  193. goto shithappens;
  194. }
  195. /* Advance to the next attribute and process recursively */
  196. if (length != attrlen) {
  197. pair = rc_avpair_gen(rh, pair, ptr + attrlen, length - attrlen,
  198. vendorpec);
  199. if (pair == NULL)
  200. return NULL;
  201. }
  202. /* Actual processing */
  203. attribute = ptr[0] | (vendorpec << 16);
  204. ptr += 2;
  205. attrlen -= 2;
  206. /* VSA */
  207. if (attribute == PW_VENDOR_SPECIFIC) {
  208. if (attrlen < 4) {
  209. rc_log(LOG_ERR, "rc_avpair_gen: received VSA "
  210. "attribute with invalid length");
  211. goto skipit;
  212. }
  213. memcpy(&lvalue, ptr, 4);
  214. vendorpec = ntohl(lvalue);
  215. if (rc_dict_getvend(rh, vendorpec) == NULL) {
  216. /* Warn and skip over the unknown VSA */
  217. rc_log(LOG_WARNING, "rc_avpair_gen: received VSA "
  218. "attribute with unknown Vendor-Id %d", vendorpec);
  219. goto skipit;
  220. }
  221. /* Process recursively */
  222. return rc_avpair_gen(rh, pair, ptr + 4, attrlen - 4,
  223. vendorpec);
  224. }
  225. /* Normal */
  226. attr = rc_dict_getattr(rh, attribute);
  227. if (attr == NULL) {
  228. buffer[0] = '\0'; /* Initial length. */
  229. x_ptr = ptr;
  230. for (x_len = attrlen; x_len > 0; x_len--, x_ptr++) {
  231. snprintf(hex, sizeof(hex), "%2.2X", x_ptr[0]);
  232. strcat(buffer, hex);
  233. }
  234. if (vendorpec == 0) {
  235. rc_log(LOG_WARNING, "rc_avpair_gen: received "
  236. "unknown attribute %d of length %d: 0x%s",
  237. attribute, attrlen + 2, buffer);
  238. } else {
  239. rc_log(LOG_WARNING, "rc_avpair_gen: received "
  240. "unknown VSA attribute %d, vendor %d of "
  241. "length %d: 0x%s", attribute & 0xffff,
  242. VENDOR(attribute), attrlen + 2, buffer);
  243. }
  244. goto skipit;
  245. }
  246. rpair = malloc(sizeof(*rpair));
  247. if (rpair == NULL) {
  248. rc_log(LOG_CRIT, "rc_avpair_gen: out of memory");
  249. goto shithappens;
  250. }
  251. memset(rpair, '\0', sizeof(*rpair));
  252. /* Insert this new pair at the beginning of the list */
  253. rpair->next = pair;
  254. pair = rpair;
  255. strcpy(pair->name, attr->name);
  256. pair->attribute = attr->value;
  257. pair->type = attr->type;
  258. switch (attr->type) {
  259. case PW_TYPE_STRING:
  260. memcpy(pair->strvalue, (char *)ptr, (size_t)attrlen);
  261. pair->strvalue[attrlen] = '\0';
  262. pair->lvalue = attrlen;
  263. break;
  264. case PW_TYPE_INTEGER:
  265. if (attrlen != 4) {
  266. rc_log(LOG_ERR, "rc_avpair_gen: received INT "
  267. "attribute with invalid length");
  268. goto skipit;
  269. }
  270. case PW_TYPE_IPADDR:
  271. if (attrlen != 4) {
  272. rc_log(LOG_ERR, "rc_avpair_gen: received IPADDR"
  273. " attribute with invalid length");
  274. goto skipit;
  275. }
  276. memcpy((char *)&lvalue, (char *)ptr, 4);
  277. pair->lvalue = ntohl(lvalue);
  278. break;
  279. case PW_TYPE_IPV6ADDR:
  280. if (attrlen != 16) {
  281. rc_log(LOG_ERR, "rc_avpair_gen: received IPV6ADDR"
  282. " attribute with invalid length");
  283. goto skipit;
  284. }
  285. memcpy(pair->strvalue, (char *)ptr, 16);
  286. pair->lvalue = attrlen;
  287. break;
  288. case PW_TYPE_IPV6PREFIX:
  289. if (attrlen > 18 || attrlen < 2) {
  290. rc_log(LOG_ERR, "rc_avpair_gen: received IPV6PREFIX"
  291. " attribute with invalid length: %d", attrlen);
  292. goto skipit;
  293. }
  294. memcpy(pair->strvalue, (char *)ptr, attrlen);
  295. pair->lvalue = attrlen;
  296. break;
  297. case PW_TYPE_DATE:
  298. if (attrlen != 4) {
  299. rc_log(LOG_ERR, "rc_avpair_gen: received DATE "
  300. "attribute with invalid length");
  301. goto skipit;
  302. }
  303. default:
  304. rc_log(LOG_WARNING, "rc_avpair_gen: %s has unknown type",
  305. attr->name);
  306. goto skipit;
  307. }
  308. skipit:
  309. return pair;
  310. shithappens:
  311. while (pair != NULL) {
  312. rpair = pair->next;
  313. free(pair);
  314. pair = rpair;
  315. }
  316. #endif
  317. return NULL;
  318. }
  319. /** Find the first attribute value-pair (which matches the given attribute) from the specified value-pair list
  320. *
  321. * @param vp a pointer to a #VALUE_PAIR structure.
  322. * @param attrid The attribute of the pair to find (e.g., %PW_USER_NAME).
  323. * @param vendorpec The vendor ID in case of a vendor specific value - 0 otherwise.
  324. * @return the value pair found.
  325. */
  326. VALUE_PAIR *rc_avpair_get (VALUE_PAIR *vp, int attrid, int vendorpec)
  327. {
  328. for (; vp != NULL && !(ATTRID(vp->attribute) == ATTRID(attrid) &&
  329. VENDOR(vp->attribute) == vendorpec); vp = vp->next)
  330. {
  331. continue;
  332. }
  333. return vp;
  334. }
  335. /** Insert a VALUE_PAIR into a list
  336. *
  337. * Given the address of an existing list "a" and a pointer to an entry "p" in that list, add the value pair "b" to
  338. * the "a" list after the "p" entry. If "p" is NULL, add the value pair "b" to the end of "a".
  339. *
  340. * @param a a #VALUE_PAIR array of values.
  341. * @param p a pointer to a #VALUE_PAIR in a.
  342. * @param b The #VALUE_PAIR pointer to add in a.
  343. */
  344. void rc_avpair_insert(VALUE_PAIR **a, VALUE_PAIR *p, VALUE_PAIR *b)
  345. {
  346. VALUE_PAIR *this_node = NULL;
  347. VALUE_PAIR *vp;
  348. if (b->next != NULL)
  349. {
  350. rc_log(LOG_CRIT, "rc_avpair_insert: value pair (0x%p) next ptr. (0x%p) not NULL", b, b->next);
  351. abort ();
  352. }
  353. if (*a == NULL)
  354. {
  355. *a = b;
  356. return;
  357. }
  358. vp = *a;
  359. if ( p == NULL) /* run to end of "a" list */
  360. {
  361. while (vp != NULL)
  362. {
  363. this_node = vp;
  364. vp = vp->next;
  365. }
  366. }
  367. else /* look for the "p" entry in the "a" list */
  368. {
  369. this_node = *a;
  370. while (this_node != NULL)
  371. {
  372. if (this_node == p)
  373. {
  374. break;
  375. }
  376. this_node = this_node->next;
  377. }
  378. }
  379. b->next = this_node->next;
  380. this_node->next = b;
  381. return;
  382. }
  383. /** Frees all value_pairs in the list
  384. *
  385. * @param pair a pointer to a VALUE_PAIR structure.
  386. */
  387. void rc_avpair_free (VALUE_PAIR *pair)
  388. {
  389. #if 0
  390. VALUE_PAIR *next;
  391. while (pair != NULL)
  392. {
  393. next = pair->next;
  394. free (pair);
  395. pair = next;
  396. }
  397. #endif
  398. }
  399. /** Copy a data field from the buffer
  400. *
  401. * Advance the buffer past the data field. Ensure that no more than len - 1 bytes are copied and that resulting
  402. * string is terminated with '\0'.
  403. *
  404. * @param string the provided string to copy.
  405. * @param uptr the current position of the buffer.
  406. * @param stopat characters to which parsing should stop.
  407. * @param len the maximum length of string.
  408. */
  409. static void rc_fieldcpy(char *string, char const **uptr, char const *stopat, size_t len)
  410. {
  411. #if 0
  412. char const *ptr, *estring;
  413. ptr = *uptr;
  414. estring = string + len - 1;
  415. if (*ptr == '"')
  416. {
  417. ptr++;
  418. while (*ptr != '"' && *ptr != '\0' && *ptr != '\n')
  419. {
  420. if (string < estring)
  421. *string++ = *ptr;
  422. ptr++;
  423. }
  424. if (*ptr == '"')
  425. {
  426. ptr++;
  427. }
  428. *string = '\0';
  429. *uptr = ptr;
  430. return;
  431. }
  432. while (*ptr != '\0' && strchr(stopat, *ptr) == NULL)
  433. {
  434. if (string < estring)
  435. *string++ = *ptr;
  436. ptr++;
  437. }
  438. *string = '\0';
  439. *uptr = ptr;
  440. #endif
  441. return;
  442. }
  443. #define PARSE_MODE_NAME 0
  444. #define PARSE_MODE_EQUAL 1
  445. #define PARSE_MODE_VALUE 2
  446. #define PARSE_MODE_INVALID 3
  447. /** Parses the buffer to extract the attribute-value pairs
  448. *
  449. * @param rh a handle to parsed configuration.
  450. * @param buffer the buffer to be parsed.
  451. * @param first_pair an allocated array of values.
  452. * @return 0 on successful parse of attribute-value pair, or -1 on syntax (or other) error detected.
  453. */
  454. int rc_avpair_parse (rc_handle const *rh, char const *buffer, VALUE_PAIR **first_pair)
  455. {
  456. #if 0
  457. int mode;
  458. char attrstr[AUTH_ID_LEN];
  459. char valstr[AUTH_STRING_LEN + 1], *p;
  460. DICT_ATTR *attr = NULL;
  461. DICT_VALUE *dval;
  462. VALUE_PAIR *pair;
  463. VALUE_PAIR *link;
  464. struct tm *tm;
  465. time_t timeval;
  466. mode = PARSE_MODE_NAME;
  467. while (*buffer != '\n' && *buffer != '\0')
  468. {
  469. if (*buffer == ' ' || *buffer == '\t')
  470. {
  471. buffer++;
  472. continue;
  473. }
  474. switch (mode)
  475. {
  476. case PARSE_MODE_NAME: /* Attribute Name */
  477. rc_fieldcpy (attrstr, &buffer, " \t\n=,", sizeof(attrstr));
  478. if ((attr =
  479. rc_dict_findattr (rh, attrstr)) == NULL)
  480. {
  481. rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute");
  482. if (*first_pair) {
  483. rc_avpair_free(*first_pair);
  484. *first_pair = NULL;
  485. }
  486. return -1;
  487. }
  488. mode = PARSE_MODE_EQUAL;
  489. break;
  490. case PARSE_MODE_EQUAL: /* Equal sign */
  491. if (*buffer == '=')
  492. {
  493. mode = PARSE_MODE_VALUE;
  494. buffer++;
  495. }
  496. else
  497. {
  498. rc_log(LOG_ERR, "rc_avpair_parse: missing or misplaced equal sign");
  499. if (*first_pair) {
  500. rc_avpair_free(*first_pair);
  501. *first_pair = NULL;
  502. }
  503. return -1;
  504. }
  505. break;
  506. case PARSE_MODE_VALUE: /* Value */
  507. rc_fieldcpy (valstr, &buffer, " \t\n,", sizeof(valstr));
  508. if ((pair = malloc (sizeof (VALUE_PAIR))) == NULL)
  509. {
  510. rc_log(LOG_CRIT, "rc_avpair_parse: out of memory");
  511. if (*first_pair) {
  512. rc_avpair_free(*first_pair);
  513. *first_pair = NULL;
  514. }
  515. return -1;
  516. }
  517. strcpy (pair->name, attr->name);
  518. pair->attribute = attr->value;
  519. pair->type = attr->type;
  520. switch (pair->type)
  521. {
  522. case PW_TYPE_STRING:
  523. strcpy (pair->strvalue, valstr);
  524. pair->lvalue = (uint32_t)strlen(valstr);
  525. break;
  526. case PW_TYPE_INTEGER:
  527. if (isdigit (*valstr))
  528. {
  529. pair->lvalue = atoi (valstr);
  530. }
  531. else
  532. {
  533. if ((dval = rc_dict_findval (rh, valstr))
  534. == NULL)
  535. {
  536. rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute value: %s", valstr);
  537. if (*first_pair) {
  538. rc_avpair_free(*first_pair);
  539. *first_pair = NULL;
  540. }
  541. free (pair);
  542. return -1;
  543. }
  544. else
  545. {
  546. pair->lvalue = dval->value;
  547. }
  548. }
  549. break;
  550. case PW_TYPE_IPADDR:
  551. if (inet_pton(AF_INET, valstr, &pair->lvalue) == 0) {
  552. rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv4 address %s", valstr);
  553. free(pair);
  554. return -1;
  555. }
  556. pair->lvalue = ntohl(pair->lvalue);
  557. break;
  558. case PW_TYPE_IPV6ADDR:
  559. if (inet_pton(AF_INET6, valstr, pair->strvalue) == 0) {
  560. rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 address %s", valstr);
  561. free(pair);
  562. return -1;
  563. }
  564. pair->lvalue = 16;
  565. break;
  566. case PW_TYPE_IPV6PREFIX:
  567. p = strchr(valstr, '/');
  568. if (p == NULL) {
  569. rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 prefix %s", valstr);
  570. free(pair);
  571. return -1;
  572. }
  573. *p = 0;
  574. p++;
  575. pair->strvalue[0] = 0;
  576. pair->strvalue[1] = atoi(p);
  577. if (inet_pton(AF_INET6, valstr, pair->strvalue+2) == 0) {
  578. rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 prefix %s", valstr);
  579. free(pair);
  580. return -1;
  581. }
  582. pair->lvalue = 2+16;
  583. break;
  584. case PW_TYPE_DATE:
  585. timeval = time (0);
  586. tm = localtime (&timeval);
  587. tm->tm_hour = 0;
  588. tm->tm_min = 0;
  589. tm->tm_sec = 0;
  590. rc_str2tm (valstr, tm);
  591. #ifdef TIMELOCAL
  592. pair->lvalue = (uint32_t) timelocal (tm);
  593. #else /* TIMELOCAL */
  594. pair->lvalue = (uint32_t) mktime (tm);
  595. #endif /* TIMELOCAL */
  596. break;
  597. default:
  598. rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute type %d", pair->type);
  599. if (*first_pair) {
  600. rc_avpair_free(*first_pair);
  601. *first_pair = NULL;
  602. }
  603. free (pair);
  604. return -1;
  605. }
  606. /* XXX: Fix up Digest-Attributes */
  607. switch (pair->attribute) {
  608. case PW_DIGEST_REALM:
  609. case PW_DIGEST_NONCE:
  610. case PW_DIGEST_METHOD:
  611. case PW_DIGEST_URI:
  612. case PW_DIGEST_QOP:
  613. case PW_DIGEST_ALGORITHM:
  614. case PW_DIGEST_BODY_DIGEST:
  615. case PW_DIGEST_CNONCE:
  616. case PW_DIGEST_NONCE_COUNT:
  617. case PW_DIGEST_USER_NAME:
  618. /* overlapping! */
  619. if (pair->lvalue > AUTH_STRING_LEN - 2)
  620. pair->lvalue = AUTH_STRING_LEN - 2;
  621. memmove(&pair->strvalue[2], &pair->strvalue[0], pair->lvalue);
  622. pair->strvalue[0] = pair->attribute - PW_DIGEST_REALM + 1;
  623. pair->lvalue += 2;
  624. pair->strvalue[1] = pair->lvalue;
  625. pair->strvalue[pair->lvalue] = '\0';
  626. pair->attribute = PW_DIGEST_ATTRIBUTES;
  627. }
  628. pair->next = NULL;
  629. if (*first_pair == NULL)
  630. {
  631. *first_pair = pair;
  632. }
  633. else
  634. {
  635. link = *first_pair;
  636. while (link->next != NULL)
  637. {
  638. link = link->next;
  639. }
  640. link->next = pair;
  641. }
  642. mode = PARSE_MODE_NAME;
  643. break;
  644. default:
  645. mode = PARSE_MODE_NAME;
  646. break;
  647. }
  648. }
  649. #endif
  650. return 0;
  651. }
  652. /** Translate an av_pair into two strings
  653. *
  654. * @param rh a handle to parsed configuration.
  655. * @param pair a pointer to a VALUE_PAIR structure.
  656. * @param name the name of the pair.
  657. * @param ln the size of name.
  658. * @param value the value of the pair.
  659. * @param lv the size of value.
  660. * @return 0 on success, -1 on failure.
  661. */
  662. int rc_avpair_tostr (rc_handle const *rh, VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
  663. {
  664. #if 0
  665. DICT_VALUE *dval;
  666. char buffer[32];
  667. struct in_addr inad;
  668. unsigned char *ptr;
  669. unsigned int pos;
  670. *name = *value = '\0';
  671. if (!pair || pair->name[0] == '\0') {
  672. rc_log(LOG_ERR, "rc_avpair_tostr: pair is NULL or empty");
  673. return -1;
  674. }
  675. strlcpy(name, pair->name, (size_t) ln);
  676. switch (pair->type)
  677. {
  678. case PW_TYPE_STRING:
  679. lv--;
  680. pos = 0;
  681. ptr = (unsigned char *) pair->strvalue;
  682. if (pair->attribute == PW_DIGEST_ATTRIBUTES) {
  683. pair->strvalue[*(ptr + 1)] = '\0';
  684. ptr += 2;
  685. }
  686. while (*ptr != '\0')
  687. {
  688. if (!(isprint (*ptr)))
  689. {
  690. if (lv >= 4) {
  691. snprintf (&value[pos], lv, "\\%03o", *ptr);
  692. pos += 4;
  693. lv -= 4;
  694. } else {
  695. break;
  696. }
  697. }
  698. else
  699. {
  700. if (lv > 0) {
  701. value[pos++] = *ptr;
  702. lv--;
  703. } else {
  704. break;
  705. }
  706. }
  707. ptr++;
  708. }
  709. if (lv > 0)
  710. value[pos++] = 0;
  711. else
  712. value[pos-1] = 0;
  713. break;
  714. case PW_TYPE_INTEGER:
  715. dval = rc_dict_getval (rh, pair->lvalue, pair->name);
  716. if (dval != NULL)
  717. {
  718. strlcpy(value, dval->name, (size_t) lv);
  719. }
  720. else
  721. {
  722. snprintf(value, lv, "%ld", (long int)pair->lvalue);
  723. }
  724. break;
  725. case PW_TYPE_IPADDR:
  726. inad.s_addr = htonl(pair->lvalue);
  727. strlcpy (value, inet_ntoa (inad), (size_t) lv);
  728. break;
  729. case PW_TYPE_IPV6ADDR:
  730. if (inet_ntop(AF_INET6, pair->strvalue, value, lv) == NULL)
  731. return -1;
  732. break;
  733. case PW_TYPE_IPV6PREFIX: {
  734. uint8_t ip[16];
  735. char txt[48];
  736. if (pair->lvalue < 2)
  737. return -1;
  738. memset(ip, 0, sizeof(ip));
  739. memcpy(ip, pair->strvalue+2, pair->lvalue-2);
  740. if (inet_ntop(AF_INET6, ip, txt, sizeof(txt)) == NULL)
  741. return -1;
  742. snprintf(value, lv, "%s/%u", txt, (unsigned)pair->strvalue[1]);
  743. break;
  744. }
  745. case PW_TYPE_DATE:
  746. strftime (value, lv, "%m/%d/%y %H:%M:%S",
  747. gmtime ((time_t *) & pair->lvalue));
  748. break;
  749. default:
  750. rc_log(LOG_ERR, "rc_avpair_tostr: unknown attribute type %d", pair->type);
  751. return -1;
  752. break;
  753. }
  754. #endif
  755. return 0;
  756. }
  757. /** Format a sequence of attribute value pairs into a printable string
  758. *
  759. * The caller should provide a storage buffer and the buffer length.
  760. *
  761. * @param rh a handle to parsed configuration.
  762. * @param pair a pointer to a #VALUE_PAIR structure.
  763. * @param buf will hold the string output of the pair.
  764. * @param len the size of buf.
  765. * @return a pointer to provided storage buffer.
  766. */
  767. char *rc_avpair_log(rc_handle const *rh, VALUE_PAIR *pair, char *buf, size_t buf_len)
  768. {
  769. #if 0
  770. size_t len, nlen;
  771. VALUE_PAIR *vp;
  772. char name[33], value[256];
  773. len = 0;
  774. for (vp = pair; vp != NULL; vp = vp->next) {
  775. if (rc_avpair_tostr(rh, vp, name, sizeof(name), value,
  776. sizeof(value)) == -1)
  777. return NULL;
  778. nlen = len + 32 + 3 + strlen(value) + 2 + 2;
  779. if(nlen<buf_len-1) {
  780. sprintf(buf + len, "%-32s = '%s'\n", name, value);
  781. } else return buf;
  782. len = nlen - 1;
  783. }
  784. #endif
  785. return buf;
  786. }
  787. #if 0
  788. /** Get a sequence of attribute value pairs from the file input and make them into a list of value_pairs
  789. *
  790. * @param rh a handle to parsed configuration.
  791. * @param input a %FILE handle.
  792. * @return the array of value pairs.
  793. */
  794. VALUE_PAIR *rc_avpair_readin(rc_handle const *rh, FILE *input)
  795. {
  796. VALUE_PAIR *vp = NULL;
  797. char buffer[1024], *q;
  798. while (fgets(buffer, sizeof(buffer), input) != NULL)
  799. {
  800. q = buffer;
  801. while(*q && isspace(*q)) q++;
  802. if ((*q == '\n') || (*q == '#') || (*q == '\0'))
  803. continue;
  804. if (rc_avpair_parse(rh, q, &vp) < 0) {
  805. rc_log(LOG_ERR, "rc_avpair_readin: malformed attribute: %s", buffer);
  806. rc_avpair_free(vp);
  807. return NULL;
  808. }
  809. }
  810. return vp;
  811. }
  812. #endif