summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortobhe <tobhe@cvs.openbsd.org>2020-03-22 15:59:06 +0000
committertobhe <tobhe@cvs.openbsd.org>2020-03-22 15:59:06 +0000
commitaa50b79f7b828e124c091b2219b110aeb33eb575 (patch)
treed9ee6a8539b9bd2847a000a91992e0da2fd7168e
parent8a75cfc2ee756012bdb7852471091b5e974a8566 (diff)
Add 'ikectl show sa' command to print information about the state of
negotiated IKE SAs, their Child SAs and resulting IPsec flows. ok patrick@
-rw-r--r--sbin/iked/control.c23
-rw-r--r--sbin/iked/ikev2.c183
-rw-r--r--sbin/iked/types.h3
-rw-r--r--usr.sbin/ikectl/ikectl.c28
-rw-r--r--usr.sbin/ikectl/parser.c3
-rw-r--r--usr.sbin/ikectl/parser.h3
6 files changed, 222 insertions, 21 deletions
diff --git a/sbin/iked/control.c b/sbin/iked/control.c
index 44c6f92e104..751d9169083 100644
--- a/sbin/iked/control.c
+++ b/sbin/iked/control.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: control.c,v 1.27 2020/03/18 22:12:43 tobhe Exp $ */
+/* $OpenBSD: control.c,v 1.28 2020/03/22 15:59:05 tobhe Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -48,10 +48,11 @@ void control_dispatch_imsg(int, short, void *);
void control_dispatch_parent(int, short, void *);
void control_imsg_forward(struct imsg *);
void control_run(struct privsep *, struct privsep_proc *, void *);
+int control_dispatch_ikev2(int, struct privsep_proc *, struct imsg *);
static struct privsep_proc procs[] = {
{ "parent", PROC_PARENT, NULL },
- { "ikev2", PROC_IKEV2, NULL }
+ { "ikev2", PROC_IKEV2, control_dispatch_ikev2 },
};
pid_t
@@ -308,6 +309,10 @@ control_dispatch_imsg(int fd, short event, void *arg)
break;
case IMSG_CTL_RESET_ID:
proc_forward_imsg(&env->sc_ps, &imsg, PROC_IKEV2, -1);
+ case IMSG_CTL_SHOW_SA:
+ proc_forward_imsg(&env->sc_ps, &imsg, PROC_IKEV2, -1);
+ c->flags |= CTL_CONN_NOTIFY;
+ break;
break;
default:
log_debug("%s: error handling imsg %d",
@@ -331,3 +336,17 @@ control_imsg_forward(struct imsg *imsg)
0, imsg->hdr.pid, -1, imsg->data,
imsg->hdr.len - IMSG_HEADER_SIZE);
}
+
+int
+control_dispatch_ikev2(int fd, struct privsep_proc *p, struct imsg *imsg)
+{
+ switch (imsg->hdr.type) {
+ case IMSG_CTL_SHOW_SA:
+ control_imsg_forward(imsg);
+ return (0);
+ default:
+ break;
+ }
+
+ return (-1);
+}
diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c
index 81d21f78529..8d729952bf2 100644
--- a/sbin/iked/ikev2.c
+++ b/sbin/iked/ikev2.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikev2.c,v 1.198 2020/03/20 18:11:39 tobhe Exp $ */
+/* $OpenBSD: ikev2.c,v 1.199 2020/03/22 15:59:05 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -46,6 +46,11 @@
#include "eap.h"
#include "dh.h"
+void ikev2_info(struct iked *, int);
+void ikev2_info_sa(struct iked *, int, const char *, struct iked_sa *);
+void ikev2_info_csa(struct iked *, int, const char *, struct iked_childsa *);
+void ikev2_info_flow(struct iked *, int, const char *, struct iked_flow *);
+
void ikev2_run(struct privsep *, struct privsep_proc *, void *);
int ikev2_dispatch_parent(int, struct privsep_proc *, struct imsg *);
int ikev2_dispatch_cert(int, struct privsep_proc *, struct imsg *);
@@ -157,6 +162,7 @@ int ikev2_resp_informational(struct iked *, struct iked_sa *,
struct iked_message *);
void ikev2_ctl_reset_id(struct iked *, struct imsg *, unsigned int);
+void ikev2_ctl_show_sa(struct iked *, struct imsg *);
static struct privsep_proc procs[] = {
{ "parent", PROC_PARENT, ikev2_dispatch_parent },
@@ -388,6 +394,9 @@ ikev2_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
case IMSG_CTL_RESET_ID:
ikev2_ctl_reset_id(env, imsg, imsg->hdr.type);
break;
+ case IMSG_CTL_SHOW_SA:
+ ikev2_ctl_show_sa(env, imsg);
+ break;
default:
return (-1);
}
@@ -395,20 +404,6 @@ ikev2_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg)
return (0);
}
-const char *
-ikev2_ikesa_info(uint64_t spi, const char *msg)
-{
- static char buf[1024];
- const char *spistr;
-
- spistr = print_spi(spi, 8);
- if (msg)
- snprintf(buf, sizeof(buf), "spi=%s: %s", spistr, msg);
- else
- snprintf(buf, sizeof(buf), "spi=%s: ", spistr);
- return buf;
-}
-
void
ikev2_ctl_reset_id(struct iked *env, struct imsg *imsg, unsigned int type)
{
@@ -441,6 +436,11 @@ ikev2_ctl_reset_id(struct iked *env, struct imsg *imsg, unsigned int type)
free(reset_id);
}
+void
+ikev2_ctl_show_sa(struct iked *env, struct imsg *imsg)
+{
+ ikev2_info(env, 0);
+}
struct iked_sa *
ikev2_getimsgdata(struct iked *env, struct imsg *imsg, struct iked_sahdr *sh,
@@ -6291,3 +6291,156 @@ ikev2_update_sa_addresses(struct iked *env, struct iked_sa *sa)
return 0;
}
+
+void
+ikev2_info_sa(struct iked *env, int dolog, const char *msg, struct iked_sa *sa)
+{
+ char idstr[IKED_ID_SIZE];
+ char *buf;
+ int buflen;
+
+ if (ikev2_print_id(IKESA_DSTID(sa), idstr, sizeof(idstr)) == -1)
+ bzero(idstr, sizeof(idstr));
+
+ buflen = asprintf(&buf,
+ "%s: %p rspi %s ispi %s %s->%s<%s>[%s] %s %c%s%s nexti %p pol %p\n",
+ msg, sa,
+ print_spi(sa->sa_hdr.sh_rspi, 8),
+ print_spi(sa->sa_hdr.sh_ispi, 8),
+ print_host((struct sockaddr *)&sa->sa_local.addr, NULL, 0),
+ print_host((struct sockaddr *)&sa->sa_peer.addr, NULL, 0),
+ idstr,
+ sa->sa_addrpool ?
+ print_host((struct sockaddr *)&sa->sa_addrpool->addr, NULL, 0) : "",
+ print_map(sa->sa_state, ikev2_state_map),
+ sa->sa_hdr.sh_initiator ? 'i' : 'r',
+ sa->sa_natt ? " natt" : "",
+ sa->sa_udpencap ? " udpecap" : "",
+ sa->sa_nexti, sa->sa_policy);
+
+ if (buflen == -1 || buf == NULL)
+ return;
+
+ if (dolog) {
+ if (buflen > 1)
+ buf[buflen - 1] = '\0';
+ log_debug("%s", buf);
+ } else
+ proc_compose(&env->sc_ps, PROC_CONTROL, IMSG_CTL_SHOW_SA,
+ buf, buflen + 1);
+ free(buf);
+}
+
+void
+ikev2_info_csa(struct iked *env, int dolog, const char *msg, struct iked_childsa *csa)
+{
+ char *buf;
+ int buflen;
+
+ buflen = asprintf(&buf,
+ "%s: %p %s %s %s %s -> %s (%s%s%s%s) B=%p P=%p @%p\n", msg, csa,
+ print_map(csa->csa_saproto, ikev2_saproto_map),
+ print_spi(csa->csa_spi.spi, csa->csa_spi.spi_size),
+ csa->csa_dir == IPSP_DIRECTION_IN ? "in" : "out",
+ print_host((struct sockaddr *)&csa->csa_local->addr, NULL, 0),
+ print_host((struct sockaddr *)&csa->csa_peer->addr, NULL, 0),
+ csa->csa_loaded ? "L" : "",
+ csa->csa_rekey ? "R" : "",
+ csa->csa_allocated ? "A" : "",
+ csa->csa_persistent ? "P" : "",
+ csa->csa_bundled,
+ csa->csa_peersa,
+ csa->csa_ikesa);
+
+ if (buflen == -1 || buf == NULL)
+ return;
+
+ if (dolog) {
+ if (buflen > 1)
+ buf[buflen - 1] = '\0';
+ log_debug("%s", buf);
+ } else
+ proc_compose(&env->sc_ps, PROC_CONTROL, IMSG_CTL_SHOW_SA,
+ buf, buflen + 1);
+ free(buf);
+}
+
+void
+ikev2_info_flow(struct iked *env, int dolog, const char *msg, struct iked_flow *flow)
+{
+ char *buf;
+ int buflen;
+
+ buflen = asprintf(&buf,
+ "%s: %p %s %s %s/%d -> %s/%d [%u] (%s) @%p\n", msg, flow,
+ print_map(flow->flow_saproto, ikev2_saproto_map),
+ flow->flow_dir == IPSP_DIRECTION_IN ? "in" : "out",
+ print_host((struct sockaddr *)&flow->flow_src.addr, NULL, 0),
+ flow->flow_src.addr_mask,
+ print_host((struct sockaddr *)&flow->flow_dst.addr, NULL, 0),
+ flow->flow_dst.addr_mask,
+ flow->flow_ipproto,
+ flow->flow_loaded ? "L" : "",
+ flow->flow_ikesa);
+
+ if (buflen == -1 || buf == NULL)
+ return;
+
+ if (dolog) {
+ if (buflen > 1)
+ buf[buflen - 1] = '\0';
+ log_debug("%s", buf);
+ } else
+ proc_compose(&env->sc_ps, PROC_CONTROL, IMSG_CTL_SHOW_SA,
+ buf, buflen + 1);
+ free(buf);
+}
+
+void
+ikev2_info(struct iked *env, int dolog)
+{
+ struct iked_sa *sa;
+ struct iked_childsa *csa, *ipcomp;
+ struct iked_flow *flow;
+
+ log_debug("%s: called", __func__);
+
+ RB_FOREACH(sa, iked_sas, &env->sc_sas) {
+ ikev2_info_sa(env, dolog, "iked_sas", sa);
+ TAILQ_FOREACH(csa, &sa->sa_childsas, csa_entry) {
+ ikev2_info_csa(env, dolog, " sa_childsas", csa);
+ if ((ipcomp = csa->csa_bundled) != NULL)
+ ikev2_info_csa(env, dolog, " ",
+ ipcomp);
+ }
+ TAILQ_FOREACH(flow, &sa->sa_flows, flow_entry) {
+ ikev2_info_flow(env, dolog, " sa_flows", flow);
+ }
+ }
+ RB_FOREACH(csa, iked_activesas, &env->sc_activesas) {
+ ikev2_info_csa(env, dolog, "iked_activesas", csa);
+ if ((ipcomp = csa->csa_bundled) != NULL)
+ ikev2_info_csa(env, dolog, " ", ipcomp);
+ }
+ RB_FOREACH(flow, iked_flows, &env->sc_activeflows) {
+ ikev2_info_flow(env, dolog, "iked_flows", flow);
+ }
+ if (dolog)
+ return;
+ /* Send empty reply to indicate end of information. */
+ proc_compose(&env->sc_ps, PROC_CONTROL, IMSG_CTL_SHOW_SA, NULL, 0);
+}
+
+const char *
+ikev2_ikesa_info(uint64_t spi, const char *msg)
+{
+ static char buf[1024];
+ const char *spistr;
+
+ spistr = print_spi(spi, 8);
+ if (msg)
+ snprintf(buf, sizeof(buf), "spi=%s: %s", spistr, msg);
+ else
+ snprintf(buf, sizeof(buf), "spi=%s: ", spistr);
+ return buf;
+}
diff --git a/sbin/iked/types.h b/sbin/iked/types.h
index 0d0d64e9ae0..9211defc2dd 100644
--- a/sbin/iked/types.h
+++ b/sbin/iked/types.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: types.h,v 1.33 2020/03/18 22:12:43 tobhe Exp $ */
+/* $OpenBSD: types.h,v 1.34 2020/03/22 15:59:05 tobhe Exp $ */
/*
* Copyright (c) 2019 Tobias Heider <tobias.heider@stusta.de>
@@ -106,6 +106,7 @@ enum imsg_type {
IMSG_CTL_FRAGMENTATION,
IMSG_CTL_NATTPORT,
IMSG_CTL_RESET_ID,
+ IMSG_CTL_SHOW_SA,
IMSG_COMPILE,
IMSG_UDP_SOCKET,
IMSG_PFKEY_SOCKET,
diff --git a/usr.sbin/ikectl/ikectl.c b/usr.sbin/ikectl/ikectl.c
index 91b3dd317bf..71f403d39ed 100644
--- a/usr.sbin/ikectl/ikectl.c
+++ b/usr.sbin/ikectl/ikectl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ikectl.c,v 1.24 2020/03/18 22:12:43 tobhe Exp $ */
+/* $OpenBSD: ikectl.c,v 1.25 2020/03/22 15:59:05 tobhe Exp $ */
/*
* Copyright (c) 2007-2013 Reyk Floeter <reyk@openbsd.org>
@@ -48,6 +48,8 @@ struct imsgname *monitor_lookup(uint8_t);
void monitor_id(struct imsg *);
int monitor(struct imsg *);
+int show_string(struct imsg *);
+
int ca_opt(struct parse_result *);
struct imsgname imsgs[] = {
@@ -56,6 +58,7 @@ struct imsgname imsgs[] = {
{ IMSG_CTL_VERBOSE, "verbose", NULL },
{ IMSG_CTL_RELOAD, "reload", NULL },
{ IMSG_CTL_RESET, "reset", NULL },
+ { IMSG_CTL_SHOW_SA, "show sa", NULL },
{ 0, NULL, NULL }
};
@@ -295,6 +298,10 @@ main(int argc, char *argv[])
imsg_compose(ibuf, IMSG_CTL_RESET_ID, 0, 0, -1,
res->id, strlen(res->id));
break;
+ case SHOW_SA:
+ imsg_compose(ibuf, IMSG_CTL_SHOW_SA, 0, 0, -1, NULL, 0);
+ done = 0;
+ break;
case RELOAD:
imsg_compose(ibuf, IMSG_CTL_RELOAD, 0, 0, -1, NULL, 0);
break;
@@ -342,6 +349,9 @@ main(int argc, char *argv[])
case MONITOR:
done = monitor(&imsg);
break;
+ case SHOW_SA:
+ done = show_string(&imsg);
+ break;
default:
break;
}
@@ -385,3 +395,19 @@ monitor(struct imsg *imsg)
return (done);
}
+
+int
+show_string(struct imsg *imsg)
+{
+ int done = 0;
+
+ if (imsg->hdr.type != IMSG_CTL_SHOW_SA)
+ return (done);
+
+ if (IMSG_DATA_SIZE(imsg) > 0)
+ printf("%s", imsg->data);
+ else
+ done = 1;
+
+ return (done);
+}
diff --git a/usr.sbin/ikectl/parser.c b/usr.sbin/ikectl/parser.c
index 1d47b98cdb1..fceb60d3d58 100644
--- a/usr.sbin/ikectl/parser.c
+++ b/usr.sbin/ikectl/parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.c,v 1.18 2020/03/18 22:12:43 tobhe Exp $ */
+/* $OpenBSD: parser.c,v 1.19 2020/03/22 15:59:05 tobhe Exp $ */
/*
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
@@ -213,6 +213,7 @@ static const struct token t_ca_key_path[] = {
static const struct token t_show[] = {
{ KEYWORD, "ca", SHOW_CA, t_show_ca },
+ { KEYWORD, "sa", SHOW_SA, NULL },
{ ENDTOKEN, "", NONE, NULL }
};
diff --git a/usr.sbin/ikectl/parser.h b/usr.sbin/ikectl/parser.h
index 35188bcc343..e69096ab2cd 100644
--- a/usr.sbin/ikectl/parser.h
+++ b/usr.sbin/ikectl/parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: parser.h,v 1.15 2020/03/18 22:12:43 tobhe Exp $ */
+/* $OpenBSD: parser.h,v 1.16 2020/03/22 15:59:05 tobhe Exp $ */
/*
* Copyright (c) 2007-2013 Reyk Floeter <reyk@openbsd.org>
@@ -55,6 +55,7 @@ enum actions {
CA_KEY_IMPORT,
SHOW_CA,
SHOW_CA_CERTIFICATES,
+ SHOW_SA,
RESET_ID
};