chap
CHAP password helpers (RFC 1994, RFC 2865 §2.2 / §5.40).
CHAP authenticates an Access-Request by including:
CHAP-Password(attribute 3) — one identifier byte followed by an MD5 digest ofid || password || challenge.CHAP-Challenge(attribute 60) — the challenge bytes. RFC 2865 permits the server to use the Request Authenticator as the challenge when noCHAP-Challengeattribute is present; pyrad2 always emits the explicit attribute to keep the request unambiguous.
CHAP is not an EAP method — the server doesn't bounce challenges
back at the client mid-exchange — so it doesn't live under
pyrad2.eap. It's its own one-shot transformation applied before
the Access-Request goes out.
build_chap_password(chap_id, password, challenge)
Build the CHAP-Password attribute value.
Wire layout (17 bytes): one CHAP Identifier byte + the 16-byte
MD5(id || password || challenge) digest.
chap_id is the value the NAS uses on its CHAP-Identifier byte
to correlate the response with the challenge. It is independent of
the RADIUS Identifier and is echoed verbatim into the digest.
Source code in pyrad2/chap.py
prepare_chap_request(pkt, password, *, chap_id=None, challenge=None)
Convert a PAP-shaped AuthPacket to CHAP authentication.
Pops any existing User-Password (RFC 2865 §5.2 forbids mixing
PAP and CHAP credentials in one request) and replaces it with
freshly-built CHAP-Password and CHAP-Challenge attributes.
Both chap_id and challenge are optional and default to
fresh random values from secrets. Pass explicit values when
you need deterministic test vectors.