commit 7728fc683d9f6fb114ac7b321c55d268bddef199
Author: Alan T. DeKok <aland@freeradius.org>
Date:   Mon Mar 22 15:39:33 2021 -0400

    add "secret" flag to attribute
    
    so we can not print it.  Sometimes.  Maybe.

commit bd1169c834583e3987de469eb2feef9cf3fe4a77
Author: Alan T. DeKok <aland@freeradius.org>
Date:   Mon Mar 22 15:53:55 2021 -0400

    add and check for "suppress_secrets"
    
    so that debug output contains fewer secrets

commit 72c1f718f0059e8af04937b2a88b94e60dd046cb
Author: Alan T. DeKok <aland@freeradius.org>
Date:   Mon Mar 22 15:57:17 2021 -0400

    suppress secrets here, too

commit a0895291c74cab4a01f069ec576dd232950c6bcd
Author: Alan T. DeKok <aland@freeradius.org>
Date:   Mon Mar 22 16:08:42 2021 -0400

    use prefix, too

commit 752bc011a860da7e443a1b16a10ff4a028138e3b
Author: Alan T. DeKok <aland@freeradius.org>
Date:   Wed Mar 24 08:22:49 2021 -0400

    typo

commit e66f45b122e9a65e4a88947d14f84cda3ff83a49
Author: Alan T. DeKok <aland@freeradius.org>
Date:   Wed Mar 24 10:20:06 2021 -0400

    suppress more secrets

commit 4141a0573beee5d594f237d23c9efffbd4216c89
Author: Alan T. DeKok <aland@freeradius.org>
Date:   Wed Mar 24 10:22:47 2021 -0400

    mark more attributes "secret"

commit efc9c8d1d5b66d4090fd90d89f74e11896aa4864
Author: Alan T. DeKok <aland@freeradius.org>
Date:   Fri Apr 2 06:13:46 2021 -0400

    document suppress_secrets


commit 99877d5cee396d2e6939067f946111ff65cf0457
Author: Alan T. DeKok <aland@freeradius.org>
Date:   Mon May 3 14:18:19 2021 -0400

    'octets' can be secret, too


Index: freeradius-server-3.0.16/src/include/libradius.h
===================================================================
--- freeradius-server-3.0.16.orig/src/include/libradius.h
+++ freeradius-server-3.0.16/src/include/libradius.h
@@ -189,6 +189,8 @@ typedef struct attr_flags {
 
 	unsigned int	compare : 1;				//!< has a paircompare registered
 
+	unsigned int	secret : 1;				//!< is a secret thingy
+
 	uint8_t		encrypt;      				//!< Ecryption method.
 	uint8_t		length;
 } ATTR_FLAGS;
Index: freeradius-server-3.0.16/src/lib/dict.c
===================================================================
--- freeradius-server-3.0.16.orig/src/lib/dict.c
+++ freeradius-server-3.0.16/src/lib/dict.c
@@ -882,6 +882,8 @@ int dict_addattr(char const *name, int a
 		return -1;
 	}
 
+	if (flags.encrypt) flags.secret = 1;
+
 	if (flags.length && (type != PW_TYPE_OCTETS)) {
 		fr_strerror_printf("The \"length\" flag can only be set for attributes of type \"octets\"");
 		return -1;
@@ -1742,6 +1744,10 @@ static int process_attribute(char const*
 							   "\"encrypt=3\" flag set", fn, line);
 					return -1;
 				}
