summaryrefslogtreecommitdiff
path: root/sbin/iked
diff options
context:
space:
mode:
authorTobias Heider <tobhe@cvs.openbsd.org>2024-01-24 10:09:08 +0000
committerTobias Heider <tobhe@cvs.openbsd.org>2024-01-24 10:09:08 +0000
commit3edd2a0e0bd880e87b6a603b53acde1486853eef (patch)
treea53c62b20bb53f884f67d84fec597e0871ebc8e8 /sbin/iked
parent03b9318690632ca9e32842782f6f891eb32000c6 (diff)
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@
Diffstat (limited to 'sbin/iked')
-rw-r--r--sbin/iked/ca.c20
-rw-r--r--sbin/iked/control.c32
-rw-r--r--sbin/iked/iked.h3
-rw-r--r--sbin/iked/ikev2.c69
4 files changed, 80 insertions, 44 deletions
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 <reyk@openbsd.org>
@@ -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 <reyk@openbsd.org>
@@ -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 <tobias.heider@stusta.de>
@@ -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 <tobias.heider@stusta.de>
@@ -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 *