The version 2 protocol was built based on lessons learned while working with the version 1 protocol. In particular, it is impossible to pass binary data with the version 1 protocol without escaping to avoid NUL bytes. It is also difficult to differentiate between different types of credentials (ie secret vs. password vs. challenge/response) since there is no indication given in the request packet what types of credentials are being sent. Spoofing attacks are possible against version 1 UDP clients, since an attacker may forge valid responses with relative ease. This second version protocol retains the efficiency of the original protocol while correcting these deficiencies.
Input to and output from the module follows a similar packet format: a packet identifier byte, a length byte L, L bytes of random data (used to help prevent spoofing of UDP responses), followed by a series of tagged strings and completed with a single NUL (zero) byte. The total size of either the input or the output must not exceed 512 bytes. The random data in the response is copied exactly from the request.
A tagged string consists of a tag byte T, a length byte L, and L bytes of data. The tag byte identifies what credential (in the input request) or what fact (in the output response) is represented by the data. Note that the initial random data in the packet may be viewed as a tagged string that just differs in the tag value convention.
The packet identifier in the input (request) packet is the protocol version number (2). Example (all numbers are hexadecimal):
0000000: 0208 0102 0304 0506 0708 0108 7573 6572 ............user 0000010: 6e61 6d65 0209 6c6f 6361 6c68 6f73 7403 name..localhost. 0000020: 0870 6173 7377 6f72 6400 .password.
The packet identifier in the output (response) packet is the error code value, with zero representing successful validation.
The module must report a temporary error if it detects malformed input (incorrect credentials, etc.). Extra data following the final NUL byte in the credentials is a fault in the invoking code, and must be rejected by the module. Similarly, extra data following the final NUL byte in the facts is a fault in the module code.
All data following an unsuccessful result status code must be ignored by the invoking code. Modules should not produce any facts when validation fails.
An executable module must exit 0 if authentication succeeds. Non-zero exit codes from an executable module should be treated as a temporary error.
The invoker of an executable module must assume a temporary error if the module either fails to completely read its input or produces incomplete output, even if the module exits without error.