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

📄 spdb_struct.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 5 页
字号:
			break;		    }		    }		    break;		case OAKLEY_GROUP_DESCRIPTION | ISAKMP_ATTR_AF_TV:		    ta.group = lookup_group(val);		    if (ta.group == NULL)		    {			ugh = "only OAKLEY_GROUP_MODP1024 and OAKLEY_GROUP_MODP1536 supported";			break;		    }		    break;		case OAKLEY_LIFE_TYPE | ISAKMP_ATTR_AF_TV:		    switch (val)		    {		    case OAKLEY_LIFE_SECONDS:		    case OAKLEY_LIFE_KILOBYTES:			if (LHAS(seen_durations, val))			{			    loglog(RC_LOG_SERIOUS				, "attribute OAKLEY_LIFE_TYPE value %s repeated"				, enum_show(&oakley_lifetime_names, val));			    return BAD_PROPOSAL_SYNTAX;			}			seen_durations |= LELEM(val);			life_type = val;			break;		    default:			ugh = builddiag("unknown value %s"			    , enum_show(&oakley_lifetime_names, val));			break;		    }		    break;		case OAKLEY_LIFE_DURATION | ISAKMP_ATTR_AF_TLV:		    val = decode_long_duration(&attr_pbs);		    /* fall through */		case OAKLEY_LIFE_DURATION | ISAKMP_ATTR_AF_TV:		    if (!LHAS(seen_attrs, OAKLEY_LIFE_TYPE))		    {			ugh = "OAKLEY_LIFE_DURATION attribute not preceded by OAKLEY_LIFE_TYPE attribute";			break;		    }		    seen_attrs &= ~(LELEM(OAKLEY_LIFE_DURATION) | LELEM(OAKLEY_LIFE_TYPE));		    switch (life_type)		    {			case OAKLEY_LIFE_SECONDS:			    if (val > OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM)				ugh = builddiag("peer requested %lu seconds"				    " which exceeds our limit %d seconds"				    , (long) val				    , OAKLEY_ISAKMP_SA_LIFETIME_MAXIMUM);			    ta.life_seconds = val;			    break;			case OAKLEY_LIFE_KILOBYTES:			    ta.life_kilobytes = val;			    break;			default:			    bad_case(life_type);		    }		    break;#ifdef IKE_ALG		case OAKLEY_KEY_LENGTH | ISAKMP_ATTR_AF_TV:		    if ((seen_attrs & LELEM(OAKLEY_ENCRYPTION_ALGORITHM)) == 0)		    {			ugh = "OAKLEY_KEY_LENGTH attribute not preceded by OAKLEY_ENCRYPTION_ALGORITHM attribute";			break;		    }		    if (ta.encrypter == NULL)		    {			ugh = "NULL encrypter with seen OAKLEY_ENCRYPTION_ALGORITHM";		        break;		    }		    /*		     * check if this keylen is compatible with 		     * specified alg_info_ike		     */		    if (!ike_alg_enc_ok(ta.encrypt, val, c->alg_info_ike, &ugh)) {			ugh = "peer proposed key_len not valid for encrypt algo setup specified";		    }		    ta.enckeylen=val;		    break;#else		case OAKLEY_KEY_LENGTH | ISAKMP_ATTR_AF_TV:#endif#if 0 /* not yet supported */		case OAKLEY_GROUP_TYPE | ISAKMP_ATTR_AF_TV:		case OAKLEY_PRF | ISAKMP_ATTR_AF_TV:		case OAKLEY_FIELD_SIZE | ISAKMP_ATTR_AF_TV:		case OAKLEY_GROUP_PRIME | ISAKMP_ATTR_AF_TV:		case OAKLEY_GROUP_PRIME | ISAKMP_ATTR_AF_TLV:		case OAKLEY_GROUP_GENERATOR_ONE | ISAKMP_ATTR_AF_TV:		case OAKLEY_GROUP_GENERATOR_ONE | ISAKMP_ATTR_AF_TLV:		case OAKLEY_GROUP_GENERATOR_TWO | ISAKMP_ATTR_AF_TV:		case OAKLEY_GROUP_GENERATOR_TWO | ISAKMP_ATTR_AF_TLV:		case OAKLEY_GROUP_CURVE_A | ISAKMP_ATTR_AF_TV:		case OAKLEY_GROUP_CURVE_A | ISAKMP_ATTR_AF_TLV:		case OAKLEY_GROUP_CURVE_B | ISAKMP_ATTR_AF_TV:		case OAKLEY_GROUP_CURVE_B | ISAKMP_ATTR_AF_TLV:		case OAKLEY_GROUP_ORDER | ISAKMP_ATTR_AF_TV:		case OAKLEY_GROUP_ORDER | ISAKMP_ATTR_AF_TLV:#endif		default:		    ugh = "unsupported OAKLEY attribute";		    break;	    }	    if (ugh != NULL)	    {		loglog(RC_LOG_SERIOUS, "%s.  Attribute %s"		    , ugh, enum_show(&oakley_attr_names, a.isaat_af_type));		break;	    }	}#ifdef IKE_ALG	/* 	 * ML: at last check for allowed transforms in alg_info_ike 	 *     (ALG_INFO_F_STRICT flag)	 */	if (ugh == NULL)	{		if (!ike_alg_ok_final(ta.encrypt, ta.enckeylen, ta.hash,			ta.group ? ta.group->group : -1, c->alg_info_ike)) {			ugh = "OAKLEY proposal refused";		}	}#endif	if (ugh == NULL)	{	    /* a little more checking is in order */	    {		lset_t missing		    = ~seen_attrs		    & (LELEM(OAKLEY_ENCRYPTION_ALGORITHM)		      | LELEM(OAKLEY_HASH_ALGORITHM)		      | LELEM(OAKLEY_AUTHENTICATION_METHOD)		      | LELEM(OAKLEY_GROUP_DESCRIPTION));		if (missing)		{		    loglog(RC_LOG_SERIOUS, "missing mandatory attribute(s) %s in Oakley Transform %u"			, bitnamesof(oakley_attr_bit_names, missing)			, trans.isat_transnum);		    return BAD_PROPOSAL_SYNTAX;		}	    }	    /* We must have liked this transform.	     * Lets finish early and leave.	     */	    DBG(DBG_PARSING | DBG_CRYPT		, DBG_log("Oakley Transform %u accepted", trans.isat_transnum));	    if (r_sa_pbs != NULL)	    {		struct isakmp_proposal r_proposal = proposal;		pb_stream r_proposal_pbs;		struct isakmp_transform r_trans = trans;		pb_stream r_trans_pbs;		/* Situation */		if (!out_struct(&ipsecdoisit, &ipsec_sit_desc, r_sa_pbs, NULL))		    impossible();		/* Proposal */#ifdef EMIT_ISAKMP_SPI		r_proposal.isap_spisize = COOKIE_SIZE;#else		r_proposal.isap_spisize = 0;#endif		r_proposal.isap_notrans = 1;		if (!out_struct(&r_proposal, &isakmp_proposal_desc, r_sa_pbs, &r_proposal_pbs))		    impossible();		/* SPI */#ifdef EMIT_ISAKMP_SPI		if (!out_raw(my_cookie, COOKIE_SIZE, &r_proposal_pbs, "SPI"))		    impossible();		r_proposal.isap_spisize = COOKIE_SIZE;#else		/* none (0) */#endif		/* Transform */		r_trans.isat_np = ISAKMP_NEXT_NONE;		if (!out_struct(&r_trans, &isakmp_isakmp_transform_desc, &r_proposal_pbs, &r_trans_pbs))		    impossible();		if (!out_raw(attr_start, attr_len, &r_trans_pbs, "attributes"))		    impossible();		close_output_pbs(&r_trans_pbs);		close_output_pbs(&r_proposal_pbs);		close_output_pbs(r_sa_pbs);	    }	    /* ??? If selection, we used to save the proposal in state.	     * We never used it.  From proposal_pbs.start,	     * length pbs_room(&proposal_pbs)	     */	    /* copy over the results */	    st->st_oakley = ta;	    return NOTHING_WRONG;	}	/* on to next transform */	no_trans_left--;	if (trans.isat_np == ISAKMP_NEXT_NONE)	{	    if (no_trans_left != 0)	    {		loglog(RC_LOG_SERIOUS, "number of Transform Payloads disagrees with Oakley Proposal Payload");		return BAD_PROPOSAL_SYNTAX;	    }	    break;	}	if (trans.isat_np != ISAKMP_NEXT_T)	{	    loglog(RC_LOG_SERIOUS, "unexpected %s payload in Oakley Proposal"		, enum_show(&payload_names, proposal.isap_np));	    return BAD_PROPOSAL_SYNTAX;	}    }    loglog(RC_LOG_SERIOUS, "no acceptable Oakley Transform");    return NO_PROPOSAL_CHOSEN;}#if defined(AGGRESSIVE)/* Initialize st_oakley field of state for use when initiating in * aggressive mode. * * This should probably get more of its parameters, like what group to use, * from the connection specification, but it's not there yet. * This should ideally be done by passing them via whack. *  *//* XXX MCR. I suspect that actually all of this is redundent */boolinit_am_st_oakley(struct state *st, lset_t policy){    struct oakley_trans_attrs ta;    struct db_attr  *enc, *hash, *auth, *grp;    struct db_trans *trans;    struct db_prop  *prop;    struct db_prop_conj *cprop;    struct db_sa    *sa;    struct db_sa    *revised_sadb;    struct connection *c = st->st_connection;    unsigned int policy_index = POLICY_ISAKMP(policy					      , c->spd.this.xauth_server					      , c->spd.this.xauth_client);    memset(&ta, 0, sizeof(ta));    /* When this SA expires (seconds) */    ta.life_seconds = st->st_connection->sa_ike_life_seconds;    ta.life_kilobytes = 1000000;    passert(policy_index < elemsof(oakley_am_sadb));    sa = &oakley_am_sadb[policy_index];        revised_sadb=oakley_alg_makedb(st->st_connection->alg_info_ike				   , sa, 1);        if(revised_sadb == NULL) {	return FALSE;    }    passert(revised_sadb->prop_conj_cnt == 1);    cprop = &revised_sadb->prop_conjs[0];    passert(cprop->prop_cnt == 1);    prop = &cprop->props[0];    passert(prop->trans_cnt == 1);    trans = &prop->trans[0];    passert(trans->attr_cnt == 4);    enc  = &trans->attrs[0];    hash = &trans->attrs[1];    auth = &trans->attrs[2];    grp  = &trans->attrs[3];    DBG(DBG_CONTROL	, DBG_log("initiating aggressive mode with IKE=E=%d-H=%d-M=%d"		  , enc->val		  , hash->val		  , grp->val));    passert(enc->type == OAKLEY_ENCRYPTION_ALGORITHM);    ta.encrypt = enc->val;             /* OAKLEY_ENCRYPTION_ALGORITHM */    ta.encrypter = crypto_get_encrypter(ta.encrypt);    passert(ta.encrypter != NULL);    ta.enckeylen = ta.encrypter->keydeflen;    passert(hash->type == OAKLEY_HASH_ALGORITHM);    ta.hash = hash->val;               /* OAKLEY_HASH_ALGORITHM */    ta.hasher = crypto_get_hasher(ta.hash);    passert(ta.hasher != NULL);    passert(auth->type == OAKLEY_AUTHENTICATION_METHOD);    ta.auth   = auth->val;             /* OAKLEY_AUTHENTICATION_METHOD */    passert(grp->type == OAKLEY_GROUP_DESCRIPTION);    ta.group = lookup_group(grp->val); /* OAKLEY_GROUP_DESCRIPTION */    passert(ta.group != NULL);    st->st_oakley = ta;    return TRUE;}#endif/** * Parse the body of an IPsec SA Payload (i.e. Phase 2 / Quick Mode). * * The main routine is parse_ipsec_sa_body; other functions defined * between here and there are just helpers. * * Various shortcuts are taken.  In particular, the policy, such as * it is, is hardwired. * * If r_sa is non-NULL, the body of an SA representing the selected * proposal is emitted into it. * * If "selection" is true, the SA is supposed to represent the * single tranform that the peer has accepted. * ??? We only check that it is acceptable, not that it is one that we offered! * * Only IPsec DOI is accepted (what is the ISAKMP DOI?). * Error response is rudimentary. * * Since all ISAKMP groups in all SA Payloads must match, st->st_pfs_group * holds this across multiple payloads. * &unset_group signifies not yet "set"; NULL signifies NONE. * * This routine is used by quick_inI1_outR1() and quick_inR1_outI2(). */static const struct ipsec_trans_attrs null_ipsec_trans_attrs = {    0,					/* transid (NULL, for now) */    0,					/* spi */    SA_LIFE_DURATION_DEFAULT,		/* life_seconds */    SA_LIFE_DURATION_K_DEFAULT,		/* life_kilobytes */    ENCAPSULATION_MODE_UNSPECIFIED,	/* encapsulation */    AUTH_ALGORITHM_NONE,		/* auth */    0,					/* key_len */    0,					/* key_rounds */};static boolparse_ipsec_transform(struct isakmp_transform *trans, struct ipsec_trans_attrs *attrs, pb_stream *prop_pbs, pb_stream *trans_pbs, struct_desc *trans_desc, int previous_transnum	/* or -1 if none */, bool selection, bool is_last, bool is_ipcomp, struct state *st)	/* current state object */{    lset_t seen_attrs = 0	, seen_durations = 0;    u_int16_t life_type;    const struct oakley_group_desc *pfs_group = NULL;    if (!in_struct(trans, trans_desc, prop_pbs, trans_pbs))	return FALSE;    if (trans->isat_transnum <= previous_transnum)    {	loglog(RC_LOG_SERIOUS, "Transform Numbers in Proposal are not monotonically increasing");	return FALSE;    }    switch (trans->isat_np)    {	case ISAKMP_NEXT_T:	    if (is_last)	    {		loglog(RC_LOG_SERIOUS, "Proposal Payload has more Transforms than specified");		return FALSE;	    }	    break;	case ISAKMP_NEXT_NONE:	    if (!is_last)	    {		loglog(RC_LOG_SERIOUS, "Proposal Payload has fewer Transforms than specified");		return FALSE;	    }	    break;	default:	    loglog(RC_LOG_SERIOUS, "expecting Transform Payload, but found %s in Proposal"		, enum_show(&payload_names, trans->isat_np));	    return FALSE;    }    *attrs = null_ipsec_trans_attrs;    attrs->transid = trans->isat_transid;    while (pbs_left(trans_pbs) != 0)    {	struct isakmp_attribute a;	pb_stream attr_pbs;	enum_names *vdesc;	u_int32_t val;	/* room for larger value */	bool ipcomp_inappropriate = is_ipcomp;	/* will get reset if OK */	if (!in_struct(&a, &isakmp_ipsec_attribute_desc, trans_pbs, &attr_pbs))	    return FALSE;	passert((a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK) < 32);	if (LHAS(seen_attrs, a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK))	{	    loglog(RC_LOG_SERIOUS, "repeated %s attribute in IPsec Transform %u"		, enum_show(&ipsec_attr_names, a.isaat_af_type)		, trans->isat_transnum);	    return FALSE;	}	seen_attrs |= LELEM(a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK);	val = a.isaat_lv;	vdesc  = ipsec_attr_val_descs[a.isaat_af_type & ISAKMP_ATTR_RTYPE_MASK];	if (vdesc != NULL)	{	    if (enum_name(vdesc, val) == NULL)	    {		loglog(RC_LOG_SERIOUS, "invalid value %u for attribute %s in IPsec Transform"		    , (unsigned)val, enum_show(&ipsec_attr_names, a.isaat_af_type));		return FALSE;	    }	    DBG(DBG_PARSING		, if ((a.isaat_af_type & ISAKMP_ATTR_AF_MASK) == ISAKMP_ATTR_AF_TV)		    DBG_log("   [%u is %s]"			, (unsigned)val, enum_show(vdesc, val)));	}	switch (a.isaat_af_type)	{	    case SA_LIFE_TYPE | ISAKMP_ATTR_AF_TV:		ipcomp_inappropriate = FALSE;		if (LHAS(seen_durations, val))		{		    loglog(RC_LOG_SERIOUS, "attribute SA_LIFE_TYPE value %s repeated in message"

⌨️ 快捷键说明

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