# # 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. # } }