summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Joerg Hoexer <hshoexer@cvs.openbsd.org>2005-09-23 14:44:04 +0000
committerHans-Joerg Hoexer <hshoexer@cvs.openbsd.org>2005-09-23 14:44:04 +0000
commitdd6cb76625db4d33697b54f6637121f15b6e763f (patch)
treeec152936d475051d6dd8d6be42c48476574b8c3d
parentf0ce098f4e5845432ac7df795c721ffaae6f5fc7 (diff)
Provide UI commands to delete phase 1 SAs.
Looks good mortiz@
-rw-r--r--sbin/isakmpd/ipsec.c4
-rw-r--r--sbin/isakmpd/message.c17
-rw-r--r--sbin/isakmpd/sa.c10
-rw-r--r--sbin/isakmpd/sa.h4
-rw-r--r--sbin/isakmpd/ui.c60
5 files changed, 73 insertions, 22 deletions
diff --git a/sbin/isakmpd/ipsec.c b/sbin/isakmpd/ipsec.c
index 729fdf33c34..9906909017c 100644
--- a/sbin/isakmpd/ipsec.c
+++ b/sbin/isakmpd/ipsec.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ipsec.c,v 1.121 2005/06/25 23:20:43 hshoexer Exp $ */
+/* $OpenBSD: ipsec.c,v 1.122 2005/09/23 14:44:03 hshoexer Exp $ */
/* $EOM: ipsec.c,v 1.143 2000/12/11 23:57:42 niklas Exp $ */
/*
@@ -1603,7 +1603,7 @@ ipsec_handle_leftover_payload(struct message *msg, u_int8_t type,
* disappear too.
*/
msg->transport->vtbl->get_dst(msg->transport, &dst);
- while ((sa = sa_lookup_by_peer(dst, SA_LEN(dst))) != 0) {
+ while ((sa = sa_lookup_by_peer(dst, SA_LEN(dst), 0)) != 0) {
/*
* Don't delete the current SA -- we received
* the notification over it, so it's obviously
diff --git a/sbin/isakmpd/message.c b/sbin/isakmpd/message.c
index d2d157267ea..5c2ee7cd697 100644
--- a/sbin/isakmpd/message.c
+++ b/sbin/isakmpd/message.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: message.c,v 1.114 2005/07/20 16:50:43 moritz Exp $ */
+/* $OpenBSD: message.c,v 1.115 2005/09/23 14:44:03 hshoexer Exp $ */
/* $EOM: message.c,v 1.156 2000/10/10 12:36:39 provos Exp $ */
/*
@@ -1745,13 +1745,24 @@ message_send_delete(struct sa *sa)
args.u.d.nspis = 1;
for (proto = TAILQ_FIRST(&sa->protos); proto;
proto = TAILQ_NEXT(proto, link)) {
- if (proto->proto == ISAKMP_PROTO_ISAKMP) {
+ switch (proto->proto) {
+ case ISAKMP_PROTO_ISAKMP:
args.spi_sz = ISAKMP_HDR_COOKIES_LEN;
args.u.d.spis = sa->cookies;
- } else {
+ break;
+
+ case IPSEC_PROTO_IPSEC_AH:
+ case IPSEC_PROTO_IPSEC_ESP:
+ case IPSEC_PROTO_IPCOMP:
args.spi_sz = proto->spi_sz[1];
args.u.d.spis = proto->spi[1];
+ break;
+ default:
+ log_print("message_send_delete: cannot delete unknown "
+ "protocol %d", proto->proto);
+ continue;
}
+
args.proto = proto->proto;
exchange_establish_p2(isakmp_sa, ISAKMP_EXCH_INFO, 0, &args,
0, 0);
diff --git a/sbin/isakmpd/sa.c b/sbin/isakmpd/sa.c
index 601b0c9360b..cf1b1ce82f1 100644
--- a/sbin/isakmpd/sa.c
+++ b/sbin/isakmpd/sa.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sa.c,v 1.101 2005/08/09 12:50:08 hshoexer Exp $ */
+/* $OpenBSD: sa.c,v 1.102 2005/09/23 14:44:03 hshoexer Exp $ */
/* $EOM: sa.c,v 1.112 2000/12/12 00:22:52 niklas Exp $ */
/*
@@ -34,6 +34,7 @@
#include <sys/types.h>
#include <stdlib.h>
#include <string.h>
+#include <netdb.h>
#include <regex.h>
#include <keynote.h>
@@ -198,8 +199,7 @@ sa_check_peer(struct sa *sa, void *v_addr)
return 0;
sa->transport->vtbl->get_dst(sa->transport, &dst);
- return SA_LEN(dst) == addr->len &&
- memcmp(dst, addr->addr, SA_LEN(dst)) == 0;
+ return (net_addrcmp(dst, addr->addr) == 0);
}
struct dst_isakmpspi_arg {
@@ -250,13 +250,13 @@ sa_lookup_isakmp_sa(struct sockaddr *dst, u_int8_t *spi)
/* Lookup a ready SA by the peer's address. */
struct sa *
-sa_lookup_by_peer(struct sockaddr *dst, socklen_t dstlen)
+sa_lookup_by_peer(struct sockaddr *dst, socklen_t dstlen, int phase)
{
struct addr_arg arg;
arg.addr = dst;
arg.len = dstlen;
- arg.phase = 0;
+ arg.phase = phase;
return sa_find(sa_check_peer, &arg);
}
diff --git a/sbin/isakmpd/sa.h b/sbin/isakmpd/sa.h
index 80a4cc1d448..cccd98a1451 100644
--- a/sbin/isakmpd/sa.h
+++ b/sbin/isakmpd/sa.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sa.h,v 1.46 2005/04/08 16:52:41 deraadt Exp $ */
+/* $OpenBSD: sa.h,v 1.47 2005/09/23 14:44:03 hshoexer Exp $ */
/* $EOM: sa.h,v 1.58 2000/10/10 12:39:01 provos Exp $ */
/*
@@ -254,7 +254,7 @@ extern void sa_reinit(void);
extern struct sa *sa_isakmp_lookup_by_peer(struct sockaddr *, socklen_t);
extern void sa_isakmp_upgrade(struct message *);
extern struct sa *sa_lookup(u_int8_t *, u_int8_t *);
-extern struct sa *sa_lookup_by_peer(struct sockaddr *, socklen_t);
+extern struct sa *sa_lookup_by_peer(struct sockaddr *, socklen_t, int);
extern struct sa *sa_lookup_by_header(u_int8_t *, int);
extern struct sa *sa_lookup_by_name(char *, int);
extern struct sa *sa_lookup_from_icookie(u_int8_t *);
diff --git a/sbin/isakmpd/ui.c b/sbin/isakmpd/ui.c
index b199c6da1a6..65f44b839b8 100644
--- a/sbin/isakmpd/ui.c
+++ b/sbin/isakmpd/ui.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ui.c,v 1.45 2005/04/08 22:32:10 cloder Exp $ */
+/* $OpenBSD: ui.c,v 1.46 2005/09/23 14:44:03 hshoexer Exp $ */
/* $EOM: ui.c,v 1.43 2000/10/05 09:25:12 niklas Exp $ */
/*
@@ -31,7 +31,10 @@
*/
#include <sys/types.h>
+#include <sys/socket.h>
#include <sys/stat.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
@@ -115,21 +118,58 @@ ui_connect(char *cmd)
connection_setup(name);
}
-/* Tear down a phase 2 connection. */
+/* Tear down a connection, can be phase 1 or 2. */
static void
ui_teardown(char *cmd)
{
- char name[81];
- struct sa *sa;
-
- if (sscanf(cmd, "t %80s", name) != 1) {
+ struct sockaddr_in addr;
+ struct sockaddr_in6 addr6;
+ struct sa *sa;
+ int phase;
+ char name[81];
+
+ /* If no phase is given, we default to phase 2. */
+ phase = 2;
+ if (sscanf(cmd, "t main %80s", name) == 1)
+ phase = 1;
+ else if (sscanf(cmd, "t quick %80s", name) == 1)
+ phase = 2;
+ else if (sscanf(cmd, "t %80s", name) != 1) {
log_print("ui_teardown: command \"%s\" malformed", cmd);
return;
}
- LOG_DBG((LOG_UI, 10, "ui_teardown: teardown connection \"%s\"", name));
- connection_teardown(name);
- while ((sa = sa_lookup_by_name(name, 2)) != 0)
- sa_delete(sa, 1);
+ 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);
+ }
}
/* Tear down all phase 2 connections. */