diff options
author | tobhe <tobhe@cvs.openbsd.org> | 2020-03-22 15:59:06 +0000 |
---|---|---|
committer | tobhe <tobhe@cvs.openbsd.org> | 2020-03-22 15:59:06 +0000 |
commit | aa50b79f7b828e124c091b2219b110aeb33eb575 (patch) | |
tree | d9ee6a8539b9bd2847a000a91992e0da2fd7168e | |
parent | 8a75cfc2ee756012bdb7852471091b5e974a8566 (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.c | 23 | ||||
-rw-r--r-- | sbin/iked/ikev2.c | 183 | ||||
-rw-r--r-- | sbin/iked/types.h | 3 | ||||
-rw-r--r-- | usr.sbin/ikectl/ikectl.c | 28 | ||||
-rw-r--r-- | usr.sbin/ikectl/parser.c | 3 | ||||
-rw-r--r-- | usr.sbin/ikectl/parser.h | 3 |
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 }; |