This is required for many cases and will be used future.
-/* $OpenBSD: radiusd.c,v 1.33 2023/10/23 00:58:32 yasuoka Exp $ */
+/* $OpenBSD: radiusd.c,v 1.34 2024/01/08 04:16:48 yasuoka Exp $ */
/*
* Copyright (c) 2013, 2023 Internet Initiative Japan Inc.
radiusd_access_request_aborted(q);
return;
}
+ if (imsg_compose_radius_packet(&module->ibuf,
+ IMSG_RADIUSD_MODULE_RESDECO0_REQ, q->id, q->req) == -1) {
+ log_warn("q=%u Could not send RESDECO0_REQ to `%s'", q->id,
+ module->name);
+ radiusd_access_request_aborted(q);
+ return;
+ }
if (imsg_compose_radius_packet(&module->ibuf,
IMSG_RADIUSD_MODULE_RESDECO, q->id, q->res) == -1) {
log_warn("q=%u Could not send RESDECO to `%s'", q->id,
-/* $OpenBSD: radiusd.h,v 1.5 2023/09/08 05:56:22 yasuoka Exp $ */
+/* $OpenBSD: radiusd.h,v 1.6 2024/01/08 04:16:48 yasuoka Exp $ */
#ifndef RADIUSD_H
#define RADIUSD_H 1
IMSG_RADIUSD_MODULE_ACCSREQ_ABORTED,
IMSG_RADIUSD_MODULE_REQDECO,
IMSG_RADIUSD_MODULE_REQDECO_DONE,
+ IMSG_RADIUSD_MODULE_RESDECO0_REQ, /* request pkt for RESDECO */
IMSG_RADIUSD_MODULE_RESDECO,
IMSG_RADIUSD_MODULE_RESDECO_DONE,
IMSG_RADIUSD_MODULE_STOP
-/* $OpenBSD: radiusd_module.c,v 1.14 2023/09/08 05:56:22 yasuoka Exp $ */
+/* $OpenBSD: radiusd_module.c,v 1.15 2024/01/08 04:16:48 yasuoka Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
static void (*module_request_decoration) (void *, u_int, const u_char *,
size_t) = NULL;
static void (*module_response_decoration) (void *, u_int, const u_char *,
- size_t) = NULL;
+ size_t, const u_char *, size_t) = NULL;
struct module_base {
void *ctx;
u_char *radpkt;
int radpktsiz;
int radpktoff;
+ u_char *radpkt2;
+ int radpkt2siz; /* allocated size */
+ int radpkt2len; /* actual size */
#ifdef USE_LIBEVENT
struct module_imsgbuf *module_imsgbuf;
void
module_destroy(struct module_base *base)
{
- imsg_clear(&base->ibuf);
+ if (base != NULL) {
+ free(base->radpkt);
+ free(base->radpkt2);
+ imsg_clear(&base->ibuf);
+ }
free(base);
}
}
case IMSG_RADIUSD_MODULE_ACCSREQ:
case IMSG_RADIUSD_MODULE_REQDECO:
+ case IMSG_RADIUSD_MODULE_RESDECO0_REQ:
case IMSG_RADIUSD_MODULE_RESDECO:
{
struct radiusd_module_radpkt_arg *accessreq;
"module doesn't support");
break;
}
- typestr = "RESDECO";
+ if (imsg->hdr.type == IMSG_RADIUSD_MODULE_RESDECO0_REQ)
+ typestr = "RESDECO0_REQ";
+ else
+ typestr = "RESDECO";
}
if (datalen <
else if (imsg->hdr.type == IMSG_RADIUSD_MODULE_REQDECO)
module_request_decoration(base->ctx, accessreq->q_id,
base->radpkt, base->radpktoff);
- else
+ else if (imsg->hdr.type == IMSG_RADIUSD_MODULE_RESDECO0_REQ) {
+ /* preserve request */
+ if (base->radpktoff > base->radpkt2siz) {
+ u_char *nradpkt;
+ if ((nradpkt = realloc(base->radpkt2,
+ base->radpktoff)) == NULL) {
+ syslog(LOG_ERR, "Could not handle "
+ "received %s message: %m", typestr);
+ base->radpktoff = 0;
+ goto accsreq_out;
+ }
+ base->radpkt2 = nradpkt;
+ base->radpkt2siz = base->radpktoff;
+ }
+ memcpy(base->radpkt2, base->radpkt, base->radpktoff);
+ base->radpkt2len = base->radpktoff;
+ } else {
module_response_decoration(base->ctx, accessreq->q_id,
- base->radpkt, base->radpktoff);
+ base->radpkt2, base->radpkt2len, base->radpkt,
+ base->radpktoff);
+ base->radpkt2len = 0;
+ }
base->radpktoff = 0;
accsreq_out:
break;
size_t pktlen);
void (*response_decoration)(void *ctx, u_int query_id,
- const u_char *pkt, size_t pktlen);
+ const u_char *req, size_t reqlen, const u_char *res, size_t reslen);
};
#define SYNTAX_ASSERT(_cond, _msg) \
-/* $OpenBSD: radiusd_standard.c,v 1.1 2023/09/08 05:56:22 yasuoka Exp $ */
+/* $OpenBSD: radiusd_standard.c,v 1.2 2024/01/08 04:16:48 yasuoka Exp $ */
/*
* Copyright (c) 2013, 2023 Internet Initiative Japan Inc.
static void module_standard_config_set(void *, const char *, int,
char * const *);
static void module_standard_reqdeco(void *, u_int, const u_char *, size_t);
-static void module_standard_resdeco(void *, u_int, const u_char *, size_t);
+static void module_standard_resdeco(void *, u_int, const u_char *, size_t,
+ const u_char *, size_t);
int
main(int argc, char *argv[])
/* response message decoration */
static void
-module_standard_resdeco(void *ctx, u_int q_id, const u_char *pkt, size_t pktlen)
+module_standard_resdeco(void *ctx, u_int q_id, const u_char *req, size_t reqlen,
+ const u_char *res, size_t reslen)
{
struct module_standard *module = ctx;
- RADIUS_PACKET *radpkt = NULL;
+ RADIUS_PACKET *radres = NULL;
struct attr *attr;
TAILQ_FOREACH(attr, &module->remove_reqattrs, next) {
- if (radpkt == NULL &&
- (radpkt = radius_convert_packet(pkt, pktlen)) == NULL) {
- syslog(LOG_ERR,
+ if (radres == NULL &&
+ (radres = radius_convert_packet(res, reslen)) == NULL) {
+ syslog(LOG_ERR,
"%s: radius_convert_packet() failed: %m", __func__);
module_stop(module->base);
return;
}
if (attr->type != RADIUS_TYPE_VENDOR_SPECIFIC)
- radius_del_attr_all(radpkt, attr->type);
+ radius_del_attr_all(radres, attr->type);
else
- radius_del_vs_attr_all(radpkt, attr->vendor,
+ radius_del_vs_attr_all(radres, attr->vendor,
attr->vtype);
}
- if (radpkt == NULL) {
- pkt = NULL;
- pktlen = 0;
+ if (radres == NULL) {
+ res = NULL;
+ reslen = 0;
} else {
- pkt = radius_get_data(radpkt);
- pktlen = radius_get_length(radpkt);
+ res = radius_get_data(radres);
+ reslen = radius_get_length(radres);
}
- if (module_resdeco_done(module->base, q_id, pkt, pktlen) == -1) {
+ if (module_resdeco_done(module->base, q_id, res, reslen) == -1) {
syslog(LOG_ERR, "%s: module_resdeco_done() failed: %m",
__func__);
module_stop(module->base);
}
- if (radpkt != NULL)
- radius_delete_packet(radpkt);
+ if (radres != NULL)
+ radius_delete_packet(radres);
}