Dear reader of this mailinglist I'm new to the RADIUS business and I did my frist FreeRadius installation just two weeks ago. I still might misunderstand some of the concepts. So keep in mind that whenever I make statments about what FreeRadius does or should do - these are all my personal assumptions only and might be totally wrong. So far I only tried to get things working. I did not look at my "solution" from a security perspective. I'm describing my solution since this might be useful to other people. And I was hoping to get some feedback. My goal was to allow our users to authenticate with our WiFi accesspoints with a 2-factor method. This means for us, that they either have to user their identity card (which has a builtin smart card chip) or their OTP-token (which generates OATH TOTP values). The solution was expected to work with both laptops (Windows and MacOS) and smart phones/tablets (iPhones, Android). It was expected to work with company-devices (manages by our own MDM) and with BYO-devices from eployees or guests. I never heard of solutions that allows an iPhone to use a smart card for authentication. And using smart cards always needs prior installation of smart card middleware. But one time passwords can be used whenever a password has to be entered. Some of our employees have a second token for generation of "guest-passwords". So using passwords generated by our OTP-tokens seemed to be the only way to go. Without two-factor authentication our employees must go to a central helpdesk, prove their identity by showing their identity card or passport, just to get a piece of paper with a password that allows WiFi acces for twelve hours only. If they forward this password to a guest, they have to fill out another piece of paper. With this situation we cannot force the devices to use certain algorithms for WiFi-authentication. OTP-authentication might require that the supplicant sends the password in clear (PAP or PAP within EAP-TTLS). But configuring guest devices to use this authentication method is unrealistic. iPhones for example can do this, but only if they are under MDM-control. So we use EAP-PEAP with MSCHAPv2 because that's supported by all devices if the accesspoint is configured for WPA2-Enterprise. At least we hope that this is true. And we don't care about guests that visit us with their Win-XP laptops. MSCHAPv2 does not send the password in cleartext within the inner tunnel. But as you all know there's no need to compare password A with password B if you just want to check wether they are equal or not. Comparing HashFunction(A) with HashFunction(B) does work as well and the hash function used by MSCHAPv2 is well documented in RFC 2759. So how do you teach FreeRadius to verify an OATH time based one time password? rlm_otp and rlm_secureid where of no help. So I read the the source code of other FreeRadius modules to find the place where FreeRadius does authentication based on the RFC2759 hash function. I found it in rlm_mschap.c in function do_mschap(). There's a switch statement which looks at the value of method. If method==AUTH_INTERNAL FreeRadius calculates the MSCHAPv2 hash on it's own and complains if the password is missing. But to my great pleasure (I love this FreeRadius-software) I spotted another FreeRadius authentication method in that switch-statement, namely AUTH_NTLM_EXEC. With that method FreeRadius delegates the decision about wether the MSCHAPv2 hash value is correct or not to an external program. The location of this external program is configured by the ntlm_auth configuration directive. And the idea behind this was obviously to let the ntlm_auth programm from Samba do the decision. But there's no real reason why the ntlm_auth programm must be the Samba one. So I put ntlm_auth = "/etc/radius/check_otp '%{mschap:User-Name}' '%{mschap:Challenge}' '%{mschap:NT-Response}' '%{Packet-SRC-IP-Address}'" into mods-enabled/mschap and wrote my own "ntlm_auth"-style routine. It takes the username, challenge and a correct token values, calculates the response from these values and compares that with the given response. The 4th-parameter has informational purpoes only and will be included in syslog-messages when something goes wrong. Actually /etc/radius/check_otp does not do anything on its own, but just forwards all arguments to our authentication server. One could avoid that indirection across check_otp and let FreeRadius talk directly with our authentication server. I don't think that's worth the minimal performance improvement. And the interface between FreeRadius and the "ntlm_auth"-program is very easy to implement. This solutions is used within our IT-department since monday and will go into production next week. So far we had no problems. Everybody is glad that he must not visit the helpdesk anymore (which is mostely closed anyway due to corona). There are some pitfalls: Most important: If a one time password turned out to be correct, it will be reused by the supplicant many times. And for obvious reasons you don't want to enter a new token value over and over again. Hence the check_otp routine must accept token values that were successfully used within the past for some amount of time. We use 12 hours for guests and I have to fight with the security staff about wether this can be increased for employees. Their main argument is, that a valid password might be given to other people. So I'm looking for a way to detect wether two supplicants are using the same user/password-combination. iOS MAC-randomization is my enemy here. Maybe someone has an idea how to do this. Kind regards Peter