char * constant_name(struct constant_map *map, int value) { static char tmp[32];/* XXX Ugly, I know. */ char *retval = constant_lookup(map, value); if (!retval) { snprintf(tmp, sizeof tmp, "<Unknown %d>", value); return tmp; } return retval; }
char * constant_name_maps(struct constant_map **maps, int value) { static char tmp[32];/* XXX Ugly, I know. */ char *retval; struct constant_map **map; for (map = maps; *map; map++) { retval = constant_lookup(*map, value); if (retval) return retval; } snprintf(tmp, sizeof tmp, "<Unknown %d>", value); return tmp; }
/* * Look at the attribute of type TYPE, located at VALUE for LEN bytes forward. * The VVS argument holds a validation state kept across invocations. * If the attribute is unacceptable to use, return non-zero, otherwise zero. */ static int attribute_unacceptable (u_int16_t type, u_int8_t *value, u_int16_t len, void *vvs) { struct validation_state *vs = vvs; struct conf_list *life_conf; struct conf_list_node *xf = vs->xf, *life; char *tag = constant_lookup (ike_attr_cst, type); char *str; struct constant_map *map; struct attr_node *node; int rv; if (!tag) { LOG_DBG ((LOG_NEGOTIATION, 60, "attribute_unacceptable: attribute type %d not known", type)); return 1; } switch (type) { case IKE_ATTR_ENCRYPTION_ALGORITHM: case IKE_ATTR_HASH_ALGORITHM: case IKE_ATTR_AUTHENTICATION_METHOD: case IKE_ATTR_GROUP_DESCRIPTION: case IKE_ATTR_GROUP_TYPE: case IKE_ATTR_PRF: str = conf_get_str (xf->field, tag); if (!str) { /* This attribute does not exist in this policy. */ LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: attr %s does not exist in %s", tag, xf->field)); return 1; } map = constant_link_lookup (ike_attr_cst, type); if (!map) return 1; if ((constant_value (map, str) == decode_16 (value)) || (!strcmp (str, "ANY"))) { /* Mark this attribute as seen. */ node = malloc (sizeof *node); if (!node) { log_error ("attribute_unacceptable: malloc (%lu) failed", (unsigned long)sizeof *node); return 1; } node->type = type; LIST_INSERT_HEAD (&vs->attrs, node, link); return 0; } LOG_DBG ((LOG_NEGOTIATION, 30, "attribute_unacceptable: %s: got '%s', expected '%s'", tag, constant_name (map, decode_16 (value)), str)); return 1; case IKE_ATTR_GROUP_PRIME: case IKE_ATTR_GROUP_GENERATOR_1: case IKE_ATTR_GROUP_GENERATOR_2: case IKE_ATTR_GROUP_CURVE_A: case IKE_ATTR_GROUP_CURVE_B: /* XXX Bignums not handled yet. */ return 1; case IKE_ATTR_LIFE_TYPE: case IKE_ATTR_LIFE_DURATION: life_conf = conf_get_list (xf->field, "Life"); if (life_conf && !strcmp (conf_get_str (xf->field, "Life"), "ANY")) return 0; rv = 1; if (!life_conf) { /* Life attributes given, but not in our policy. */ LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: " "received unexpected life attribute")); return 1; } /* * Each lifetime type must match, otherwise we turn the proposal down. * In order to do this we need to find the specific section of our * policy's "Life" list and match its duration */ switch (type) { case IKE_ATTR_LIFE_TYPE: for (life = TAILQ_FIRST (&life_conf->fields); life; life = TAILQ_NEXT (life, link)) { str = conf_get_str (life->field, "LIFE_TYPE"); if (!str) { LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: " "section [%s] has no LIFE_TYPE", life->field)); continue; } /* * If this is the type we are looking at, save a pointer * to this section in vs->life. */ if (constant_value (ike_duration_cst, str) == decode_16 (value)) { vs->life = strdup (life->field); rv = 0; goto bail_out; } } LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: unrecognized LIFE_TYPE %d", decode_16 (value))); vs->life = 0; break; case IKE_ATTR_LIFE_DURATION: if (!vs->life) { LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: " "LIFE_DURATION without LIFE_TYPE")); rv = 1; goto bail_out; } str = conf_get_str (vs->life, "LIFE_DURATION"); if (str) { if (!strcmp (str, "ANY")) rv = 0; else rv = !conf_match_num (vs->life, "LIFE_DURATION", len == 4 ? decode_32 (value) : decode_16 (value)); } else { LOG_DBG ((LOG_NEGOTIATION, 70, "attribute_unacceptable: " "section [%s] has no LIFE_DURATION", vs->life)); rv = 1; } free (vs->life); vs->life = 0; break; } bail_out: conf_free_list (life_conf); return rv; case IKE_ATTR_KEY_LENGTH: case IKE_ATTR_FIELD_SIZE: case IKE_ATTR_GROUP_ORDER: if (conf_match_num (xf->field, tag, decode_16 (value))) { /* Mark this attribute as seen. */ node = malloc (sizeof *node); if (!node) { log_error ("attribute_unacceptable: malloc (%lu) failed", (unsigned long)sizeof *node); return 1; } node->type = type; LIST_INSERT_HEAD (&vs->attrs, node, link); return 0; } return 1; } return 1; }