Example #1
0
/*
 * Setup expiration timers for SA.  This is used for ISAKMP SAs, but also
 * possible to use for application SAs if the application does not deal
 * with expirations itself.  An example is the Linux FreeS/WAN KLIPS IPsec
 * stack.
 */
int
sa_setup_expirations(struct sa *sa)
{
	struct timeval  expiration;
	u_int64_t       seconds = sa->seconds;

	/*
	 * Set the soft timeout to a random percentage between 85 & 95 of
	 * the negotiated lifetime to break strictly synchronized
	 * renegotiations.  This works better when the randomization is on the
	 * order of processing plus network-roundtrip times, or larger.
	 * I.e. it depends on configuration and negotiated lifetimes.
	 * It is not good to do the decrease on the hard timeout, because then
	 * we may drop our SA before our peer.
	 * XXX Better scheme to come?
	 */
	if (!sa->soft_death) {
		gettimeofday(&expiration, 0);
		/*
		 * XXX This should probably be configuration controlled
		 * somehow.
		 */
		seconds = sa->seconds * (850 + rand_32() % 100) / 1000;
		LOG_DBG((LOG_TIMER, 95,
		    "sa_setup_expirations: SA %p soft timeout in %llu seconds",
		    sa, seconds));
		expiration.tv_sec += seconds;
		sa->soft_death = timer_add_event("sa_soft_expire",
		    sa_soft_expire, sa, &expiration);
		if (!sa->soft_death) {
			/* If we don't give up we might start leaking...  */
			sa_delete(sa, 1);
			return -1;
		}
		sa_reference(sa);
	}
	if (!sa->death) {
		gettimeofday(&expiration, 0);
		LOG_DBG((LOG_TIMER, 95,
		    "sa_setup_expirations: SA %p hard timeout in %llu seconds",
		    sa, sa->seconds));
		expiration.tv_sec += sa->seconds;
		sa->death = timer_add_event("sa_hard_expire", sa_hard_expire,
		    sa, &expiration);
		if (!sa->death) {
			/* If we don't give up we might start leaking...  */
			sa_delete(sa, 1);
			return -1;
		}
		sa_reference(sa);
	}
	return 0;
}
Example #2
0
/* Tear down a connection, can be phase 1 or 2.  */
static void
ui_teardown(char *cmd)
{
	struct sockaddr_in	 addr;
	struct sockaddr_in6	 addr6;
	struct sa		*sa;
	int			 phase;
	char			 name[201];

	/* If no phase is given, we default to phase 2. */
	phase = 2;
	if (sscanf(cmd, "t main %200s", name) == 1)
		phase = 1;
	else if (sscanf(cmd, "t quick %200s", name) == 1)
		phase = 2;
	else if (sscanf(cmd, "t %200s", name) != 1) {
		log_print("ui_teardown: command \"%s\" malformed", cmd);
		return;
	}
	LOG_DBG((LOG_UI, 10, "ui_teardown: teardown connection \"%s\", "
	    "phase %d", name, phase));

	bzero(&addr, sizeof(addr));
	bzero(&addr6, sizeof(addr6));

	if (inet_pton(AF_INET, name, &addr.sin_addr) == 1) {
		addr.sin_len = sizeof(addr);
		addr.sin_family = AF_INET;

		while ((sa = sa_lookup_by_peer((struct sockaddr *)&addr,
		    SA_LEN((struct sockaddr *)&addr), phase)) != 0) {
			if (sa->name)
				connection_teardown(sa->name);
			sa_delete(sa, 1);
		}
	} else if (inet_pton(AF_INET6, name, &addr6.sin6_addr) == 1) {
		addr6.sin6_len = sizeof(addr6);
		addr6.sin6_family = AF_INET6;

		while ((sa = sa_lookup_by_peer((struct sockaddr *)&addr6,
		    SA_LEN((struct sockaddr *)&addr6), phase)) != 0) {
			if (sa->name)
				connection_teardown(sa->name);
			sa_delete(sa, 1);
		}
	} else {
		if (phase == 2)
			connection_teardown(name);
		while ((sa = sa_lookup_by_name(name, phase)) != 0)
			sa_delete(sa, 1);
	}
}
Example #3
0
/* Teardown all SAs.  */
void
sa_teardown_all(void)
{
	int             i;
	struct sa      *sa, *next = 0;

	LOG_DBG((LOG_SA, 70, "sa_teardown_all:"));
	/* Get Phase 2 SAs.  */
	for (i = 0; i <= bucket_mask; i++)
		for (sa = LIST_FIRST(&sa_tab[i]); sa; sa = next) {
			next = LIST_NEXT(sa, link);
			if (sa->phase == 2) {
				/*
				 * Teardown the phase 2 SAs by name, similar
				 * to ui_teardown.
				 */
				LOG_DBG((LOG_SA, 70,
				    "sa_teardown_all: tearing down SA %s",
				    sa->name ? sa->name : "<unnamed>"));
				if (sa->name)
					connection_teardown(sa->name);
				sa_delete(sa, 1);
			}
		}
}
Example #4
0
static void
ui_delete(char *cmd)
{
	char            cookies_str[ISAKMP_HDR_COOKIES_LEN * 2 + 1];
	char            message_id_str[ISAKMP_HDR_MESSAGE_ID_LEN * 2 + 1];
	u_int8_t        cookies[ISAKMP_HDR_COOKIES_LEN];
	u_int8_t        message_id_buf[ISAKMP_HDR_MESSAGE_ID_LEN];
	u_int8_t       *message_id = message_id_buf;
	struct sa      *sa;

	if (sscanf(cmd, "d %32s %8s", cookies_str, message_id_str) != 2) {
		log_print("ui_delete: command \"%s\" malformed", cmd);
		return;
	}
	if (strcmp(message_id_str, "-") == 0)
		message_id = 0;

	if (hex2raw(cookies_str, cookies, ISAKMP_HDR_COOKIES_LEN) == -1 ||
	    (message_id && hex2raw(message_id_str, message_id_buf,
	    ISAKMP_HDR_MESSAGE_ID_LEN) == -1)) {
		log_print("ui_delete: command \"%s\" has bad arguments", cmd);
		return;
	}
	sa = sa_lookup(cookies, message_id);
	if (!sa) {
		log_print("ui_delete: command \"%s\" found no SA", cmd);
		return;
	}
	LOG_DBG((LOG_UI, 20,
	    "ui_delete: deleting SA for cookie \"%s\" msgid \"%s\"",
	    cookies_str, message_id_str));
	sa_delete(sa, 1);
}
Example #5
0
/* SA has passed its best before date.  */
static void
sa_hard_expire(void *v_sa)
{
	struct sa      *sa = v_sa;

	sa->death = 0;
	sa_release(sa);

	if ((sa->flags & (SA_FLAG_STAYALIVE | SA_FLAG_REPLACED)) ==
	    SA_FLAG_STAYALIVE)
		exchange_establish(sa->name, 0, 0, 1);

	sa_delete(sa, 1);
}
Example #6
0
static void
daemon_shutdown(void)
{
	/* Perform a (protocol-wise) clean shutdown of the daemon.  */
	struct sa	*sa;

	if (sigtermed == 1) {
		log_print("isakmpd: shutting down...");

		if (delete_sas &&
		    strncmp("no", conf_get_str("General", "Delete-SAs"), 2)) {
			/*
			 * Delete all active SAs.  First IPsec SAs, then
			 * ISAKMPD.  Each DELETE is another (outgoing) message.
			 */
			while ((sa = sa_find(phase2_sa_check, NULL)))
				sa_delete(sa, 1);

			while ((sa = sa_find(phase1_sa_check, NULL)))
				sa_delete(sa, 1);
		}

		/* We only want to do this once. */
		sigtermed++;
	}
	if (transport_prio_sendqs_empty()) {
		/*
		 * When the prioritized transport sendq:s are empty, i.e all
		 * the DELETE notifications have been sent, we can shutdown.
		 */

		log_packet_stop();
		log_print("isakmpd: exit");
		exit(0);
	}
}
Example #7
0
static void
daemon_shutdown (void)
{
  /* Perform a (protocol-wise) clean shutdown of the daemon.  */
  struct sa *sa;

  if (sigtermed == 1)
    {
      log_print ("isakmpd: shutting down...");

      /* Delete all active phase 2 SAs.  */
      while ((sa = sa_find (phase2_sa_check, NULL)))
	{
	  /* Each DELETE is another (outgoing) message.  */
	  sa_delete (sa, 1);
	}
      sigtermed++;
    }

  if (transport_prio_sendqs_empty ())
    {
      /*
       * When the prioritized transport sendq:s are empty, i.e all
       * the DELETE notifications have been sent, we can shutdown.
       */
	
#ifdef USE_DEBUG
      log_packet_stop ();
#endif
      /* Remove FIFO and pid files.  */
      unlink (ui_fifo);
      unlink (pid_file);
      log_print ("isakmpd: exit");
      exit (0);
    }
}