freeradius3: update to 3.2.10

Patches:
- Drop 003-freeradius-fix-error-for-expansion-of-macro.patch (upstream
  restructured src/include/threads.h) and add
  003-configure-assume-cross-tls.patch instead: the AC_RUN_IFELSE
  __thread probe cannot run when cross-compiling, so TLS_STORAGE_CLASS
  stays undefined and threads.h hits '#error unsupported' (since 3.2.9).
- Drop 002-disable-session-cache-CVE-2017-9148.patch, 3.2.x is not
  affected per https://nvd.nist.gov/vuln/detail/CVE-2017-9148.
- Replace 004-get-hostname-from-proc-in-radtest.patch with
  004-radtest-nas-name-from-hostname-env.patch: prefer $HOSTNAME and keep
  the upstream `hostname || uname -n` fallback instead of reading
  /proc/sys/kernel/hostname unconditionally.
- Re-do 020-fix-freeradius3-krb5.patch, also sent upstream for review.
- Give the touched patches the git format-patch headers 'git am' needs,
  with the diff bodies unchanged so they still match 'quilt refresh'.

Depend on libopenssl-legacy when built against OpenSSL: with OpenSSL 3.x
tls_global_init() unconditionally does OSSL_PROVIDER_load(NULL, "legacy")
for MD4/MS-CHAP and errors out when it is missing, so radiusd exits during
startup before it ever serves a request.

Add a test.sh covering the freeradius3, -common, -utils and -democerts
packages: radiusd -XC starts the server for real, the config tree it reads
is checked, the dictionaries the master dictionary still $INCLUDEs must
all be packaged, and the demo certificates must be real PEM.

Signed-off-by: Alexandru Ardelean <alex@shruggie.ro>
This commit is contained in:
Alexandru Ardelean authored and Josef Schlehofer committed 2026-07-23 01:10:15 +02:00
1 parent f33158e88d
commit 71223e9e07
9 files changed
+215 -113

No files matched your search

