]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
make our own Proxy-State 64-bit
authorAlan T. DeKok <aland@freeradius.org>
Fri, 27 Dec 2024 14:18:26 +0000 (09:18 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Fri, 27 Dec 2024 14:19:43 +0000 (09:19 -0500)
which means that collisions are essentially impossible.

src/modules/rlm_radius/bio.c
src/modules/rlm_radius/rlm_radius.c
src/protocols/radius/base.c
src/protocols/radius/client.h
src/protocols/radius/radius.h

index 8bc203f9103dced4ae8b329fc27a068931201080..94602671b0c669c7cb0892052ecd32df5a5ad261 100644 (file)
@@ -1243,7 +1243,7 @@ static int encode(bio_handle_t *h, request_t *request, bio_request_t *u, uint8_t
                MEM(vp = fr_pair_afrom_da(u->packet, attr_proxy_state));
                fr_pair_value_memdup(vp, (uint8_t const *) &inst->common_ctx.proxy_state, sizeof(inst->common_ctx.proxy_state), false);
                fr_pair_append(&u->extra, vp);
-               packet_len += 6;
+               packet_len += 2 + sizeof(inst->common_ctx.proxy_state);
        }
 
        /*
@@ -1527,21 +1527,37 @@ static void request_mux(UNUSED fr_event_list_t *el,
 
        /*
         *      Warn people about misconfigurations and loops.
+        *
+        *      There should _never_ be two instances of the same Proxy-State in the packet.
         */
        if (RDEBUG_ENABLED && u->proxied) {
+               unsigned int count = 0;
+
                fr_pair_list_foreach(&request->request_pairs, vp) {
                        if (vp->vp_length != sizeof(h->ctx.radius_ctx.proxy_state)) continue;
 
                        if (memcmp(vp->vp_octets, &h->ctx.radius_ctx.proxy_state,
                                   sizeof(h->ctx.radius_ctx.proxy_state)) == 0) {
+
+                               /*
+                                *      Cancel proxying when there are two instances of the same Proxy-State
+                                *      in the packet.  This limitation could be configurable, but it likely
+                                *      doesn't make sense to make it configurable.
+                                */
+                               if (count == 1) {
+                                       RWARN("Canceling proxy due to loop of multiple %pV", vp);
+                                       trunk_request_signal_cancel(treq);
+                                       u->treq = NULL;
+                                       return;
+                               }
+
                                RWARN("Proxied packet contains our own %pV", vp);
                                RWARN("Check if there is a proxy loop.  Perhaps the server has been configured to proxy to itself.");
-                               break;
+                               count++;
                        }
                }
        }
 
-
        mod_write(request, treq, h);
 }
 
index d564673b5caaae613425ce033705908f7fc0eded..d2600387702330045988fab488926d41485d1bfd 100644 (file)
@@ -693,7 +693,7 @@ check_others:
        inst->common_ctx = (fr_radius_ctx_t) {
                .secret = inst->secret,
                .secret_length = inst->secret ? talloc_array_length(inst->secret) - 1 : 0,
-               .proxy_state = fr_rand(),
+               .proxy_state = ((uint64_t) fr_rand()) << 32 | fr_rand(),
        };
 
        /*
index 5fbeea61a178be9284666d01d0cc57873f9161c5..22440fec039189b33ce2a74c48f450a776fc9f9b 100644 (file)
@@ -1070,7 +1070,7 @@ ssize_t fr_radius_encode(fr_dbuff_t *dbuff, fr_pair_list_t *vps, fr_radius_encod
         *      Add Proxy-State to the end of the packet if the caller requested it.
         */
        if (packet_ctx->add_proxy_state) {
-               FR_DBUFF_IN_BYTES_RETURN(&work_dbuff, FR_PROXY_STATE, 6);
+               FR_DBUFF_IN_BYTES_RETURN(&work_dbuff, FR_PROXY_STATE, (uint8_t) (2 + sizeof(packet_ctx->common->proxy_state)));
                FR_DBUFF_IN_RETURN(&work_dbuff, packet_ctx->common->proxy_state);
        }
 
index c5fd9bb799851ac25e770eea71cfe918c8306e07..f243bd836c349ab82cea72d09ad4cabee1c2fd95 100644 (file)
@@ -44,7 +44,7 @@ typedef struct {
        fr_time_delta_t         connection_timeout;
 
        bool                    add_proxy_state;
-       uint32_t                proxy_state;
+       uint64_t                proxy_state;
 
        bool                    outgoing[FR_RADIUS_CODE_MAX];   //!< allowed outgoing packet types
 
index e019f9c9c069623965ccb8567e211b994ee6825a..d9d4676f0b028d69dbf0a03da0db8da82ea7ca8a 100644 (file)
@@ -97,7 +97,7 @@ typedef struct {
 
        bool                    secure_transport;       //!< for TLS
 
-       uint32_t                proxy_state;            //!< if so, this is its value
+       uint64_t                proxy_state;
 } fr_radius_ctx_t;
 
 typedef struct {