Example #1
0
/* Generate the NAT-D payload hash : HASH(CKY-I | CKY-R | IP | Port).  */
static u_int8_t *
nat_t_generate_nat_d_hash(struct message *msg, struct sockaddr *sa,
    size_t *hashlen)
{
	struct ipsec_exch *ie = (struct ipsec_exch *)msg->exchange->data;
	struct hash	 *hash;
	u_int8_t	 *res;
	in_port_t	  port;

	hash = hash_get(ie->hash->type);
	if (hash == NULL) {
		log_print ("nat_t_generate_nat_d_hash: no hash");
		return NULL;
	}

	*hashlen = hash->hashsize;

	res = malloc(*hashlen);
	if (!res) {
		log_print("nat_t_generate_nat_d_hash: malloc (%lu) failed",
		    (unsigned long)*hashlen);
		*hashlen = 0;
		return NULL;
	}

	port = sockaddr_port(sa);
	bzero(res, *hashlen);

	hash->Init(hash->ctx);
	hash->Update(hash->ctx, msg->exchange->cookies,
	    sizeof msg->exchange->cookies);
	hash->Update(hash->ctx, sockaddr_addrdata(sa), sockaddr_addrlen(sa));
	hash->Update(hash->ctx, (unsigned char *)&port, sizeof port);
	hash->Final(res, hash->ctx);
	return res;
}
Example #2
0
/* Receive ID.  */
int
ike_phase_1_recv_ID (struct message *msg)
{
    struct exchange *exchange = msg->exchange;
    struct payload *payload;
    char header[80], *rs = 0, *rid = 0, *p;
    int initiator = exchange->initiator;
    u_int8_t **id, id_type;
    size_t *id_len, sz;
    struct sockaddr *sa;

    payload = TAILQ_FIRST (&msg->payload[ISAKMP_PAYLOAD_ID]);

    if (exchange->name)
        rs = conf_get_str (exchange->name, "Remote-ID");

    if (rs)
    {
        sz = ipsec_id_size (rs, &id_type);
        if (sz == -1)
        {
            log_print ("ike_phase_1_recv_ID: could not handle specified "
                       "Remote-ID [%s]", rs);
            return -1;
        }

        rid = malloc (sz);
        if (!rid)
        {
            log_error ("ike_phase_1_recv_ID: malloc (%lu) failed",
                       (unsigned long)sz);
            return -1;
        }

        switch (id_type)
        {
        case IPSEC_ID_IPV4_ADDR:
        case IPSEC_ID_IPV6_ADDR:
            p = conf_get_str (rs, "Address");
            if (!p)
            {
                log_print ("ike_phase_1_recv_ID: "
                           "failed to get Address in Remote-ID section [%s]",
                           rs);
                free (rid);
                return -1;
            }

            if (text2sockaddr (p, 0, &sa) == -1)
            {
                log_print ("ike_phase_1_recv_ID: failed to parse address %s", p);
                free (rid);
                return -1;
            }

            if ((id_type == IPSEC_ID_IPV4_ADDR && sa->sa_family != AF_INET)
                    || (id_type == IPSEC_ID_IPV6_ADDR && sa->sa_family != AF_INET6))
            {
                log_print ("ike_phase_1_recv_ID: "
                           "address %s not of expected family", p);
                free (rid);
                free (sa);
                return -1;
            }

            memcpy (rid, sockaddr_addrdata (sa), sockaddr_addrlen (sa));
            free (sa);
            break;

        case IPSEC_ID_FQDN:
        case IPSEC_ID_USER_FQDN:
        case IPSEC_ID_KEY_ID:
            p = conf_get_str (rs, "Name");
            if (!p)
            {
                log_print ("ike_phase_1_recv_ID: "
                           "failed to get Name in Remote-ID section [%s]", rs);
                free (rid);
                return -1;
            }

            memcpy (rid, p, sz);
            break;

        default:
            log_print ("ike_phase_1_recv_ID: unsupported ID type %d", id_type);
            free (rid);
            return -1;
        }

        /* Compare expected/desired and received remote ID */
        if (bcmp (rid, payload->p + ISAKMP_ID_DATA_OFF, sz))
        {
            free (rid);
            log_print ("ike_phase_1_recv_ID: "
                       "received remote ID other than expected %s", p);
            return -1;
        }

        free (rid);
    }

    /* Choose the right fields to fill in */
    id = initiator ? &exchange->id_r : &exchange->id_i;
    id_len = initiator ? &exchange->id_r_len : &exchange->id_i_len;

    *id_len = GET_ISAKMP_GEN_LENGTH (payload->p) - ISAKMP_GEN_SZ;
    *id = malloc (*id_len);
    if (!*id)
    {
        log_error ("ike_phase_1_recv_ID: malloc (%lu) failed",
                   (unsigned long)*id_len);
        return -1;
    }
    memcpy (*id, payload->p + ISAKMP_GEN_SZ, *id_len);
    snprintf (header, sizeof header, "ike_phase_1_recv_ID: %s",
              constant_name (ipsec_id_cst, GET_ISAKMP_ID_TYPE (payload->p)));
    LOG_DBG_BUF ((LOG_NEGOTIATION, 40, header, payload->p + ISAKMP_ID_DATA_OFF,
                  *id_len + ISAKMP_GEN_SZ - ISAKMP_ID_DATA_OFF));
    payload->flags |= PL_MARK;

    return 0;
}
Example #3
0
int
ike_phase_1_send_ID (struct message *msg)
{
    struct exchange *exchange = msg->exchange;
    u_int8_t *buf;
    char header[80];
    ssize_t sz;
    struct sockaddr *src;
    int initiator = exchange->initiator;
    u_int8_t **id;
    size_t *id_len;
    char *my_id = 0;
    u_int8_t id_type;

    /* Choose the right fields to fill-in.  */
    id = initiator ? &exchange->id_i : &exchange->id_r;
    id_len = initiator ? &exchange->id_i_len : &exchange->id_r_len;

    if (exchange->name)
        my_id = conf_get_str (exchange->name, "ID");

    if (!my_id)
        my_id = conf_get_str ("General", "Default-phase-1-ID");

    msg->transport->vtbl->get_src (msg->transport, &src);
    sz = my_id ? ipsec_id_size (my_id, &id_type) : sockaddr_addrlen (src);
    if (sz == -1)
        return -1;

    sz += ISAKMP_ID_DATA_OFF;
    buf = malloc (sz);
    if (!buf)
    {
        log_error ("ike_phase_1_send_ID: malloc (%lu) failed",
                   (unsigned long)sz);
        return -1;
    }

    SET_IPSEC_ID_PROTO (buf + ISAKMP_ID_DOI_DATA_OFF, 0);
    SET_IPSEC_ID_PORT (buf + ISAKMP_ID_DOI_DATA_OFF, 0);
    if (my_id)
    {
        SET_ISAKMP_ID_TYPE (buf, id_type);
        switch (id_type)
        {
        case IPSEC_ID_IPV4_ADDR:
        case IPSEC_ID_IPV6_ADDR:
            /* Already in network byteorder.  */
            memcpy (buf + ISAKMP_ID_DATA_OFF, sockaddr_addrdata (src),
                    sockaddr_addrlen (src));
            break;

        case IPSEC_ID_FQDN:
        case IPSEC_ID_USER_FQDN:
        case IPSEC_ID_KEY_ID:
            memcpy (buf + ISAKMP_ID_DATA_OFF, conf_get_str (my_id, "Name"),
                    sz - ISAKMP_ID_DATA_OFF);
            break;

        default:
            log_print ("ike_phase_1_send_ID: unsupported ID type %d", id_type);
            free (buf);
            return -1;
        }
    }
    else
    {
        switch (src->sa_family)
        {
        case AF_INET:
            SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_IPV4_ADDR);
            break;
        case AF_INET6:
            SET_ISAKMP_ID_TYPE (buf, IPSEC_ID_IPV6_ADDR);
            break;
        }
        /* Already in network byteorder.  */
        memcpy (buf + ISAKMP_ID_DATA_OFF, sockaddr_addrdata (src),
                sockaddr_addrlen (src));
    }

    if (message_add_payload (msg, ISAKMP_PAYLOAD_ID, buf, sz, 1))
    {
        free (buf);
        return -1;
    }
    *id_len = sz - ISAKMP_GEN_SZ;
    *id = malloc (*id_len);
    if (!*id)
    {
        log_error ("ike_phase_1_send_ID: malloc (%lu) failed",
                   (unsigned long)*id_len);
        return -1;
    }
    memcpy (*id, buf + ISAKMP_GEN_SZ, *id_len);
    snprintf (header, sizeof header, "ike_phase_1_send_ID: %s",
              constant_name (ipsec_id_cst, GET_ISAKMP_ID_TYPE (buf)));
    LOG_DBG_BUF ((LOG_NEGOTIATION, 40, header, buf + ISAKMP_ID_DATA_OFF,
                  sz - ISAKMP_ID_DATA_OFF));

    return 0;
}