summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2024-07-22 09:39:24 +0000
committerYASUOKA Masahiko <yasuoka@cvs.openbsd.org>2024-07-22 09:39:24 +0000
commit986428a3fd53c383b162ea5329b9cf2e3937b925 (patch)
tree058720c78717f6033ba30d6739a7ef4a2c54a0ae /usr.sbin
parent0cffbe26a53662ec01b5dfa27a67005d5d35cdbf (diff)
Modify ipcp module to return a result for
IMSG_RADIUSD_MODULE_IPCP_DISCONNECT and radiusctl to handle the result.
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/radiusctl/radiusctl.c11
-rw-r--r--usr.sbin/radiusd/radiusd_ipcp.c48
2 files changed, 55 insertions, 4 deletions
diff --git a/usr.sbin/radiusctl/radiusctl.c b/usr.sbin/radiusctl/radiusctl.c
index 9caaabe181a..d3bc45eb866 100644
--- a/usr.sbin/radiusctl/radiusctl.c
+++ b/usr.sbin/radiusctl/radiusctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: radiusctl.c,v 1.10 2024/07/14 11:12:32 yasuoka Exp $ */
+/* $OpenBSD: radiusctl.c,v 1.11 2024/07/22 09:39:23 yasuoka Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
*
@@ -180,7 +180,6 @@ main(int argc, char *argv[])
iov[niov++].iov_len = sizeof(res->session_seq);
imsg_composev(&ibuf, IMSG_RADIUSD_MODULE_IPCP_DISCONNECT, 0, 0,
-1, iov, niov);
- done = 1;
break;
}
while (ibuf.w.queued) {
@@ -200,6 +199,7 @@ main(int argc, char *argv[])
case IPCP_SHOW:
case IPCP_DUMP:
case IPCP_MONITOR:
+ case IPCP_DISCONNECT:
done = ipcp_handle_imsg(res, &imsg, cnt++);
break;
default:
@@ -625,6 +625,13 @@ ipcp_handle_imsg(struct parse_result *res, struct imsg *imsg, int cnt)
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
switch (imsg->hdr.type) {
+ case IMSG_OK:
+ if (datalen > 0 && *((char *)imsg->data + datalen - 1) == '\0')
+ fprintf(stderr, "OK: %s\n", (char *)imsg->data);
+ else
+ fprintf(stderr, "OK\n");
+ done = 1;
+ break;
case IMSG_NG:
if (datalen > 0 && *((char *)imsg->data + datalen - 1) == '\0')
fprintf(stderr, "error: %s\n", (char *)imsg->data);
diff --git a/usr.sbin/radiusd/radiusd_ipcp.c b/usr.sbin/radiusd/radiusd_ipcp.c
index d007067ecf0..4f34d2972fd 100644
--- a/usr.sbin/radiusd/radiusd_ipcp.c
+++ b/usr.sbin/radiusd/radiusd_ipcp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: radiusd_ipcp.c,v 1.5 2024/07/17 11:31:46 yasuoka Exp $ */
+/* $OpenBSD: radiusd_ipcp.c,v 1.6 2024/07/22 09:39:23 yasuoka Exp $ */
/*
* Copyright (c) 2024 Internet Initiative Japan Inc.
@@ -68,6 +68,11 @@ struct user {
char name[0];
};
+struct radiusctl_client {
+ int peerid;
+ TAILQ_ENTRY(radiusctl_client) entry;
+};
+
struct module_ipcp_dae;
struct assigned_ipv4 {
@@ -98,6 +103,7 @@ struct assigned_ipv4 {
TAILQ_ENTRY(assigned_ipv4) dae_next;
int dae_ntry;
struct event dae_evtimer;
+ TAILQ_HEAD(, radiusctl_client) dae_clients;
};
struct module_ipcp_ctrlconn {
@@ -517,6 +523,7 @@ ipcp_config_set(void *ctx, const char *name, int argc, char * const * argv)
*dae0 = dae;
TAILQ_INIT(&dae0->reqs);
TAILQ_INSERT_TAIL(&module->daes, dae0, next);
+ dae0->ipcp = module;
} else if (strcmp(name, "_debug") == 0)
log_init(1);
else if (strncmp(name, "_", 1) == 0)
@@ -544,6 +551,8 @@ ipcp_dispatch_control(void *ctx, struct imsg *imsg)
size_t dumpsiz;
u_int datalen;
unsigned seq;
+ struct radiusctl_client *client;
+ const char *cause;
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
switch (imsg->hdr.type) {
@@ -616,9 +625,13 @@ ipcp_dispatch_control(void *ctx, struct imsg *imsg)
if (assign->seq == seq)
break;
}
- if (assign == NULL)
+ if (assign == NULL) {
+ cause = "session not found";
log_warnx("Disconnect seq=%u requested, but the "
"session is not found", seq);
+ module_imsg_compose(self->base, IMSG_NG,
+ imsg->hdr.peerid, 0, -1, cause, strlen(cause) + 1);
+ }
else {
if (assign->dae == NULL)
log_warnx("Disconnect seq=%u requested, but "
@@ -626,9 +639,18 @@ ipcp_dispatch_control(void *ctx, struct imsg *imsg)
else {
log_info("Disconnect seq=%u requested",
assign->seq);
+ if ((client = calloc(1, sizeof(struct
+ radiusctl_client))) == NULL) {
+ log_warn("%s: calloc: %m",
+ __func__);
+ goto fail;
+ }
+ client->peerid = imsg->hdr.peerid;
if (assign->dae_ntry == 0)
ipcp_dae_send_disconnect_request(
assign);
+ TAILQ_INSERT_TAIL(&assign->dae_clients,
+ client, entry);
}
}
break;
@@ -1189,6 +1211,7 @@ ipcp_ipv4_assign(struct module_ipcp *self, struct user *user,
ip->authtime = self->uptime;
RB_INSERT(assigned_ipv4_tree, &self->ipv4s, ip);
TAILQ_INSERT_TAIL(&user->ipv4s, ip, next);
+ TAILQ_INIT(&ip->dae_clients);
self->nsessions++;
ip->seq = self->seq++;
@@ -1562,12 +1585,14 @@ void
ipcp_dae_on_event(int fd, short ev, void *ctx)
{
struct module_ipcp_dae *dae = ctx;
+ struct module_ipcp *self = dae->ipcp;
RADIUS_PACKET *radres = NULL;
int code;
uint32_t u32;
struct assigned_ipv4 *assign;
char buf[80], causestr[80];
const char *cause = "";
+ struct radiusctl_client *client;
if ((ev & EV_READ) == 0)
return;
@@ -1627,6 +1652,19 @@ ipcp_dae_on_event(int fd, short ev, void *ctx)
&dae->nas_addr, buf, sizeof(buf)));
break;
}
+
+ TAILQ_FOREACH(client, &assign->dae_clients, entry) {
+ if (*cause != '\0')
+ module_imsg_compose(self->base,
+ (code == RADIUS_CODE_DISCONNECT_ACK)
+ ? IMSG_OK : IMSG_NG, client->peerid, 0, -1,
+ cause + 1, strlen(cause + 1) + 1);
+ else
+ module_imsg_compose(self->base,
+ (code == RADIUS_CODE_DISCONNECT_ACK)
+ ? IMSG_OK : IMSG_NG, client->peerid, 0, -1,
+ NULL, 0);
+ }
ipcp_dae_reset_request(assign);
out:
if (radres != NULL)
@@ -1636,6 +1674,8 @@ ipcp_dae_on_event(int fd, short ev, void *ctx)
void
ipcp_dae_reset_request(struct assigned_ipv4 *assign)
{
+ struct radiusctl_client *client, *clientt;
+
if (assign->dae != NULL) {
if (assign->dae_ntry > 0)
TAILQ_REMOVE(&assign->dae->reqs, assign, dae_next);
@@ -1645,6 +1685,10 @@ ipcp_dae_reset_request(struct assigned_ipv4 *assign)
assign->dae_reqpkt = NULL;
if (evtimer_pending(&assign->dae_evtimer, NULL))
evtimer_del(&assign->dae_evtimer);
+ TAILQ_FOREACH_SAFE(client, &assign->dae_clients, entry, clientt) {
+ TAILQ_REMOVE(&assign->dae_clients, client, entry);
+ free(client);
+ }
assign->dae_ntry = 0;
}