📄 ipsec_doi.c
字号:
"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 + -