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

📄 ipsec_doi.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 5 页
字号:
			    "already replacing IPSEC State #%lu in %d seconds"			    , dst->st_serialno, (int)(dst->st_event->ev_time - now()));		    }		    else		    {			loglog(RC_LOG_SERIOUS, "received Delete SA payload: "			    "replace IPSEC State #%lu in %d seconds"			    , dst->st_serialno, DELETE_SA_DELAY);			dst->st_margin = DELETE_SA_DELAY;			delete_event(dst);			event_schedule(EVENT_SA_REPLACE, DELETE_SA_DELAY, dst);		    }		}		else		{		    loglog(RC_LOG_SERIOUS, "received Delete SA(0x%08lx) payload: "			   "deleting IPSEC State #%lu"			   , (unsigned long)ntohl((unsigned long)*(ipsec_spi_t *)spi)			   , dst->st_serialno);		    delete_state(dst);		}		/* reset connection */		set_cur_connection(oldc);	    }	}    }}/** The whole message must be a multiple of 4 octets. * I'm not sure where this is spelled out, but look at * rfc2408 3.6 Transform Payload. * Note: it talks about 4 BYTE boundaries! * * @param pbs PB Stream */voidclose_message(pb_stream *pbs){    size_t padding =  pad_up(pbs_offset(pbs), 4);    if (padding != 0)	(void) out_zero(padding, pbs, "message padding");    close_output_pbs(pbs);}/* Initiate an Oakley Main Mode exchange. * --> HDR;SA * Note: this is not called from demux.c */static stf_statusmain_outI1(int whack_sock	   , struct connection *c	   , struct state *predecessor	   , lset_t policy	   , unsigned long try	   , enum crypto_importance importance){    struct state *st = new_state();    pb_stream reply;	/* not actually a reply, but you know what I mean */    pb_stream rbody;    /* set up new state */    st->st_connection = c;    set_cur_state(st);	/* we must reset before exit */    st->st_policy = policy & ~POLICY_IPSEC_MASK;    st->st_whack_sock = whack_sock;    st->st_try = try;    st->st_state = STATE_MAIN_I1;    st->st_import = importance;     get_cookie(TRUE, st->st_icookie, COOKIE_SIZE, &c->spd.that.host_addr);    insert_state(st);	/* needs cookies, connection, and msgid (0) */    if (HAS_IPSEC_POLICY(policy))	add_pending(dup_any(whack_sock), st, c, policy, 1	    , predecessor == NULL? SOS_NOBODY : predecessor->st_serialno);    if (predecessor == NULL)	openswan_log("initiating Main Mode");    else	openswan_log("initiating Main Mode to replace #%lu", predecessor->st_serialno);    /* set up reply */    init_pbs(&reply, reply_buffer, sizeof(reply_buffer), "reply packet");    /* HDR out */    {	struct isakmp_hdr hdr;	zero(&hdr);	/* default to 0 */	hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;	hdr.isa_np = ISAKMP_NEXT_SA;	hdr.isa_xchg = ISAKMP_XCHG_IDPROT;	memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);	/* R-cookie, flags and MessageID are left zero */	if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))	{	    reset_cur_state();	    return STF_INTERNAL_ERROR;	}    }    /* SA out */    {	u_char *sa_start = rbody.cur;	int    policy_index = POLICY_ISAKMP(policy					    , c->spd.this.xauth_server					    , c->spd.this.xauth_client);	/* if we  have an OpenPGP certificate we assume an	 * OpenPGP peer and have to send the Vendor ID	 */	int np = (SEND_PLUTO_VID || c->spd.this.cert.type == CERT_PGP) ?	    ISAKMP_NEXT_VID : ISAKMP_NEXT_NONE;	if (!out_sa(&rbody		    , &oakley_sadb[policy_index], st, TRUE, FALSE, np))	{	    openswan_log("outsa fail");	    reset_cur_state();	    return STF_INTERNAL_ERROR;	}	/* save initiator SA for later HASH */	passert(st->st_p1isa.ptr == NULL);	/* no leak!  (MUST be first time) */	clonetochunk(st->st_p1isa, sa_start, rbody.cur - sa_start	    , "sa in main_outI1");    }    if (SEND_PLUTO_VID || c->spd.this.cert.type == CERT_PGP)    {	char *vendorid = (c->spd.this.cert.type == CERT_PGP) ?	    pgp_vendorid : pluto_vendorid;	if (!out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_vendor_id_desc, &rbody	, vendorid, strlen(vendorid), "Vendor ID"))	    return STF_INTERNAL_ERROR;    }    /* ALWAYS Announce our ability to do Dead Peer Detection to the peer */    if (!out_modify_previous_np(ISAKMP_NEXT_VID, &rbody))        return STF_INTERNAL_ERROR;    if( !out_generic_raw(ISAKMP_NEXT_NONE, &isakmp_vendor_id_desc,                &rbody, dpd_vendorid, sizeof(dpd_vendorid), "V_ID"))        return STF_INTERNAL_ERROR;#ifdef NAT_TRAVERSAL    if (nat_traversal_enabled) {	/* Add supported NAT-Traversal VID */	if (!nat_traversal_add_vid(ISAKMP_NEXT_NONE, &rbody)) {	    reset_cur_state();	    return STF_INTERNAL_ERROR;	}    }#endif#ifdef XAUTH    if(c->spd.this.xauth_client || c->spd.this.xauth_server)    {	if(!out_vendorid(ISAKMP_NEXT_NONE, &rbody, VID_MISC_XAUTH))	{	    return STF_INTERNAL_ERROR;	}    }#endif	    close_message(&rbody);    close_output_pbs(&reply);    clonetochunk(st->st_tpacket, reply.start, pbs_offset(&reply)	, "reply packet for main_outI1");    /* Transmit */    send_packet(st, "main_outI1");    /* Set up a retransmission event, half a minute henceforth */    delete_event(st);    event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);    if (predecessor != NULL)    {	update_pending(predecessor, st);	whack_log(RC_NEW_STATE + STATE_MAIN_I1	    , "%s: initiate, replacing #%lu"	    , enum_name(&state_names, st->st_state)	    , predecessor->st_serialno);    }    else    {	whack_log(RC_NEW_STATE + STATE_MAIN_I1	    , "%s: initiate", enum_name(&state_names, st->st_state));    }    reset_cur_state();    return STF_OK;}/* * Initiate an Oakley Aggressive Mode exchange. * --> HDR, SA, KE, Ni, IDii */static stf_statusaggr_outI1_tail(struct pluto_crypto_req_cont *pcrc		, struct pluto_crypto_req *r);static voidaggr_outI1_continue(struct pluto_crypto_req_cont *pcrc		    , struct pluto_crypto_req *r		    , err_t ugh){  struct ke_continuation *ke = (struct ke_continuation *)pcrc;  struct msg_digest *md = ke->md;  struct state *const st = md->st;  stf_status e;    DBG(DBG_CONTROLMORE      , DBG_log("aggr outI1: calculated ke+nonce, sending I1"));    /* XXX should check out ugh */  passert(ugh == NULL);  passert(cur_state == NULL);  passert(st != NULL);  passert(st->st_suspended_md == ke->md);  st->st_suspended_md = NULL;	/* no longer connected or suspended */  set_cur_state(st);  e = aggr_outI1_tail(pcrc, r);    if(ke->md != NULL) {      complete_state_transition(&ke->md, e);      release_md(ke->md);  }  reset_globals();  passert(GLOBALS_ARE_RESET());}static stf_statusaggr_outI1(int whack_sock,	   struct connection *c,	   struct state *predecessor,	   lset_t policy,	   unsigned long try	   , enum crypto_importance importance){    struct state *st;    /* set up new state */    cur_state = st = new_state();    st->st_connection = c;#ifdef DEBUG    extra_debugging(c);#endif    st->st_policy = policy & ~POLICY_IPSEC_MASK;    st->st_whack_sock = whack_sock;    st->st_try = try;    st->st_state = STATE_AGGR_I1;    get_cookie(TRUE, st->st_icookie, COOKIE_SIZE, &c->spd.that.host_addr);    insert_state(st);	/* needs cookies, connection, and msgid (0) */    if(init_am_st_oakley(st, policy) == FALSE) {	loglog(RC_AGGRALGO, "can not initiate aggressive mode, at most one algorithm may be provided");	reset_globals();	return STF_FAIL;    }    if (HAS_IPSEC_POLICY(policy))	add_pending(dup_any(whack_sock), st, c, policy, 1	    , predecessor == NULL? SOS_NOBODY : predecessor->st_serialno);    if (predecessor == NULL) {	openswan_log("initiating Aggressive Mode #%lu, connection \"%s\""		     , st->st_serialno, st->st_connection->name);    }    else {	openswan_log("initiating Aggressive Mode #%lu to replace #%lu, connection \"%s\""		     , st->st_serialno, predecessor->st_serialno		     , st->st_connection->name);    }    {	struct ke_continuation *ke = alloc_thing(struct ke_continuation						 , "outI2 KE");	stf_status e;	ke->md = alloc_md();	ke->md->st = st;	st->st_suspended_md = ke->md;	if (!st->st_sec_in_use) {	    ke->ke_pcrc.pcrc_func = aggr_outI1_continue;	    e = build_ke(&ke->ke_pcrc, st, st->st_oakley.group, importance);	    if(e != STF_SUSPEND) {	      loglog(RC_CRYPTOFAILED, "system too busy");	      delete_state(st);	    }	} else {	    e = aggr_outI1_tail((struct pluto_crypto_req_cont *)ke					, NULL);	}		reset_globals();	return e;    }}static stf_statusaggr_outI1_tail(struct pluto_crypto_req_cont *pcrc		, struct pluto_crypto_req *r){    struct ke_continuation *ke = (struct ke_continuation *)pcrc;    struct msg_digest *md = ke->md;    struct state *const st = md->st;    struct connection *c = st->st_connection;    u_char space[8192];	/* NOTE: we assume 8192 is big enough to build the packet */    pb_stream reply;	/* not actually a reply, but you know what I mean */    pb_stream rbody;    /* set up reply */    init_pbs(&reply, space, sizeof(space), "reply packet");    /* HDR out */    {	struct isakmp_hdr hdr;	memset(&hdr, '\0', sizeof(hdr));	/* default to 0 */	hdr.isa_version = ISAKMP_MAJOR_VERSION << ISA_MAJ_SHIFT | ISAKMP_MINOR_VERSION;	hdr.isa_np = ISAKMP_NEXT_SA;	hdr.isa_xchg = ISAKMP_XCHG_AGGR;	memcpy(hdr.isa_icookie, st->st_icookie, COOKIE_SIZE);	/* R-cookie, flags and MessageID are left zero */	if (!out_struct(&hdr, &isakmp_hdr_desc, &reply, &rbody))	{	    cur_state = NULL;	    return STF_INTERNAL_ERROR;	}    }    /* SA out */    {	u_char *sa_start = rbody.cur;	int    policy_index = POLICY_ISAKMP(st->st_policy					    , c->spd.this.xauth_server					    , c->spd.this.xauth_client);		if (!out_sa(&rbody		    , &oakley_am_sadb[policy_index], st		    , TRUE, TRUE, ISAKMP_NEXT_KE))	{	    return STF_INTERNAL_ERROR;	    cur_state = NULL;	}	/* save initiator SA for later HASH */	passert(st->st_p1isa.ptr == NULL);	/* no leak! */	clonetochunk(st->st_p1isa, sa_start, rbody.cur - sa_start,		     "sa in aggr_outI1");    }    /* KE out */    if (!ship_KE(st, r, &st->st_gi, 			   &rbody, ISAKMP_NEXT_NONCE))	return STF_INTERNAL_ERROR;    /* Ni out */    if (!ship_nonce(&st->st_ni, r, &rbody, ISAKMP_NEXT_ID, "Ni"))	return STF_INTERNAL_ERROR;    /* IDii out */    {	struct isakmp_ipsec_id id_hd;	chunk_t id_b;	pb_stream id_pbs;	build_id_payload(&id_hd, &id_b, &st->st_connection->spd.this);	id_hd.isaiid_np = ISAKMP_NEXT_VID;	if (!out_struct(&id_hd, &isakmp_ipsec_identification_desc, &rbody, &id_pbs)	|| !out_chunk(id_b, &id_pbs, "my identity"))	    return STF_INTERNAL_ERROR;	close_output_pbs(&id_pbs);    }    /* ALWAYS Announce our ability to do Dead Peer Detection to the peer */    {      int np = ISAKMP_NEXT_NONE;	      if (nat_traversal_enabled	  || c->spd.this.xauth_client	  || c->spd.this.xauth_server) {		/* Add supported NAT-Traversal VID */	np = ISAKMP_NEXT_VID;      }      if( !out_generic_raw(np, &isakmp_vendor_id_desc,			   &rbody, dpd_vendorid, sizeof(dpd_vendorid), "V_ID"))        return STF_INTERNAL_ERROR;    }#ifdef NAT_TRAVERSAL    if (nat_traversal_enabled) {	/* Add supported NAT-Traversal VID */	int np = ISAKMP_NEXT_NONE;#ifdef XAUTH	if(c->spd.this.xauth_client || c->spd.this.xauth_server) {	    np = ISAKMP_NEXT_VID;	}#endif		if (!nat_traversal_add_vid(np, &rbody)) {	    reset_cur_state();	    return STF_INTERNAL_ERROR;	}    }#endif#ifdef XAUTH    if(c->spd.this.xauth_client || c->spd.this.xauth_server)    {	if(!out_vendorid(ISAKMP_NEXT_NONE, &rbody, VID_MISC_XAUTH))	{	    return STF_INTERNAL_ERROR;	}    }#endif	    /* finish message */    close_message(&rbody);    close_output_pbs(&reply);    clonetochunk(st->st_tpacket, reply.start, pbs_offset(&reply),		 "reply packet from aggr_outI1");    /* Transmit */    DBG_cond_dump(DBG_RAW, "sending:\n",		  st->st_tpacket.ptr, st->st_tpacket.len);    send_packet(st, "aggr_outI1");    /* Set up a retransmission event, half a minute henceforth */    delete_event(st);    event_schedule(EVENT_RETRANSMIT, EVENT_RETRANSMIT_DELAY_0, st);    whack_log(RC_NEW_STATE + STATE_AGGR_I1,	      "%s: initiate", enum_name(&state_names, st->st_state));    cur_state = NULL;    return STF_IGNORE;}voidipsecdoi_initiate(int whack_sock		  , struct connection *c		  , lset_t policy		  , unsigned long try		  , so_serial_t replacing		  , enum crypto_importance importance){

⌨️ 快捷键说明

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