2
2
* valuepair.c Functions to handle VALUE_PAIRs
4
* Version: $Id: valuepair.c,v 1.141 2008/04/18 14:09:56 aland Exp $
6
6
* This library is free software; you can redistribute it and/or
7
7
* modify it under the terms of the GNU Lesser General Public
170
177
void pairbasicfree(VALUE_PAIR *pair)
179
if (pair->type == PW_TYPE_TLV) free(pair->vp_tlv);
172
180
/* clear the memory here */
173
181
memset(pair, 0, sizeof(*pair));
310
318
if ((n = malloc(sizeof(*n) + name_len)) == NULL) {
311
librad_log("out of memory");
319
fr_strerror_printf("out of memory");
314
322
memcpy(n, vp, sizeof(*n) + name_len);
325
if ((n->type == PW_TYPE_TLV) &&
326
(n->vp_tlv != NULL)) {
327
n->vp_tlv = malloc(n->length);
328
memcpy(n->vp_tlv, vp->vp_tlv, n->length);
806
821
* double-check the parsed value, to be sure it's legal for that
807
822
* type (length, etc.)
824
static uint32_t getint(const char *value, char **end)
826
if ((value[0] == '0') && (value[1] == 'x')) {
827
return strtoul(value, end, 16);
830
return strtoul(value, end, 10);
809
833
VALUE_PAIR *pairparsevalue(VALUE_PAIR *vp, const char *value)
815
839
DICT_VALUE *dval;
841
if (!value) return NULL;
818
844
* Even for integers, dates and ip addresses we
819
845
* keep the original string in vp->vp_strvalue.
821
strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
822
vp->length = strlen(vp->vp_strvalue);
847
if (vp->type != PW_TYPE_TLV) {
848
strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
849
vp->length = strlen(vp->vp_strvalue);
824
852
switch(vp->type) {
825
853
case PW_TYPE_STRING:
912
940
if (ip_hton(cs, AF_INET, &ipaddr) < 0) {
914
librad_log("Failed to find IP address for %s", cs);
942
fr_strerror_printf("Failed to find IP address for %s", cs);
924
952
case PW_TYPE_BYTE:
925
if (value && (value[0] == '0') && (value[1] == 'x')) {
930
954
* Note that ALL integers are unsigned!
932
vp->vp_integer = (uint32_t) strtoul(value, &p, 10);
956
vp->vp_integer = getint(value, &p);
934
958
if (vp->vp_integer > 255) {
935
librad_log("Byte value \"%s\" is larger than 255", value);
959
fr_strerror_printf("Byte value \"%s\" is larger than 255", value);
946
970
if ((dval = dict_valbyname(vp->attribute, value)) == NULL) {
947
librad_log("Unknown value %s for attribute %s",
971
fr_strerror_printf("Unknown value %s for attribute %s",
948
972
value, vp->name);
957
981
* Note that ALL integers are unsigned!
959
vp->vp_integer = (uint32_t) strtoul(value, &p, 10);
983
vp->vp_integer = getint(value, &p);
961
985
if (vp->vp_integer > 65535) {
962
librad_log("Byte value \"%s\" is larger than 65535", value);
986
fr_strerror_printf("Byte value \"%s\" is larger than 65535", value);
973
997
if ((dval = dict_valbyname(vp->attribute, value)) == NULL) {
974
librad_log("Unknown value %s for attribute %s",
998
fr_strerror_printf("Unknown value %s for attribute %s",
975
999
value, vp->name);
984
1008
* Note that ALL integers are unsigned!
986
vp->vp_integer = (uint32_t) strtoul(value, &p, 10);
1010
vp->vp_integer = getint(value, &p);
996
1020
if ((dval = dict_valbyname(vp->attribute, value)) == NULL) {
997
librad_log("Unknown value %s for attribute %s",
1021
fr_strerror_printf("Unknown value %s for attribute %s",
998
1022
value, vp->name);
1042
1066
* then fall through to raw octets, so that
1043
1067
* the user can at least make them by hand...
1047
1071
/* raw octets: 0x01020304... */
1048
1072
case PW_TYPE_OCTETS:
1049
1073
if (strncasecmp(value, "0x", 2) == 0) {
1068
1092
unsigned int tmp;
1070
1094
if (sscanf(cp, "%02x", &tmp) != 1) {
1071
librad_log("Non-hex characters at %c%c", cp[0], cp[1]);
1095
fr_strerror_printf("Non-hex characters at %c%c", cp[0], cp[1]);
1111
1135
buffer[p - value] = '\0';
1113
1137
if (inet_pton(AF_INET6, buffer, vp->vp_octets + 2) <= 0) {
1114
librad_log("failed to parse IPv6 address "
1138
fr_strerror_printf("failed to parse IPv6 address "
1115
1139
"string \"%s\"", value);
1119
1143
prefix = strtoul(p + 1, &eptr, 10);
1120
1144
if ((prefix > 128) || *eptr) {
1121
librad_log("failed to parse IPv6 address "
1145
fr_strerror_printf("failed to parse IPv6 address "
1122
1146
"string \"%s\"", value);
1150
1174
c1 = c2 = NULL;
1152
1176
if (!c1 || !c2 || (length >= sizeof(vp->vp_ether))) {
1153
librad_log("failed to parse Ethernet address \"%s\"", value);
1177
fr_strerror_printf("failed to parse Ethernet address \"%s\"", value);
1156
1180
vp->vp_ether[length] = ((c1-hextab)<<4) + (c2-hextab);
1160
1184
vp->length = 6;
1187
case PW_TYPE_COMBO_IP:
1188
if (inet_pton(AF_INET6, value, vp->vp_strvalue) > 0) {
1189
vp->type = PW_TYPE_IPV6ADDR;
1190
vp->length = 16; /* length of IPv6 address */
1191
vp->vp_strvalue[vp->length] = '\0';
1196
if (ip_hton(value, AF_INET, &ipaddr) < 0) {
1197
fr_strerror_printf("Failed to find IPv4 address for %s", value);
1201
vp->type = PW_TYPE_IPADDR;
1202
vp->vp_ipaddr = ipaddr.ipaddr.ip4addr.s_addr;
1207
case PW_TYPE_SIGNED: /* Damned code for 1 WiMAX attribute */
1208
vp->vp_signed = (int32_t) strtol(value, &p, 10);
1212
case PW_TYPE_TLV: /* don't use this! */
1213
if (strncasecmp(value, "0x", 2) != 0) {
1214
fr_strerror_printf("Invalid TLV specification");
1217
length = strlen(value + 2) / 2;
1218
if (vp->length < length) {
1222
vp->vp_tlv = malloc(length);
1224
fr_strerror_printf("No memory");
1227
if (fr_hex2bin(value + 2, vp->vp_tlv,
1228
length) != length) {
1229
fr_strerror_printf("Invalid hex data in TLV");
1232
vp->length = length;
1164
1236
* Anything else.
1167
librad_log("unknown attribute type %d", vp->type);
1239
fr_strerror_printf("unknown attribute type %d", vp->type);
1192
1264
* Unknown attributes MUST be of type 'octets'
1194
1266
if (value && (strncasecmp(value, "0x", 2) != 0)) {
1195
librad_log("Invalid octet string \"%s\" for attribute name \"%s\"", value, attribute);
1267
fr_strerror_printf("Invalid octet string \"%s\" for attribute name \"%s\"", value, attribute);
1202
1274
* Pull off vendor prefix first.
1205
1277
if (strncasecmp(p, "Vendor-", 7) == 0) {
1206
1278
vendor = (int) strtol(p + 7, &q, 10);
1207
1279
if ((vendor == 0) || (vendor > 65535)) {
1208
librad_log("Invalid vendor value in attribute name \"%s\"", attribute);
1280
fr_strerror_printf("Invalid vendor value in attribute name \"%s\"", attribute);
1217
1289
q = strchr(p, '-');
1220
librad_log("Invalid vendor name in attribute name \"%s\"", attribute);
1292
fr_strerror_printf("Invalid vendor name in attribute name \"%s\"", attribute);
1224
1296
if ((size_t) (q - p) >= sizeof(buffer)) {
1225
librad_log("Vendor name too long in attribute name \"%s\"", attribute);
1297
fr_strerror_printf("Vendor name too long in attribute name \"%s\"", attribute);
1251
1323
if (strncasecmp(p, "Attr-", 5) != 0) {
1252
librad_log("Invalid format in attribute name \"%s\"", attribute);
1324
fr_strerror_printf("Invalid format in attribute name \"%s\"", attribute);
1259
1331
* Invalid, or trailing text after number.
1261
1333
if ((attr == 0) || *q) {
1262
librad_log("Invalid value in attribute name \"%s\"", attribute);
1334
fr_strerror_printf("Invalid value in attribute name \"%s\"", attribute);
1303
1375
* dictionary, and creates the appropriate type for it.
1305
1377
if ((vp = paircreate(attr, PW_TYPE_OCTETS)) == NULL) {
1306
librad_log("out of memory");
1378
fr_strerror_printf("out of memory");
1381
1449
ts = strrchr(attribute, ':');
1382
1450
if (ts && !ts[1]) {
1383
librad_log("Invalid tag for attribute %s", attribute);
1451
fr_strerror_printf("Invalid tag for attribute %s", attribute);
1429
1497
if (value && (*value == ':' && da->flags.has_tag)) {
1430
1498
/* If we already found a tag, this is invalid */
1431
1499
if(found_tag) {
1433
librad_log("Duplicate tag %s for attribute %s",
1500
fr_strerror_printf("Duplicate tag %s for attribute %s",
1434
1501
value, vp->name);
1435
1502
DEBUG("Duplicate tag %s for attribute %s\n",
1436
1503
value, vp->name);
1440
1507
/* Colon found and attribute allows a tag */
1441
1508
if (value[1] == '*' && value[2] == ':') {
1479
1546
case T_OP_REG_EQ: /* =~ */
1480
1547
case T_OP_REG_NE: /* !~ */
1481
if (vp->type == PW_TYPE_INTEGER) {
1486
* Regular expression match with no regular
1487
* expression is wrong.
1494
res = regcomp(&cre, value, REG_EXTENDED|REG_NOSUB);
1498
regerror(res, &cre, msg, sizeof(msg));
1499
librad_log("Illegal regular expression in attribute: %s: %s",
1506
librad_log("Regular expressions not enabled in this build, error in attribute %s",
1549
fr_strerror_printf("No regular expression found in %s",
1555
strlcpy(vp->vp_strvalue, value, sizeof(vp->vp_strvalue));
1556
vp->length = strlen(vp->vp_strvalue);
1558
* If anything goes wrong, this is a run-time error,
1559
* not a compile-time error.
1572
1624
*eol = T_OP_INVALID;
1573
librad_log("No token read where we expected an attribute name");
1625
fr_strerror_printf("No token read where we expected an attribute name");
1577
1629
if (*p == '#') {
1579
librad_log("Read a comment instead of a token");
1631
fr_strerror_printf("Read a comment instead of a token");
1609
1661
/* Now we should have an operator here. */
1610
1662
token = gettoken(ptr, buf, sizeof(buf));
1611
1663
if (token < T_EQSTART || token > T_EQEND) {
1612
librad_log("expecting operator");
1664
fr_strerror_printf("expecting operator");
1616
1668
/* Read value. Note that empty string values are allowed */
1617
1669
xlat = gettoken(ptr, value, sizeof(value));
1618
1670
if (xlat == T_EOL) {
1619
librad_log("failed to get value");
1671
fr_strerror_printf("failed to get value");
1627
1679
t = gettoken(&p, buf, sizeof(buf));
1628
1680
if (t != T_EOL && t != T_COMMA && t != T_HASH) {
1629
librad_log("Expected end of line or comma");
1681
fr_strerror_printf("Expected end of line or comma");
1651
1703
p = strchr(value, '%');
1652
1704
if (p && (p[1] == '{')) {
1653
1705
if (strlen(value) >= sizeof(vp->vp_strvalue)) {
1654
librad_log("Value too long");
1706
fr_strerror_printf("Value too long");
1657
1709
vp = pairmake(attr, NULL, token);
1664
1716
vp->flags.do_xlat = 1;
1665
1717
vp->length = 0;
1720
* Parse && escape it, as defined by the
1667
1723
vp = pairmake(attr, value, token);
1725
*eol = T_OP_INVALID;
1731
case T_SINGLE_QUOTED_STRING:
1732
vp = pairmake(attr, NULL, token);
1734
*eol = T_OP_INVALID;
1739
* String and octet types get copied verbatim.
1741
if ((vp->type == PW_TYPE_STRING) ||
1742
(vp->type == PW_TYPE_OCTETS)) {
1743
strlcpy(vp->vp_strvalue, value,
1744
sizeof(vp->vp_strvalue));
1745
vp->length = strlen(vp->vp_strvalue);
1748
* Everything else gets parsed: it's
1749
* DATA, not a string!
1751
} else if (!pairparsevalue(vp, value)) {
1753
*eol = T_OP_INVALID;
1673
1759
* Mark the pair to be allocated later.
1675
1761
case T_BACK_QUOTED_STRING:
1676
1762
if (strlen(value) >= sizeof(vp->vp_strvalue)) {
1677
librad_log("Value too long");
1763
fr_strerror_printf("Value too long");
1779
1865
last_token = userparse(buf, &vp);
1781
1867
if (last_token != T_EOL) {
1782
librad_perror("%s", errprefix);
1868
fr_perror("%s", errprefix);
1839
1927
if (compare != 0) {
1840
1928
regerror(compare, ®, buffer, sizeof(buffer));
1841
librad_log("Illegal regular expression in attribute: %s: %s",
1929
fr_strerror_printf("Illegal regular expression in attribute: %s: %s",
1842
1930
one->name, buffer);