
Radius Authentication Server Project
We implement a simple Radius Authentication server, mostly compliant with the protocol given RFC 2865: Remote Authentication Dial In User Service
NAME
mini-radius
SYNOPSIS
mini-radius [-vR -k shared-key -p port] -h host username password
mini-radius [-vLR -k shared-key -p port] password-file
DESCRIPTION
The program runs as either client or server, depending on the whether the -h option
is present. If server, the password-file is opened and the servers listens on the
port for authentication requests. If client, the given username password is
authenticated to the server/port as given in the option, and YES or NO is
printed, according to the result.
The protocol is described in RFC 2865, simplified for only password authentication.
The access-request (code 1) packet sent by the client has two attributes, user-name
(code 1) and user-password (code 2); and the response is either an access-accept
(code 2) or an access-reject (code 3).
The protocol is modified so that the client does not send the password, but the
MD5 hash of the password. This simplifies our program by keeping the password attribute
a fixed size; it also does not reveal the length of the password.
The password file on the server stores MD5 hash of the MD5 hash of the password.
The client provides the MD5 hash of the password and the server MD5 hashes that
and checks for a match in its database.
OPTIONS
-k the shared key for encrypting, the default is pa55word0
-p the port the server listens (is listening) on, the default is 1812
-h the radius server hostname
-v Verbose. Helpful debugging output to stdout.
-R no randomness. The stream of random bytes used by the program is
set to 1, 2, 3, ...
-L when run as a server, do not loop; answer one full request and terminate
FILE FORMAT
Username/Passwords are stored in file on the server. It is of the format
(name:passwordhash\n)+
where name is a non-empty strings from (a-z, A-Z, 0-9)* and password hash is
hexidecimal encoded, by default the MD5 hash of the password known to the user.
BUGS
The MD5 is not secure and I should have specified SHA-2 or SHA-3 as the hash function.
The username is not included in the reply packet and therefore not involved in the
response authenticator. Since the encryption is malleable it is possible the server
is authenticating the user of the attackers choice.
The server secret is global for all clients. Clients can impersonate the server.
Passwords in password file must be of format exactly [0-9a-f]{32}.
HISTORY
First introduced in Spring 2017.
LAST UPDATED
26 March 2023
29 March 2024
Detailed description
This is a simple one round protocol, consisting of the client leading off with a UDP packet to the server, and the server responding with a UDP packet back to the client. The server port is well-known, and the client port is ephemeral.
The initial packet from client to server is an Access-Request followed by an User-Name attribute and an User-Password attribute, in any order.
The response packet from server to client is an Access-Accept or an Access-Reject, as the case may be, with no attributes.
The Cryptography
The client must be assured that the server response is authentically from the server, and has not been replayed, modified, or forged. A form of Message Authentication Code (MAC) is used to cryptographically attest to the authenticity and integrity of the response.
The MAC is a signature on the return message based on two random, or hopefully random, strings,
Response Authenticator
The value of the Authenticator field in Access-Accept, Access-
Reject, and Access-Challenge packets is called the Response
Authenticator, and contains a one-way MD5 hash calculated over
a stream of octets consisting of: the RADIUS packet, beginning
with the Code field, including the Identifier, the Length, the
Request Authenticator field from the Access-Request packet, and
the response Attributes, followed by the shared secret. That is,
ResponseAuth = MD5(Code+ID+Length+RequestAuth+Attributes+Secret)
where + denotes concatenation.
The password is encrypted using a Vernon Cipher, see the User-Password attribute, section 5.2.
On transmission, the password is hidden. The password is first
padded at the end with nulls to a multiple of 16 octets. A one-
way MD5 hash is calculated over a stream of octets consisting of
the shared secret followed by the Request Authenticator. This
value is XORed with the first 16 octet segment of the password and
placed in the first 16 octets of the String field of the User-
Password Attribute.
A pseudo-random pad (key stream) is needed for the Vernum cipher. The pad is computed by both the client and server by hasing the concatenation of secret shared key and the Request-Authenticator by the MD5 hash function. The MD5 hash function is cryptographically strong — i.e. there is strong circumstantial evidence that the function acts as if it is assigning a randomly chosen output for each input.
The openssl library has the MD5 function, see [man 3 md5].
Authentication Logic
The system includes a double hashing of the password that the user has memorized. The first is just a convenience hash. Call the the password-hash. Windows has the NT-Hash that is how the password is stored in the SAM. It is not the same system as the unix hash.
The second has is the unix-type hash, and the result of the second has is stored in the password file. Proof of identity is that the hash of what is received from the client matches this hash in the password file.
______
request / pw |
packet +--+ | file |
| | +------+
| | |
+-+ | | +-+ |
|/| | | |/| +-----+ +-----+
user-name ------------------------->|/| ======> |/|--->| SEL |--->| ==? |---> Y/N
|/| | | |/| +-----+ +-----+
+-+ | | +-+ ^
| | |
+-+ | | +-+ |
+-----+ +-----+ |/| | | |/| +-----+ +----+
user-passwd --->| MD5 |--->| ENC |--->|/| ======> |/|--->| ENC |--->| MD5 |
+-----+ +-----+ |/| | | |/| +-----+ +----+
^ ^ + + | | +-+ ^ ^
| | | | | |
shared-key --+ | +-+ | | +-+ | +-- shared-key
| |/| | | |/| |
auth request ---------------+----->|/| ======> |/|------+
|/| | | |/|
+-+ | | +-+
| |
MD5 - hash function | | the request packet includes user-name,
ENC - encryption +--+ encrypted user-passd, auth request
SEL - select pw by username chosen randomly, and the header: code,
ID and length.
MAC Calculation
+-+ | | +-+ +-------+ +-+ | | +-+
ACC_REQ |/| | | |/| | Auth | |/| | | |/| ACC_ACE/ACC_REJ
Id |/| ======> |/| | Dec- | |/|---+------->|/| Id
Length |/| | | |/| | ision | |/| | | | |/| Length
+-+ | | +-+ +-------+ +-+ | | | +-+
| | | | |
| | +---------------+ | |
+-+ | | | ++ | | +-+
| | | | | | \ | | | |
Request | | | | 128 +-->| \ 128 | | | | Response
Authenti. | | ==========/===========>|MD5\ ==/===========>| | Authenticator
| | | | +------->| / | | | |
| | | | | | / | | | |
+-+ | | +------------+ | / | | +-+
| | | shared key | ++
+----------+ | | +------------+
| username | -------------------------> attributes
+----------+ | | in
+----------+ | | any
| pw (enc) | -------------------------> order
+----------+ | |
The Attributes
Requests from client to server and responses from server to client can carry additional information in the sequence of attributes following the fixed format of the beginning of the packet. In our case, the request includes the user-name and password attribute, and the response carries no attributes.
The attributes have a common format, and can occur in any order. In our implementation the type will be either 1 for username or 2 for password.
0 1 2
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
| Type | Length | String ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-

Author: Burton Rosenberg
Created: 28 March 2017
Last Update: 29 March 2024