/* * Process the VALUE command */ static int process_value(const char* fn, const int line, char **argv, int argc) { int value; if (argc != 3) { fr_strerror_printf("dict_init: %s[%d]: invalid VALUE line", fn, line); return -1; } /* * For Compatibility, skip "Server-Config" */ if (strcasecmp(argv[0], "Server-Config") == 0) return 0; /* * Validate all entries */ if (!sscanf_i(argv[2], &value)) { fr_strerror_printf("dict_init: %s[%d]: invalid value", fn, line); return -1; } if (dict_addvalue(argv[1], argv[0], value) < 0) { fr_strerror_printf("dict_init: %s[%d]: %s", fn, line, fr_strerror()); return -1; } return 0; }
/* * Process the ATTRIBUTE command */ static int process_attribute(const char* fn, const int line, const int block_vendor, DICT_ATTR *block_tlv, char **argv, int argc) { int vendor = 0; int value; int type; ATTR_FLAGS flags; if ((argc < 3) || (argc > 4)) { fr_strerror_printf("dict_init: %s[%d]: invalid ATTRIBUTE line", fn, line); return -1; } /* * Validate all entries */ if (!sscanf_i(argv[1], &value)) { fr_strerror_printf("dict_init: %s[%d]: invalid value", fn, line); return -1; } /* * find the type of the attribute. */ type = fr_str2int(type_table, argv[2], -1); if (type < 0) { fr_strerror_printf("dict_init: %s[%d]: invalid type \"%s\"", fn, line, argv[2]); return -1; } /* * Only look up the vendor if the string * is non-empty. */ memset(&flags, 0, sizeof(flags)); if (argc == 4) { char *key, *next, *last; key = argv[3]; do { next = strchr(key, ','); if (next) *(next++) = '\0'; if (strcmp(key, "has_tag") == 0 || strcmp(key, "has_tag=1") == 0) { /* Boolean flag, means this is a tagged attribute */ flags.has_tag = 1; } else if (strncmp(key, "encrypt=", 8) == 0) { /* Encryption method, defaults to 0 (none). Currently valid is just type 2, Tunnel-Password style, which can only be applied to strings. */ flags.encrypt = strtol(key + 8, &last, 0); if (*last) { fr_strerror_printf( "dict_init: %s[%d] invalid option %s", fn, line, key); return -1; } } else if (strncmp(key, "array", 8) == 0) { flags.array = 1; switch (type) { case PW_TYPE_IPADDR: case PW_TYPE_BYTE: case PW_TYPE_SHORT: case PW_TYPE_INTEGER: case PW_TYPE_DATE: break; default: fr_strerror_printf( "dict_init: %s[%d] Only IP addresses can have the \"array\" flag set.", fn, line); return -1; } /* * The only thing is the vendor name, * and it's a known name: allow it. */ } else if ((key == argv[3]) && !next && !block_vendor && ((vendor = dict_vendorbyname(key)) !=0)) { break; } else { fr_strerror_printf( "dict_init: %s[%d]: unknown option \"%s\"", fn, line, key); return -1; } key = next; if (key && !*key) break; } while (key); } if (block_vendor) vendor = block_vendor; /* * Special checks for tags, they make our life much more * difficult. */ if (flags.has_tag) { /* * Only string, octets, and integer can be tagged. */ switch (type) { case PW_TYPE_STRING: case PW_TYPE_INTEGER: break; default: fr_strerror_printf("dict_init: %s[%d]: Attributes of type %s cannot be tagged.", fn, line, fr_int2str(type_table, type, "?Unknown?")); return -1; } } if (type == PW_TYPE_TLV) { flags.has_tlv = 1; } if (block_tlv) { /* * TLV's can be only one octet. */ if ((value <= 0) || (value > 255)) { fr_strerror_printf( "dict_init: %s[%d]: sub-tlv's cannot have value > 255", fn, line); return -1; } if (flags.encrypt != FLAG_ENCRYPT_NONE) { fr_strerror_printf( "dict_init: %s[%d]: sub-tlv's cannot be encrypted", fn, line); return -1; } /* * */ value <<= 8; value |= (block_tlv->attr & 0xffff); flags.is_tlv = 1; } #ifdef WITH_DICTIONARY_WARNINGS /* * Hack to help us discover which vendors have illegal * attributes. */ if (!vendor && (value < 256) && !strstr(fn, "rfc") && !strstr(fn, "illegal")) { fprintf(stderr, "WARNING: Illegal Attribute %s in %s\n", argv[0], fn); } #endif /* * Add it in. */ if (dict_addattr(argv[0], vendor, type, value, flags) < 0) { char buffer[256]; strlcpy(buffer, fr_strerror(), sizeof(buffer)); fr_strerror_printf("dict_init: %s[%d]: %s", fn, line, buffer); return -1; } return 0; }