+3 -3
View File
@@ -8,13 +8,13 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=freeradius3
PKG_VERSION:=3.2.8
PKG_VERSION:=3.2.10
PKG_VERSION_UNDERSCORE:=$(subst .,_,${PKG_VERSION})
PKG_RELEASE:=1
PKG_SOURCE:=freeradius-server-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/FreeRADIUS/freeradius-server/releases/download/release_$(PKG_VERSION_UNDERSCORE)/
PKG_HASH:=3846498103d3faf182abd968a440128cb0c5589330bdcdd58c466ef15d9f9fdf
PKG_HASH:=40e0cdfdcceb22cf0acb79bc29cf7c32995466a61fda09445ce5220608a55afd
PKG_MAINTAINER:=Alexandru Ardelean <ardeleanalex@gmail.com>
PKG_LICENSE:=GPL-2.0
@@ -63,7 +63,7 @@ endef
define Package/freeradius3-common
$(call Package/freeradius3/Default)
TITLE:=common files
DEPENDS:= +USE_GLIBC:libcrypt-compat +USE_GLIBC:libpthread +USE_GLIBC:libbsd +FREERADIUS3_OPENSSL:libopenssl +libcap +libpcap +libncurses +libreadline +libtalloc +libatomic
DEPENDS:=+USE_GLIBC:libcrypt-compat +USE_GLIBC:libpthread +USE_GLIBC:libbsd +FREERADIUS3_OPENSSL:libopenssl +FREERADIUS3_OPENSSL:libopenssl-legacy +libcap +libpcap +libncurses +libreadline +libtalloc +libatomic
endef
define Package/freeradius3-default
@@ -1,47 +0,0 @@
Description: disable session caching in the server (as opposed to in the
config, which would be way harder to get right) to address
https://security-tracker.debian.org/tracker/CVE-2017-9148
Author: Michael Stapelberg <stapelberg@debian.org>
Forwarded: not-needed
Last-Update: 2020-04-28
---
--- a/src/main/tls.c
+++ b/src/main/tls.c
@@ -860,7 +860,7 @@ after_chain:
}
if (vp) vp->vp_integer = state->mtu;
- if (conf->session_cache_enable) state->allow_session_resumption = true; /* otherwise it's false */
+ if (/*conf->session_cache_enable*/0) state->allow_session_resumption = true; /* otherwise it's false */
return state;
}
@@ -4520,7 +4520,7 @@ post_ca:
/*
* Callbacks, etc. for session resumption.
*/
- if (conf->session_cache_enable) {
+ if (/*conf->session_cache_enable*/0) {
/*
* Cache sessions on disk if requested.
*/
@@ -4600,7 +4600,7 @@ post_ca:
/*
* Setup session caching
*/
- if (conf->session_cache_enable) {
+ if (/*conf->session_cache_enable*/0) {
/*
* Create a unique context Id per EAP-TLS configuration.
*/
@@ -4890,7 +4890,7 @@ fr_tls_server_conf_t *tls_server_conf_pa
goto error;
}
- if (conf->session_cache_enable) {
+ if (/*conf->session_cache_enable*/0) {
CONF_SECTION *subcs;
CONF_ITEM *ci;
@@ -0,0 +1,23 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexandru Ardelean <alex@shruggie.ro>
Date: Wed, 3 Jun 2026 01:48:03 +0300
Subject: [PATCH] configure: assume __thread TLS works when cross-compiling
OpenWrt cross-compiles with gcc on musl, which supports __thread. The
AC_RUN_IFELSE check in fr_tls.m4 defaults to "no" for cross builds, so
TLS_STORAGE_CLASS is never defined, __THREAD is never set, and threads.h
falls through to '#error unsupported' (added in 3.2.9).
Signed-off-by: Alexandru Ardelean <alex@shruggie.ro>
---
--- a/configure
+++ b/configure
@@ -12625,7 +12625,7 @@ fi
printf %s "checking for __thread support in compiler... " >&6; }
if test "$cross_compiling" = yes
then :
- have_tls=no
+ have_tls=yes
else $as_nop
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
@@ -1,33 +0,0 @@
--- a/src/include/threads.h
+++ b/src/include/threads.h
@@ -92,7 +92,7 @@ static _t __fr_thread_local_init_##_n(pt
# define fr_thread_local_get(_n) _n
#elif defined(HAVE_PTHREAD_H)
# include <pthread.h>
-# define fr_thread_local_setup(_t, _n) \
+# define fr_thread_local_setup(_t, _n) static __thread _t _n;\
static pthread_key_t __fr_thread_local_key_##_n;\
static pthread_once_t __fr_thread_local_once_##_n = PTHREAD_ONCE_INIT;\
static pthread_destructor_t __fr_thread_local_destructor_##_n = NULL;\
@@ -103,17 +103,17 @@ static void __fr_thread_local_destroy_##
static void __fr_thread_local_key_init_##_n(void)\
{\
(void) pthread_key_create(&__fr_thread_local_key_##_n, __fr_thread_local_destroy_##_n);\
- (void) pthread_setspecific(__fr_thread_local_key_##_n, &(_n));\
}\
static _t __fr_thread_local_init_##_n(pthread_destructor_t func)\
{\
__fr_thread_local_destructor_##_n = func;\
if (_n) return _n; \
(void) pthread_once(&__fr_thread_local_once_##_n, __fr_thread_local_key_init_##_n);\
+ (void) pthread_setspecific(__fr_thread_local_key_##_n, &(_n));\
return _n;\
}
-# define fr_thread_local_init(_n, _f) __fr_thread_local_init_##_n(_f)
-# define fr_thread_local_set(_n, _v) __fr_thread_local_set_##_n(_v)
-# define fr_thread_local_get(_n) __fr_thread_local_get_##_n()
+# define fr_thread_local_init(_n, _f) __fr_thread_local_init_##_n(_f)
+# define fr_thread_local_set(_n, _v) ((int)!((_n = _v) || 1))
+# define fr_thread_local_get(_n) _n
#endif
#endif
@@ -1,11 +0,0 @@
--- a/src/main/radtest.in
+++ b/src/main/radtest.in
@@ -117,7 +117,7 @@ if [ "$7" ]
then
nas=$7
else
- nas=`(hostname || uname -n) 2>/dev/null | sed 1q`
+ nas=$(cat /proc/sys/kernel/hostname)
fi
(
@@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexandru Ardelean <alex@shruggie.ro>
Date: Wed, 3 Jun 2026 01:48:03 +0300
Subject: [PATCH] radtest: use $HOSTNAME for the NAS name when it is set
radtest derives the NAS name from `hostname` or `uname -n`, neither of
which is guaranteed to be present in a minimal image. Prefer the
$HOSTNAME environment variable when the shell exports it, and keep the
original command substitution as the fallback.
Signed-off-by: Alexandru Ardelean <alex@shruggie.ro>
---
--- a/src/main/radtest.in
+++ b/src/main/radtest.in
@@ -117,7 +117,12 @@ if [ "$7" ]
then
nas=$7
else
- nas=`(hostname || uname -n) 2>/dev/null | sed 1q`
+ if [ -n "$HOSTNAME" ]
+ then
+ nas=$HOSTNAME
+ else
+ nas=`(hostname || uname -n) 2>/dev/null | sed 1q`
+ fi
fi
(
@@ -1,6 +1,19 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Rosen Penev <rosenp@gmail.com>
Date: Sun, 2 Aug 2020 15:07:47 -0700
Subject: [PATCH] fix compilation without deprecated OpenSSL APIs
Guard the OpenSSL 1.0 locking callbacks and the explicit library
init/cleanup calls behind a version check, switch X509_get_notAfter() and
X509_get_notBefore() to their X509_get0_* replacements, replace the
SSLeay() aliases with OpenSSL_version_num()/OpenSSL_version(), and
include <openssl/dh.h> explicitly.
Signed-off-by: Rosen Penev <rosenp@gmail.com>
---
--- a/src/main/threads.c
+++ b/src/main/threads.c
@@ -275,6 +275,7 @@ static void ssl_locking_function(int mod
@@ -257,6 +257,7 @@ static void ssl_locking_function(int mod
*/
int tls_mutexes_init(void)
{
@@ -8,7 +21,7 @@
int i, num;
rad_assert(ssl_mutexes == NULL);
@@ -292,6 +293,7 @@ int tls_mutexes_init(void)
@@ -274,6 +275,7 @@ int tls_mutexes_init(void)
}
CRYPTO_set_locking_callback(ssl_locking_function);
@@ -26,7 +39,7 @@
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
# include <openssl/provider.h>
@@ -2943,7 +2944,7 @@ int cbtls_verify(int ok, X509_STORE_CTX
@@ -2985,7 +2986,7 @@ int cbtls_verify(int ok, X509_STORE_CTX
int my_ok = ok;
ASN1_INTEGER *sn = NULL;
@@ -35,7 +48,7 @@
VALUE_PAIR **certs;
char **identity;
#ifdef HAVE_OPENSSL_OCSP_H
@@ -3035,7 +3036,7 @@ int cbtls_verify(int ok, X509_STORE_CTX
@@ -3077,7 +3078,7 @@ int cbtls_verify(int ok, X509_STORE_CTX
* Get the Expiration Date
*/
buf[0] = '\0';
@@ -44,7 +57,7 @@
if (certs && (lookup <= 1) && asn_time &&
(asn_time->length < (int) sizeof(buf))) {
memcpy(buf, (char*) asn_time->data, asn_time->length);
@@ -3048,7 +3049,7 @@ int cbtls_verify(int ok, X509_STORE_CTX
@@ -3090,7 +3091,7 @@ int cbtls_verify(int ok, X509_STORE_CTX
* Get the Valid Since Date
*/
buf[0] = '\0';
@@ -53,7 +66,7 @@
if (certs && (lookup <= 1) && asn_time &&
(asn_time->length < (int) sizeof(buf))) {
memcpy(buf, (char*) asn_time->data, asn_time->length);
@@ -3655,10 +3656,12 @@ static int set_ecdh_curve(SSL_CTX *ctx,
@@ -3697,10 +3698,12 @@ static int set_ecdh_curve(SSL_CTX *ctx,
*/
int tls_global_init(TLS_UNUSED bool spawn_flag, TLS_UNUSED bool check)
{
@@ -66,7 +79,7 @@
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
EVP_set_default_properties(NULL, "-fips");
@@ -3762,6 +3765,7 @@ int tls_global_version_check(char const
@@ -3806,6 +3809,7 @@ int tls_global_version_check(char const
*/
void tls_global_cleanup(void)
{
@@ -74,7 +87,7 @@
#if OPENSSL_VERSION_NUMBER < 0x10000000L
ERR_remove_state(0);
#elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
@@ -3787,6 +3791,7 @@ void tls_global_cleanup(void)
@@ -3833,6 +3837,7 @@ void tls_global_cleanup(void)
ERR_free_strings();
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
@@ -1,23 +1,43 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alexandru Ardelean <alex@shruggie.ro>
Date: Mon, 13 Jul 2026 22:18:27 +0300
Subject: [PATCH] rlm_krb5: assume thread-safety when cross-compiling
The autoconf probe for krb5_is_thread_safe() has no action-if-cross-compiling
argument, so once libkrb5 provides the symbol configure aborts outright with
"cannot run test program while cross compiling".
Add the missing argument: warn that the probe was skipped, and assume
thread-safety, which is correct for all modern krb5 builds.
Signed-off-by: Alexandru Ardelean <alex@shruggie.ro>
---
--- a/src/modules/rlm_krb5/configure
+++ b/src/modules/rlm_krb5/configure
@@ -4003,12 +4003,6 @@ if test "x$smart_lib" != "x"; then
fi
@@ -4004,10 +4004,9 @@ fi
if test "x$ac_cv_lib_krb5_krb5_is_thread_safe" = xyes; then
- if test "$cross_compiling" = yes; then :
if test "$cross_compiling" = yes; then :
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run test program while cross compiling
-See \`config.log' for more details" "$LINENO" 5; }
-else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cross compiling: not checking" >&5
+$as_echo "$as_me: WARNING: cross compiling: not checking" >&2;}
+ krb5threadsafe="-DKRB5_IS_THREAD_SAFE"
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <krb5.h>
@@ -4028,7 +4022,6 @@ $as_echo "$as_me: WARNING: libkrb5 is no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
--- a/src/modules/rlm_krb5/configure.ac
+++ b/src/modules/rlm_krb5/configure.ac
@@ -143,7 +143,9 @@ if test "$krb5threadsafe" != "no"; then
FR_SMART_CHECK_LIB(krb5, krb5_is_thread_safe)
if test "x$ac_cv_lib_krb5_krb5_is_thread_safe" = xyes; then
AC_RUN_IFELSE([AC_LANG_PROGRAM([[#include <krb5.h>]], [[return krb5_is_thread_safe() ? 0 : 1]])],
- [krb5threadsafe="-DKRB5_IS_THREAD_SAFE"], [AC_MSG_WARN([[libkrb5 is not threadsafe]])])
+ [krb5threadsafe="-DKRB5_IS_THREAD_SAFE"], [AC_MSG_WARN([[libkrb5 is not threadsafe]])],
+ [AC_MSG_WARN(cross compiling: not checking)
+ krb5threadsafe="-DKRB5_IS_THREAD_SAFE"])
fi
else
krb5threadsafe=""
+109
View File
@@ -0,0 +1,109 @@
#!/bin/sh
FR_ETC="/etc/freeradius3"
FR_LIB="/usr/lib/freeradius3"
FR_SHARE="/usr/share/freeradius3"
case "$1" in
freeradius3)
[ -x /usr/sbin/radiusd ] || { echo "FAIL: /usr/sbin/radiusd not installed"; exit 1; }
for f in radiusd.conf clients.conf proxy.conf \
policy.d/accounting policy.d/filter \
sites-available/default sites-enabled/default; do
[ -s "$FR_ETC/$f" ] || { echo "FAIL: $FR_ETC/$f missing or empty"; exit 1; }
done
# radiusd derives every other config path from raddbdir.
grep -q "^raddbdir = $FR_ETC\$" "$FR_ETC/radiusd.conf" || {
echo "FAIL: radiusd.conf does not set raddbdir to $FR_ETC"
grep -n '^raddbdir' "$FR_ETC/radiusd.conf"
exit 1
}
[ -x /etc/init.d/radiusd ] || { echo "FAIL: /etc/init.d/radiusd not installed"; exit 1; }
;;
freeradius3-default)
# Pulls in the modules radiusd.conf expects in mods-enabled/, so this is
# the first package where the server can start. -XC reads the whole
# config, loads every module and initialises OpenSSL, then exits.
radiusd -XC || {
echo "FAIL: 'radiusd -XC' could not start the server"
exit 1
}
;;
freeradius3-common)
for l in dhcp eap radius server; do
[ -s "$FR_LIB/libfreeradius-$l.so" ] || {
echo "FAIL: $FR_LIB/libfreeradius-$l.so not installed"; exit 1; }
done
[ -s "$FR_ETC/dictionary" ] || { echo "FAIL: $FR_ETC/dictionary missing or empty"; exit 1; }
[ -s "$FR_SHARE/dictionary" ] || { echo "FAIL: $FR_SHARE/dictionary missing or empty"; exit 1; }
# The Makefile packages only PKG_DICTIONARIES; a still-active $INCLUDE
# without a file behind it stops radiusd from starting.
includes=$(sed -n 's/^\$INCLUDE[[:space:]][[:space:]]*\(dictionary\.[^[:space:]]*\).*/\1/p' \
"$FR_SHARE/dictionary")
[ -n "$includes" ] || {
echo "FAIL: no active \$INCLUDE lines in $FR_SHARE/dictionary"; exit 1; }
missing=
for d in $includes; do
[ -f "$FR_SHARE/$d" ] || missing="$missing $d"
done
[ -z "$missing" ] || {
echo "FAIL: \$INCLUDE with no dictionary file behind it:$missing"; exit 1; }
;;
freeradius3-utils)
for t in radclient radeapclient radwho; do
[ -x "/usr/bin/$t" ] || { echo "FAIL: /usr/bin/$t not installed"; exit 1; }
"/usr/bin/$t" -h 2>&1 | grep -q "Usage: $t" || {
echo "FAIL: '$t -h' did not print its usage"
"/usr/bin/$t" -h 2>&1 | head -n 5
exit 1
}
done
[ -x /usr/bin/radtest ] || { echo "FAIL: /usr/bin/radtest not installed"; exit 1; }
radtest 2>&1 | grep -q "Usage: radtest" || {
echo "FAIL: 'radtest' did not print its usage"
radtest 2>&1 | head -n 5
exit 1
}
# Use a TEST-NET HOSTNAME with no NAS name to verify patch 004 passes it
# as NAS-IP-Address; capture xtrace and stop radclient with no server.
nas_ip="192.0.2.77"
radtest_out="/tmp/radtest-hostname.$$"
HOSTNAME="$nas_ip" sh -x /usr/bin/radtest u p 127.0.0.1:1812 0 testing123 \
>"$radtest_out" 2>&1 &
radtest_pid=$!
sleep 3
kill "$radtest_pid" 2>/dev/null
killall radclient 2>/dev/null
grep -q "NAS-IP-Address = $nas_ip" "$radtest_out" || {
echo "FAIL: radtest did not use \$HOSTNAME ($nas_ip) for NAS-IP-Address"
grep -E 'nas=|NAS-IP-Address' "$radtest_out" | head -n 10
rm -f "$radtest_out"
exit 1
}
rm -f "$radtest_out"
;;
freeradius3-democerts)
for f in ca.pem server.pem; do
[ -s "$FR_ETC/certs/$f" ] || { echo "FAIL: $FR_ETC/certs/$f missing or empty"; exit 1; }
grep -q "BEGIN CERTIFICATE" "$FR_ETC/certs/$f" || {
echo "FAIL: $FR_ETC/certs/$f holds no certificate"; exit 1; }
done
grep -q "BEGIN .*PRIVATE KEY" "$FR_ETC/certs/server.pem" || {
echo "FAIL: $FR_ETC/certs/server.pem holds no private key"; exit 1; }
;;
esac
exit 0