|
This manual page describes the protocols used to authorize connections,
confirm the identities of users and machines, and maintain the
associated databases. The machine that provides these services
is called the authentication server (AS). The AS may be a stand–alone
machine or a general–use machine such as a
CPU server. The network database ndb(6) holds for each public
machine, such as a CPU server or file server, the name of the
authentication server that machine uses.
Each machine contains four values important to authentication;
a 56–bit DES key, a 128–bit AES key, a 28–byte authentication ID,
and a 48–byte authentication domain name. The ID is a user name
and identifies who is currently responsible for the kernel running
on that machine. The domain name identifies the
machines across which the ID is valid. Together, the ID and domain
name identify the owner of a key.
When a terminal boots, factotum(4) prompts for user name and password.
The user name becomes the terminal's authentication ID. The password
is converted using passtokey (see authsrv(2)) into a 56–bit DES
and 128–bit AES keys and saved in memory. The authentication domain
is set to the null string. If possible,
factotum validates the key with the AS before saving it. For Internet
machines the correct AS to ask is found using dhcpd(8).
When a CPU or file server boots, factotum reads the key, ID, and
domain name from non–volatile RAM. This allows servers to reboot
without operator intervention.
The details of any authentication are mixed with the semantics
of the particular service they are authenticating so we describe
them one case at a time. The following definitions will be used
in the descriptions:
Ks server's host ID's key
Kc client's host ID's key
Kn a nonce key created for a ticket (key)
K{m} message m encrypted with key K
CHc an 8–byte random challenge from a client (chal)
CHs an 8–byte random challenge from a server (chal)
IDs server's ID (authid)
DN server's authentication domain name (authdom)
IDc client's ID (hostid, cuid)
IDr client's desired ID on server (uid, suid)
YAc client → AS DH public key
YBc AS → client DH public key
YAs server → AS DH public key
YBs AS → server DH public key
RNc client's 32–byte random string
RNs server's 32–byte random string
The parenthesized names are the ones used in the Ticketreq and
Ticket structures in <authsrv.h>.
The message type constants AuthTreq, AuthChal, AuthPass, AuthOK,
AuthErr, AuthMod, AuthApop, AuthOKvar, AuthChap, AuthMSchap, AuthCram,
AuthVNC, and AuthPAK (type) are defined in <authsrv.h>, as are the
encrypted message types AuthTs, AuthAs, AuthAc, AuthTp, and AuthHr
(num).
Ticket Service
When a client and server wish to authenticate to each other, they
do so using tickets issued by the AS. Obtaining tickets from the
AS is the client's responsibility.
The protocol to obtain a ticket pair is:
C→A:AuthTreq, IDs, DN, CHs, IDc, IDr
A→C:AuthOK, Kc{AuthTc, CHs, IDc, IDr, Kn}, Ks{AuthTs, CHs, IDc,
IDr, Kn}
The two tickets are identical except for their type fields and
the keys with which they are encrypted. The client and server
can each decrypt one of the tickets, establishing a shared secret
Kn.
The tickets can be viewed as a statement by the AS that ``a client
possessing the Kn key is allowed to authenticate as IDr.''
The presence of the server challenge CHs in the ticket allows
the server to verify the freshness of the ticket pair.
The AS sets the IDr in the tickets to the requested IDr only if
IDc is allowed to speak for (q.v.) IDr. If not, the AS sets IDr
to the empty string.
If the users IDc or IDs do not exist, the AS silently generates
one–time random keys to use in place of Kc or Ks, so that clients
cannot probe the AS to learn whether a user name is valid.
P9sk1
The Plan 9 shared key protocol p9sk1 allows a client and server
to authenticate each other. The protocol is:
C→S:CHc
| |
The client starts by sending a random challenge to the server.
|
S→C:AuthTreq, IDs, DN, CHs, –, –
| |
The server replies with a ticket request giving its id and authentication
domain along with its own random challenge.
|
C→S:Ks{AuthTs, CHs, IDc, IDr, Kn}, Kn{AuthAc, CHs}
| |
The client adds IDc and IDr to the ticket request and obtains
a ticket pair from the AS as described above. The client relays
the server's ticket along with an authenticator, the AuthAc message.
The authenticator proves to the server that the client knows Kn
and is therefore allowed to authenticate as IDr. (The
inclusion of CHs in the authenticator avoids replay attacks.)
|
S→C:Kn{AuthAs, CHc}
| |
The server replies with its own authenticator, proving to the
client that it also knows Kn and therefore Ks.
|
The 64–bit shared secret Kn is used as the session secret.
Password authenticated key exchange
Initially, the server and client keys Ks and Kc were equivalent
to the password derived 56–bit DES keys, which made the encrypted
tickets subject to offline dictionary attacks and provided too
small a key space against brute force attacks on current hardware.
The AuthPAK protocol is used to establish new 256–bit random keys
with the AS for Ks and Kc before each ticket request on the connection.
The protocol is based on SPAKE2EE, where a hash of the user's
secret is used to encypt the public keys of a Elliptic–Curve Diffie–Hellman
key exchange. The user's ID and 128–bit AES key is hashed and mapped
(using Elligator2) into two curve points PM and PN, called the
pakhash. Both sides generate a random number
xa/xb and make the public keys YA/YB as: YA=xa*G+PM, YB=xb*G+PN.
After the public keys have been exchanged, each side calculates
the shared secret as: Z=xa*(YB–PN)=xb*(YA–PM). The shared secret
Z is then hashed with the transmitted public keys YA|YB producing
the 256–bit pakkey.
The pakkey is then used in place of Ks and Kc to authenticate
and encrypt tickets from the AS using Chacha20/Poly1305 AEAD for
the next following request made on the connection.
The protocol (for AuthTreq) to establish keys Ks and Kc with the
AS for IDs and IDc is:
C→A:AuthPAK, IDs, DN, CHs, IDc, IDr, YAs, YAc
A→C:AuthOK, YBs, YBc
The protocol (for AuthApop, AuthChap...) to establish a single
server key Ks for IDs:
C→A:AuthPAK, –, DN, CHs, IDs, IDc, YAs
A→C:AuthOK, YBs
The protocol (for AuthPass) to establish a single client key Kc
for IDc:
C→A:AuthPAK, –, –, CHc, –, IDc, YAc
A→C:AuthOK, YBc
Dp9ik
The dp9ik protocol is an extended version of p9sk1 that adds the
random strings RNc and RNs in the authenticator messages for the
session key derivation and uses the password authenticated key
exchange as described above to derive the ticket encryption keys
Ks and Kc:
C→S:CHc
| |
The client starts by sending a random challenge to the server.
|
S→C:AuthPAK, IDs, DN, CHs, –, –, YAs
| |
The server generates a new public key YAs and replies with a AuthPAK
request giving its IDs and authentication domain DNs along with
its own random challenge CHs and its public key YAs.
|
C→S:YBs, Ks{AuthTs, CHs, IDc, IDr, Kn}, Kn{AuthAc, CHs, RNc}
| |
The client generates its own public key YAc and adds it along
with IDc and IDr to the AuthPAK request and obtains the public
keys YBs and YBc from the AS response. At this point, client and
AS have completed their authenticated key exchange and derive
Kc as described above. Then the client requests a ticket
pair using the same message but with AuthPAK type changed to AuthTreq.
It decrypts his ticket with Kc extracting the shared secret Kn.
The client relays the server's YBs and ticket along with an authenticator,
the AuthAc message. The server finishes his authenticated key
exchange using YBs and derives Ks to
decrypt his ticket to extract the shared secret Kn. When the decryption
of the clients authenticator using Kn is successfull then this
proves to the server that the client knows Kn and is therefore
allowed to authenticate as IDr. The random string RNc is used
in the derivation of the session secret.
|
S→C:Kn{AuthAs, CHc, RNs}
| |
The server replies with its own authenticator, proving to the
client that it also knows Kn and contributes its random string
RNs for the session secret.
|
The 2048–bit session secret is derived with HKDF–SHA256 hashing
the concatenated random strings RNc|RNs with the the shared secret
key Kn.
P9any
P9any is the standard Plan 9 authentication protocol. It consists
of a negotiation to determine a common protocol, followed by the
agreed–upon protocol.
The negotiation protocol is:
S→C:proto@authdom proto@authdom ...
C→S:proto dom
Each message is a NUL–terminated UTF string. The server begins
by sending a list of proto, authdom pairs it is willing to use.
The client responds with its choice.
A second version of this protocol exists (indicated by the v.2
prefix before the list) where the server sends an explicit confirmation
with a OK message before the agreed–upon protocol starts.
S→C:v.2 proto@authdom proto@authdom ...
C→S:proto dom
S→C:OK
The p9any protocol is the protocol used by all Plan 9 services.
The file server runs it over special authentication files (see
fauth(2) and attach(5)). Other services, such as rcpu(1), rexport(1),
rimport(1) and tlssrv(8) run p9any over the network and then use
the session secret to derive an tls(3) key to encrypt the rest
of
their communications.
Password Change
Users connect directly to the AS to change their passwords. The
protocol is:
C→A:AuthPass, –, –, CHc, –, IDc
| |
The client sends a password change ticket request.
|
A→C:Kc{AuthTp, CHc, IDc, IDc, Kn}
| |
The server responds with a ticket containing the key Kn encrypted
with the client's key Kc
|
C→A:Kn{AuthPass, old, new, changesecret, secret}
| |
The client decrypts the ticket using the old password and then
sends back an encrypted password request (Passwordreq structure)
containing the old password and the new password. If changesecret
is set, the AS also changes the user's secret, the password used
for non–Plan 9 authentications.
|
A→C:AuthOK or AuthErr, 64–byte error message
| |
The AS responds with simply AuthOK or with AuthErr followed by
a 64–byte error message.
|
Authentication Database
An ndb(2) database file /lib/ndb/auth exists for the AS. This
database maintains ``speaks for'' relationships, i.e., it lists
which users may speak for other users when authenticating. The
attribute types used by the AS are hostid and uid. The value in
the hostid is a client host's ID. The values in the uid
pairs in the same entry list which users that host ID may speak
for. A uid value of * means the host ID may speak for all users.
A uid value of !user means the host ID may not speak for user.
For example:
hostid=bootes
is interpreted as bootes may speak for any user except sys and
adm. This property is used heavily on CPU servers.
Foreign Protocols
The AS accepts ticket request messages of types other than AuthTreq
to allow users to authenticate using non–Plan 9 protocols. In these
situations, the server communicates directly with the AS. Some
protocols must begin without knowing the client's name. They ignore
the client name in the ticket request. All the
protocols end with the AS sending an AuthOK message containing
a server ticket and authenticator.
AuthOK messages always have a fixed but context–dependent size.
The occasional variable–length OK message starts with a AuthOKvar
byte and a five–byte space–padded decimal length of the data that
follows.
Anywhere an AuthOK message is expected, a AuthErr message may
be substituted.
S→A:AuthChal, –, DN, CHs, IDs, IDc
A→S:AuthOK, challenge
S→A:response
A→S:AuthOK, Ks{AuthTs, CHs, IDc, IDc, Kn}, Kn{AuthAc, CHs}
| |
This protocol allows the use of handheld authenticators such as
SecureNet keys and SecureID tokens in programs such as telnetd
and ftpd (see ipserv(8)).
Challenge and response are text strings, NUL –padded to 16 bytes
(NETCHLEN). The challenge is a random five–digit decimal number.
When using a SecureNet key or netkey (see passwd(1)), the response
is an eight–digit decimal or hexadecimal number that is an encryption
of the challenge using the user's DES
key.
When using a SecureID token, the challenge is ignored. The response
is the user's PIN followed by the six–digit number currently displayed
on the token. In this case, the AS queries an external RADIUS
server to check the response. Use of a RADIUS server requires
an entry in the authentication database. For
example:
| |
radius=server–name secret=xyzzy
uid=howard rid=trickey
uid=sape rid=smullender
|
In this example, the secret xyzzy is the hash key used in talking
to the RADIUS server. The uid/rid lines map from Plan 9 user ids
to RADIUS ids. Users not listed are assumed to have the same id
in both places.
|
S→A:AuthApop, –, DN, CHs, IDs, –
A→S:AuthOKvar, challenge
S→A:AuthApop, –, DN, CHs, IDs, IDc; hexadecimal MD5 checksum
A→S:AuthOK, Ks{AuthTs, CHs, IDc, IDc, Kn}, Kn{AuthAc, CHs}
| |
This protocol implements APOP authentication (see pop3(8)). After
receiving a ticket request of type AuthApop, the AS generates
a random challenge of the form <random@domain>. The client then
replies with a new ticket request giving the user name followed
by the MD5 checksum of the challenge
concatenated with the user's secret. If the response is correct,
the authentication server sends back a ticket and authenticator.
If the response is incorrect, the client may repeat the ticket
request/MD5 checksum message to try again.
The AuthCram protocol runs identically to the AuthApop protocol,
except that the expected MD5 checksum is the keyed MD5 hash using
the user's secret as the key (see hmac_md5 in sechash(2)).
|
S→A:AuthChap, –, DN, CHs, IDs, –
A→S:challenge
S→A:pktid, IDc, response
A→S:AuthOK, Ks{AuthTs, CHs, IDc, IDc, Kn}, Kn{AuthAc, CHs}
| |
This protocol implements CHAP authentication (see ppp(8)). The
challenge is eight random bytes. The response is a 16–byte MD5
checksum over the packet id, user's secret, and challenge. The
reply packet is defined as OChapreply in <authsrv.h>.
|
S→A:AuthMSchap, –, DN, CHs, IDs, –
A→S:challenge
S→A:IDc, lm–response, nt–response
A→S:AuthOK, Ks{AuthTs, CHs, IDc, IDc, Kn}, Kn{AuthAc, CHs}
| |
This protocol implements Microsoft's MS–CHAP authentication (see
ppp(8)). The challenge is eight random bytes. The two responses
are Microsoft's LM and NT hashes. Only the NT hash may be used
to authenticate, as the LM hash is considered too weak. The reply
packet is defined as OMSchapreply in
<authsrv.h>.
|
S→A:AuthVNC, –, DN, CHs, IDs, IDc
A→S:AuthOKvar, challenge
S→A:response
A→S:AuthOK, Ks{AuthTs, CHs, IDc, IDc, Kn}, Kn{AuthAc, CHs}
| |
This protocol implements VNC authentication (see vncs in vnc(1)).
The challenge is 16 random bytes, and the response is a DES ECB
encryption of the challenge. The method by which VNC converts
the user's secret into a DES key is weak, considering only the
first eight bytes of the secret.
|
|