gpg authentication patch for tremulous;
Tremulous client and server run as a single thread, 20 'frames' per
second. Because of this time limit, the current system for identifying
admins on a server consists of a 32byte cookie named 'cl_guid' which is
stored (if the user has any admin priviledges) on the server in
admin.dat and sent by the client in plaintext at connect time. This is
less-than-ideal.
I don't think it would be too difficult to fork off an authentication
thread which uses pgp to do a proper signed-challenge authentication.
This would be a completely different thread and not constrained by the
50ms frame timelimit.
My suggestion, connecting clients optionally send a cl_gpgauth flag
which indicates if they're willing to gpg-authenticate. If the server
doesn't care then we don't ignore it (as an unpatched server will do)
and their guid is accepted as-is.
If we want to give them ops, the server requests they sent their public
key which is stored in the admin.dat in some appropriate manner.
If at the time they connect the guid they've sent is in the admin.dat
and has a public key, the server immediately sets their GUID to “”,
sends them a 'challenge' of 256 bytes (2048 bits) which is also stored
locally, and carries on. If they're in admin dat and don't have a public
key, no problem.. existing behaviour.
(There might need to be some kind of connection-rate-limit and
challenge-drop-time to prevent denial of service attacks on the server
at this point.)
Until they answer the challenge, or if they ignore the challenge
completely, they end up with an effective GUID of “”
Client binary, on receiving the challenge, forks off a gpg process to
sign the challenge block with their Tremulous private key. When the fork
ends (perhaps dozens of frames later) the next reply to the server will
include a detatched signature of the challenge data.
The server then forks off a GPG process and checks that they've
correctly signed the challenge block, and (again perhaps dozend of
frames later) if the gpg result is correct, their ingame guid is set
back to the one listed in the admin.dat, and existing server code
handles whatever privileges are implied by this. Result, connecting ops
have their guid set to "" immediately when they first connect, it should
only take a few seconds to do the authentication, and they'll have their
regular ID back faster than it takes to unpack all the models and
textures.
Note; cl_guid is not their gpg-key signature or anything like that, it's
still just a big random number, and the server keeps a record of both
only if there's any reason for them to be authenticated.