Projects/OTPOverRADIUS
Contents
Description
In 1.11 KRB5 gained client side support for OTP Preauth (RFC 6560), but up until now there is no server side support in tree. Red Hat has created an out-of-tree solution (AuthHub), based upon a plugin model. But our experimenting with this approach has demonstrated:
- Access to vendor SDKs is non-trivial
- All vendors provide a RADIUS server for OTP validation
Proposal
The KDC-side support for OTP should read configuration from a user string and forward token validation to an appropriate RADIUS server. This plugin will be called otp_radius.
User String
The user string otp_radius would contain a JSON formatted object which roughly reflects PA-OTP-CHALLENGE and is a near-duplicate of KRB5_RESPONDER_QUESTION_OTP, but containing support for RADIUS configuration:
{ "service": <string>, "tokenInfo": [{ "vendor": <string>, "challenge": <base64string>, "length": <integer>, "format": <integer>, "tokenID": <base64string>, "algID": <string>, "servers": [{ "host": <string>, "port": <integer>, "secret": <string>, "attributes": { "custom": [[<number_or_string>, <string>], ...] } }, ...] }, ...] }
In the object above, all fields are optional. If tokenInfo or servers is not specified, '[{}]' is assumed. If a server object is missing any fields, the following defaults are assumed:
- host: localhost
- port: getservbyname("radius", "udp")
- secret: send password in cleartext
- attributes: {}
RADIUS attributes may be specified by a string ONLY in the case of the attributes defined in RFC 2865. Otherwise, a number must be used. Support for custom dictionaries is NOT provided.
Workflow
In the first pass (no PA-OTP-REQUEST present), a PA-OTP-CHALLENGE will be generated from the user string (using all fields present except servers).
Upon receipt of a PA-OTP-REQUEST, the KDC will attempt to match the PA-OTP-REQUEST with a tokenInfo from the user string. All matching tokenInfo objects will then be used as configuration for RADIUS validation, in the order they were specified, stopping after the first AccessAccept response is received. A round-robin approach will be used on the servers specified for load balancing.
RADIUS Packet
The packet sent to the configured RADIUS server will contain:
- User-Name (default: user principal)
- User-Password (otp-value from PA-OTP-REQUEST)
- NAS-Identifier (default: gethostname())
- NAS-IP-Address (default: getsockname())
- Any custom attributes defined
Any of the attributes specified above may be overridden by custom attribute except User-Password.
Remaining Issues
- Should we use a RADIUS library or hand-craft packets? We should use a RADIUS library which provides support for EAP methods.
- Should the default value of User-Name contain the realm or not?