+				flags.secret = 1;
+
+			} else if (strncmp(key, "secret", 6) == 0) {
+				flags.secret = 1;
 
 			} else if (strncmp(key, "array", 6) == 0) {
 				flags.array = 1;
Index: freeradius-server-3.0.16/src/include/radiusd.h
===================================================================
--- freeradius-server-3.0.16.orig/src/include/radiusd.h
+++ freeradius-server-3.0.16/src/include/radiusd.h
@@ -173,6 +173,7 @@ typedef struct main_config {
 #ifdef ENABLE_OPENSSL_VERSION_CHECK
 	char const	*allow_vulnerable_openssl;	//!< The CVE number of the last security issue acknowledged.
 #endif
+	bool		suppress_secrets;		//!< for debug levels < 3
 } main_config_t;
 
 #if defined(WITH_VERIFY_PTR)
@@ -311,7 +312,8 @@ struct rad_request {
 #define RAD_REQUEST_LVL_DEBUG4	(4)
 
 #define RAD_REQUEST_OPTION_COA	(1 << 0)
-#define RAD_REQUEST_OPTION_CTX	(1 << 1)
+#define RAD_REQUEST_OPTION_CTX 	(1 << 1)
+#define RAD_REQUEST_OPTION_CANCELLED (1 << 2)
 
 #define SECONDS_PER_DAY		86400
 #define MAX_REQUEST_TIME	30
Index: freeradius-server-3.0.16/src/main/mainconfig.c
===================================================================
--- freeradius-server-3.0.16.orig/src/main/mainconfig.c
+++ freeradius-server-3.0.16/src/main/mainconfig.c
@@ -142,6 +142,7 @@ static const CONF_PARSER log_config[] =
 	{ "colourise",FR_CONF_POINTER(PW_TYPE_BOOLEAN, &do_colourise), NULL },
 	{ "use_utc", FR_CONF_POINTER(PW_TYPE_BOOLEAN, &log_dates_utc), NULL },
 	{ "msg_denied", FR_CONF_POINTER(PW_TYPE_STRING, &main_config.denied_msg), "You are already logged in - access denied" },
+	{ "suppress_secrets", FR_CONF_POINTER(PW_TYPE_BOOLEAN, &main_config.suppress_secrets), NULL },
 	CONF_PARSER_TERMINATOR
 };
 
Index: freeradius-server-3.0.16/src/main/pair.c
===================================================================
--- freeradius-server-3.0.16.orig/src/main/pair.c
+++ freeradius-server-3.0.16/src/main/pair.c
@@ -734,6 +734,11 @@ void rdebug_pair(log_lvl_t level, REQUES
 
 	if (!radlog_debug_enabled(L_DBG, level, request)) return;
 
+	if (vp->da->flags.secret && request->root->suppress_secrets && (rad_debug_lvl < 3)) {
+		RDEBUGX(level, "%s%s = <<< secret >>>", prefix ? prefix : "", vp->da->name);
+		return;
+	}
+
 	vp_prints(buffer, sizeof(buffer), vp);
 	RDEBUGX(level, "%s%s", prefix ? prefix : "",  buffer);
 }
@@ -759,6 +764,11 @@ void rdebug_pair_list(log_lvl_t level, R
 	     vp = fr_cursor_next(&cursor)) {
 		VERIFY_VP(vp);
 
+		if (vp->da->flags.secret && request->root->suppress_secrets && (rad_debug_lvl < 3)) {
+			RDEBUGX(level, "%s%s = <<< secret >>>", prefix ? prefix : "", vp->da->name);
+			continue;
+		}
+
 		vp_prints(buffer, sizeof(buffer), vp);
 		RDEBUGX(level, "%s%s", prefix ? prefix : "",  buffer);
 	}
@@ -786,6 +796,12 @@ void rdebug_proto_pair_list(log_lvl_t le
 		VERIFY_VP(vp);
 		if ((vp->da->vendor == 0) &&
 		    ((vp->da->attr & 0xFFFF) > 0xff)) continue;
+
+		if (vp->da->flags.secret && request->root->suppress_secrets && (rad_debug_lvl < 3)) {
+			RDEBUGX(level, "%s = <<< secret >>>", vp->da->name);
+			continue;
+		}
+
 		vp_prints(buffer, sizeof(buffer), vp);
 		RDEBUGX(level, "%s", buffer);
 	}
Index: freeradius-server-3.0.16/src/modules/rlm_perl/rlm_perl.c
===================================================================
--- freeradius-server-3.0.16.orig/src/modules/rlm_perl/rlm_perl.c
+++ freeradius-server-3.0.16/src/modules/rlm_perl/rlm_perl.c
@@ -629,15 +629,26 @@ static void perl_vp_to_svpvn_element(REQ
 
 	switch (vp->da->type) {
 	case PW_TYPE_STRING:
-		RDEBUG("$%s{'%s'}[%i] = &%s:%s -> '%s'", hash_name, vp->da->name, *i,
-		       list_name, vp->da->name, vp->vp_strvalue);
+        if (vp->da->flags.secret && request->root->suppress_secrets && (rad_debug_lvl < 3)) {
+            RDEBUG("$%s{'%s'}[%i] = &%s:%s -> <<< secret >>>", hash_name, vp->da->name, *i,
+                   list_name, vp->da->name);
+        } else {
+		    RDEBUG("$%s{'%s'}[%i] = &%s:%s -> '%s'", hash_name, vp->da->name, *i,
+		           list_name, vp->da->name, vp->vp_strvalue);
+        }
+    
 		av_push(av, newSVpvn(vp->vp_strvalue, vp->vp_length));
 		break;
 
 	default:
 		len = vp_prints_value(buffer, sizeof(buffer), vp, 0);
-		RDEBUG("$%s{'%s'}[%i] = &%s:%s -> '%s'", hash_name, vp->da->name, *i,
-		       list_name, vp->da->name, buffer);
+		if (vp->da->flags.secret && request->root->suppress_secrets && (rad_debug_lvl < 3)) {
+			RDEBUG("$%s{'%s'}[%i] = &%s:%s -> <<< secret >>>", hash_name, vp->da->name, *i,
+			       list_name, vp->da->name);
+		} else {
+			RDEBUG("$%s{'%s'}[%i] = &%s:%s -> '%s'", hash_name, vp->da->name, *i,
+			       list_name, vp->da->name, buffer);
+		}
 		av_push(av, newSVpvn(buffer, truncate_len(len, sizeof(buffer))));
 		break;
 	}
@@ -720,15 +731,25 @@ static void perl_store_vps(UNUSED TALLOC
 		 */
 		switch (vp->da->type) {
 		case PW_TYPE_STRING:
-			RDEBUG("$%s{'%s'} = &%s:%s -> '%s'", hash_name, vp->da->name, list_name,
-			       vp->da->name, vp->vp_strvalue);
+			if (vp->da->flags.secret && request->root->suppress_secrets && (rad_debug_lvl < 3)) {
+				RDEBUG("$%s{'%s'} = &%s:%s -> <<< secret >>>", hash_name, vp->da->name, list_name,
+				       vp->da->name);
+			} else {
+				RDEBUG("$%s{'%s'} = &%s:%s -> '%s'", hash_name, vp->da->name, list_name,
+				       vp->da->name, vp->vp_strvalue);
+			}
 			(void)hv_store(rad_hv, name, strlen(name), newSVpvn(vp->vp_strvalue, vp->vp_length), 0);
 			break;
 
 		default:
 			len = vp_prints_value(tbuff, tbufflen, vp, 0);
-			RDEBUG("$%s{'%s'} = &%s:%s -> '%s'", hash_name, vp->da->name,
-			       list_name, vp->da->name, tbuff);
+			if (vp->da->flags.secret && request->root->suppress_secrets && (rad_debug_lvl < 3)) {
+				RDEBUG("$%s{'%s'} = &%s:%s -> <<< secret >>>", hash_name, vp->da->name, list_name,
+				       vp->da->name);
+			} else {
+				RDEBUG("$%s{'%s'} = &%s:%s -> '%s'", hash_name, vp->da->name,
+				       list_name, vp->da->name, tbuff);
+			}
 			(void)hv_store(rad_hv, name, strlen(name),
 				       newSVpvn(tbuff, truncate_len(len, tbufflen)), 0);
 			break;
@@ -748,7 +769,7 @@ static void perl_store_vps(UNUSED TALLOC
 static void pairadd_sv(TALLOC_CTX *ctx, REQUEST *request, VALUE_PAIR **vps, char *key, SV *sv, FR_TOKEN op,
 		      const char *hash_name, const char *list_name)
 {
-	char		*val = NULL;
+	char const     	*val = NULL;
 	VALUE_PAIR      *vp;
 	STRLEN len;
 
@@ -779,6 +800,10 @@ static void pairadd_sv(TALLOC_CTX *ctx,
 		if (fr_pair_value_from_str(vp, val, len) < 0) goto fail;
 	}
 
+	if (vp->da->flags.secret && request->root->suppress_secrets && (rad_debug_lvl < 3)) {
+		val = "<<< secret >>>";
+	}
+
 	RDEBUG("&%s:%s %s $%s{'%s'} -> '%s'", list_name, key, fr_int2str(fr_tokens, op, "<INVALID>"),
 	       hash_name, key, val);
 }
Index: freeradius-server-3.0.16/share/dictionary.freeradius.internal
===================================================================
--- freeradius-server-3.0.16.orig/share/dictionary.freeradius.internal
+++ freeradius-server-3.0.16/share/dictionary.freeradius.internal
@@ -147,7 +147,7 @@ VALUE	EAP-IKEv2-IDType		DER_ASN1_GN		10
 VALUE	EAP-IKEv2-IDType		KEY_ID			11
 
 ATTRIBUTE	EAP-IKEv2-ID				1104	string
-ATTRIBUTE	EAP-IKEv2-Secret			1105	string
+ATTRIBUTE	EAP-IKEv2-Secret			1105	string	secret
 ATTRIBUTE	EAP-IKEv2-AuthType			1106	integer
 
 VALUE	EAP-IKEv2-AuthType		none			0
@@ -189,7 +189,7 @@ ATTRIBUTE	FreeRADIUS-Client-Require-MA
 VALUE	FreeRADIUS-Client-Require-MA	no			0
 VALUE	FreeRADIUS-Client-Require-MA	yes			1
 
-ATTRIBUTE	FreeRADIUS-Client-Secret		1123	string
+ATTRIBUTE	FreeRADIUS-Client-Secret		1123	string secret
 ATTRIBUTE	FreeRADIUS-Client-Shortname		1124	string
 ATTRIBUTE	FreeRADIUS-Client-NAS-Type		1125	string
 ATTRIBUTE	FreeRADIUS-Client-Virtual-Server	1126	string
Index: freeradius-server-3.0.16/raddb/radiusd.conf.in
===================================================================
--- freeradius-server-3.0.16.orig/raddb/radiusd.conf.in
+++ freeradius-server-3.0.16/raddb/radiusd.conf.in
@@ -328,6 +328,25 @@ log {
 	#  The message when the user exceeds the Simultaneous-Use limit.
 	#
 	msg_denied = "You are already logged in - access denied"
+
+	#  Suppress "secret" attributes when printing them in debug mode.
+	#
+	#  Secrets are NOT tracked across xlat expansions.  If your
+	#  configuration puts secrets into other strings, they will
+	#  still get printed.
+	#
+	#  Setting this to "yes" means that the server prints
+	#
+	#	<<< secret >>>
+	#
+	#  instead of the value, for attriburtes which contain secret
+	#  information.  e.g. User-Name, Tunnel-Password, etc.
+	#
+	#  This configuration is disabled by default.  It is extremely
+	#  important for administrators to be able to debug user logins
+	#  by seeing what is actually being sent.
+	#
+#	suppress_secrets = no
 }
 
 #  The program to execute to do concurrency checks.
