Beispiel #1
0
static void
aggr_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);

  st->st_calculating = FALSE;

  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());
}
Beispiel #2
0
/*
 * delete all states that were created for a given connection,
 * additionally delete any states for which func(st, arg)
 * returns true.
 */
static void
foreach_states_by_connection_func(struct connection *c
				  , bool (*comparefunc)(struct state *st, struct connection *c, void *arg, int pass)
				 , void (*successfunc)(struct state *st, struct connection *c, void *arg)
				 , void *arg)
{
    int pass;
    /* this kludge avoids an n^2 algorithm */

    /* We take two passes so that we delete any ISAKMP SAs last.
     * This allows Delete Notifications to be sent.
     * ?? We could probably double the performance by caching any
     * ISAKMP SA states found in the first pass, avoiding a second.
     */
    for (pass = 0; pass != 2; pass++)
    {
	int i;

	/* For each hash chain... */
	for (i = 0; i < STATE_TABLE_SIZE; i++)
	{
	    struct state *st;

	    /* For each state in the hash chain... */
	    for (st = statetable[i]; st != NULL; )
	    {
		struct state *this = st;

		st = st->st_hashchain_next;	/* before this is deleted */

		/* on pass 2, ignore phase2 states */
 		if(pass == 1 && IS_ISAKMP_SA_ESTABLISHED(this->st_state)) {
		    continue;
		}

		/* call comparison function */
                if ((*comparefunc)(this, c, arg, pass))
                {
		    struct state *old_cur_state
			= cur_state == this? NULL : cur_state;
#ifdef DEBUG
		    lset_t old_cur_debugging = cur_debugging;
#endif

    set_cur_state(this);
		    (*successfunc)(this, c, arg);

		    cur_state = old_cur_state;
#ifdef DEBUG
		    set_debugging(old_cur_debugging);
#endif
		}
	    }
	}
    }
}
Beispiel #3
0
/*
 * continuation from second calculation (the DH one)
 *
 */
static void aggr_inI1_outR1_continue2(struct pluto_crypto_req_cont *pcrc,
				      struct pluto_crypto_req *r,
				      err_t ugh)
{
	struct dh_continuation *dh = (struct dh_continuation *)pcrc;
	struct msg_digest *md = dh->dh_md;
	struct state *const st = md->st;
	stf_status e;

	DBG(DBG_CONTROL,
		DBG_log("aggr_inI1_outR1_continue2 for #%lu: calculated ke+nonce+DH, sending R1",
			dh->dh_pcrc.pcrc_serialno));

	if (st == NULL) {
		loglog(RC_LOG_SERIOUS,
		       "%s: Request was disconnected from state",
		       __FUNCTION__);
		passert(dh->dh_pcrc.pcrc_serialno == SOS_NOBODY);	/* transitional */
		release_any_md(&dh->dh_md);
		return;
	}

	passert(dh->dh_pcrc.pcrc_serialno == st->st_serialno);	/* transitional */

	/* XXX should check out ugh */
	passert(ugh == NULL);
	passert(cur_state == NULL);
	passert(st != NULL);

	passert(st->st_suspended_md == dh->dh_md);
	unset_suspended(st); /* no longer connected or suspended */

	set_cur_state(st);
	DBG(DBG_CONTROLMORE, DBG_log("#%lu %s:%u st->st_calculating = FALSE;", st->st_serialno, __FUNCTION__, __LINE__));
	st->st_calculating = FALSE;

	e = aggr_inI1_outR1_tail(pcrc, r);

	if (dh->dh_md != NULL) {
		complete_v1_state_transition(&dh->dh_md, e);
		release_any_md(&dh->dh_md);
	}
	reset_cur_state();
}
Beispiel #4
0
/*
 * for aggressive mode, this is sub-optimal, since we should have
 * had the crypto helper actually do everything, but we need to do
 * some additional work to set that all up, so this is fine for now.
 *
 */
static void aggr_inI1_outR1_continue1(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->ke_md;
	struct state *const st = md->st;
	stf_status e;

	DBG(DBG_CONTROLMORE,
	    DBG_log("aggr inI1_outR1: calculated ke+nonce, calculating DH"));

	if (st == NULL) {
		loglog(RC_LOG_SERIOUS,
		       "%s: Request was disconnected from state",
		       __FUNCTION__);
		release_any_md(&ke->ke_md);
		return;
	}

	/* XXX should check out ugh */
	passert(ugh == NULL);
	passert(cur_state == NULL);
	passert(st != NULL);

	passert(st->st_suspended_md == ke->ke_md);
	unset_suspended(st); /* no longer connected or suspended */

	set_cur_state(st);
	DBG(DBG_CONTROLMORE, DBG_log("#%lu %s:%u st->st_calculating = FALSE;", st->st_serialno, __FUNCTION__, __LINE__));
	st->st_calculating = FALSE;

	/* unpack first calculation */
	unpack_KE(st, r, &st->st_gr);

	/* unpack nonce too */
	unpack_nonce(&st->st_nr, r);

	/* NOTE: the "r" reply will get freed by our caller */

	/* set up second calculation */
	{
		struct dh_continuation *dh = alloc_thing(
			struct dh_continuation,
			"aggr outR1 DH");

		dh->dh_md = md;
		set_suspended(st, md);
		dh->dh_pcrc.pcrc_serialno = st->st_serialno;	/* transitional */
		pcrc_init(&dh->dh_pcrc, aggr_inI1_outR1_continue2);
		e = start_dh_secretiv(&dh->dh_pcrc, st,
				      st->st_import,
				      O_RESPONDER,
				      st->st_oakley.group->group);

		if (e != STF_SUSPEND) {
			if (dh->dh_md != NULL) {
				complete_v1_state_transition(&dh->dh_md, e);
				release_any_md(&dh->dh_md);
			}
		}

		reset_cur_state();
	}
}