From: tobhe Date: Wed, 24 Jan 2024 10:09:07 +0000 (+0000) Subject: Use per connection peerid for control replies X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=0fbd6532620f9c8c7edb0900f5f2142fbbbab551;p=openbsd Use per connection peerid for control replies instead of 'broadcasting' replies for 'ikectl show sa' and similar control requests, we now assign a uniq peerid to each request and pass this peerid between the processes so the reply can be sent on the matching connection. from markus@ --- diff --git a/sbin/iked/ca.c b/sbin/iked/ca.c index 398a9ffacc4..8c1cdd21848 100644 --- a/sbin/iked/ca.c +++ b/sbin/iked/ca.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ca.c,v 1.98 2024/01/15 15:29:00 tobhe Exp $ */ +/* $OpenBSD: ca.c,v 1.99 2024/01/24 10:09:07 tobhe Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter @@ -76,7 +76,7 @@ int ca_x509_subjectaltname_get(X509 *cert, struct iked_id *); int ca_dispatch_parent(int, struct privsep_proc *, struct imsg *); int ca_dispatch_ikev2(int, struct privsep_proc *, struct imsg *); int ca_dispatch_control(int, struct privsep_proc *, struct imsg *); -void ca_store_info(struct iked *, const char *, X509_STORE *); +void ca_store_info(struct iked *, struct imsg *, const char *, X509_STORE *); static struct privsep_proc procs[] = { { "parent", PROC_PARENT, ca_dispatch_parent }, @@ -391,11 +391,12 @@ ca_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg) switch (imsg->hdr.type) { case IMSG_CTL_SHOW_CERTSTORE: - ca_store_info(env, "CA", store->ca_cas); - ca_store_info(env, "CERT", store->ca_certs); + ca_store_info(env, imsg, "CA", store->ca_cas); + ca_store_info(env, imsg, "CERT", store->ca_certs); /* Send empty reply to indicate end of information. */ - proc_compose(&env->sc_ps, PROC_CONTROL, IMSG_CTL_SHOW_CERTSTORE, - NULL, 0); + proc_compose_imsg(&env->sc_ps, PROC_CONTROL, -1, + IMSG_CTL_SHOW_CERTSTORE, imsg->hdr.peerid, + -1, NULL, 0); break; default: return (-1); @@ -1333,7 +1334,7 @@ ca_subjectpubkey_digest(X509 *x509, uint8_t *md, unsigned int *size) } void -ca_store_info(struct iked *env, const char *msg, X509_STORE *ctx) +ca_store_info(struct iked *env, struct imsg *imsg, const char *msg, X509_STORE *ctx) { STACK_OF(X509_OBJECT) *h; X509_OBJECT *xo; @@ -1357,8 +1358,9 @@ ca_store_info(struct iked *env, const char *msg, X509_STORE *ctx) OPENSSL_free(name); if (buflen == -1) continue; - proc_compose(&env->sc_ps, PROC_CONTROL, IMSG_CTL_SHOW_CERTSTORE, - buf, buflen + 1); + proc_compose_imsg(&env->sc_ps, PROC_CONTROL, -1, + IMSG_CTL_SHOW_CERTSTORE, imsg->hdr.peerid, + -1, buf, buflen + 1); free(buf); } } diff --git a/sbin/iked/control.c b/sbin/iked/control.c index 5b734703338..d690af946bd 100644 --- a/sbin/iked/control.c +++ b/sbin/iked/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.37 2023/03/08 04:43:06 guenther Exp $ */ +/* $OpenBSD: control.c,v 1.38 2024/01/24 10:09:07 tobhe Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter @@ -36,6 +36,7 @@ #define CONTROL_BACKLOG 5 struct ctl_connlist ctl_conns = TAILQ_HEAD_INITIALIZER(ctl_conns); +uint32_t ctl_peerid; void control_accept(int, short, void *); @@ -45,6 +46,7 @@ void control_close(int, struct control_sock *); void control_dispatch_imsg(int, short, void *); void control_dispatch_parent(int, short, void *); void control_imsg_forward(struct imsg *); +void control_imsg_forward_peerid(struct imsg *); void control_run(struct privsep *, struct privsep_proc *, void *); int control_dispatch_ikev2(int, struct privsep_proc *, struct imsg *); int control_dispatch_ca(int, struct privsep_proc *, struct imsg *); @@ -160,6 +162,7 @@ control_accept(int listenfd, short event, void *arg) socklen_t len; struct sockaddr_un s_un; struct ctl_conn *c; + struct ctl_conn *other; event_add(&cs->cs_ev, NULL); if ((event & EV_TIMEOUT)) @@ -197,6 +200,12 @@ control_accept(int listenfd, short event, void *arg) c->iev.handler, c->iev.data); event_add(&c->iev.ev, NULL); + /* O(n^2), but n is small */ + c->peerid = ctl_peerid++; + TAILQ_FOREACH(other, &ctl_conns, entry) + if (c->peerid == other->peerid) + c->peerid = ctl_peerid++; + TAILQ_INSERT_TAIL(&ctl_conns, c, entry); } @@ -277,6 +286,9 @@ control_dispatch_imsg(int fd, short event, void *arg) control_imsg_forward(&imsg); + /* record peerid of connection for reply */ + imsg.hdr.peerid = c->peerid; + switch (imsg.hdr.type) { case IMSG_CTL_NOTIFY: if (c->flags & CTL_CONN_NOTIFY) { @@ -311,11 +323,9 @@ control_dispatch_imsg(int fd, short event, void *arg) case IMSG_CTL_SHOW_SA: case IMSG_CTL_SHOW_STATS: proc_forward_imsg(&env->sc_ps, &imsg, PROC_IKEV2, -1); - c->flags |= CTL_CONN_NOTIFY; break; case IMSG_CTL_SHOW_CERTSTORE: proc_forward_imsg(&env->sc_ps, &imsg, PROC_CERT, -1); - c->flags |= CTL_CONN_NOTIFY; break; default: log_debug("%s: error handling imsg %d", @@ -340,13 +350,25 @@ control_imsg_forward(struct imsg *imsg) imsg->hdr.len - IMSG_HEADER_SIZE); } +void +control_imsg_forward_peerid(struct imsg *imsg) +{ + struct ctl_conn *c; + + TAILQ_FOREACH(c, &ctl_conns, entry) + if (c->peerid == imsg->hdr.peerid) + imsg_compose_event(&c->iev, imsg->hdr.type, + 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: case IMSG_CTL_SHOW_STATS: - control_imsg_forward(imsg); + control_imsg_forward_peerid(imsg); return (0); default: break; @@ -360,7 +382,7 @@ control_dispatch_ca(int fd, struct privsep_proc *p, struct imsg *imsg) { switch (imsg->hdr.type) { case IMSG_CTL_SHOW_CERTSTORE: - control_imsg_forward(imsg); + control_imsg_forward_peerid(imsg); return (0); default: break; diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h index 89d491aba29..9717489714c 100644 --- a/sbin/iked/iked.h +++ b/sbin/iked/iked.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iked.h,v 1.225 2024/01/15 15:29:00 tobhe Exp $ */ +/* $OpenBSD: iked.h,v 1.226 2024/01/24 10:09:07 tobhe Exp $ */ /* * Copyright (c) 2019 Tobias Heider @@ -99,6 +99,7 @@ struct ctl_conn { uint8_t flags; #define CTL_CONN_NOTIFY 0x01 struct imsgev iev; + uint32_t peerid; }; TAILQ_HEAD(ctl_connlist, ctl_conn); diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c index 27f246c3a21..0f7a966a623 100644 --- a/sbin/iked/ikev2.c +++ b/sbin/iked/ikev2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ikev2.c,v 1.382 2024/01/15 21:37:58 jan Exp $ */ +/* $OpenBSD: ikev2.c,v 1.383 2024/01/24 10:09:07 tobhe Exp $ */ /* * Copyright (c) 2019 Tobias Heider @@ -48,10 +48,13 @@ #include "chap_ms.h" #include "version.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_info(struct iked *, struct imsg *, int); +void ikev2_info_sa(struct iked *, struct imsg *, int, const char *, + struct iked_sa *); +void ikev2_info_csa(struct iked *, struct imsg *, int, const char *, + struct iked_childsa *); +void ikev2_info_flow(struct iked *, struct imsg *, int, const char *, + struct iked_flow *); void ikev2_log_established(struct iked_sa *); void ikev2_log_proposal(struct iked_sa *, struct iked_proposals *); void ikev2_log_cert_info(const char *, struct iked_id *); @@ -188,8 +191,8 @@ 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 *); -void ikev2_ctl_show_stats(struct iked *); +void ikev2_ctl_show_sa(struct iked *, struct imsg *); +void ikev2_ctl_show_stats(struct iked *, struct imsg *); static struct privsep_proc procs[] = { { "parent", PROC_PARENT, ikev2_dispatch_parent }, @@ -512,10 +515,10 @@ ikev2_dispatch_control(int fd, struct privsep_proc *p, struct imsg *imsg) ikev2_ctl_reset_id(env, imsg, imsg->hdr.type); break; case IMSG_CTL_SHOW_SA: - ikev2_ctl_show_sa(env); + ikev2_ctl_show_sa(env, imsg); break; case IMSG_CTL_SHOW_STATS: - ikev2_ctl_show_stats(env); + ikev2_ctl_show_stats(env, imsg); break; default: return (-1); @@ -572,15 +575,16 @@ ikev2_ctl_reset_id(struct iked *env, struct imsg *imsg, unsigned int type) } void -ikev2_ctl_show_sa(struct iked *env) +ikev2_ctl_show_sa(struct iked *env, struct imsg *imsg) { - ikev2_info(env, 0); + ikev2_info(env, imsg, 0); } void -ikev2_ctl_show_stats(struct iked *env) +ikev2_ctl_show_stats(struct iked *env, struct imsg *imsg) { - proc_compose(&env->sc_ps, PROC_CONTROL, IMSG_CTL_SHOW_STATS, + proc_compose_imsg(&env->sc_ps, PROC_CONTROL, -1, + IMSG_CTL_SHOW_STATS, imsg->hdr.peerid, -1, &env->sc_stats, sizeof(env->sc_stats)); } @@ -7444,7 +7448,8 @@ ikev2_update_sa_addresses(struct iked *env, struct iked_sa *sa) } void -ikev2_info_sa(struct iked *env, int dolog, const char *msg, struct iked_sa *sa) +ikev2_info_sa(struct iked *env, struct imsg *imsg, int dolog, const char *msg, + struct iked_sa *sa) { char idstr[IKED_ID_SIZE]; char *buf; @@ -7476,13 +7481,15 @@ ikev2_info_sa(struct iked *env, int dolog, const char *msg, struct iked_sa *sa) buf[buflen - 1] = '\0'; log_debug("%s", buf); } else - proc_compose(&env->sc_ps, PROC_CONTROL, IMSG_CTL_SHOW_SA, + proc_compose_imsg(&env->sc_ps, PROC_CONTROL, -1, + IMSG_CTL_SHOW_SA, imsg->hdr.peerid, -1, buf, buflen + 1); free(buf); } void -ikev2_info_csa(struct iked *env, int dolog, const char *msg, struct iked_childsa *csa) +ikev2_info_csa(struct iked *env, struct imsg *imsg, int dolog, const char *msg, + struct iked_childsa *csa) { char *buf; int buflen; @@ -7510,13 +7517,15 @@ ikev2_info_csa(struct iked *env, int dolog, const char *msg, struct iked_childsa buf[buflen - 1] = '\0'; log_debug("%s", buf); } else - proc_compose(&env->sc_ps, PROC_CONTROL, IMSG_CTL_SHOW_SA, + proc_compose_imsg(&env->sc_ps, PROC_CONTROL, -1, + IMSG_CTL_SHOW_SA, imsg->hdr.peerid, -1, buf, buflen + 1); free(buf); } void -ikev2_info_flow(struct iked *env, int dolog, const char *msg, struct iked_flow *flow) +ikev2_info_flow(struct iked *env, struct imsg *imsg, int dolog, const char *msg, + struct iked_flow *flow) { char prenat_mask[10]; char *buf; @@ -7555,13 +7564,14 @@ ikev2_info_flow(struct iked *env, int dolog, const char *msg, struct iked_flow * buf[buflen - 1] = '\0'; log_debug("%s", buf); } else - proc_compose(&env->sc_ps, PROC_CONTROL, IMSG_CTL_SHOW_SA, + proc_compose_imsg(&env->sc_ps, PROC_CONTROL, -1, + IMSG_CTL_SHOW_SA, imsg->hdr.peerid, -1, buf, buflen + 1); free(buf); } void -ikev2_info(struct iked *env, int dolog) +ikev2_info(struct iked *env, struct imsg *imsg, int dolog) { struct iked_sa *sa; struct iked_childsa *csa, *ipcomp; @@ -7570,32 +7580,33 @@ ikev2_info(struct iked *env, int dolog) log_debug("%s: called", __func__); RB_FOREACH(sa, iked_sas, &env->sc_sas) { - ikev2_info_sa(env, dolog, "iked_sas", sa); + ikev2_info_sa(env, imsg, dolog, "iked_sas", sa); TAILQ_FOREACH(csa, &sa->sa_childsas, csa_entry) { - ikev2_info_csa(env, dolog, " sa_childsas", csa); + ikev2_info_csa(env, imsg, dolog, " sa_childsas", csa); if ((ipcomp = csa->csa_bundled) != NULL) - ikev2_info_csa(env, dolog, " ", + ikev2_info_csa(env, imsg, dolog, " ", ipcomp); } TAILQ_FOREACH(flow, &sa->sa_flows, flow_entry) { - ikev2_info_flow(env, dolog, " sa_flows", flow); + ikev2_info_flow(env, imsg, dolog, " sa_flows", flow); } } RB_FOREACH(csa, iked_activesas, &env->sc_activesas) { - ikev2_info_csa(env, dolog, "iked_activesas", csa); + ikev2_info_csa(env, imsg, dolog, "iked_activesas", csa); if ((ipcomp = csa->csa_bundled) != NULL) - ikev2_info_csa(env, dolog, " ", ipcomp); + ikev2_info_csa(env, imsg, dolog, " ", ipcomp); } RB_FOREACH(flow, iked_flows, &env->sc_activeflows) { - ikev2_info_flow(env, dolog, "iked_flows", flow); + ikev2_info_flow(env, imsg, dolog, "iked_flows", flow); } RB_FOREACH(sa, iked_dstid_sas, &env->sc_dstid_sas) { - ikev2_info_sa(env, dolog, "iked_dstid_sas", sa); + ikev2_info_sa(env, imsg, dolog, "iked_dstid_sas", sa); } if (dolog) return; /* Send empty reply to indicate end of information. */ - proc_compose(&env->sc_ps, PROC_CONTROL, IMSG_CTL_SHOW_SA, NULL, 0); + proc_compose_imsg(&env->sc_ps, PROC_CONTROL, -1, IMSG_CTL_SHOW_SA, + imsg->hdr.peerid, -1, NULL, 0); } const char *