Pass the request packet to response decorations for future use.
authoryasuoka <yasuoka@openbsd.org>
Mon, 8 Jan 2024 04:16:48 +0000 (04:16 +0000)
committeryasuoka <yasuoka@openbsd.org>
Mon, 8 Jan 2024 04:16:48 +0000 (04:16 +0000)
This is required for many cases and will be used future.

usr.sbin/radiusd/radiusd.c
usr.sbin/radiusd/radiusd.h
usr.sbin/radiusd/radiusd_module.c
usr.sbin/radiusd/radiusd_module.h
usr.sbin/radiusd/radiusd_standard.c

index 733344a..7d87d04 100644 (file)
@@ -1,4 +1,4 @@
-/*     $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.
@@ -1545,6 +1545,13 @@ radiusd_module_response_decoration(struct radiusd_module *module,
                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,
index 87ea9dd..6cc56b6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $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
@@ -42,6 +42,7 @@ enum imsg_type {
        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
index 02d9b52..0b482a1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $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>
@@ -49,7 +49,7 @@ static void   (*module_access_request) (void *, u_int, const u_char *,
 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;
@@ -60,6 +60,9 @@ struct module_base {
        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;
@@ -131,7 +134,11 @@ module_run(struct module_base *base)
 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);
 }
 
@@ -438,6 +445,7 @@ module_imsg_handler(struct module_base *base, struct imsg *imsg)
            }
        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;
@@ -464,7 +472,10 @@ module_imsg_handler(struct module_base *base, struct imsg *imsg)
                                    "module doesn't support");
                                break;
                        }
-                       typestr = "RESDECO";
+                       if (imsg->hdr.type == IMSG_RADIUSD_MODULE_RESDECO0_REQ)
+                               typestr = "RESDECO0_REQ";
+                       else
+                               typestr = "RESDECO";
                }
 
                if (datalen <
@@ -512,9 +523,28 @@ module_imsg_handler(struct module_base *base, struct imsg *imsg)
                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;
index 42380ea..6b993ad 100644 (file)
@@ -41,7 +41,7 @@ struct module_handlers {
            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)                             \
index 04052df..615938e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $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.
@@ -52,7 +52,8 @@ struct module_standard {
 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[])
@@ -261,38 +262,39 @@ module_standard_reqdeco(void *ctx, u_int q_id, const u_char *pkt, size_t pktlen)
 
 /* 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);
 }