Example #1
0
void
p2_dpd_outI1(struct state *p2st)
{
    struct state *st;
    time_t delay = p2st->st_connection->dpd_delay;
    time_t timeout = p2st->st_connection->dpd_timeout;

    /* find the related Phase 1 state */
    st = find_phase1_state(p2st->st_connection, ISAKMP_SA_ESTABLISHED_STATES);

    if (st == NULL)
    {
        loglog(RC_LOG_SERIOUS, "DPD Error: could not find newest phase 1 state");
        return;
    }

    dpd_outI(st, p2st, TRUE, delay, timeout);
}
Example #2
0
/** Lookup information about the hostpair, and set things like bandwidth
 * relative crypto strength, compression and credentials.
 * 
 * @param IPsec Policy Query
 * @return void
 */
static void
info_lookuphostpair(struct ipsec_policy_cmd_query *ipcq)
{
    struct connection *c;
    struct state *p1st, *p2st;


    /* default result: no crypto */
    ipcq->strength  = IPSEC_PRIVACY_NONE;
    ipcq->bandwidth = IPSEC_QOS_WIRESPEED;
    ipcq->credential_count = 0;

#ifdef DEBUG
    {
	char sstr[ADDRTOT_BUF], dstr[ADDRTOT_BUF];

	addrtot(&ipcq->query_local,  0, sstr, sizeof(sstr));
	addrtot(&ipcq->query_remote, 0, dstr, sizeof(dstr));
	DBG_log("info request for %s -> %s", sstr, dstr);
    }
#endif

    /* okay, look up what connection handles this ip pair */

    c = find_connection_for_clients(NULL,
				    &ipcq->query_local,
				    &ipcq->query_remote,
				    ipcq->proto);
    if (c == NULL)
    {
	/* try reversing it */
	c = find_connection_for_clients(NULL,
					&ipcq->query_remote,
					&ipcq->query_local,
					ipcq->proto);
	if (c != NULL)
	{
	    ip_address tmp;
	    /* If it is reversed, swap it */
	    tmp = ipcq->query_local;
	    ipcq->query_local = ipcq->query_remote;
	    ipcq->query_remote = tmp;
	}
    }
    
    if (c == NULL)
    {
#ifdef DEBUG
	DBG_log("no connection found");
#endif
	return;	/* no crypto */
    }

    if (c->newest_ipsec_sa == SOS_NOBODY)
    {
	ip_subnet us, them;

	DBG_log("connection %s found, no ipsec state, looking again", c->name);
	addrtosubnet(&ipcq->query_local, &us);
	addrtosubnet(&ipcq->query_remote, &them);
	c = find_client_connection(c, &us, &them, 0, 0, 0, 0);

	if (c == NULL)
	    return;	/* no crypto */
    }

    DBG_log("connection %s[%ld] with state %u"
	, c->name, c->instance_serial
	, (unsigned int)c->newest_ipsec_sa);

    if (c->newest_ipsec_sa == SOS_NOBODY)
	return;	/* no crypto */

    /* we found a connection, try to lookup the state */
    p2st = state_with_serialno(c->newest_ipsec_sa);

    p1st = find_phase1_state(c, ISAKMP_SA_ESTABLISHED_STATES);

    if (p1st == NULL || p2st == NULL)
    {
	DBG_log("connection %s[%ld] has missing states %s %s"
	    , c->name, c->instance_serial
	    , (p1st ? "phase1" : "")
	    , (p2st ? "phase1" : ""));
	return;	/* no crypto */
    }

    /* if we have AH present, then record minimal info */
    if (p2st->st_ah.present)
    {
	ipcq->strength = IPSEC_PRIVACY_INTEGRAL;
	ipcq->auth_detail = p2st->st_esp.attrs.transattrs.integ_hash;
    }

    if (p2st->st_esp.present)
    {
	/*
	 * XXX-mcr Please do not shout at me about relative strengths
	 *         here. I'm not a cryptographer. I just diddle bits.
	 */
	switch (p2st->st_esp.attrs.transattrs.encrypt)
	{
	case ESP_NULL:
	    /* actually, do not change it if we set it from AH */
	    break;

	case ESP_DES:
	case ESP_DES_IV64:
	case ESP_DES_IV32:
	case ESP_RC4:
	    ipcq->strength = IPSEC_PRIVACY_ROT13;
	    break;
	    
	case ESP_RC5:
	case ESP_IDEA:
	case ESP_CAST:
	case ESP_BLOWFISH:
	case ESP_3DES:
	    ipcq->strength = IPSEC_PRIVACY_PRIVATE;
	    ipcq->bandwidth = IPSEC_QOS_VOIP;
	    break;

	case ESP_3IDEA:
	    ipcq->strength = IPSEC_PRIVACY_STRONG;
	    ipcq->bandwidth = IPSEC_QOS_INTERACTIVE;
	    break;

	case ESP_AES:
	    ipcq->strength = IPSEC_PRIVACY_STRONG;
	    ipcq->bandwidth = IPSEC_QOS_FTP;
	    break;
	}
	ipcq->esp_detail = p2st->st_esp.attrs.transattrs.encrypt;
    }

    if (p2st->st_ipcomp.present)
	ipcq->comp_detail = p2st->st_esp.attrs.transattrs.encrypt;

    /* now! the credentails that were used */
    /* for the moment we only have 1 credential, the DNS name,
     * because the DNS servers do not return the chain of SIGs yet
     */

    if(!c->spd.this.key_from_DNS_on_demand)
    {
	/* the key didn't come from the DNS in some way,
	 * so it must have been loaded locally.
	 */
	ipcq->credential_count = 1;
	ipcq->credentials[0].ii_type   = c->spd.this.id.kind;
	ipcq->credentials[0].ii_format = CERT_RAW_RSA;
    }
	
#if 0
    switch (c->spd.id.kind)
    {
    case ID_IPV4_ADDR:
    }
    if (c->gw_info == NULL)
    {
	plog("rcv_info: connection %s had NULL gw_info.", c->name);
	return
    }
#endif

    ipcq->credential_count = 1;

    /* pull credentials out of gw_info */
    
    switch (p1st->st_peer_pubkey->dns_auth_level)
    {
    case DAL_UNSIGNED:
    case DAL_NOTSEC:
	/* these seem to be the same for this purpose */
	ipcq->credentials[0].ii_type   = p1st->st_peer_pubkey->id.kind;
	ipcq->credentials[0].ii_type   = CERT_NONE;
	idtoa(&p1st->st_peer_pubkey->id
	    , ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn
	    , sizeof(ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn));
	break;
	
    case DAL_SIGNED:
	ipcq->credentials[0].ii_type   = p1st->st_peer_pubkey->id.kind;
	ipcq->credentials[0].ii_format = CERT_DNS_SIGNED_KEY;
	idtoa(&p1st->st_peer_pubkey->id
	    , ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn
	    , sizeof(ipcq->credentials[0].ii_credential.ipsec_dns_signed.fqdn));

	if (p1st->st_peer_pubkey->dns_sig != NULL)
	{
	    strncat(ipcq->credentials[0].ii_credential.ipsec_dns_signed.dns_sig
		, p1st->st_peer_pubkey->dns_sig
		, sizeof(ipcq->credentials[0].ii_credential.ipsec_dns_signed.dns_sig) - strlen(ipcq->credentials[0].ii_credential.ipsec_dns_signed.dns_sig -1));
	}
	break;

    case DAL_LOCAL:
	ipcq->credentials[0].ii_type   = p1st->st_peer_pubkey->id.kind;
	ipcq->credentials[0].ii_format = CERT_RAW_RSA;
	idtoa(&p1st->st_peer_pubkey->id
	    , ipcq->credentials[0].ii_credential.ipsec_raw_key.id_name
	    , sizeof(ipcq->credentials[0].ii_credential.ipsec_raw_key.id_name));
	break;
    }
}
Example #3
0
		       so_serial_t replacing,
		       enum crypto_importance importance
#ifdef HAVE_LABELED_IPSEC
		       , struct xfrm_user_sec_ctx_ike *uctx
#endif
		       )
{
	/* If there's already an ISAKMP SA established, use that and
	 * go directly to Quick Mode.  We are even willing to use one
	 * that is still being negotiated, but only if we are the Initiator
	 * (thus we can be sure that the IDs are not going to change;
	 * other issues around intent might matter).
	 * Note: there is no way to initiate with a Road Warrior.
	 */
	struct state *st = find_phase1_state(c,
					     ISAKMP_SA_ESTABLISHED_STATES |
					     PHASE1_INITIATOR_STATES);

	if (st == NULL) {
		initiator_function *initiator = pick_initiator(c, policy);

		if (initiator != NULL) {
			(void) initiator(whack_sock, c, NULL, policy, try, importance
#ifdef HAVE_LABELED_IPSEC
					 , uctx
#endif
					 );
		} else {
			/* fizzle: whack_sock will be unused */
			close_any(whack_sock);
		}