📄 demux.c
字号:
cur_from_port = md->sender_port;#ifdef NAT_TRAVERSAL if (ifp->ike_float == TRUE) { u_int32_t non_esp; if (packet_len < (int)sizeof(u_int32_t)) { openswan_log("recvfrom %s:%u too small packet (%d)" , ip_str(cur_from), (unsigned) cur_from_port, packet_len); return FALSE; } memcpy(&non_esp, _buffer, sizeof(u_int32_t)); if (non_esp != 0) { openswan_log("recvfrom %s:%u has no Non-ESP marker" , ip_str(cur_from), (unsigned) cur_from_port); return FALSE; } _buffer += sizeof(u_int32_t); packet_len -= sizeof(u_int32_t); }#endif /* Clone actual message contents * and set up md->packet_pbs to describe it. */ init_pbs(&md->packet_pbs#ifdef NAT_TRAVERSAL , clone_bytes(_buffer, packet_len, "message buffer in comm_handle()")#else , clone_bytes(bigbuffer, packet_len, "message buffer in comm_handle()")#endif , packet_len, "packet"); DBG(DBG_RAW | DBG_CRYPT | DBG_PARSING | DBG_CONTROL, { DBG_log(BLANK_FORMAT); DBG_log("*received %d bytes from %s:%u on %s" , (int) pbs_room(&md->packet_pbs) , ip_str(cur_from), (unsigned) cur_from_port , ifp->rname); }); DBG(DBG_RAW, DBG_dump("", md->packet_pbs.start, pbs_room(&md->packet_pbs)));#ifdef NAT_TRAVERSAL if ((pbs_room(&md->packet_pbs)==1) && (md->packet_pbs.start[0]==0xff)) { /** * NAT-T Keep-alive packets should be discared by kernel ESPinUDP * layer. But boggus keep-alive packets (sent with a non-esp marker) * can reach this point. Complain and discard them. */ DBG(DBG_NATT, DBG_log("NAT-T keep-alive (boggus ?) should not reach this point. " "Ignored. Sender: %s:%u", ip_str(cur_from), (unsigned) cur_from_port); ); return FALSE; }#endif return TRUE;}/* process an input packet, possibly generating a reply. * * If all goes well, this routine eventually calls a state-specific * transition function. */static voidprocess_packet(struct msg_digest **mdp){ struct msg_digest *md = *mdp; const struct state_microcode *smc; bool new_iv_set = FALSE; struct state *st = NULL; enum state_kind from_state = STATE_UNDEFINED; /* state we started in */#define SEND_NOTIFICATION(t) { \ if (st) send_notification_from_state(st, from_state, t); \ else send_notification_from_md(md, t); } if (!in_struct(&md->hdr, &isakmp_hdr_desc, &md->packet_pbs, &md->message_pbs)) { /* Identify specific failures: * - bad ISAKMP major/minor version numbers */ if (md->packet_pbs.roof - md->packet_pbs.cur >= (ptrdiff_t)isakmp_hdr_desc.size) { struct isakmp_hdr *hdr = (struct isakmp_hdr *)md->packet_pbs.cur; if ((hdr->isa_version >> ISA_MAJ_SHIFT) != ISAKMP_MAJOR_VERSION) { SEND_NOTIFICATION(INVALID_MAJOR_VERSION); return; } else if ((hdr->isa_version & ISA_MIN_MASK) != ISAKMP_MINOR_VERSION) { SEND_NOTIFICATION(INVALID_MINOR_VERSION); return; } } SEND_NOTIFICATION(PAYLOAD_MALFORMED); return; } if (md->packet_pbs.roof != md->message_pbs.roof) { openswan_log("size (%u) differs from size specified in ISAKMP HDR (%u)" , (unsigned) pbs_room(&md->packet_pbs), md->hdr.isa_length); return; } switch (md->hdr.isa_xchg) {#ifdef NOTYET case ISAKMP_XCHG_NONE: case ISAKMP_XCHG_BASE: case ISAKMP_XCHG_AO:#endif case ISAKMP_XCHG_AGGR: case ISAKMP_XCHG_IDPROT: /* part of a Main Mode exchange */ if (md->hdr.isa_msgid != MAINMODE_MSGID) { openswan_log("Message ID was 0x%08lx but should be zero in phase 1", (unsigned long) md->hdr.isa_msgid); SEND_NOTIFICATION(INVALID_MESSAGE_ID); return; } if (is_zero_cookie(md->hdr.isa_icookie)) { openswan_log("Initiator Cookie must not be zero in phase 1 message"); SEND_NOTIFICATION(INVALID_COOKIE); return; } if (is_zero_cookie(md->hdr.isa_rcookie)) { /* initial message from initiator * ??? what if this is a duplicate of another message? */ if (md->hdr.isa_flags & ISAKMP_FLAG_ENCRYPTION) { openswan_log("initial phase 1 message is invalid:" " its Encrypted Flag is on"); SEND_NOTIFICATION(INVALID_FLAGS); return; } /* don't build a state until the message looks tasty */ from_state = (md->hdr.isa_xchg == ISAKMP_XCHG_IDPROT ? STATE_MAIN_R0 : STATE_AGGR_R0); } else { /* not an initial message */ st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie , &md->sender, md->hdr.isa_msgid); if (st == NULL) { /* perhaps this is a first message from the responder * and contains a responder cookie that we've not yet seen. */ st = find_state(md->hdr.isa_icookie, zero_cookie , &md->sender, md->hdr.isa_msgid); if (st == NULL) { openswan_log("phase 1 message is part of an unknown exchange"); /* XXX Could send notification back */ return; } } set_cur_state(st); from_state = st->st_state; } break; case ISAKMP_XCHG_INFO: /* an informational exchange */ st = find_info_state(md->hdr.isa_icookie, md->hdr.isa_rcookie , &md->sender, MAINMODE_MSGID); if (st != NULL) set_cur_state(st); if (md->hdr.isa_flags & ISAKMP_FLAG_ENCRYPTION) { if (st == NULL) { openswan_log("Informational Exchange is for an unknown (expired?) SA"); /* XXX Could send notification back */ return; } if (!IS_ISAKMP_ENCRYPTED(st->st_state)) { loglog(RC_LOG_SERIOUS, "encrypted Informational Exchange message is invalid" " because no key is known"); /* XXX Could send notification back */ return; } if (md->hdr.isa_msgid == MAINMODE_MSGID) { loglog(RC_LOG_SERIOUS, "Informational Exchange message is invalid because" " it has a Message ID of 0"); /* XXX Could send notification back */ return; } if (!reserve_msgid(st, md->hdr.isa_msgid)) { loglog(RC_LOG_SERIOUS, "Informational Exchange message is invalid because" " it has a previously used Message ID (0x%08lx)" , (unsigned long)md->hdr.isa_msgid); /* XXX Could send notification back */ return; } init_phase2_iv(st, &md->hdr.isa_msgid); new_iv_set = TRUE; from_state = STATE_INFO_PROTECTED; } else { if (st != NULL && (IS_ISAKMP_AUTHENTICATED(st->st_state))) { loglog(RC_LOG_SERIOUS, "Informational Exchange message" " must be encrypted"); /* XXX Could send notification back */ return; } from_state = STATE_INFO; } break; case ISAKMP_XCHG_QUICK: /* part of a Quick Mode exchange */ if (is_zero_cookie(md->hdr.isa_icookie)) { openswan_log("Quick Mode message is invalid because" " it has an Initiator Cookie of 0"); SEND_NOTIFICATION(INVALID_COOKIE); return; } if (is_zero_cookie(md->hdr.isa_rcookie)) { openswan_log("Quick Mode message is invalid because" " it has a Responder Cookie of 0"); SEND_NOTIFICATION(INVALID_COOKIE); return; } if (md->hdr.isa_msgid == MAINMODE_MSGID) { openswan_log("Quick Mode message is invalid because" " it has a Message ID of 0"); SEND_NOTIFICATION(INVALID_MESSAGE_ID); return; } st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie , &md->sender, md->hdr.isa_msgid); if (st == NULL) { /* No appropriate Quick Mode state. * See if we have a Main Mode state. * ??? what if this is a duplicate of another message? */ st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie , &md->sender, MAINMODE_MSGID); if (st == NULL) { openswan_log("Quick Mode message is for a non-existent (expired?)" " ISAKMP SA"); /* XXX Could send notification back */ return; }#ifdef XAUTH if(st->st_oakley.xauth != 0) { openswan_log("Cannot do Quick Mode until XAUTH done."); return; }#endif #ifdef MODECFG if(st->st_state == STATE_MODE_CFG_R2) /* Have we just give an IP address to peer? */ { st->st_state = STATE_MAIN_R3; /* ISAKMP is up... */ }#endif set_cur_state(st); if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state)) { loglog(RC_LOG_SERIOUS, "Quick Mode message is unacceptable because" " it is for an incomplete ISAKMP SA"); SEND_NOTIFICATION(PAYLOAD_MALFORMED /* XXX ? */); return; } /* only accept this new Quick Mode exchange if it has a unique message ID */ if (!reserve_msgid(st, md->hdr.isa_msgid)) { loglog(RC_LOG_SERIOUS, "Quick Mode I1 message is unacceptable because" " it uses a previously used Message ID 0x%08lx" " (perhaps this is a duplicated packet)" , (unsigned long) md->hdr.isa_msgid); SEND_NOTIFICATION(INVALID_MESSAGE_ID); return; } /* Quick Mode Initial IV */ init_phase2_iv(st, &md->hdr.isa_msgid); new_iv_set = TRUE; from_state = STATE_QUICK_R0; } else {#ifdef XAUTH if(st->st_oakley.xauth != 0) { openswan_log("Cannot do Quick Mode until XAUTH done."); return; }#endif set_cur_state(st); from_state = st->st_state; } break;#ifdef MODECFG case ISAKMP_XCHG_MODE_CFG: if (is_zero_cookie(md->hdr.isa_icookie)) { openswan_log("Mode Config message is invalid because" " it has an Initiator Cookie of 0"); /* XXX Could send notification back */ return; } if (is_zero_cookie(md->hdr.isa_rcookie)) { openswan_log("Mode Config message is invalid because" " it has a Responder Cookie of 0"); /* XXX Could send notification back */ return; } if (md->hdr.isa_msgid == 0) { openswan_log("Mode Config message is invalid because" " it has a Message ID of 0"); /* XXX Could send notification back */ return; } st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie , &md->sender, md->hdr.isa_msgid); if (st == NULL) { /* No appropriate Mode Config state. * See if we have a Main Mode state. * ??? what if this is a duplicate of another message? */ st = find_state(md->hdr.isa_icookie, md->hdr.isa_rcookie , &md->sender, 0); if (st == NULL) { openswan_log("Mode Config message is for a non-existent (expired?)" " ISAKMP SA"); /* XXX Could send notification back */ return; } set_cur_state(st); if (!IS_ISAKMP_SA_ESTABLISHED(st->st_state)) { loglog(RC_LOG_SERIOUS, "Mode Config message is unacceptable because" " it is for an incomplete ISAKMP SA (state=%s)" , enum_name(&state_names, st->st_state)); /* XXX Could send notification back */ return; } init_phase2_iv(st, &md->hdr.isa_msgid); new_iv_set = TRUE; /* * okay, now we have to figure out if we are receiving a bogus * new message in an oustanding XAUTH server conversation * (i.e. a reply to our challenge) * (this occurs with some broken other implementations). * * or if receiving for the first time, an XAUTH challenge. * * or if we are getting a MODECFG request. * * we distinguish these states because we can not both be an * XAUTH server and client, and our policy tells us which * one we are. * * to complicate further, it is normal to start a new msgid * when going from one state to another, or when restarting * the challenge. * */ if(st->st_connection->spd.this.xauth_server && st->st_state == STATE_XAUTH_R1 && st->quirks.xauth_ack_msgid) { from_state = STATE_XAUTH_R1; } else if(st->st_connection->spd.this.xauth_client && IS_PHASE1(st->st_state)) { from_state = STATE_XAUTH_I0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -