summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1999-02-26 03:43:42 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1999-02-26 03:43:42 +0000
commit154fe199b1767a4ec0e7e9d39092fd1e4e40d457 (patch)
treee82d6a2c58ca15c544af600d999f7f7879a34344 /sbin
parentf173261242fff88943ce2812b3c4b0cf1c62a453 (diff)
Merge from the Ericsson repository
| revision 1.82 | date: 1999/02/25 13:35:41; author: niklas; state: Exp; lines: +6 -2 | doh wrong replay window default | ---------------------------- | revision 1.81 | date: 1999/02/25 11:39:07; author: niklas; state: Exp; lines: +3 -2 | include sysdep.h everywhere | ---------------------------- | revision 1.80 | date: 1999/02/25 11:09:38; author: niklas; state: Exp; lines: +2 -2 | Make conf_get_num take a default value to give back when tag does not exist | ---------------------------- | revision 1.79 | date: 1999/02/25 10:21:32; author: niklas; state: Exp; lines: +10 -5 | Replay window changes was done at the wrong level | ---------------------------- | revision 1.78 | date: 1999/02/25 09:30:25; author: niklas; state: Exp; lines: +12 -1 | Replay protection window configurable | ---------------------------- | revision 1.77 | date: 1999/02/14 00:21:10; author: niklas; state: Exp; lines: +62 -5 | Find relevant SAs out of IPsec expiration info. Do not automatically rekey. | ---------------------------- | revision 1.76 | date: 1999/01/31 01:16:59; author: niklas; state: Exp; lines: +67 -45 | splitup ipsec_build_id into more useful API | ----------------------------
Diffstat (limited to 'sbin')
-rw-r--r--sbin/isakmpd/ipsec.c202
1 files changed, 151 insertions, 51 deletions
diff --git a/sbin/isakmpd/ipsec.c b/sbin/isakmpd/ipsec.c
index 84e099b8528..7c002b1175b 100644
--- a/sbin/isakmpd/ipsec.c
+++ b/sbin/isakmpd/ipsec.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: ipsec.c,v 1.4 1998/12/21 01:02:24 niklas Exp $ */
-/* $EOM: ipsec.c,v 1.75 1998/12/15 09:11:57 niklas Exp $ */
+/* $OpenBSD: ipsec.c,v 1.5 1999/02/26 03:43:41 niklas Exp $ */
+/* $EOM: ipsec.c,v 1.82 1999/02/25 13:35:41 niklas Exp $ */
/*
* Copyright (c) 1998 Niklas Hallqvist. All rights reserved.
@@ -41,6 +41,8 @@
#include <stdlib.h>
#include <string.h>
+#include "sysdep.h"
+
#include "attribute.h"
#include "conf.h"
#include "constants.h"
@@ -60,11 +62,13 @@
#include "message.h"
#include "prf.h"
#include "sa.h"
-#include "sysdep.h"
#include "timer.h"
#include "transport.h"
#include "util.h"
+/* The replay window size used for all IPSec protocols if not overridden. */
+#define DEFAULT_REPLAY_WINDOW 16
+
struct ipsec_decode_arg {
struct message *msg;
struct sa *sa;
@@ -81,6 +85,7 @@ static void ipsec_free_sa_data (void *);
static struct keystate *ipsec_get_keystate (struct message *);
static u_int8_t *ipsec_get_spi (size_t *, u_int8_t, struct message *);
static int ipsec_initiator (struct message *);
+static void ipsec_proto_init (struct proto *, char *);
static int ipsec_responder (struct message *);
static void ipsec_setup_situation (u_int8_t *);
static size_t ipsec_situation_size (void);
@@ -109,6 +114,7 @@ static struct doi ipsec_doi = {
ipsec_get_keystate,
ipsec_get_spi,
ipsec_is_attribute_incompatible,
+ ipsec_proto_init,
ipsec_setup_situation,
ipsec_situation_size,
ipsec_spi_size,
@@ -180,14 +186,28 @@ ipsec_finalize_exchange (struct message *msg)
break;
}
- /* If a lifetime was negotiated setup the death timer. */
+ /* If a lifetime was negotiated setup the expiration timers. */
if (isakmp_sa->seconds)
{
gettimeofday(&expiration, 0);
+ expiration.tv_sec += isakmp_sa->seconds * 9 / 10;
+ isakmp_sa->soft_death
+ = timer_add_event ("sa_soft_expire",
+ (void (*) (void *))sa_soft_expire, isakmp_sa,
+ &expiration);
+ if (!isakmp_sa->soft_death)
+ {
+ /* If we don't give up we might start leaking... */
+ sa_delete (isakmp_sa, 1);
+ return;
+ }
+
+ gettimeofday(&expiration, 0);
expiration.tv_sec += isakmp_sa->seconds;
- isakmp_sa->death = timer_add_event ("sa_rekey_p1",
- (void (*) (void *))sa_rekey_p1,
- isakmp_sa, &expiration);
+ isakmp_sa->death
+ = timer_add_event ("sa_hard_expire",
+ (void (*) (void *))sa_hard_expire, isakmp_sa,
+ &expiration);
if (!isakmp_sa->death)
{
/* If we don't give up we might start leaking... */
@@ -270,7 +290,7 @@ ipsec_finalize_exchange (struct message *msg)
isa->src_net, isa->src_mask, isa->dst_net,
isa->dst_mask);
- if (sysdep_ipsec_enable_spi (sa, initiator))
+ if (sysdep_ipsec_enable_sa (sa, initiator))
/* XXX Tear down this exchange. */
return;
}
@@ -1150,118 +1170,140 @@ ipsec_keymat_length (struct proto *proto)
}
/*
- * Out of a named section SECTION in the configuration file build an
- * ISAKMP ID payload. Ths payload size should be stashed in SZ.
- * The caller is responsible for freeing the payload.
+ * Out of a named section SECTION in the configuration file find out
+ * the network address and mask as well as the ID type. Put the info
+ * in the areas pointed to by ADDR, MASK and ID respectively. Return
+ * 0 on success and -1 on failure.
*/
-u_int8_t *
-ipsec_build_id (char *section, size_t *sz)
+int
+ipsec_get_id (char *section, int *id, struct in_addr *addr,
+ struct in_addr *mask)
{
char *type, *address, *netmask;
- struct in_addr addr, mask;
- u_int8_t *p;
- int id;
type = conf_get_str (section, "ID-type");
if (!type)
{
- log_print ("ipsec_build_id: section %s has no ID-type", section);
- return 0;
+ log_print ("ipsec_get_id: section %s has no \"ID-type\" tag", section);
+ return -1;
}
- *sz = ISAKMP_ID_SZ;
-
- id = constant_value (ipsec_id_cst, type);
- switch (id)
+ *id = constant_value (ipsec_id_cst, type);
+ switch (*id)
{
case IPSEC_ID_IPV4_ADDR:
address = conf_get_str (section, "Address");
if (!address)
{
- log_print ("ipsec_id_build: section %s has no \"Address\" tag",
+ log_print ("ipsec_get_id: section %s has no \"Address\" tag",
section);
- return 0;
+ return -1;
}
- if (!inet_aton (address, &addr))
+ if (!inet_aton (address, addr))
{
- log_print ("ipsec_id_build: invalid section %s address %s", section,
+ log_print ("ipsec_get_id: invalid address %s in section %s", section,
address);
- return 0;
+ return -1;
}
-
- *sz += sizeof (in_addr_t);
break;
#ifdef notyet
case IPSEC_ID_FQDN:
- return 0;
+ return -1;
case IPSEC_ID_USER_FQDN:
- return 0;
+ return -1;
#endif
case IPSEC_ID_IPV4_ADDR_SUBNET:
address = conf_get_str (section, "Network");
if (!address)
{
- log_print ("ipsec_id_build: section %s has no \"Network\" tag",
+ log_print ("ipsec_get_id: section %s has no \"Network\" tag",
section);
- return 0;
+ return -1;
}
- if (!inet_aton (address, &addr))
+ if (!inet_aton (address, addr))
{
- log_print ("ipsec_id_build: invalid section %s network %s", section,
+ log_print ("ipsec_get_id: invalid section %s network %s", section,
address);
- return 0;
+ return -1;
}
netmask = conf_get_str (section, "Netmask");
if (!netmask)
{
- log_print ("ipsec_id_build: section %s has no \"Netmask\" tag",
+ log_print ("ipsec_get_id: section %s has no \"Netmask\" tag",
section);
- return 0;
+ return -1;
}
- if (!inet_aton (netmask, &mask))
+ if (!inet_aton (netmask, mask))
{
log_print ("ipsec_id_build: invalid section %s network %s", section,
netmask);
- return 0;
+ return -1;
}
-
- *sz += 2 * sizeof (in_addr_t);
break;
#ifdef notyet
case IPSEC_ID_IPV6_ADDR:
- return 0;
+ return -1;
case IPSEC_ID_IPV6_ADDR_SUBNET:
- return 0;
+ return -1;
case IPSEC_ID_IPV4_RANGE:
- return 0;
+ return -1;
case IPSEC_ID_IPV6_RANGE:
- return 0;
+ return -1;
case IPSEC_ID_DER_ASN1_DN:
- return 0;
+ return -1;
case IPSEC_ID_DER_ASN1_GN:
- return 0;
+ return -1;
case IPSEC_ID_KEY_ID:
- return 0;
+ return -1;
#endif
default:
- log_print ("ipsec_build_id: unknown ID type \"%s\" in section %s", type,
+ log_print ("ipsec_get_id: unknown ID type \"%s\" in section %s", type,
section);
- return 0;
+ return -1;
+ }
+
+ return 0;
+}
+
+/*
+ * Out of a named section SECTION in the configuration file build an
+ * ISAKMP ID payload. Ths payload size should be stashed in SZ.
+ * The caller is responsible for freeing the payload.
+ */
+u_int8_t *
+ipsec_build_id (char *section, size_t *sz)
+{
+ struct in_addr addr, mask;
+ u_int8_t *p;
+ int id;
+
+ if (ipsec_get_id (section, &id, &addr, &mask))
+ return 0;
+
+ *sz = ISAKMP_ID_SZ;
+ switch (id)
+ {
+ case IPSEC_ID_IPV4_ADDR:
+ *sz += sizeof addr;
+ break;
+ case IPSEC_ID_IPV4_ADDR_SUBNET:
+ *sz += sizeof addr + sizeof mask;
+ break;
}
p = malloc (*sz);
@@ -1287,3 +1329,61 @@ ipsec_build_id (char *section, size_t *sz)
return p;
}
+
+struct dst_spi_proto_arg {
+ in_addr_t dst;
+ u_int32_t spi;
+ u_int8_t proto;
+};
+
+static int
+ipsec_sa_check (struct sa *sa, void *v_arg)
+{
+ struct dst_spi_proto_arg *arg = v_arg;
+ struct proto *proto;
+ struct sockaddr *dst, *src;
+ int dstlen, srclen;
+ int incoming;
+
+ sa->transport->vtbl->get_dst (sa->transport, &dst, &dstlen);
+ if (((struct sockaddr_in *)dst)->sin_addr.s_addr == arg->dst)
+ incoming = 0;
+ else
+ {
+ sa->transport->vtbl->get_src (sa->transport, &src, &srclen);
+ if (((struct sockaddr_in *)src)->sin_addr.s_addr == arg->dst)
+ incoming = 1;
+ else
+ return 0;
+ }
+
+ for (proto = TAILQ_FIRST (&sa->protos); proto;
+ proto = TAILQ_NEXT (proto, link))
+ if (proto->proto == arg->proto
+ && memcmp (proto->spi[incoming], &arg->spi, sizeof arg->spi) == 0)
+ return 1;
+ return 0;
+}
+
+struct sa *
+ipsec_sa_lookup (in_addr_t dst, u_int32_t spi, u_int8_t proto)
+{
+ struct dst_spi_proto_arg arg = { dst, spi, proto };
+
+ return sa_find (ipsec_sa_check, &arg);
+}
+
+/*
+ * IPSec-specific PROTO initializations. SECTION is only set if we are the
+ * initiator thus only usable there.
+ * XXX I want to fix this later.
+ */
+void
+ipsec_proto_init (struct proto *proto, char *section)
+{
+ struct ipsec_proto *iproto = proto->data;
+
+ if (proto->sa->phase == 2 && section)
+ iproto->replay_window
+ = conf_get_num (section, "ReplayWindow", DEFAULT_REPLAY_WINDOW);
+}