From af754e596a8dbb05ed8580c342e7fe02e08b28e0 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 13 Apr 2024 16:11:00 +0200 Subject: Adding upstream version 3.2.3+dfsg. Signed-off-by: Daniel Baumann --- raddb/policy.d/filter | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 raddb/policy.d/filter (limited to 'raddb/policy.d/filter') diff --git a/raddb/policy.d/filter b/raddb/policy.d/filter new file mode 100644 index 0000000..ff8f531 --- /dev/null +++ b/raddb/policy.d/filter @@ -0,0 +1,211 @@ +# +# Example of forbidding all attempts to login via +# realms. +# +deny_realms { + if (&User-Name && (&User-Name =~ /@|\\/)) { + reject + } +} + +# +# Filter the username +# +# Force some sanity on User-Name. This helps to avoid issues +# issues where the back-end database is "forgiving" about +# what constitutes a user name. +# +filter_username { + if (&User-Name) { + # + # reject mixed case e.g. "UseRNaMe" + # + #if (&User-Name != "%{tolower:%{User-Name}}") { + # reject + #} + + # + # reject all whitespace + # e.g. "user@ site.com", or "us er", or " user", or "user " + # + if (&User-Name =~ / /) { + update request { + &Module-Failure-Message += 'Rejected: User-Name contains whitespace' + } + reject + } + + # + # reject Multiple @'s + # e.g. "user@site.com@site.com" + # + if (&User-Name =~ /@[^@]*@/ ) { + update request { + &Module-Failure-Message += 'Rejected: Multiple @ in User-Name' + } + reject + } + + # + # reject double dots + # e.g. "user@site..com" + # + if (&User-Name =~ /\.\./ ) { + update request { + &Module-Failure-Message += 'Rejected: User-Name contains multiple ..s' + } + reject + } + + # + # must have at least 1 string-dot-string after @ + # e.g. "user@site.com" + # + if ((&User-Name =~ /@/) && (&User-Name !~ /@(.+)\.(.+)$/)) { + update request { + &Module-Failure-Message += 'Rejected: Realm does not have at least one dot separator' + } + reject + } + + # + # Realm ends with a dot + # e.g. "user@site.com." + # + if (&User-Name =~ /\.$/) { + update request { + &Module-Failure-Message += 'Rejected: Realm ends with a dot' + } + reject + } + + # + # Realm begins with a dot + # e.g. "user@.site.com" + # + if (&User-Name =~ /@\./) { + update request { + &Module-Failure-Message += 'Rejected: Realm begins with a dot' + } + reject + } + } +} + +# +# Filter the User-Password +# +# Some equipment sends passwords with embedded zeros. +# This policy filters them out. +# +filter_password { + if (&User-Password && \ + (&User-Password != "%{string:User-Password}")) { + update request { + &Tmp-String-0 := "%{string:User-Password}" + &User-Password := "%{string:Tmp-String-0}" + &Tmp-String-0 !* "" + } + } +} + +filter_inner_identity { + # + # No names, reject. + # + if (!&outer.request:User-Name || !&User-Name) { + update request { + Module-Failure-Message = "User-Name is required for tunneled authentication" + } + reject + } + + # + # Do detailed checks only if the inner and outer + # NAIs are different. + # + # If the NAIs are the same, it violates user privacy, + # but is allowed. + # + if (&outer.request:User-Name != &User-Name) { + # + # Get the outer realm. + # + if (&outer.request:User-Name =~ /@([^@]+)$/) { + update request { + Outer-Realm-Name = "%{1}" + } + + # + # When we have an outer realm name, the user portion + # MUST either be empty, or begin with "anon". + # + # We don't check for the full "anonymous", because + # some vendors don't follow the standards. + # + if (&outer.request:User-Name !~ /^(anon|@)/) { + update request { + Module-Failure-Message = "User-Name is not anonymized" + } + reject + } + } + + # + # There's no outer realm. The outer NAI is different from the + # inner NAI. The User-Name MUST be anonymized. + # + # Otherwise, you could log in as outer "bob", and inner "doug", + # and we'd have no idea which one was correct. + # + elsif (&outer.request:User-Name !~ /^anon/) { + update request { + Module-Failure-Message = "User-Name is not anonymized" + } + reject + } + + # + # Get the inner realm. + # + if (&User-Name =~ /@([^@]+)$/) { + update request { + Inner-Realm-Name = "%{1}" + } + + # + # Note that we do EQUALITY checks for realm names. + # There is no simple way to do case insensitive checks + # on internationalized domain names. There is no reason + # to allow outer "anonymous@EXAMPLE.COM" and inner + # "user@example.com". The user should enter the same + # realm for both identities. + # + # If the inner realm isn't the same as the outer realm, + # the inner realm MUST be a subdomain of the outer realm. + # + if (&Outer-Realm-Name && \ + (&Inner-Realm-Name != &Outer-Realm-Name) && \ + (&Inner-Realm-Name !~ /\.%{Outer-Realm-Name}$/)) { + update request { + Module-Failure-Message = "Inner realm '%{Inner-Realm-Name}' and outer realm '%{Outer-Realm-Name}' are not from the same domain." + } + reject + } + + # + # It's OK to have an inner realm and no outer realm. + # + # That won't work for roaming, but the local RADIUS server + # can still authenticate the user. + # + } + + # + # It's OK to have an outer realm and no inner realm. + # + # It will work for roaming, and the local RADIUS server + # can authenticate the user without the realm. + # + } +} -- cgit v1.2.3