diff options
Diffstat (limited to 'sbin/isakmpd')
-rw-r--r-- | sbin/isakmpd/ipsec.c | 4 | ||||
-rw-r--r-- | sbin/isakmpd/message.c | 17 | ||||
-rw-r--r-- | sbin/isakmpd/sa.c | 10 | ||||
-rw-r--r-- | sbin/isakmpd/sa.h | 4 | ||||
-rw-r--r-- | sbin/isakmpd/ui.c | 60 |
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. */ |