⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spdb_struct.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 5 页
字号:
		    loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous AH Proposals");		    return BAD_PROPOSAL_SYNTAX;		}		ah_seen = TRUE;		ah_prop_pbs = next_proposal_pbs;		ah_proposal = next_proposal;		ah_spi = next_spi;		break;	    case PROTO_IPSEC_ESP:		if (esp_seen)		{		    loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous ESP Proposals");		    return BAD_PROPOSAL_SYNTAX;		}		esp_seen = TRUE;		esp_prop_pbs = next_proposal_pbs;		esp_proposal = next_proposal;		esp_spi = next_spi;		break;	    case PROTO_IPCOMP:		if (ipcomp_seen)		{		    loglog(RC_LOG_SERIOUS, "IPsec SA contains two simultaneous IPCOMP Proposals");		    return BAD_PROPOSAL_SYNTAX;		}		ipcomp_seen = TRUE;		ipcomp_prop_pbs = next_proposal_pbs;		ipcomp_proposal = next_proposal;		ipcomp_cpi = next_spi;		break;	    default:		loglog(RC_LOG_SERIOUS, "unexpected Protocol ID (%s) in IPsec Proposal"		    , enum_show(&protocol_names, next_proposal.isap_protoid));		return INVALID_PROTOCOL_ID;	    }	    /* refill next_proposal */	    if (next_proposal.isap_np == ISAKMP_NEXT_NONE)	    {		next_full = FALSE;		break;	    }	    else if (next_proposal.isap_np != ISAKMP_NEXT_P)	    {		loglog(RC_LOG_SERIOUS, "unexpected in Proposal: %s"		    , enum_show(&payload_names, next_proposal.isap_np));		return BAD_PROPOSAL_SYNTAX;	    }	    if (!in_struct(&next_proposal, &isakmp_proposal_desc, sa_pbs, &next_proposal_pbs))		return BAD_PROPOSAL_SYNTAX;	} while (next_proposal.isap_proposal == propno);	/* Now that we have all conjuncts, we should try	 * the Cartesian product of eachs tranforms!	 * At the moment, we take short-cuts on account of	 * our rudimentary hard-wired policy.	 * For now, we find an acceptable AH (if any)	 * and then an acceptable ESP.  The only interaction	 * is that the ESP acceptance can know whether there	 * was an acceptable AH and hence not require an AUTH.	 */	if (ah_seen)	{	    int previous_transnum = -1;	    int tn;	    for (tn = 0; tn != ah_proposal.isap_notrans; tn++)	    {		int ok_transid = 0;		bool ok_auth = FALSE;		if (!parse_ipsec_transform(&ah_trans		, &ah_attrs		, &ah_prop_pbs		, &ah_trans_pbs		, &isakmp_ah_transform_desc		, previous_transnum		, selection		, tn == ah_proposal.isap_notrans - 1		, FALSE		, st))		    return BAD_PROPOSAL_SYNTAX;		previous_transnum = ah_trans.isat_transnum;		/* we must understand ah_attrs.transid		 * COMBINED with ah_attrs.auth.		 * See RFC 2407 "IPsec DOI" section 4.4.3		 * The following combinations are legal,		 * but we don't implement all of them:		 * It seems as if each auth algorithm		 * only applies to one ah transid.		 * AH_MD5, AUTH_ALGORITHM_HMAC_MD5		 * AH_MD5, AUTH_ALGORITHM_KPDK (unimplemented)		 * AH_SHA, AUTH_ALGORITHM_HMAC_SHA1		 * AH_DES, AUTH_ALGORITHM_DES_MAC (unimplemented)		 */		switch (ah_attrs.auth)		{		    case AUTH_ALGORITHM_NONE:			loglog(RC_LOG_SERIOUS, "AUTH_ALGORITHM attribute missing in AH Transform");			return BAD_PROPOSAL_SYNTAX;		    case AUTH_ALGORITHM_HMAC_MD5:			ok_auth = TRUE;			/* fall through */		    case AUTH_ALGORITHM_KPDK:			ok_transid = AH_MD5;			break;		    case AUTH_ALGORITHM_HMAC_SHA1:			ok_auth = TRUE;			ok_transid = AH_SHA;			break;		    case AUTH_ALGORITHM_DES_MAC:			ok_transid = AH_DES;			break;		}		if (ah_attrs.transid != ok_transid)		{		    loglog(RC_LOG_SERIOUS, "%s attribute inappropriate in %s Transform"			, enum_name(&auth_alg_names, ah_attrs.auth)			, enum_show(&ah_transformid_names, ah_attrs.transid));		    return BAD_PROPOSAL_SYNTAX;		}		if (!ok_auth)		{		    DBG(DBG_CONTROL | DBG_CRYPT			, DBG_log("%s attribute unsupported"			    " in %s Transform from %s"			    , enum_name(&auth_alg_names, ah_attrs.auth)			    , enum_show(&ah_transformid_names, ah_attrs.transid)			    , ip_str(&c->spd.that.host_addr)));		    continue;   /* try another */		}		break;	/* we seem to be happy */	    }	    if (tn == ah_proposal.isap_notrans)		continue;	/* we didn't find a nice one */	    ah_attrs.spi = ah_spi;	    inner_proto = IPPROTO_AH;	    if (ah_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)		tunnel_mode = TRUE;	}	if (esp_seen)	{	    int previous_transnum = -1;	    int tn;	    err_t ugh;	    for (tn = 0; tn != esp_proposal.isap_notrans; tn++)	    {		if (!parse_ipsec_transform(&esp_trans		, &esp_attrs		, &esp_prop_pbs		, &esp_trans_pbs		, &isakmp_esp_transform_desc		, previous_transnum		, selection		, tn == esp_proposal.isap_notrans - 1		, FALSE		, st))		    return BAD_PROPOSAL_SYNTAX;		previous_transnum = esp_trans.isat_transnum;		ugh = "no alg";#ifdef KERNEL_ALG		if(c->alg_info_esp) {		    ugh = kernel_alg_esp_enc_ok(esp_attrs.transid, esp_attrs.key_len,						c->alg_info_esp);		}#endif		if(ugh != NULL) {		    switch (esp_attrs.transid)			{#ifdef KERNEL_ALG	/* strictly use runtime information */			case ESP_AES:			case ESP_3DES:			    break;#endif			    #ifdef SUPPORT_ESP_NULL	/* should be about as secure as AH-only */#warning "Building with ESP-Null"			case ESP_NULL:			    if (esp_attrs.auth == AUTH_ALGORITHM_NONE)				{				    loglog(RC_LOG_SERIOUS, "ESP_NULL requires auth algorithm");				    return BAD_PROPOSAL_SYNTAX;				}			    if (st->st_policy & POLICY_ENCRYPT)				{				    DBG(DBG_CONTROL | DBG_CRYPT					, DBG_log("ESP_NULL Transform Proposal from %s"						  " does not satisfy POLICY_ENCRYPT"						  , ip_str(&c->spd.that.host_addr)));				    continue;   /* try another */				}			    break;#endif			    			case ESP_DES:          /* NOT safe */			    loglog(RC_LOG_SERIOUS, "1DES was proposed, it is insecure");			default:			    loglog(RC_LOG_SERIOUS, "kernel algorithm does not like: %s", ugh);			    loglog(RC_LOG_SERIOUS, "unsupported ESP Transform %s from %s"				   , enum_show(&esp_transformid_names, esp_attrs.transid)				   , ip_str(&c->spd.that.host_addr));			    continue;   /* try another */			}		}#ifdef KERNEL_ALG		ugh = kernel_alg_esp_auth_ok(esp_attrs.auth, c->alg_info_esp);#endif		if(ugh != NULL) {		    switch (esp_attrs.auth)			{			case AUTH_ALGORITHM_NONE:			    if (!ah_seen)				{				    DBG(DBG_CONTROL | DBG_CRYPT					, DBG_log("ESP from %s must either have AUTH or be combined with AH"						  , ip_str(&c->spd.that.host_addr)));				    continue;   /* try another */				}			    break;#ifdef KERNEL_ALG	/* strictly use runtime information */			case AUTH_ALGORITHM_HMAC_MD5:			case AUTH_ALGORITHM_HMAC_SHA1:			    break;#endif			default:			    loglog(RC_LOG_SERIOUS, "unsupported ESP auth alg %s from %s"				   , enum_show(&auth_alg_names, esp_attrs.auth)				   , ip_str(&c->spd.that.host_addr));			    continue;   /* try another */			}		}		    		if (ah_seen && ah_attrs.encapsulation != esp_attrs.encapsulation)		{		    /* ??? This should be an error, but is it? */		    loglog(RC_LOG_SERIOUS			   , "AH and ESP transforms disagree about encapsulation; TUNNEL presumed");		}		break;	/* we seem to be happy */	    }	    if (tn == esp_proposal.isap_notrans)		continue;	/* we didn't find a nice one */#ifdef KERNEL_ALG	    /* 	     * ML: at last check for allowed transforms in alg_info_esp 	     *     (ALG_INFO_F_STRICT flag)	     *	     */	    if (c->alg_info_esp!=NULL		&& !kernel_alg_esp_ok_final(esp_attrs.transid, esp_attrs.key_len,					    esp_attrs.auth, c->alg_info_esp))		    continue;#endif	    esp_attrs.spi = esp_spi;	    inner_proto = IPPROTO_ESP;	    if (esp_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)		tunnel_mode = TRUE;	}	else if (st->st_policy & POLICY_ENCRYPT)	{	    DBG(DBG_CONTROL | DBG_CRYPT		, DBG_log("policy for \"%s\" requires encryption but ESP not in Proposal from %s"		    , c->name, ip_str(&c->spd.that.host_addr)));	    continue;	/* we needed encryption, but didn't find ESP */	}	else if ((st->st_policy & POLICY_AUTHENTICATE) && !ah_seen)	{	    DBG(DBG_CONTROL | DBG_CRYPT		, DBG_log("policy for \"%s\" requires authentication"		    " but none in Proposal from %s"		    , c->name, ip_str(&c->spd.that.host_addr)));	    continue;	/* we need authentication, but we found neither ESP nor AH */	}	if (ipcomp_seen)	{	    int previous_transnum = -1;	    int tn;#ifdef NEVER	/* we think IPcomp is working now */	    /**** FUDGE TO PREVENT UNREQUESTED IPCOMP:	     **** NEEDED BECAUSE OUR IPCOMP IS EXPERIMENTAL (UNSTABLE).	     ****/	    if (!(st->st_policy & POLICY_COMPRESS))	    {		plog("compression proposed by %s, but policy for \"%s\" forbids it"		    , ip_str(&c->spd.that.host_addr), c->name);		continue;	/* unwanted compression proposal */	    }#endif	    if (!can_do_IPcomp)	    {		openswan_log("compression proposed by %s, but KLIPS is not configured with IPCOMP"		    , ip_str(&c->spd.that.host_addr));		continue;	    }	    if (well_known_cpi != 0 && !ah_seen && !esp_seen)	    {		openswan_log("illegal proposal: bare IPCOMP used with well-known CPI");		return BAD_PROPOSAL_SYNTAX;	    }	    for (tn = 0; tn != ipcomp_proposal.isap_notrans; tn++)	    {		if (!parse_ipsec_transform(&ipcomp_trans		, &ipcomp_attrs		, &ipcomp_prop_pbs		, &ipcomp_trans_pbs		, &isakmp_ipcomp_transform_desc		, previous_transnum		, selection		, tn == ipcomp_proposal.isap_notrans - 1		, TRUE		, st))		    return BAD_PROPOSAL_SYNTAX;		previous_transnum = ipcomp_trans.isat_transnum;		if (well_known_cpi != 0 && ipcomp_attrs.transid != well_known_cpi)		{		    openswan_log("illegal proposal: IPCOMP well-known CPI disagrees with transform");		    return BAD_PROPOSAL_SYNTAX;		}		switch (ipcomp_attrs.transid)		{		    case IPCOMP_DEFLATE:    /* all we can handle! */			break;		    default:			DBG(DBG_CONTROL | DBG_CRYPT			    , DBG_log("unsupported IPCOMP Transform %s from %s"				, enum_show(&ipcomp_transformid_names, ipcomp_attrs.transid)				, ip_str(&c->spd.that.host_addr)));			continue;   /* try another */		}		if (ah_seen && ah_attrs.encapsulation != ipcomp_attrs.encapsulation)		{		    /* ??? This should be an error, but is it? */		    DBG(DBG_CONTROL | DBG_CRYPT			, DBG_log("AH and IPCOMP transforms disagree about encapsulation; TUNNEL presumed"));		} else if (esp_seen && esp_attrs.encapsulation != ipcomp_attrs.encapsulation)		{		    /* ??? This should be an error, but is it? */		    DBG(DBG_CONTROL | DBG_CRYPT			, DBG_log("ESP and IPCOMP transforms disagree about encapsulation; TUNNEL presumed"));		}		break;	/* we seem to be happy */	    }	    if (tn == ipcomp_proposal.isap_notrans)		continue;	/* we didn't find a nice one */	    ipcomp_attrs.spi = ipcomp_cpi;	    inner_proto = IPPROTO_COMP;	    if (ipcomp_attrs.encapsulation == ENCAPSULATION_MODE_TUNNEL)		tunnel_mode = TRUE;	}	/* Eureka: we liked what we saw -- accept it. */	if (r_sa_pbs != NULL)	{	    /* emit what we've accepted */	    /* Situation */	    if (!out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL))		impossible();	    /* AH proposal */	    if (ah_seen)		echo_proposal(ah_proposal		    , ah_trans		    , esp_seen || ipcomp_seen? ISAKMP_NEXT_P : ISAKMP_NEXT_NONE		    , r_sa_pbs		    , &st->st_ah		    , &isakmp_ah_transform_desc		    , &ah_trans_pbs		    , &st->st_connection->spd		    , tunnel_mode && inner_proto == IPPROTO_AH);	    /* ESP proposal */	    if (esp_seen)		echo_proposal(esp_proposal		    , esp_trans		    , ipcomp_seen? ISAKMP_NEXT_P : ISAKMP_NEXT_NONE		    , r_sa_pbs		    , &st->st_esp		    , &isakmp_esp_transform_desc		    , &esp_trans_pbs		    , &st->st_connection->spd		    , tunnel_mode && inner_proto == IPPROTO_ESP);	    /* IPCOMP proposal */	    if (ipcomp_seen)		echo_proposal(ipcomp_proposal		    , ipcomp_trans		    , ISAKMP_NEXT_NONE		    , r_sa_pbs		    , &st->st_ipcomp		    , &isakmp_ipcomp_transform_desc		    , &ipcomp_trans_pbs		    , &st->st_connection->spd		    , tunnel_mode && inner_proto == IPPROTO_COMP);	    close_output_pbs(r_sa_pbs);	}	/* save decoded version of winning SA in state */	st->st_ah.present = ah_seen;	if (ah_seen)	    st->st_ah.attrs = ah_attrs;	st->st_esp.present = esp_seen;	if (esp_seen)	    st->st_esp.attrs = esp_attrs;	st->st_ipcomp.present = ipcomp_seen;	if (ipcomp_seen)	    st->st_ipcomp.attrs = ipcomp_attrs;	return NOTHING_WRONG;    }    loglog(RC_LOG_SERIOUS, "no acceptable Proposal in IPsec SA");    return NO_PROPOSAL_CHOSEN;}/* * Local Variables: * c-style: pluto * c-basic-offset: 4 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -