예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
/*
 * 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;
}