CVE fixed:
- CVE-2024-3596 freeradius: forgery attack
Upstream-Status: Backport from v3.0.x branch, commit range 
3a00a6ecc188629b0441fd45ad61ca8986de156e..da643f1edc267ce95260dc36069e6f1a7a4d66f8

Signed-off-by: Rohini Sangam <[email protected]>
Signed-off-by: Siddharth Doshi <[email protected]>
---
 .../freeradius/files/CVE-2024-3596.patch      | 1506 +++++++++++++++++
 .../freeradius/freeradius_3.0.21.bb           |    1 +
 2 files changed, 1507 insertions(+)
 create mode 100644 
meta-networking/recipes-connectivity/freeradius/files/CVE-2024-3596.patch

diff --git 
a/meta-networking/recipes-connectivity/freeradius/files/CVE-2024-3596.patch 
b/meta-networking/recipes-connectivity/freeradius/files/CVE-2024-3596.patch
new file mode 100644
index 000000000..1778e8e92
--- /dev/null
+++ b/meta-networking/recipes-connectivity/freeradius/files/CVE-2024-3596.patch
@@ -0,0 +1,1506 @@
+From 441967ba1d1ec28aa9582ab0253ad01e14b42148 Mon Sep 17 00:00:00 2001
+From: Arran Cudbard-Bell <[email protected]>
+Date: Sun, 30 Jun 2024 14:03:17 -0600
+Subject: [PATCH] CVE-2024-3596: Backport fix for BlastRADIUS
+
+Upstream-Status: Backport from v3.0.x branch, commit range 
3a00a6ecc188629b0441fd45ad61ca8986de156e..da643f1edc267ce95260dc36069e6f1a7a4d66f8
+CVE: CVE-2024-3596
+
+Signed-off-by: Rohini Sangam <[email protected]>
+---
+ man/man1/radclient.1    |  10 ++-
+ man/man1/radtest.1      |  11 ++-
+ raddb/clients.conf      |  47 ++++++++--
+ raddb/proxy.conf        |  19 +++++
+ raddb/radiusd.conf.in   | 185 ++++++++++++++++++++++++++++++++++++++++
+ src/include/clients.h   |   6 +-
+ src/include/conffile.h  |   1 +
+ src/include/libradius.h |  19 ++++-
+ src/include/radius.h    |   1 +
+ src/include/radiusd.h   |   6 ++
+ src/include/realms.h    |   1 +
+ src/lib/radius.c        |  87 +++++++++++++++++--
+ src/main/client.c       |  45 ++++++++--
+ src/main/conffile.c     |   4 +-
+ src/main/listen.c       | 141 +++++++++++++++++++++++++++++-
+ src/main/mainconfig.c   |  70 +++++++++++++++
+ src/main/process.c      |  65 ++++++++++++++
+ src/main/radclient.c    | 147 ++++++++++++++++++++++++++++++-
+ src/main/radtest.in     |   6 +-
+ src/main/realms.c       |  11 +++
+ src/main/tls_listen.c   |   5 ++
+ 21 files changed, 855 insertions(+), 32 deletions(-)
+
+diff --git a/man/man1/radclient.1 b/man/man1/radclient.1
+index 229dcae0c7..b83bee931a 100644
+--- a/man/man1/radclient.1
++++ b/man/man1/radclient.1
+@@ -1,10 +1,11 @@
+-.TH RADCLIENT 1 "22 March 2019" "" "FreeRADIUS Daemon"
++.TH RADCLIENT 1 "21 May 2024" "" "FreeRADIUS Daemon"
+ .SH NAME
+ radclient - send packets to a RADIUS server, show reply
+ .SH SYNOPSIS
+ .B radclient
+ .RB [ \-4 ]
+ .RB [ \-6 ]
++.RB [ \-b ]
+ .RB [ \-c
+ .IR count ]
+ .RB [ \-d
+@@ -52,6 +53,13 @@ automatically encrypted before the packet is sent to the 
server.
+ Use IPv4 (default)
+ .IP \-6
+ Use IPv6
++.IP \-b
++Enforce the Blast RADIUS checks.  All replies to an Access-Request packet
++must contain a Message-Authenticator as the first attribute.
++
++For compatibility with old servers, this flag is not set by default.
++However, radclient still checks for the Blast RADIUS signature, and
++discards packets which match the attack.
+ .IP \-c\ \fIcount\fP
+ Send each packet \fIcount\fP times.
+ .IP \-d\ \fIraddb_directory\fP
+diff --git a/man/man1/radtest.1 b/man/man1/radtest.1
+index b3184779c0..6bfab75944 100644
+--- a/man/man1/radtest.1
++++ b/man/man1/radtest.1
+@@ -1,4 +1,4 @@
+-.TH RADTEST 1 "5 April 2010" "" "FreeRADIUS Daemon"
++.TH RADTEST 1 "21 May 2024" "" "FreeRADIUS Daemon"
+ .SH NAME
+ radtest - send packets to a RADIUS server, show reply
+ .SH SYNOPSIS
+@@ -15,6 +15,8 @@ radtest - send packets to a RADIUS server, show reply
+ .IR ]
+ .RB [ \-6
+ .IR ]
++.RB [ \-b
++.IR
+ .I user password radius-server nas-port-number secret
+ .RB [ ppphint ]
+ .RB [ nasname ]
+@@ -26,6 +28,13 @@ way to test a radius server.
+ 
+ .SH OPTIONS
+ 
++.IP \-b
++Enforce the Blast RADIUS checks.  All replies to an Access-Request packet
++must contain a Message-Authenticator as the first attribute.
++
++For compatibility with old servers, this flag is not set by default.
++However, radclient still checks for the Blast RADIUS signature, and
++discards packets which match the attack.
+ .IP "\-d \fIraddb_directory\fP"
+ The directory that contains the RADIUS dictionary files. Defaults to
+ \fI/etc/raddb\fP.
+diff --git a/raddb/clients.conf b/raddb/clients.conf
+index 76b300d3c5..d55414b7d2 100644
+--- a/raddb/clients.conf
++++ b/raddb/clients.conf
+@@ -100,15 +100,44 @@ client localhost {
+       secret = testing123
+ 
+       #
+-      #  Old-style clients do not send a Message-Authenticator
+-      #  in an Access-Request.  RFC 5080 suggests that all clients
+-      #  SHOULD include it in an Access-Request.  The configuration
+-      #  item below allows the server to require it.  If a client
+-      #  is required to include a Message-Authenticator and it does
+-      #  not, then the packet will be silently discarded.
+-      #
+-      #  allowed values: yes, no
+-      require_message_authenticator = no
++      #  The global configuration "security.require_message_authenticator"
++      #  flag sets the default for all clients.  That default can be
++      #  over-ridden here, by setting it to a value.  If no value is set,
++      #  then the default from the "radiusd.conf" file is used.
++      #
++      #  See that file for full documentation on the flag, along
++      #  with allowed values and meanings.
++      #
++      #  This flag exists solely for legacy clients which do not send
++      #  Message-Authenticator in all Access-Request packets.  We do not
++      #  recommend setting it to "no".
++      #
++      #  The number one way to protect yourself from the BlastRADIUS
++      #  attack is to update all RADIUS servers, and then set this
++      #  flag to "yes".  If all RADIUS servers are updated, and if
++      #  all of them have this flag set to "yes" for all clients,
++      #  then your network is safe.  You can then upgrade the
++      #  clients when it is convenient, instead of rushing the
++      #  upgrades.
++      #
++      #  allowed values: yes, no, auto
++#     require_message_authenticator = no
++
++      #
++      #  The global configuration "security.limit_proxy_state"
++      #  flag sets the default for all clients.  That default can be
++      #  over-ridden here, by setting it to "no".
++      #
++      #  See that file for full documentation on the flag, along
++      #  with allowed values,and meanings.
++      #
++      #  This flag exists solely for legacy clients which do not send
++      #  Message-Authenticator in all Access-Request packets.  We do not
++      #  recommend setting it to "no".
++      #
++      #  allowed values: yes, no, auto
++      #
++#     limit_proxy_state = yes
+ 
+       #
+       #  The short name is used as an alias for the fully qualified
+diff --git a/raddb/proxy.conf b/raddb/proxy.conf
+index 91b4b37930..fa362b8a74 100644
+--- a/raddb/proxy.conf
++++ b/raddb/proxy.conf
+@@ -204,6 +204,25 @@ home_server localhost {
+       #
+       secret = testing123
+ 
++
++      #
++      #  The global configuration "security.require_message_authenticator"
++      #  flag sets the default for all home servers.  That default can be
++      #  over-ridden here, by setting it to a value.  If no value is set,
++      #  then the default from the "radiusd.conf" file is used.
++      #
++      #  See that file for full documentation on the flag, along
++      #  with allowed values and meanings.
++      #
++      #  This flag exists solely for legacy home servers which do
++      #  not send Message-Authenticator in all Access-Accept,
++      #  Access-Reject, or Access-Challenge packets.  We do not
++      #  recommend setting it to "no".
++      #
++      #  allowed values: yes, no, auto
++      #
++#     require_message_authenticator = no
++
+       ############################################################
+       #
+       #  The rest of the configuration items listed here are optional,
+diff --git a/raddb/radiusd.conf.in b/raddb/radiusd.conf.in
+index e8aee3c001..5b8800bfc8 100644
+--- a/raddb/radiusd.conf.in
++++ b/raddb/radiusd.conf.in
+@@ -564,6 +564,191 @@ security {
+       #
+       status_server = yes
+ 
++      #
++      #  Global configuration for requiring Message-Authenticator in
++      #  all Access-* packets sent over UDP or TCP.  This flag is
++      #  ignored for TLS.
++      #
++      #  The number one way to protect yourself from the BlastRADIUS
++      #  attack is to update all RADIUS servers, and then set this
++      #  flag to "yes".  If all RADIUS servers are updated, and if
++      #  all of them have this flag set to "yes" for all clients,
++      #  then your network is safe.  You can then upgrade the
++      #  clients when it is convenient, instead of rushing the
++      #  upgrades.
++      #
++      #  This flag sets the global default for all clients and home
++      #  servers.  It can be over-ridden in an individual client or
++      #  home_server definition by adding the same flag to that
++      #  section with an appropriate value.
++      #
++      #  All upgraded RADIUS implementations should send
++      #  Message-Authenticator in all Access-Request, Access-Accept,
++      #  Access-Reject, and Access-Challenge packets.  Once all
++      #  systems are upgraded, setting this flag to "yes" is the
++      #  best protection from the attack.
++      #
++      #  The possible values and meanings for
++      #  "require_message_authenticator" are;
++      #
++      #  * "no" - allow Access-* packet which do not contain
++      #    Message-Authenticator
++      #
++      #    For a client, if this flag is set to "no", then the
++      #    "limit_proxy_state" flag, below, is also checked.
++      #
++      #    For a home_server, if this flag is set to "no", then the
++      #    Access-Accept, Access-Reject, and Access-Challenge
++      #    packets do not need to contain Message-Authenticator.
++      #
++      #    The only reason to set this flag to "no" is when the
++      #    RADIUS client or home server has not been updated.  It is
++      #    always safer to set this flag "no" in the individual
++      #    client or home_server definition.  The global flag SHOULD
++      #    still be set to a safe value: "yes".
++      #
++      #    WARNING: Setting this flag and the "limit_proxy_state"
++      #    flag to "no" will allow MITM attackers to create fake
++      #    Access-Accept packets to the NAS!  At least one of them
++      #    MUST be set to "yes" for the system to have any
++      #    protection against the attack.
++      #
++      #  * "yes" - Require that all Access-* packets (client and
++      #    home_server) contain Message-Authenticator.  If a packet
++      #    does not contain Message-Authenticator, then it is
++      #    discarded.
++      #
++      #  * "auto" - Automatically determine the value of the flag,
++      #    based on the first packet received from that client or
++      #    home_server.
++      #
++      #    If the packet does not contain Message-Authenticator,
++      #    then the value of the flag is automatically switched to
++      #    "no".
++      #
++      #    If the packet contains Message-Authenticator but not
++      #    EAP-Message, then the value of the flag is automatically
++      #    switched to "yes".  The server has to check for
++      #    EAP-Message, because the previous RFCs require that the
++      #    packet contains Message-Authenticator when it also
++      #    contains EAP-Message.  So having a Message-Authenticator
++      #    in those packets doesn't give the server enough
++      #    information to determined if the client or home_server
++      #    has been updated.
++      #
++      #    If the packet contains Message-Authenticator and
++      #    EAP-Message, then the flag is left at the "auto" value.
++      #
++      #    WARNING: This switch is done for the first packet
++      #    received from that client or home server.  The change
++      #    does NOT persist across server restarts.  You MUST change
++      #    the to "yes" manually, in order to make a permanent
++      #    change to the configuration.
++      #
++      #    WARNING: If there are multiple NASes with the same source
++      #    IP and client definitions, BUT the NASes have different
++      #    behavior, then this flag WILL LIKELY BREAK YOUR NETWORK.
++      #
++      #    That is, when there are multiple different RADIUS clients
++      #    behind one NATed IP address, then these security settings
++      #    have to be set to allow the MOST INSECURE packets to be
++      #    processed.  This is a terrible idea, and will leave your
++      #    network vulnerable to the attack.  Please upgrade all
++      #    clients immediately.
++      #
++      #    The only solution to that rare configuration is to set
++      #    this flag to "no", in which case the network will work,
++      #    but will be vulnerable to the attack.
++      #
++      require_message_authenticator = auto
++
++      #
++      #  Global configuration for limiting the combination of
++      #  Proxy-State and Message-Authenticator.  This flag only
++      #  applies to packets sent over UDP or TCP.  This flag is
++      #  ignored for TLS.
++      #
++      #  This flag sets the global default for all clients.  It can
++      #  be over-ridden in an individual client definition by adding
++      #  the same flag to that section with an appropriate value.
++      #
++      #  If "require_message_authenticator" is set to "yes", this
++      #  configuration item is ignored.
++      #
++      #  If "require_message_authenticator" is set to "no", this
++      #  configuration item is checked.
++      #
++      #  The possible values and meanings for "limit_proxy_state" are;
++      #
++      #  * "no" - allow any packets from the client, even packets
++      #    which contain the BlastRADIUS attack.  Please be aware
++      #    that in this configuration the server will complain for
++      #    EVERY packet which it receives.
++      #
++      #    The only reason to set this flag to "no" is when the
++      #    client is a proxy, AND the proxy does not send
++      #    Message-Authenticator in Access-Request packets.  Even
++      #    then, the best approach to fix the issue is to (1) update
++      #    the proxy to send Message-Authenticator, and if that
++      #    can't be done, then (2) set this flag to "no", but ONLY
++      #    for that one client.  The global flag SHOULD still be set
++      #    to a safe value: "yes".
++      #
++      #    WARNING: Setting both this flag and the
++      #    "require_message_authenticator" flag to "no" will allow
++      #    MITM attackers to create fake Access-Accept packets to the
++      #    NAS!  At least one of them MUST be set to "yes" for the
++      #    system to have any protection against the attack.
++      #
++      #  * "yes" - Allow packets without Message-Authenticator,
++      #    but only when they do not contain Proxy-State.
++      #    packets which contain Proxy-State MUST also contain
++      #    Message-Authenticator, otherwise they are discarded.
++      #
++      #    This setting is safe for most NASes, GGSNs, BRAS, etc.
++      #    Most regular RADIUS clients do not send Proxy-State
++      #    attributes for Access-Request packets that they originate.
++      #    However some aggregators (e.g. Wireless LAN Controllers)
++      #    may act as a RADIUS proxy for requests from their cohort
++      #    of managed devices, and in such cases will provide a
++      #    Proxy-State attribute. For those systems, you _must_ look
++      #    at the actual packets to determine what to do. It may be
++      #    that the only way to fix the vulnerability is to upgrade
++      #    the WLC, and set "require_message_authenticator" to "yes".
++      #
++      #  * "auto" - Automatically determine the value of the flag,
++      #    based on the first packet received from that client.
++      #
++      #    If the packet contains Proxy-State but no
++      #    Message-Authenticator, then the value of the flag is
++      #    automatically switched to "no".
++      #
++      #    For all other situations, the value of the flag is
++      #    automatically switched to "yes".
++      #
++      #    WARNING: This switch is done for the first packet
++      #    received from that client.  The change does NOT persist
++      #    across server restarts.  You MUST change the to "yes"
++      #    manually, in order to make a permanent change to the
++      #    configuration.
++      #
++      #    WARNING: If there are multiple NASes with the same source
++      #    IP and client definitions, BUT the NASes have different
++      #    behavior, then this flag WILL LIKELY BREAK YOUR NETWORK.
++      #
++      #    That is, when there are multiple different RADIUS clients
++      #    behind one NATed IP address, then these security settings
++      #    have to be set to allow the MOST INSECURE packets to be
++      #    processed.  This is a terrible idea, and will leave your
++      #    network vulnerable to the attack.  Please upgrade all
++      #    clients immediately.
++      #
++      #    The only solution to that rare configuration is to set
++      #    this flag to "no", in which case the network will work,
++      #    but will be vulnerable to the attack.
++      #
++      limit_proxy_state = auto
++
+ @openssl_version_check_config@
+ }
+ 
+diff --git a/src/include/clients.h b/src/include/clients.h
+index 560211557f..0aeb1da8d9 100644
+--- a/src/include/clients.h
++++ b/src/include/clients.h
+@@ -39,7 +39,11 @@ typedef struct radclient {
+ 
+       char const              *secret;                //!< Secret PSK.
+ 
+-      bool                    message_authenticator;  //!< Require RADIUS 
message authenticator in requests.
++      fr_bool_auto_t          require_ma;             //!< Require RADIUS 
message authenticator in requests.
++
++      bool                    dynamic_require_ma;     //!< for dynamic clients
++
++      fr_bool_auto_t          limit_proxy_state;      //!< Limit Proxy-State 
in requests
+ 
+       char const              *nas_type;              //!< Type of client 
(arbitrary).
+ 
+diff --git a/src/include/conffile.h b/src/include/conffile.h
+index 8cb045c946..ddbcae4e4f 100644
+--- a/src/include/conffile.h
++++ b/src/include/conffile.h
+@@ -140,6 +140,7 @@ typedef struct timeval _timeval_t;
+ #define PW_TYPE_MULTI         (1 << 18) //!< CONF_PAIR can have multiple 
copies.
+ #define PW_TYPE_NOT_EMPTY     (1 << 19) //!< CONF_PAIR is required to have a 
non zero length value.
+ #define PW_TYPE_FILE_EXISTS   ((1 << 20) | PW_TYPE_STRING) //!< File matching 
value must exist
++#define PW_TYPE_IGNORE_DEFAULT        (1 << 21) //!< don't set from .dflt if 
the CONF_PAIR is missing
+ /* @} **/
+ 
+ #define FR_INTEGER_COND_CHECK(_name, _var, _cond, _new)\
+diff --git a/src/include/libradius.h b/src/include/libradius.h
+index ce2f713de1..2efef8b1d3 100644
+--- a/src/include/libradius.h
++++ b/src/include/libradius.h
+@@ -402,6 +402,10 @@ typedef struct radius_packet {
+       size_t                  partial;
+       int                     proto;
+ #endif
++      bool                    tls;            //!< uses secure transport
++      bool                    message_authenticator;
++      bool                    proxy_state;
++      bool                    eap_message;
+ } RADIUS_PACKET;
+ 
+ typedef enum {
+@@ -507,6 +511,13 @@ DICT_VENDOR       *dict_vendorbyvalue(int vendor);
+ /* radius.c */
+ int           rad_send(RADIUS_PACKET *, RADIUS_PACKET const *, char const 
*secret);
+ bool          rad_packet_ok(RADIUS_PACKET *packet, int flags, decode_fail_t 
*reason);
++
++/*
++ *    1 == require_ma
++ *    2 == msg_peek
++ *    4 == limit_proxy_state
++ *    8 == require_ma for Access-* replies and Protocol-Error
++ */
+ RADIUS_PACKET *rad_recv(TALLOC_CTX *ctx, int fd, int flags);
+ ssize_t rad_recv_header(int sockfd, fr_ipaddr_t *src_ipaddr, uint16_t 
*src_port, int *code);
+ void          rad_recv_discard(int sockfd);
+@@ -694,7 +705,7 @@ extern bool        fr_dns_lookups; /* do IP -> hostname 
lookups? */
+ extern bool   fr_hostname_lookups; /* do hostname -> IP lookups? */
+ extern int    fr_debug_lvl;   /* 0 = no debugging information */
+ extern uint32_t       fr_max_attributes; /* per incoming packet */
+-#define       FR_MAX_PACKET_CODE (52)
++#define       FR_MAX_PACKET_CODE (53)
+ extern char const *fr_packet_codes[FR_MAX_PACKET_CODE];
+ #define is_radius_code(_x) ((_x > 0) && (_x < FR_MAX_PACKET_CODE))
+ extern FILE   *fr_log_fp;
+@@ -932,6 +943,12 @@ int               fr_socket_wait_for_connect(int sockfd, 
struct timeval *timeout);
+ }
+ #endif
+ 
++typedef enum {
++      FR_BOOL_FALSE = 0,
++      FR_BOOL_TRUE,
++      FR_BOOL_AUTO,
++} fr_bool_auto_t;
++
+ #include <freeradius-devel/packet.h>
+ 
+ #ifdef WITH_TCP
+diff --git a/src/include/radius.h b/src/include/radius.h
+index 473528d65d..147d674eed 100644
+--- a/src/include/radius.h
++++ b/src/include/radius.h
+@@ -61,6 +61,7 @@ typedef enum {
+       PW_CODE_COA_REQUEST             = 43,   //!< RFC3575/RFC5176 - 
CoA-Request
+       PW_CODE_COA_ACK                 = 44,   //!< RFC3575/RFC5176 - CoA-Ack 
(positive)
+       PW_CODE_COA_NAK                 = 45,   //!< RFC3575/RFC5176 - CoA-Nak 
(not willing to perform)
++      PW_CODE_PROTOCOL_ERROR          = 52,   //!< RFC7930 - Protocol layer 
issue
+       PW_CODE_MAX                     = 255,  //!< Maximum possible code
+ } PW_CODE;
+ 
+diff --git a/src/include/radiusd.h b/src/include/radiusd.h
+index b2a0a0f642..e429c5be7a 100644
+--- a/src/include/radiusd.h
++++ b/src/include/radiusd.h
+@@ -171,6 +171,10 @@ typedef struct main_config {
+ 
+       bool            exiting;                        //!< are we exiting?
+ 
++      fr_bool_auto_t          require_ma;                     //!< global 
configuration for all clients and home servers
++
++      fr_bool_auto_t          limit_proxy_state;              //!< global 
configuration for all clients
++
+ 
+ #ifdef ENABLE_OPENSSL_VERSION_CHECK
+       char const      *allow_vulnerable_openssl;      //!< The CVE number of 
the last security issue acknowledged.
+@@ -558,6 +562,8 @@ int main_config_free(void);
+ void main_config_hup(void);
+ void hup_logfile(void);
+ 
++int   fr_bool_auto_parse(CONF_PAIR *cp, fr_bool_auto_t *out, char const *str);
++
+ /* listen.c */
+ void listen_free(rad_listen_t **head);
+ int listen_init(CONF_SECTION *cs, rad_listen_t **head, bool spawn_flag);
+diff --git a/src/include/realms.h b/src/include/realms.h
+index 6dae8b4f85..e643818e43 100644
+--- a/src/include/realms.h
++++ b/src/include/realms.h
+@@ -59,6 +59,7 @@ typedef struct home_server {
+                                                       //!< stats or when 
specifying home servers for a pool.
+ 
+       bool                    dual;                   //!< One of a pair of 
homeservers on consecutive ports.
++      fr_bool_auto_t          require_ma;             //!< for all replies to 
Access-Request and Status-Server
+       char const              *server;                //!< For internal 
proxying
+       char const              *parent_server;
+ 
+diff --git a/src/lib/radius.c b/src/lib/radius.c
+index 3881111f7d..7b91a4bde2 100644
+--- a/src/lib/radius.c
++++ b/src/lib/radius.c
+@@ -142,8 +142,9 @@ char const *fr_packet_codes[FR_MAX_PACKET_CODE] = {
+   "47",
+   "48",
+   "49",
+-  "IP-Address-Allocate",
+-  "IP-Address-Release",                       //!< 50
++  "IP-Address-Allocate",              //!< 50
++  "IP-Address-Release",
++  "Protocol-Error",
+ };
+ 
+ 
+@@ -1700,6 +1701,15 @@ int rad_vp2attr(RADIUS_PACKET const *packet, 
RADIUS_PACKET const *original,
+       return rad_vp2vsa(packet, original, secret, pvp, start, room);
+ }
+ 
++static const bool code2ma[FR_MAX_PACKET_CODE] = {
++      [ PW_CODE_ACCESS_REQUEST ] = true,
++      [ PW_CODE_ACCESS_ACCEPT ] = true,
++      [ PW_CODE_ACCESS_REJECT ] = true,
++      [ PW_CODE_ACCESS_CHALLENGE ] = true,
++      [ PW_CODE_STATUS_SERVER ] = true,
++      [ PW_CODE_PROTOCOL_ERROR ] = true,
++};
++
+ 
+ /** Encode a packet
+  *
+@@ -1712,6 +1722,7 @@ int rad_encode(RADIUS_PACKET *packet, RADIUS_PACKET 
const *original,
+       uint16_t                total_length;
+       int                     len;
+       VALUE_PAIR const        *reply;
++      bool                    seen_ma = false;
+ 
+       /*
+        *      A 4K packet, aligned on 64-bits.
+@@ -1775,6 +1786,27 @@ int rad_encode(RADIUS_PACKET *packet, RADIUS_PACKET 
const *original,
+        *      memcpy.
+        */
+ 
++      /*
++       *      Always add Message-Authenticator for replies to
++       *      Access-Request packets, and for all Access-Accept,
++       *      Access-Reject, Access-Challenge.
++       *
++       *      It must be the FIRST attribute in the packet.
++       */
++      if (!packet->tls &&
++          ((code2ma[packet->code]) || (original && code2ma[original->code]))) 
{
++              seen_ma = true;
++
++              packet->offset = RADIUS_HDR_LEN;
++
++              ptr[0] = PW_MESSAGE_AUTHENTICATOR;
++              ptr[1] = 18;
++              memset(ptr + 2, 0, 16);
++
++              ptr += 18;
++              total_length += 18;
++      }
++
+       /*
+        *      Loop over the reply attributes for the packet.
+        */
+@@ -1832,6 +1864,13 @@ int rad_encode(RADIUS_PACKET *packet, RADIUS_PACKET 
const *original,
+                *      length and initial value.
+                */
+               if (!reply->da->vendor && (reply->da->attr == 
PW_MESSAGE_AUTHENTICATOR)) {
++                      /*
++                       *      We have already encoded the 
Message-Authenticator, don't do it again.
++                       */
++                      if (seen_ma) {
++                              reply = reply->next;
++                              continue;
++                      }
+                       if (room < 18) break;
+ 
+                       /*
+@@ -2323,6 +2362,8 @@ bool rad_packet_ok(RADIUS_PACKET *packet, int flags, 
decode_fail_t *reason)
+       radius_packet_t         *hdr;
+       char                    host_ipaddr[128];
+       bool                    require_ma = false;
++      bool                    limit_proxy_state = false;
++      bool                    seen_proxy_state = false;
+       bool                    seen_ma = false;
+       uint32_t                num_attributes;
+       decode_fail_t           failure = DECODE_FAIL_NONE;
+@@ -2371,15 +2412,26 @@ bool rad_packet_ok(RADIUS_PACKET *packet, int flags, 
decode_fail_t *reason)
+       }
+ 
+       /*
+-       *      Message-Authenticator is required in Status-Server
+-       *      packets, otherwise they can be trivially forged.
++       *      If the caller requires Message-Authenticator, then set
++       *      the flag.
+        */
+-      if (hdr->code == PW_CODE_STATUS_SERVER) require_ma = true;
+ 
+       /*
+-       *      It's also required if the caller asks for it.
++       *      We also require Message-Authenticator if the packet
++       *      code is Status-Server.
++       *
++       *      If we're receiving packets from a proxy socket, then
++       *      require Message-Authenticator for Access-* replies,
++       *      and for Protocol-Error.
+        */
+-      if (flags) require_ma = true;
++      require_ma = ((flags & 0x01) != 0) || (hdr->code == 
PW_CODE_STATUS_SERVER) || (((flags & 0x08) != 0) && code2ma[hdr->code]);
++
++      /*
++       *
++       *      We only limit Proxy-State if we're not requiring
++       *      Message-Authenticator.
++       */
++      limit_proxy_state = ((flags & 0x04) != 0) && !require_ma;
+ 
+       /*
+        *      Repeat the length checks.  This time, instead of
+@@ -2534,6 +2586,7 @@ bool rad_packet_ok(RADIUS_PACKET *packet, int flags, 
decode_fail_t *reason)
+               case PW_EAP_MESSAGE:
+                       require_ma = true;
+                       eap = true;
++                      packet->eap_message = true;
+                       break;
+ 
+               case PW_USER_PASSWORD:
+@@ -2542,6 +2595,11 @@ bool rad_packet_ok(RADIUS_PACKET *packet, int flags, 
decode_fail_t *reason)
+                       non_eap = true;
+                       break;
+ 
++              case PW_PROXY_STATE:
++                      seen_proxy_state = true;
++                      packet->proxy_state = true;
++                      break;
++
+               case PW_MESSAGE_AUTHENTICATOR:
+                       if (attr[1] != 2 + AUTH_VECTOR_LEN) {
+                               FR_DEBUG_STRERROR_PRINTF("Malformed RADIUS 
packet from host %s: Message-Authenticator has invalid length %d",
+@@ -2553,6 +2611,7 @@ bool rad_packet_ok(RADIUS_PACKET *packet, int flags, 
decode_fail_t *reason)
+                               goto finish;
+                       }
+                       seen_ma = true;
++                      packet->message_authenticator = true;
+                       break;
+               }
+ 
+@@ -2609,7 +2668,19 @@ bool rad_packet_ok(RADIUS_PACKET *packet, int flags, 
decode_fail_t *reason)
+        *      Message-Authenticator attributes.
+        */
+       if (require_ma && !seen_ma) {
+-              FR_DEBUG_STRERROR_PRINTF("Insecure packet from host %s:  Packet 
does not contain required Message-Authenticator attribute",
++              FR_DEBUG_STRERROR_PRINTF("Insecure packet from host %s:  Packet 
does not contain required Message-Authenticator attribute.  You may need to set 
\"require_message_authenticator = no\" in the configuration.",
++                         inet_ntop(packet->src_ipaddr.af,
++                                   &packet->src_ipaddr.ipaddr,
++                                   host_ipaddr, sizeof(host_ipaddr)));
++              failure = DECODE_FAIL_MA_MISSING;
++              goto finish;
++      }
++
++      /*
++       *      The client is a NAS which shouldn't send Proxy-State, but it 
did!
++       */
++      if (limit_proxy_state && seen_proxy_state && !seen_ma) {
++              FR_DEBUG_STRERROR_PRINTF("Insecure packet from host %s:  Packet 
does not contain required Message-Authenticator attribute, but still has one or 
more Proxy-State attributes",
+                          inet_ntop(packet->src_ipaddr.af,
+                                    &packet->src_ipaddr.ipaddr,
+                                    host_ipaddr, sizeof(host_ipaddr)));
+diff --git a/src/main/client.c b/src/main/client.c
+index 6228438c47..875dc37d60 100644
+--- a/src/main/client.c
++++ b/src/main/client.c
+@@ -283,7 +283,8 @@ bool client_add(RADCLIENT_LIST *clients, RADCLIENT *client)
+                   (old->coa_server == client->coa_server) &&
+                   (old->coa_pool == client->coa_pool) &&
+ #endif
+-                  (old->message_authenticator == 
client->message_authenticator)) {
++                  (old->require_ma == client->require_ma) &&
++                  (old->limit_proxy_state == client->limit_proxy_state)) {
+                       WARN("Ignoring duplicate client %s", client->longname);
+                       client_free(client);
+                       return true;
+@@ -445,6 +446,8 @@ static fr_ipaddr_t cl_ipaddr;
+ static uint32_t cl_netmask;
+ static char const *cl_srcipaddr = NULL;
+ static char const *hs_proto = NULL;
++static char const *require_message_authenticator = NULL;
++static char const *limit_proxy_state = NULL;
+ 
+ #ifdef WITH_TCP
+ static CONF_PARSER limit_config[] = {
+@@ -467,7 +470,8 @@ static const CONF_PARSER client_config[] = {
+ 
+       { "src_ipaddr", FR_CONF_POINTER(PW_TYPE_STRING, &cl_srcipaddr), NULL },
+ 
+-      { "require_message_authenticator",  FR_CONF_OFFSET(PW_TYPE_BOOLEAN, 
RADCLIENT, message_authenticator), "no" },
++      { "require_message_authenticator", FR_CONF_POINTER(PW_TYPE_STRING| 
PW_TYPE_IGNORE_DEFAULT, &require_message_authenticator), NULL },
++      { "limit_proxy_state", FR_CONF_POINTER(PW_TYPE_STRING| 
PW_TYPE_IGNORE_DEFAULT, &limit_proxy_state), NULL },
+ 
+       { "secret", FR_CONF_OFFSET(PW_TYPE_STRING | PW_TYPE_SECRET, RADCLIENT, 
secret), NULL },
+       { "shortname", FR_CONF_OFFSET(PW_TYPE_STRING, RADCLIENT, shortname), 
NULL },
+@@ -663,7 +667,7 @@ static const CONF_PARSER dynamic_config[] = {
+       { "FreeRADIUS-Client-Src-IP-Address", FR_CONF_OFFSET(PW_TYPE_IPV4_ADDR, 
RADCLIENT, src_ipaddr), NULL },
+       { "FreeRADIUS-Client-Src-IPv6-Address", 
FR_CONF_OFFSET(PW_TYPE_IPV6_ADDR, RADCLIENT, src_ipaddr), NULL },
+ 
+-      { "FreeRADIUS-Client-Require-MA", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, 
RADCLIENT, message_authenticator), NULL },
++      { "FreeRADIUS-Client-Require-MA", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, 
RADCLIENT, dynamic_require_ma), NULL },
+ 
+       { "FreeRADIUS-Client-Secret",  FR_CONF_OFFSET(PW_TYPE_STRING, 
RADCLIENT, secret), "" },
+       { "FreeRADIUS-Client-Shortname",  FR_CONF_OFFSET(PW_TYPE_STRING, 
RADCLIENT, shortname), "" },
+@@ -845,8 +849,19 @@ RADCLIENT *client_afrom_cs(TALLOC_CTX *ctx, CONF_SECTION 
*cs, bool in_server, bo
+       c = talloc_zero(ctx, RADCLIENT);
+       c->cs = cs;
+ 
++      /*
++       *      Set the "require message authenticator" and "limit
++       *      proxy state" flags from the global default.  If the
++       *      configuration item exists, AND is set, it will
++       *      over-ride the flag.
++       */
++      c->require_ma = main_config.require_ma;
++      c->limit_proxy_state = main_config.limit_proxy_state;
++
+       memset(&cl_ipaddr, 0, sizeof(cl_ipaddr));
+       cl_netmask = 255;
++      require_message_authenticator = NULL;
++      limit_proxy_state = NULL;
+ 
+       if (cf_section_parse(cs, c, client_config) < 0) {
+               cf_log_err_cs(cs, "Error parsing client section");
+@@ -857,6 +872,9 @@ RADCLIENT *client_afrom_cs(TALLOC_CTX *ctx, CONF_SECTION 
*cs, bool in_server, bo
+               cl_srcipaddr = NULL;
+ #endif
+ 
++              require_message_authenticator = NULL;
++              limit_proxy_state = NULL;
++
+               return NULL;
+       }
+ 
+@@ -1114,6 +1132,16 @@ done_coa:
+       }
+ #endif
+ 
++      if (fr_bool_auto_parse(cf_pair_find(cs, 
"require_message_authenticator"), &c->require_ma, 
require_message_authenticator) < 0) {
++              goto error;
++      }
++
++      if (c->require_ma != FR_BOOL_TRUE) {
++              if (fr_bool_auto_parse(cf_pair_find(cs, "limit_proxy_state"), 
&c->limit_proxy_state, limit_proxy_state) < 0) {
++                      goto error;
++              }
++      }
++
+       return c;
+ }
+ 
+@@ -1158,7 +1186,7 @@ RADCLIENT *client_afrom_query(TALLOC_CTX *ctx, char 
const *identifier, char cons
+       if (shortname) c->shortname = talloc_typed_strdup(c, shortname);
+       if (type) c->nas_type = talloc_typed_strdup(c, type);
+       if (server) c->server = talloc_typed_strdup(c, server);
+-      c->message_authenticator = require_ma;
++      c->require_ma = require_ma;
+ 
+       return c;
+ }
+@@ -1344,10 +1372,10 @@ RADCLIENT *client_afrom_request(RADCLIENT_LIST 
*clients, REQUEST *request)
+                       *pi = vp->vp_integer;
+ 
+                       /*
+-                       *      Same nastiness as above.
++                       *      Same nastiness as above, but hard-coded for 
require Message-Authenticator.
+                        */
+                       for (parse = client_config; parse->name; parse++) {
+-                              if (parse->offset == dynamic_config[i].offset) 
break;
++                              if (parse->type == PW_TYPE_BOOLEAN) break;
+                       }
+                       if (!parse) break;
+ 
+@@ -1436,6 +1464,11 @@ validate:
+               goto error;
+       }
+ 
++      /*
++       *      It can't be set to "auto".  Too bad.
++       */
++      c->require_ma = (fr_bool_auto_t) c->dynamic_require_ma;
++
+       if (!client_add_dynamic(clients, request->client, c)) {
+               return NULL;
+       }
+diff --git a/src/main/conffile.c b/src/main/conffile.c
+index a8c667bfb5..61754e991f 100644
+--- a/src/main/conffile.c
++++ b/src/main/conffile.c
+@@ -1418,6 +1418,7 @@ int cf_item_parse(CONF_SECTION *cs, char const *name, 
unsigned int type, void *d
+ {
+       int rcode;
+       bool deprecated, required, attribute, secret, file_input, 
cant_be_empty, tmpl, multi, file_exists;
++      bool ignore_dflt;
+       char **q;
+       char const *value;
+       CONF_PAIR *cp = NULL;
+@@ -1441,6 +1442,7 @@ int cf_item_parse(CONF_SECTION *cs, char const *name, 
unsigned int type, void *d
+       cant_be_empty = (type & PW_TYPE_NOT_EMPTY);
+       tmpl = (type & PW_TYPE_TMPL);
+       multi = (type & PW_TYPE_MULTI);
++      ignore_dflt = (type & PW_TYPE_IGNORE_DEFAULT);
+ 
+       if (attribute) required = true;
+       if (required) cant_be_empty = true;     /* May want to review this in 
the future... */
+@@ -1464,7 +1466,7 @@ int cf_item_parse(CONF_SECTION *cs, char const *name, 
unsigned int type, void *d
+        *      section, use the default value.
+        */
+       if (!cp) {
+-              if (deprecated) return 0;       /* Don't set the default value 
*/
++              if (deprecated || ignore_dflt) return 0;        /* Don't set 
the default value */
+ 
+               rcode = 1;
+               value = dflt;
+diff --git a/src/main/listen.c b/src/main/listen.c
+index ebf7f5221c..c20fea243d 100644
+--- a/src/main/listen.c
++++ b/src/main/listen.c
+@@ -456,6 +456,122 @@ int rad_status_server(REQUEST *request)
+       return 0;
+ }
+ 
++static void blastradius_checks(RADIUS_PACKET *packet, RADCLIENT *client)
++{
++      if (client->require_ma == FR_BOOL_TRUE) return;
++
++      if (client->require_ma == FR_BOOL_AUTO) {
++              if (!packet->message_authenticator) {
++                      
ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++                      ERROR("BlastRADIUS check: Received packet without 
Message-Authenticator.");
++                      ERROR("Setting \"require_message_authenticator = 
false\" for client %s", client->shortname);
++                      
ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++                      ERROR("UPGRADE THE CLIENT AS YOUR NETWORK IS VULNERABLE 
TO THE BLASTRADIUS ATTACK.");
++                      ERROR("Once the client is upgraded, set 
\"require_message_authenticator = true\" for  client %s", client->shortname);
++                      
ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++                      client->require_ma = FR_BOOL_FALSE;
++
++                      /*
++                       *      And fall through to the
++                       *      limit_proxy_state checks, which might
++                       *      complain again.  Oh well, maybe that
++                       *      will make people read the messages.
++                       */
++
++              } else if (packet->eap_message) {
++                      /*
++                       *      Don't set it to "true" for packets
++                       *      with EAP-Message.  It's already
++                       *      required there, and we might get a
++                       *      non-EAP packet with (or without)
++                       *      Message-Authenticator
++                       */
++                      return;
++              } else {
++                      
ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++                      ERROR("BlastRADIUS check: Received packet with 
Message-Authenticator.");
++                      ERROR("Setting \"require_message_authenticator = true\" 
for client %s", client->shortname);
++                      
ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++                      ERROR("It looks like the client has been updated to 
protect from the BlastRADIUS attack.");
++                      ERROR("Please set \"require_message_authenticator = 
true\" for client %s", client->shortname);
++                      
ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++
++                      client->require_ma = FR_BOOL_TRUE;
++                      return;
++              }
++
++      }
++
++      /*
++       *      If all of the checks are turned off, then complain for every 
packet we receive.
++       */
++      if (client->limit_proxy_state == FR_BOOL_FALSE) {
++              /*
++               *      We have a Message-Authenticator, and it's valid.  We 
don't need to compain.
++               */
++              if (!fr_debug_lvl) return; /* easier than checking for each 
line below */
++
++              
DEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++              DEBUG("BlastRADIUS check: Received packet without 
Message-Authenticator.");
++              DEBUG("YOU MUST SET \"require_message_authenticator = true\", 
or");
++              DEBUG("YOU MUST SET \"limit_proxy_state = true\" for client 
%s", client->shortname);
++              
DEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++              DEBUG("The packet does not contain Message-Authenticator, which 
is a security issue");
++              DEBUG("UPGRADE THE CLIENT AS YOUR NETWORK IS VULNERABLE TO THE 
BLASTRADIUS ATTACK.");
++              DEBUG("Once the client is upgraded, set 
\"require_message_authenticator = true\" for client %s", client->shortname);
++              
DEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++              return;
++      }
++
++      /*
++       *      Don't complain here.  rad_packet_ok() will instead
++       *      complain about every packet with Proxy-State but which
++       *      is missing Message-Authenticator.
++       */
++      if (client->limit_proxy_state == FR_BOOL_TRUE) {
++              return;
++      }
++
++      if (packet->proxy_state && !packet->message_authenticator) {
++              
ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++              ERROR("BlastRADIUS check: Received packet with Proxy-State, but 
without Message-Authenticator.");
++              ERROR("This is either a BlastRADIUS attack, OR");
++              ERROR("the client is a proxy RADIUS server which has not been 
upgraded.");
++              ERROR("Setting \"limit_proxy_state = false\" for client %s", 
client->shortname);
++              
ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++              ERROR("UPGRADE THE CLIENT AS YOUR NETWORK IS VULNERABLE TO THE 
BLASTRADIUS ATTACK.");
++              DEBUG("Once the client is upgraded, set 
\"require_message_authenticator = true\" for client %s", client->shortname);
++              
ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++
++              client->limit_proxy_state = FR_BOOL_FALSE;
++
++      } else {
++              client->limit_proxy_state = FR_BOOL_TRUE;
++
++              
ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++              if (!packet->proxy_state) {
++                      ERROR("BlastRADIUS check: Received packet without 
Proxy-State.");
++              } else {
++                      ERROR("BlastRADIUS check: Received packet with 
Proxy-State and Message-Authenticator.");
++              }
++
++              ERROR("Setting \"limit_proxy_state = true\" for client %s", 
client->shortname);
++              
ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++
++              if (!packet->message_authenticator) {
++                      ERROR("The packet does not contain 
Message-Authenticator, which is a security issue.");
++                      ERROR("UPGRADE THE CLIENT AS YOUR NETWORK MAY BE 
VULNERABLE TO THE BLASTRADIUS ATTACK.");
++                      DEBUG("Once the client is upgraded, set 
\"require_message_authenticator = true\" for client %s", client->shortname);
++              } else {
++                      ERROR("The packet contains Message-Authenticator.");
++                      if (!packet->eap_message) ERROR("The client has likely 
been upgraded to protect from the attack.");
++                      ERROR("Please set \"require_message_authenticator = 
true\" for client %s", client->shortname);
++              }
++              
ERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++      }
++}
++
++
+ #ifdef WITH_TCP
+ static int dual_tcp_recv(rad_listen_t *listener)
+ {
+@@ -532,6 +648,21 @@ static int dual_tcp_recv(rad_listen_t *listener)
+       switch (packet->code) {
+       case PW_CODE_ACCESS_REQUEST:
+               if (listener->type != RAD_LISTEN_AUTH) goto bad_packet;
++
++              /*
++               *      Enforce BlastRADIUS checks on TCP, too.
++               */
++              if (!rad_packet_ok(packet, (client->require_ma == FR_BOOL_TRUE) 
| ((client->limit_proxy_state == FR_BOOL_TRUE) << 2), NULL)) {
++                      FR_STATS_INC(auth, total_malformed_requests);
++                      rad_free(&sock->packet);
++                      return 0;
++              }
++
++              /*
++               *      Perform BlastRADIUS checks and warnings.
++               */
++              if (packet->code == PW_CODE_ACCESS_REQUEST) 
blastradius_checks(packet, client);
++
+               FR_STATS_INC(auth, total_requests);
+               fun = rad_authenticate;
+               break;
+@@ -1562,7 +1693,7 @@ static int auth_socket_recv(rad_listen_t *listener)
+        *      Now that we've sanity checked everything, receive the
+        *      packet.
+        */
+-      packet = rad_recv(ctx, listener->fd, client->message_authenticator);
++      packet = rad_recv(ctx, listener->fd, (client->require_ma == 
FR_BOOL_TRUE) | ((client->limit_proxy_state == FR_BOOL_TRUE) << 2));
+       if (!packet) {
+               FR_STATS_INC(auth, total_malformed_requests);
+               if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror());
+@@ -1570,6 +1701,12 @@ static int auth_socket_recv(rad_listen_t *listener)
+               return 0;
+       }
+ 
++
++      /*
++       *      Perform BlastRADIUS checks and warnings.
++       */
++      if (packet->code == PW_CODE_ACCESS_REQUEST) blastradius_checks(packet, 
client);
++
+ #ifdef __APPLE__
+ #ifdef WITH_UDPFROMTO
+       /*
+@@ -1955,7 +2092,7 @@ static int coa_socket_recv(rad_listen_t *listener)
+        *      Now that we've sanity checked everything, receive the
+        *      packet.
+        */
+-      packet = rad_recv(ctx, listener->fd, client->message_authenticator);
++      packet = rad_recv(ctx, listener->fd, client->require_ma | (((int) 
client->limit_proxy_state) << 2));
+       if (!packet) {
+               FR_STATS_INC(coa, total_malformed_requests);
+               if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror());
+diff --git a/src/main/mainconfig.c b/src/main/mainconfig.c
+index e9dd412dee..520d7fa474 100644
+--- a/src/main/mainconfig.c
++++ b/src/main/mainconfig.c
+@@ -73,6 +73,8 @@ static char const *gid_name = NULL;
+ static char const *chroot_dir = NULL;
+ static bool allow_core_dumps = false;
+ static char const *radlog_dest = NULL;
++static char const *require_message_authenticator = NULL;
++static char const *limit_proxy_state = NULL;
+ 
+ /*
+  *    These are not used anywhere else..
+@@ -87,6 +89,53 @@ static bool         do_colourise = false;
+ 
+ static char const     *radius_dir = NULL;     //!< Path to raddb directory
+ 
++static const FR_NAME_NUMBER fr_bool_auto_names[] = {
++      { "false",      FR_BOOL_FALSE     },
++      { "no",         FR_BOOL_FALSE     },
++      { "0",          FR_BOOL_FALSE     },
++
++      { "true",       FR_BOOL_TRUE      },
++      { "yes",        FR_BOOL_TRUE      },
++      { "1",          FR_BOOL_TRUE      },
++
++      { "auto",       FR_BOOL_AUTO      },
++
++      { NULL, 0 }
++};
++
++/*
++ *    Get decent values for false / true / auto
++ */
++int fr_bool_auto_parse(CONF_PAIR *cp, fr_bool_auto_t *out, char const *str)
++{
++      int value;
++
++      /*
++       *      Don't change anything.
++       */
++      if (!str) return 0;
++
++      value = fr_str2int(fr_bool_auto_names, str, -1);
++      if (value >= 0) {
++              *out = value;
++              return 0;
++      }
++
++      /*
++       *      This should never happen, as the defaults are in the
++       *      source code.  If there's no CONF_PAIR, and there's a
++       *      parse error, then the source code is wrong.
++       */
++      if (!cp) {
++              fprintf(stderr, "%s: Error - Invalid value in configuration", 
main_config.name);
++              return -1;
++      }
++
++      cf_log_err(cf_pair_to_item(cp), "Invalid value for \"%s\"", 
cf_pair_attr(cp));
++      return -1;
++}
++
++
+ /**********************************************************************
+  *
+  *    We need to figure out where the logs go, before doing anything
+@@ -159,6 +208,8 @@ static const CONF_PARSER security_config[] = {
+       { "max_attributes",  FR_CONF_POINTER(PW_TYPE_INTEGER, 
&fr_max_attributes), STRINGIFY(0) },
+       { "reject_delay",  FR_CONF_POINTER(PW_TYPE_TIMEVAL, 
&main_config.reject_delay), STRINGIFY(0) },
+       { "status_server", FR_CONF_POINTER(PW_TYPE_BOOLEAN, 
&main_config.status_server), "no"},
++      { "require_message_authenticator", FR_CONF_POINTER(PW_TYPE_STRING, 
&require_message_authenticator), "auto"},
++      { "limit_proxy_state", FR_CONF_POINTER(PW_TYPE_STRING, 
&limit_proxy_state), "auto"},
+ #ifdef ENABLE_OPENSSL_VERSION_CHECK
+       { "allow_vulnerable_openssl", FR_CONF_POINTER(PW_TYPE_STRING, 
&main_config.allow_vulnerable_openssl), "no"},
+ #endif
+@@ -838,6 +889,8 @@ int main_config_init(void)
+       if (!main_config.dictionary_dir) {
+               main_config.dictionary_dir = DICTDIR;
+       }
++      main_config.require_ma = FR_BOOL_AUTO;
++      main_config.limit_proxy_state = FR_BOOL_AUTO;
+ 
+       /*
+        *      About sizeof(REQUEST) + sizeof(RADIUS_PACKET) * 2 + 
sizeof(VALUE_PAIR) * 400
+@@ -1127,6 +1180,23 @@ do {\
+       main_config.init_delay.tv_sec = 0;
+       main_config.init_delay.tv_usec = 2* (1000000 / 3);
+ 
++      {
++              CONF_PAIR *cp = NULL;
++
++              subcs = cf_section_sub_find(cs, "security");
++              if (subcs) cp = cf_pair_find(subcs, 
"require_message_authenticator");
++              if (fr_bool_auto_parse(cp, &main_config.require_ma, 
require_message_authenticator) < 0) {
++                      cf_file_free(cs);
++                      return -1;
++              }
++
++              if (subcs) cp = cf_pair_find(subcs, "limit_proxy_state");
++              if (fr_bool_auto_parse(cp, &main_config.limit_proxy_state, 
limit_proxy_state) < 0) {
++                      cf_file_free(cs);
++                      return -1;
++              }
++      }
++
+       /*
+        *      Free the old configuration items, and replace them
+        *      with the new ones.
+diff --git a/src/main/process.c b/src/main/process.c
+index 1a48517d43..401033bdd6 100644
+--- a/src/main/process.c
++++ b/src/main/process.c
+@@ -2593,6 +2593,23 @@ int request_proxy_reply(RADIUS_PACKET *packet)
+ 
+       PTHREAD_MUTEX_UNLOCK(&proxy_mutex);
+ 
++      if (!request->proxy_reply) {
++              decode_fail_t reason;
++
++              /*
++               *      If the home server configuration requires a 
Message-Authenticator, then set the flag,
++               *      but only if the proxied packet is Access-Request or 
Status-Sercer.
++               *
++               *      The realms.c file already clears require_ma for TLS 
connections.
++               */
++              bool require_ma = (request->home_server->require_ma == 
FR_BOOL_TRUE) && (request->proxy->code == PW_CODE_ACCESS_REQUEST);
++
++              if(!rad_packet_ok(packet, require_ma, &reason)) {
++                      DEBUG("Ignoring invalid packet - %s", fr_strerror());
++                      return 0;
++              }
++      }
++
+       /*
+        *      No reply, BUT the current packet fails verification:
+        *      ignore it.  This does the MD5 calculations in the
+@@ -2618,6 +2635,54 @@ int request_proxy_reply(RADIUS_PACKET *packet)
+               return 0;
+       }
+ 
++
++              /*
++               *      BlastRADIUS checks.  We're running in the main
++               *      listener thread, so there's no conflict
++               *      checking or setting these fields.
++               */
++              if (!request->proxy_reply && (request->proxy->code == 
PW_CODE_ACCESS_REQUEST) &&
++#ifdef WITH_TLS
++                  !request->home_server->tls &&
++#endif
++                  !packet->eap_message) {
++                      if (request->home_server->require_ma == FR_BOOL_AUTO) {
++                              if (!packet->message_authenticator) {
++                                      
RERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++                                      RERROR("BlastRADIUS check: Received 
response to Access-Request without Message-Authenticator.");
++                                      RERROR("Setting 
\"require_message_authenticator = false\" for home_server %s", 
request->home_server->name);
++                                      
RERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++                                      RERROR("UPGRADE THE HOME SERVER AS YOUR 
NETWORK IS VULNERABLE TO THE BLASTRADIUS ATTACK.");
++                                      RERROR("Once the home_server is 
upgraded, set \"require_message_authenticator = true\" for home_server %s.", 
request->home_server->name);
++                                      
RERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++
++                                      request->home_server->require_ma = 
FR_BOOL_FALSE;
++                              } else {
++                                      
RERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++                                      RERROR("BlastRADIUS check: Received 
response to Access-Request with Message-Authenticator.");
++                                      RERROR("Setting 
\"require_message_authenticator = true\" for home_server %s", 
request->home_server->name);
++                                      
RERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++                                      RERROR("It looks like the home server 
has been updated to protect from the BlastRADIUS attack.");
++                                      RERROR("Please set 
\"require_message_authenticator = true\" for home_server %s", 
request->home_server->name);
++                                      
RERROR("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++
++                                      request->home_server->require_ma = 
FR_BOOL_TRUE;
++                              }
++
++                      } else if (fr_debug_lvl && 
(request->home_server->require_ma == FR_BOOL_FALSE) && 
!packet->message_authenticator) {
++                              /*
++                               *      If it's "no" AND we don't have a 
Message-Authenticator, then complain on every packet.
++                               */
++                              
RDEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++                              RDEBUG("BlastRADIUS check: Received packet 
without Message-Authenticator from home_server %s", request->home_server->name);
++                              
RDEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++                              RDEBUG("The packet does not contain 
Message-Authenticator, which is a security issue");
++                              RDEBUG("UPGRADE THE HOME SERVER AS YOUR NETWORK 
IS VULNERABLE TO THE BLASTRADIUS ATTACK.");
++                              RERROR("Once the home_server is upgraded, set 
\"require_message_authenticator = true\" for home_server %s.", 
request->home_server->name);
++                              
RDEBUG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
++                      }
++              }
++
+       /*
+        *      This shouldn't happen, but threads and race
+        *      conditions.
+diff --git a/src/main/radclient.c b/src/main/radclient.c
+index 52d2872b13..47d5f07785 100644
+--- a/src/main/radclient.c
++++ b/src/main/radclient.c
+@@ -54,6 +54,7 @@ static fr_ipaddr_t server_ipaddr;
+ static int resend_count = 1;
+ static bool done = true;
+ static bool print_filename = false;
++static bool blast_radius = false;
+ 
+ static fr_ipaddr_t client_ipaddr;
+ static uint16_t client_port = 0;
+@@ -89,6 +90,7 @@ static void NEVER_RETURNS usage(void)
+       fprintf(stderr, "  <command>              One of auth, acct, status, 
coa, disconnect or auto.\n");
+       fprintf(stderr, "  -4                     Use IPv4 address of 
server\n");
+       fprintf(stderr, "  -6                     Use IPv6 address of 
server.\n");
++      fprintf(stderr, "  -b                     Mandate checks for Blast 
RADIUS (this is not set by default).\n");
+       fprintf(stderr, "  -c <count>             Send each packet 'count' 
times.\n");
+       fprintf(stderr, "  -d <raddb>             Set user dictionary directory 
(defaults to " RADDBDIR ").\n");
+       fprintf(stderr, "  -D <dictdir>           Set main dictionary directory 
(defaults to " DICTDIR ").\n");
+@@ -1000,6 +1002,130 @@ static int send_one_packet(rc_request_t *request)
+       return 0;
+ }
+ 
++/*
++ *    Do Blast RADIUS checks.
++ *
++ *    The request is an Access-Request, and does NOT contain Proxy-State.
++ *
++ *    The reply is a raw packet, and is NOT yet decoded.
++ */
++static int blast_radius_check(rc_request_t *request, RADIUS_PACKET *reply)
++{
++      uint8_t *attr, *end;
++      VALUE_PAIR *vp;
++      bool have_message_authenticator = false;
++
++      /*
++       *      We've received a raw packet.  Nothing has (as of yet) checked
++       *      anything in it other than the length, and that it's a
++       *      well-formed RADIUS packet.
++       */
++      switch (reply->data[0]) {
++      case PW_CODE_ACCESS_ACCEPT:
++      case PW_CODE_ACCESS_REJECT:
++      case PW_CODE_ACCESS_CHALLENGE:
++              if (reply->data[1] != request->packet->id) {
++                      ERROR("Invalid reply ID %d to Access-Request ID %d", 
reply->data[1], request->packet->id);
++                      return -1;
++              }
++              break;
++
++      default:
++              ERROR("Invalid reply code %d to Access-Request", 
reply->data[0]);
++              return -1;
++      }
++
++      /*
++       *      If the reply has a Message-Authenticator, then it MIGHT be fine.
++       */
++      attr = reply->data + 20;
++      end = reply->data + reply->data_len;
++
++      /*
++       *      It should be the first attribute, so we warn if it isn't there.
++       *
++       *      But it's not a fatal error.
++       */
++      if (blast_radius && (attr[0] != PW_MESSAGE_AUTHENTICATOR)) {
++              RDEBUG("WARNING The %s reply packet does not have 
Message-Authenticator as the first attribute.  The packet may be vulnerable to 
Blast RADIUS attacks.",
++                     fr_packet_codes[reply->data[0]]);
++      }
++
++      /*
++       *      Set up for Proxy-State checks.
++       *
++       *      If we see a Proxy-State in the reply which we didn't send, then 
it's a Blast RADIUS attack.
++       */
++      vp = fr_pair_find_by_num(request->packet->vps, PW_PROXY_STATE, 0, 
TAG_ANY);
++
++      while (attr < end) {
++              /*
++               *      Blast RADIUS work-arounds require that
++               *      Message-Authenticator is the first attribute in the
++               *      reply.  Note that we don't check for it being the
++               *      first attribute, but simply that it exists.
++               *
++               *      That check is a balance between securing the reply
++               *      packet from attacks, and not violating the RFCs which
++               *      say that there is no order to attributes in the
++               *      packet.
++               *
++               *      However, no matter the status of the '-b' flag we
++               *      still can check for the signature of the attack, and
++               *      discard packets which are suspicious.  This behavior
++               *      protects radclient from the attack, without mandating
++               *      new behavior on the server side.
++               *
++               *      Note that we don't set the '-b' flag by default.
++               *      radclient is intended for testing / debugging, and is
++               *      not intended to be used as part of a secure login /
++               *      user checking system.
++               */
++              if (attr[0] == PW_MESSAGE_AUTHENTICATOR) {
++                      have_message_authenticator = true;
++                      goto next;
++              }
++
++              /*
++               *      If there are Proxy-State attributes in the reply, they 
must
++               *      match EXACTLY the Proxy-State attributes in the request.
++               *
++               *      Note that we don't care if there are more Proxy-States
++               *      in the request than in the reply.  The Blast RADIUS
++               *      issue requires _adding_ Proxy-State attributes, and
++               *      cannot work when the server _deletes_ Proxy-State
++               *      attributes.
++               */
++              if (attr[0] == PW_PROXY_STATE) {
++                      if (!vp || (vp->length != (size_t) (attr[1] - 2)) || 
(memcmp(vp->vp_octets, attr + 2, vp->length) != 0)) {
++                              ERROR("Invalid reply to Access-Request ID %d - 
Discarding packet due to Blast RADIUS attack being detected.", 
request->packet->id);
++                              ERROR("We received a Proxy-State in the reply 
which we did not send, or which is different from what we sent.");
++                              return -1;
++                      }
++
++                      vp = fr_pair_find_by_num(vp->next, PW_PROXY_STATE, 0, 
TAG_ANY);
++              }
++
++      next:
++              attr += attr[1];
++      }
++
++      /*
++       *      If "-b" is set, then we require Message-Authenticator in the 
reply.
++       */
++      if (blast_radius && !have_message_authenticator) {
++              ERROR("The %s reply packet does not contain 
Message-Authenticator - discarding packet due to Blast RADIUS checks.",
++                    fr_packet_codes[reply->data[0]]);
++              return -1;
++      }
++
++      /*
++       *      The packet doesn't look like it's a Blast RADIUS attack.  The
++       *      caller will now verify the packet signature.
++       */
++      return 0;
++}
++
+ /*
+  *    Receive one packet, maybe.
+  */
+@@ -1051,6 +1177,21 @@ static int recv_one_packet(int wait_time)
+       }
+       request = fr_packet2myptr(rc_request_t, packet, packet_p);
+ 
++
++      /*
++       *      We want radclient to be able to send any packet, including
++       *      imperfect ones.  However, we do NOT want to be vulnerable to
++       *      the "Blast RADIUS" issue.  Instead of adding command-line
++       *      flags to enable/disable similar flags to what the server
++       *      sends, we just do a few more smart checks to double-check
++       *      things.
++       */
++      if ((request->packet->code == PW_CODE_ACCESS_REQUEST) &&
++          blast_radius_check(request, reply) < 0) {
++              rad_free(&reply);
++              return -1;
++      }
++
+       /*
+        *      Fails the signature validation: not a real reply.
+        *      FIXME: Silently drop it and listen for another packet.
+@@ -1183,7 +1324,7 @@ int main(int argc, char **argv)
+               exit(1);
+       }
+ 
+-      while ((c = getopt(argc, argv, "46c:d:D:f:Fhn:p:qr:sS:t:vx"
++      while ((c = getopt(argc, argv, "46bc:d:D:f:Fhn:p:qr:sS:t:vx"
+ #ifdef WITH_TCP
+               "P:"
+ #endif
+@@ -1192,6 +1333,10 @@ int main(int argc, char **argv)
+                       force_af = AF_INET;
+                       break;
+ 
++              case 'b':
++                      blast_radius = true;
++                      break;
++
+               case '6':
+                       force_af = AF_INET6;
+                       break;
+diff --git a/src/main/radtest.in b/src/main/radtest.in
+index 38b1ba9a0f..8a6741a26c 100644
+--- a/src/main/radtest.in
++++ b/src/main/radtest.in
+@@ -19,6 +19,7 @@ usage() {
+       echo "        -x                  Enable debug output" >&2
+       echo "        -4                  Use IPv4 for the NAS address 
(default)" >&2
+       echo "        -6                  Use IPv6 for the NAS address" >&2
++      echo "        -6                  Mandate checks for Blast RADIUS (this 
is not set by default)." >&2
+       exit 1
+ }
+ 
+@@ -55,6 +56,10 @@ do
+               NAS_ADDR_ATTR="NAS-IPv6-Address"
+               shift
+               ;;
++      -b)
++              OPTIONS="$OPTIONS -b"
++              shift
++              ;;
+       -d) 
+               OPTIONS="$OPTIONS -d $2"
+               shift;shift
+@@ -120,7 +125,6 @@ fi
+       echo "$PASSWORD = \"$2\""
+       echo "$NAS_ADDR_ATTR = $nas"
+       echo "NAS-Port = $4"
+-      echo "Message-Authenticator = 0x00"
+       if [ "$radclient" = "$radeapclient" ]
+       then
+           echo "EAP-Code = Response"
+diff --git a/src/main/realms.c b/src/main/realms.c
+index eb42598116..5e1215c0bb 100644
+--- a/src/main/realms.c
++++ b/src/main/realms.c
+@@ -366,7 +366,10 @@ static CONF_PARSER home_server_coa[] = {
+ };
+ #endif
+ 
++static const char *require_message_authenticator = NULL;
++
+ static CONF_PARSER home_server_config[] = {
++      { "require_message_authenticator", FR_CONF_POINTER(PW_TYPE_STRING| 
PW_TYPE_IGNORE_DEFAULT, &require_message_authenticator), NULL },
+       { "ipaddr", FR_CONF_OFFSET(PW_TYPE_COMBO_IP_ADDR, home_server_t, 
ipaddr), NULL },
+       { "ipv4addr", FR_CONF_OFFSET(PW_TYPE_IPV4_ADDR, home_server_t, ipaddr), 
NULL },
+       { "ipv6addr", FR_CONF_OFFSET(PW_TYPE_IPV6_ADDR, home_server_t, ipaddr), 
NULL },
+@@ -640,6 +643,9 @@ home_server_t *home_server_afrom_cs(TALLOC_CTX *ctx, 
realm_config_t *rc, CONF_SE
+       home->cs = cs;
+       home->state = HOME_STATE_UNKNOWN;
+       home->proto = IPPROTO_UDP;
++      home->require_ma = main_config.require_ma;
++
++      require_message_authenticator = false;
+ 
+       /*
+        *      Parse the configuration into the home server
+@@ -647,6 +653,10 @@ home_server_t *home_server_afrom_cs(TALLOC_CTX *ctx, 
realm_config_t *rc, CONF_SE
+        */
+       if (cf_section_parse(cs, home, home_server_config) < 0) goto error;
+ 
++      if (fr_bool_auto_parse(cf_pair_find(cs, 
"require_message_authenticator"), &home->require_ma, 
require_message_authenticator) < 0) {
++              goto error;
++      }
++
+       /*
+        *      It has an IP address, it must be a remote server.
+        */
+@@ -924,6 +934,7 @@ home_server_t *home_server_afrom_cs(TALLOC_CTX *ctx, 
realm_config_t *rc, CONF_SE
+                *      Parse the SSL client configuration.
+                */
+               if (tls) {
++                      home->require_ma = false;
+                       home->tls = tls_client_conf_parse(tls);
+                       if (!home->tls) {
+                               goto error;
+diff --git a/src/main/tls_listen.c b/src/main/tls_listen.c
+index 0eed87b64f..4ae3c5b975 100644
+--- a/src/main/tls_listen.c
++++ b/src/main/tls_listen.c
+@@ -299,6 +299,8 @@ get_application_data:
+       packet->vps = NULL;
+       PTHREAD_MUTEX_UNLOCK(&sock->mutex);
+ 
++      packet->tls = true;
++
+       if (!rad_packet_ok(packet, 0, NULL)) {
+               if (DEBUG_ENABLED) ERROR("Receive - %s", fr_strerror());
+               DEBUG("Closing TLS socket from client");
+@@ -713,6 +715,8 @@ int proxy_tls_recv(rad_listen_t *listener)
+       memcpy(packet->data, data, packet->data_len);
+       memcpy(packet->vector, packet->data + 4, 16);
+ 
++      packet->tls = true;
++
+       /*
+        *      FIXME: Client MIB updates?
+        */
+@@ -765,6 +769,7 @@ int proxy_tls_send(rad_listen_t *listener, REQUEST 
*request)
+        *      if there's no packet, encode it here.
+        */
+       if (!request->proxy->data) {
++              request->reply->tls = true;
+               request->proxy_listener->encode(request->proxy_listener,
+                                               request);
+       }
+-- 
+2.35.7
+
diff --git 
a/meta-networking/recipes-connectivity/freeradius/freeradius_3.0.21.bb 
b/meta-networking/recipes-connectivity/freeradius/freeradius_3.0.21.bb
index db37f6591..01d23fdf8 100644
--- a/meta-networking/recipes-connectivity/freeradius/freeradius_3.0.21.bb
+++ b/meta-networking/recipes-connectivity/freeradius/freeradius_3.0.21.bb
@@ -35,6 +35,7 @@ SRC_URI = 
"git://github.com/FreeRADIUS/freeradius-server.git;branch=v3.0.x;lfs=0
     file://0001-version.c-don-t-print-build-flags.patch \
     file://CVE-2022-41860.patch \
     file://CVE-2022-41861.patch \
+    file://CVE-2024-3596.patch \
 "
 
 raddbdir="${sysconfdir}/${MLPREFIX}raddb"
-- 
2.34.1

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#112924): 
https://lists.openembedded.org/g/openembedded-devel/message/112924
Mute This Topic: https://lists.openembedded.org/mt/109018135/21656
Group Owner: [email protected]
Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub 
[[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to