A recent IRC discussion (okay, I admit, it was mostly a monologue) got me thinking about bots and preventing botting. Anti-bot measures have frequently gotten on my bad side because they are typically a) easy to defeat b) unreliable (large numbers of false positives). Here's what I have on my mind:
On the server-side there would be an authentication daemon that has a database of correct checksums for a selection of approved PlaneShift client binaries (one for each supported OS/arch combination and possibly a few more for e.g. working around strange Linux distros). There would be a client side unit that takes checksums of the running PlaneShift binary as well as itself, sends that to the server over an encrypted connection, and then monitors the running program space for code injections from e.g. a debugger. (The exact mechanics of that depends greatly upon the OS. On Linux, we're probably talking about ptrace()ing the PS client and sounding alarms if the trace gets broken.)
Every time an account is created it would be assigned a private key. When a client logs in with an account it hasn't logged in with before, a unique compilation of the client side unit is generated on the fly and downloaded by the client. The account key is embedded in the client side auth unit in such a way that no automated process can extract it (probably by placing fragments of the key at completely random offsets, combined with some evil assembly tricks). The client side auth unit then establishes an encrypted connection with the authentication daemon, using the account's private key as the encryption key for the cipher of the connection itself. This connection stays active as long as the PS client is open, and has a heartbeat going. The PS client is kicked if the auth client stops responding or reports an anomaly (which requires the whole handshake to happen again next time they login).
If that's not enough to stop bots, we can start adding things on to the client, like scanning the system's hardware registry for known bots (a bit tricky on Linux since hardware information isn't all in one place) and searching the process list for suspicious programs.
Here's some rationale:
a) The client auth unit is specifically keyed to accounts for a reason -- if all clients had the same key, or randomly generated keys, it would be trivial to develop a distributable version of an exploit that could be used on any account. But if the auth client is tied specifically to each account, then the exploit must be hand-crafted for each account it will be used on, making it impossible to distribute, and completely shutting down script kiddies who are the real botting abusers. (Trust me, those yokels have never done any real work in a disassembler, and wouldn't be able to even begin hunting down an obfuscated key in x86 bytecode.)
b) The connection is encrypted for a reason -- if it was plaintext, a proxy could easily manipulate the checksums being sent to be "right". If it's encrypted using a key that is obfuscated in the binary, you could IN THEORY spend hours in a disassembler hunting down all the pieces of the key throughout the binary, brute force the right order, and then write a proxy that uses that to change the keys in it on the fly, but at that point, you're investing a MASSIVE amount of time and effort just to get a little automation going in a free MMORPG. And if you use a decent enough cipher, brute forcing the key directly from packets sent in the authentication would take literally years, and even if it does become a problem, you can make the account private keys time out.
The main drawbacks I can see:
a) Linux users will be required to use precompiled binaries. It's simply impossible to account for all the different possible compiler results and dynamic libraries and etc etc. that can result from compiling from source. But hey, if id Software and Epic Games can make binaries that'll run on any modern Linux distro, so can the open source community.
b) On the same token, people won't be able to bugger around with the sources to add features and run those features on the main server. For this reason you'll have to run a secondary "developer" server that will take any client that speaks the protocol.