- isakmp_reschedule_info_monitor_if_pending(iph1,
- "ike packets received from peer");
-#endif /* DPD */
- }
-
- switch (isakmp->etype) {
- case ISAKMP_ETYPE_IDENT:
- case ISAKMP_ETYPE_AGG:
- case ISAKMP_ETYPE_BASE:
- /* phase 1 validity check */
- if (isakmp->msgid != 0) {
- plog(LLV_ERROR, LOCATION, remote,
- "message id should be zero in phase1.\n");
- return -1;
- }
-
- /* search for isakmp status record of phase 1 */
- if (iph1 == NULL) {
- /*
- * the packet must be the 1st message from a initiator
- * or the 2nd message from the responder.
- */
-
- /* search for phase1 handle by index without r_ck */
- iph1 = getph1byindex0(index);
- if (iph1 == NULL) {
- /*it must be the 1st message from a initiator.*/
- if (memcmp(&isakmp->r_ck, r_ck0,
- sizeof(cookie_t)) != 0) {
-
- plog(LLV_DEBUG, LOCATION, remote,
- "malformed cookie received "
- "or the spi expired.\n");
- return -1;
- }
-
- /* it must be responder's 1st exchange. */
- if (isakmp_ph1begin_r(msg, remote, local,
- isakmp->etype) < 0)
- return -1;
- break;
-
- /*NOTREACHED*/
- }
-
- /* it must be the 2nd message from the responder. */
- if (iph1->side != INITIATOR) {
- IPSECSESSIONTRACEREVENT(iph1->parent_session,
- IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
- CONSTSTR("malformed cookie and unexpected side"),
- CONSTSTR("Failed to process phase1 message (unexpected side)"));
- plog(LLV_DEBUG, LOCATION, remote,
- "malformed cookie received. "
- "it has to be as the initiator. %s\n",
- isakmp_pindex(&iph1->index, 0));
- return -1;
- }
- }
-
- /*
- * Don't delete phase 1 handler when the exchange type
- * in handler is not equal to packet's one because of no
- * authencication completed.
- */
- if (iph1->etype != isakmp->etype) {
- IPSECSESSIONTRACEREVENT(iph1->parent_session,
- IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
- CONSTSTR("mismatched exchange type"),
- CONSTSTR("Failed to process phase1 message (mismatched exchange type)"));
- plog(LLV_ERROR, LOCATION, iph1->remote,
- "exchange type is mismatched: "
- "db=%s packet=%s, ignore it.\n",
- s_isakmp_etype(iph1->etype),
- s_isakmp_etype(isakmp->etype));
- return -1;
- }
-
-#ifdef ENABLE_FRAG
- if (isakmp->np == ISAKMP_NPTYPE_FRAG)
- return frag_handler(iph1, msg, remote, local);
-#endif
-
- /* call main process of phase 1 */
- if (ph1_main(iph1, msg) < 0) {
- plog(LLV_ERROR, LOCATION, iph1->remote,
- "phase1 negotiation failed.\n");
- remph1(iph1);
- delph1(iph1);
- return -1;
- }
- break;
-
- case ISAKMP_ETYPE_AUTH:
- plog(LLV_INFO, LOCATION, remote,
- "unsupported exchange %d received.\n",
- isakmp->etype);
- break;
-
- case ISAKMP_ETYPE_INFO:
- case ISAKMP_ETYPE_ACKINFO:
- /*
- * iph1 must be present for Information message.
- * if iph1 is null then trying to get the phase1 status
- * as the packet from responder againt initiator's 1st
- * exchange in phase 1.
- * NOTE: We think such informational exchange should be ignored.
- */
- if (iph1 == NULL) {
- iph1 = getph1byindex0(index);
- if (iph1 == NULL) {
- plog(LLV_ERROR, LOCATION, remote,
- "unknown Informational "
- "exchange received.\n");
- return -1;
- }
- if (cmpsaddrstrict(iph1->remote, remote) != 0) {
- plog(LLV_WARNING, LOCATION, remote,
- "remote address mismatched. "
- "db=%s\n",
- saddr2str(iph1->remote));
- }
- }
-
-#ifdef ENABLE_FRAG
- if (isakmp->np == ISAKMP_NPTYPE_FRAG)
- return frag_handler(iph1, msg, remote, local);
-#endif
-
- if (isakmp_info_recv(iph1, msg) < 0)
- return -1;
- break;
-
- case ISAKMP_ETYPE_QUICK:
- {
- struct ph2handle *iph2;
-
- if (iph1 == NULL) {
- isakmp_info_send_nx(isakmp, remote, local,
- ISAKMP_NTYPE_INVALID_COOKIE, NULL);
- plog(LLV_ERROR, LOCATION, remote,
- "can't start the quick mode, "
- "there is no ISAKMP-SA, %s\n",
- isakmp_pindex((isakmp_index *)&isakmp->i_ck,
- isakmp->msgid));
- return -1;
- }
-#ifdef ENABLE_HYBRID
- /* Reinit the IVM if it's still there */
- if (iph1->mode_cfg && iph1->mode_cfg->ivm) {
- oakley_delivm(iph1->mode_cfg->ivm);
- iph1->mode_cfg->ivm = NULL;
- }
-#endif
-#ifdef ENABLE_FRAG
- if (isakmp->np == ISAKMP_NPTYPE_FRAG)
- return frag_handler(iph1, msg, remote, local);
-#endif
-
- /* check status of phase 1 whether negotiated or not. */
- if (iph1->status != PHASE1ST_ESTABLISHED) {
- IPSECSESSIONTRACEREVENT(iph1->parent_session,
- IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_DROP,
- CONSTSTR("can't start phase2 without valid phase1"),
- CONSTSTR("Failed to start phase2 resonder (no established phase1"));
- plog(LLV_ERROR, LOCATION, remote,
- "can't start the quick mode, "
- "there is no valid ISAKMP-SA, %s\n",
- isakmp_pindex(&iph1->index, iph1->msgid));
- return -1;
- }
-
- /* search isakmp phase 2 stauts record. */
- iph2 = getph2bymsgid(iph1, msgid);
- if (iph2 == NULL) {
- /* it must be new negotiation as responder */
- if (isakmp_ph2begin_r(iph1, msg) < 0)
- return -1;
- return 0;
- /*NOTREACHED*/
- }
-
- /* commit bit. */
- /* XXX
- * we keep to set commit bit during negotiation.
- * When SA is configured, bit will be reset.
- * XXX
- * don't initiate commit bit. should be fixed in the future.
- */
- if (ISSET(isakmp->flags, ISAKMP_FLAG_C))
- iph2->flags |= ISAKMP_FLAG_C;
-
- if (ISSET(isakmp->flags, ISAKMP_FLAG_E) &&
- (iph2->ph1 == NULL || iph2->ph1->approval == NULL)) {
- IPSECSESSIONTRACEREVENT(iph2->parent_session,
- IPSECSESSIONEVENTCODE_IKEV1_PH2_INIT_DROP,
- CONSTSTR("can't continue phase2 without valid phase1"),
- CONSTSTR("Failed to continue phase2 resonder (invalid linked phase1"));
- plog(LLV_ERROR, LOCATION, remote,
- "can't start the quick mode, "
- "invalid linked ISAKMP-SA\n");
- return -1;
- }
-
- /* call main process of quick mode */
- if (quick_main(iph2, msg) < 0) {
- plog(LLV_ERROR, LOCATION, iph1->remote,
- "phase2 negotiation failed.\n");
- unbindph12(iph2);
- remph2(iph2);
- delph2(iph2);
- return -1;
- }
- }
- break;
-
- case ISAKMP_ETYPE_NEWGRP:
- if (iph1 == NULL) {
- plog(LLV_ERROR, LOCATION, remote,
- "Unknown new group mode exchange, "
- "there is no ISAKMP-SA.\n");
- return -1;
- }
-
-#ifdef ENABLE_FRAG
- if (isakmp->np == ISAKMP_NPTYPE_FRAG)
- return frag_handler(iph1, msg, remote, local);
-#endif
-
- isakmp_newgroup_r(iph1, msg);
- break;
-
-#ifdef ENABLE_HYBRID
- case ISAKMP_ETYPE_CFG:
- if (iph1 == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "mode config %d from %s, "
- "but we have no ISAKMP-SA.\n",
- isakmp->etype, saddr2str(remote));
- return -1;
- }
-
-#ifdef ENABLE_FRAG
- if (isakmp->np == ISAKMP_NPTYPE_FRAG)
- return frag_handler(iph1, msg, remote, local);
-#endif
-
- isakmp_cfg_r(iph1, msg);
- break;
-#endif
-
- case ISAKMP_ETYPE_NONE:
- default:
- plog(LLV_ERROR, LOCATION, NULL,
- "Invalid exchange type %d from %s.\n",
- isakmp->etype, saddr2str(remote));
- return -1;
- }
-
- return 0;
-}
-
-/*
- * main function of phase 1.
- */
-static int
-ph1_main(iph1, msg)
- struct ph1handle *iph1;
- vchar_t *msg;
-{
- int error;
- int ini_contact = iph1->rmconf->ini_contact;
-#ifdef ENABLE_STATS
- struct timeval start, end;
-#endif
- int spi_cmp;
- u_int rekey_lifetime;
-
- /* ignore a packet */
- if (iph1->status == PHASE1ST_ESTABLISHED)
- return 0;
-
-#ifdef ENABLE_STATS
- gettimeofday(&start, NULL);
-#endif
- /* receive */
- if (ph1exchange[etypesw1(iph1->etype)]
- [iph1->side]
- [iph1->status] == NULL) {
- IPSECSESSIONTRACEREVENT(iph1->parent_session,
- IPSECSESSIONEVENTCODE_IKE_PACKET_RX_FAIL,
- CONSTSTR("unavailable function"),
- CONSTSTR("Failed to process phase1 message (no state function)"));
- plog(LLV_ERROR, LOCATION, iph1->remote,
- "why isn't the function defined.\n");
- return -1;
- }
- error = (ph1exchange[etypesw1(iph1->etype)]
- [iph1->side]
- [iph1->status])(iph1, msg);
- if (error != 0) {
-
- /* XXX
- * When an invalid packet is received on phase1, it should
- * be selected to process this packet. That is to respond
- * with a notify and delete phase 1 handler, OR not to respond
- * and keep phase 1 handler. However, in PHASE1ST_START when
- * acting as RESPONDER we must not keep phase 1 handler or else
- * it will stay forever.
- */
-
- if (iph1->side == RESPONDER && iph1->status == PHASE1ST_START) {
- plog(LLV_ERROR, LOCATION, iph1->remote,
- "failed to pre-process packet.\n");
- return -1;
- } else {
- /* ignore the error and keep phase 1 handler */
- return 0;
- }
- }
-
-#ifndef ENABLE_FRAG
- /* free resend buffer */
- if (iph1->sendbuf == NULL) {
- plog(LLV_ERROR, LOCATION, NULL,
- "no buffer found as sendbuf\n");
- return -1;
- }
-#endif
-
- VPTRINIT(iph1->sendbuf);
-
- /* turn off schedule */
- SCHED_KILL(iph1->scr);
-
- /* send */
- plog(LLV_DEBUG, LOCATION, NULL, "===\n");
- if ((ph1exchange[etypesw1(iph1->etype)]
- [iph1->side]
- [iph1->status])(iph1, msg) != 0) {
- plog(LLV_ERROR, LOCATION, iph1->remote,
- "failed to process packet.\n");
- return -1;
- }
-
-#ifdef ENABLE_STATS
- gettimeofday(&end, NULL);
- syslog(LOG_NOTICE, "%s(%s): %8.6f",
- "phase1", s_isakmp_state(iph1->etype, iph1->side, iph1->status),
- timedelta(&start, &end));
-#endif
- if (iph1->status == PHASE1ST_ESTABLISHED) {