Skip to content

Commit

Permalink
add support for third-party auth servers (#75)
Browse files Browse the repository at this point in the history
* add support for third-party auth servers

integrates p1xbraten's authservers.patch, except that the master server remains independent and is not treated as "just another auth server". adds the 'addauthserver' command.

* decrease diff to vanilla fpsgame/server.cpp
  • Loading branch information
sauerbraten authored Apr 19, 2021
1 parent 8667251 commit dd8102f
Show file tree
Hide file tree
Showing 5 changed files with 477 additions and 40 deletions.
3 changes: 2 additions & 1 deletion src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ SERVER_OBJS= \
mod/cryptomod/polarssl/library/sha1-standalone.o \
mod/cryptomod/polarssl/library/sha2-standalone.o \
mod/cryptomod/polarssl/library/sha4-standalone.o \
mod/banlist-standalone.o
mod/banlist-standalone.o \
mod/authservers-standalone.o

# geoip
ifeq ($(USE_GEOIP),true)
Expand Down
36 changes: 36 additions & 0 deletions src/engine/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "rconmod.h"
#include "remod.h"
#include "commandev.h"
#include "authservers.h"

#ifdef IRC
#include "irc.h"
Expand Down Expand Up @@ -553,6 +554,15 @@ void checkserversockets() // reply all server info requests
ENET_SOCKETSET_ADD(readset, mastersock);
if(!masterconnected) ENET_SOCKETSET_ADD(writeset, mastersock);
}
// remod: check auth servers sockets
enumerate(remod::auth::servers, remod::auth::authserver, a, {
if(a.sock != ENET_SOCKET_NULL)
{
maxsock = max(maxsock, a.sock);
ENET_SOCKETSET_ADD(readset, a.sock);
if(!a.connected) ENET_SOCKETSET_ADD(writeset, a.sock);
}
});
if(lansock != ENET_SOCKET_NULL)
{
maxsock = max(maxsock, lansock);
Expand Down Expand Up @@ -598,6 +608,30 @@ void checkserversockets() // reply all server info requests
}
if(mastersock != ENET_SOCKET_NULL && ENET_SOCKETSET_CHECK(readset, mastersock)) flushmasterinput();
}
// remod
enumerate(remod::auth::servers, remod::auth::authserver, a, {
if(a.sock != ENET_SOCKET_NULL)
{
if(!a.connected)
{
if(ENET_SOCKETSET_CHECK(readset, a.sock) || ENET_SOCKETSET_CHECK(writeset, a.sock))
{
int error = 0;
if(enet_socket_get_option(a.sock, ENET_SOCKOPT_ERROR, &error) < 0 || error)
{
logoutf("could not connect to auth server, error: %d", error);
a.disconnect();
}
else
{
a.connecting = 0;
a.connected = totalmillis ? totalmillis : 1;
}
}
}
if(a.sock != ENET_SOCKET_NULL && ENET_SOCKETSET_CHECK(readset, a.sock)) a.flushinput();
}
});
}

VAR(serveruprate, 0, 0, INT_MAX);
Expand Down Expand Up @@ -659,6 +693,8 @@ void serverslice(bool dedicated, uint timeout) // main server update, called f
server::serverupdate();

flushmasteroutput();
// remod
enumerate(remod::auth::servers, remod::auth::authserver, a, { a.flushoutput(); });
checkserversockets();

if(!lastupdatemaster || totalmillis-lastupdatemaster>60*60*1000) // send alive signal to masterserver every hour of uptime
Expand Down
87 changes: 48 additions & 39 deletions src/fpsgame/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "commandev.h"
#include "fpsgame.h"
#include "remod.h"
#include "authservers.h"

namespace game
{
Expand Down Expand Up @@ -1069,26 +1070,27 @@ namespace server

SVAR(serverauth, "");

struct userkey
{
char *name;
char *desc;
// remod: moved to authservers.h
// struct userkey
// {
// char *name;
// char *desc;

userkey() : name(NULL), desc(NULL) {}
userkey(char *name, char *desc) : name(name), desc(desc) {}
};
// userkey() : name(NULL), desc(NULL) {}
// userkey(char *name, char *desc) : name(name), desc(desc) {}
// };

static inline uint hthash(const userkey &k) { return ::hthash(k.name); }
static inline bool htcmp(const userkey &x, const userkey &y) { return !strcmp(x.name, y.name) && !strcmp(x.desc, y.desc); }
// static inline uint hthash(const userkey &k) { return ::hthash(k.name); }
// static inline bool htcmp(const userkey &x, const userkey &y) { return !strcmp(x.name, y.name) && !strcmp(x.desc, y.desc); }

struct userinfo : userkey
{
void *pubkey;
int privilege;
// struct userinfo : userkey
// {
// void *pubkey;
// int privilege;

userinfo() : pubkey(NULL), privilege(PRIV_NONE) {}
~userinfo() { delete[] name; delete[] desc; if(pubkey) freepubkey(pubkey); }
};
// userinfo() : pubkey(NULL), privilege(PRIV_NONE) {}
// ~userinfo() { delete[] name; delete[] desc; if(pubkey) freepubkey(pubkey); }
// };
hashset<userinfo> users;

void adduser(char *name, char *desc, char *pubkey, char *priv)
Expand Down Expand Up @@ -1137,7 +1139,8 @@ namespace server

extern void connected(clientinfo *ci);

bool setmaster(clientinfo *ci, bool val, const char *pass = "", const char *authname = NULL, const char *authdesc = NULL, int authpriv = PRIV_MASTER, bool force = false, bool trial = false)
// remod: defaults in authservers.h
bool setmaster(clientinfo *ci, bool val, const char *pass, const char *authname, const char *authdesc, int authpriv, bool force, bool trial)
{
if(authname && !val) return false;
const char *name = "";
Expand Down Expand Up @@ -1220,7 +1223,8 @@ namespace server
return true;
}

bool trykick(clientinfo *ci, int victim, const char *reason = NULL, const char *authname = NULL, const char *authdesc = NULL, int authpriv = PRIV_NONE, bool trial = false)
// remod: defaults in authservers.h
bool trykick(clientinfo *ci, int victim, const char *reason, const char *authname, const char *authdesc, int authpriv, bool trial)
{
int priv = ci->privilege;
if(authname)
Expand Down Expand Up @@ -2601,25 +2605,27 @@ namespace server
return ci && ci->connected;
}

// remod: "overriden" in authservers.cpp
clientinfo *findauth(uint id)
{
loopv(clients) if(clients[i]->authreq == id) return clients[i];
return NULL;
}


void authfailed(clientinfo *ci)
{
if(!ci) return;
ci->cleanauth();
if(ci->connectauth) disconnect_client(ci->clientnum, ci->connectauth);
}

// remod: "overriden" in authservers.cpp
void authfailed(uint id)
{
authfailed(findauth(id));
}


// remod: "overriden" in authservers.cpp
void authsucceeded(uint id)
{
clientinfo *ci = findauth(id);
Expand All @@ -2629,21 +2635,23 @@ namespace server
if(ci->authkickvictim >= 0)
{
if(setmaster(ci, true, "", ci->authname, NULL, PRIV_AUTH, false, true))
trykick(ci, ci->authkickvictim, ci->authkickreason, ci->authname, NULL, PRIV_AUTH);
trykick(ci, ci->authkickvictim, ci->authkickreason, ci->authname, NULL, PRIV_AUTH);
ci->cleanauthkick();
}
else setmaster(ci, true, "", ci->authname, NULL, PRIV_AUTH);
}


// remod: "overriden" in authservers.cpp
void authchallenged(uint id, const char *val, const char *desc = "")
{
clientinfo *ci = findauth(id);
if(!ci) return;
sendf(ci->clientnum, 1, "risis", N_AUTHCHAL, desc, id, val);
}

uint nextauthreq = 0;


// remod: "overriden" in authservers.cpp
bool tryauth(clientinfo *ci, const char *user, const char *desc)
{
ci->cleanauth();
Expand All @@ -2654,7 +2662,7 @@ namespace server
if(ci->authdesc[0])
{
userinfo *u = users.access(userkey(ci->authname, ci->authdesc));
if(u)
if(u)
{
uint seed[3] = { ::hthash(serverauth) + detrnd(size_t(ci) + size_t(user) + size_t(desc), 0x10000), uint(totalmillis), randomMT() };
vector<char> buf;
Expand All @@ -2672,10 +2680,11 @@ namespace server
if(ci->connectauth) disconnect_client(ci->clientnum, ci->connectauth);
return false;
}


// remod: "overriden" in authservers.cpp
bool answerchallenge(clientinfo *ci, uint id, char *val, const char *desc)
{
if(ci->authreq != id || strcmp(ci->authdesc, desc))
if(ci->authreq != id || strcmp(ci->authdesc, desc))
{
ci->cleanauth();
return !ci->connectauth;
Expand All @@ -2689,7 +2698,7 @@ namespace server
if(ci->authchallenge && checkchallenge(val, ci->authchallenge))
{
userinfo *u = users.access(userkey(ci->authname, ci->authdesc));
if(u)
if(u)
{
if(ci->connectauth) connected(ci);
if(ci->authkickvictim >= 0)
Expand All @@ -2700,8 +2709,8 @@ namespace server
else setmaster(ci, true, "", ci->authname, ci->authdesc, u->privilege);
}
}
ci->cleanauth();
}
ci->cleanauth();
}
else if(!requestmasterf("confauth %u %s\n", id, val))
{
ci->cleanauth();
Expand All @@ -2719,7 +2728,7 @@ namespace server
loopvrev(clients)
{
clientinfo *ci = clients[i];
if(ci->authreq) authfailed(ci);
if(ci->authreq && !ci->authdesc[0]) authfailed(ci); // remod: check for gauth desc
}
}

Expand All @@ -2728,11 +2737,11 @@ namespace server
uint id;
string val;
if(sscanf(cmd, "failauth %u", &id) == 1)
authfailed(id);
remod::authfailed(id, ""); // remod
else if(sscanf(cmd, "succauth %u", &id) == 1)
authsucceeded(id);
remod::authsucceeded(id, ""); // remod
else if(sscanf(cmd, "chalauth %u %255s", &id, val) == 2)
authchallenged(id, val);
remod::authchallenged(id, val, ""); // remod
else if(matchstring(cmd, cmdlen, "cleargbans"))
gbans.clear();
else if(sscanf(cmd, "addgban %100s", val) == 1)
Expand Down Expand Up @@ -2834,7 +2843,7 @@ namespace server
int disc = allowconnect(ci, password);
if(disc)
{
if(disc == DISC_LOCAL || !serverauth[0] || strcmp(serverauth, authdesc) || !tryauth(ci, authname, authdesc))
if(disc == DISC_LOCAL || !serverauth[0] || strcmp(serverauth, authdesc) || !remod::tryauth(ci, authname, authdesc)) // remod
{
disconnect_client(sender, disc);
return;
Expand All @@ -2851,7 +2860,7 @@ namespace server
getstring(desc, p, sizeof(desc));
uint id = (uint)getint(p);
getstring(ans, p, sizeof(ans));
if(!answerchallenge(ci, id, ans, desc))
if(!remod::answerchallenge(ci, id, ans, desc)) // remod
{
disconnect_client(sender, ci->connectauth);
return;
Expand Down Expand Up @@ -3597,7 +3606,7 @@ namespace server
string desc, name;
getstring(desc, p, sizeof(desc));
getstring(name, p, sizeof(name));
tryauth(ci, name, desc);
remod::tryauth(ci, name, desc); // remod
break;
}

Expand All @@ -3616,7 +3625,7 @@ namespace server
if(u) authpriv = u->privilege; else break;
}
if(ci->local || ci->privilege >= authpriv) trykick(ci, victim, text);
else if(trykick(ci, victim, text, name, desc, authpriv, true) && tryauth(ci, name, desc))
else if(trykick(ci, victim, text, name, desc, authpriv, true) && remod::tryauth(ci, name, desc)) // remod
{
ci->authkickvictim = victim;
ci->authkickreason = newstring(text);
Expand All @@ -3630,7 +3639,7 @@ namespace server
getstring(desc, p, sizeof(desc));
uint id = (uint)getint(p);
getstring(ans, p, sizeof(ans));
answerchallenge(ci, id, ans, desc);
remod::answerchallenge(ci, id, ans, desc); // remod
break;
}

Expand Down
Loading

0 comments on commit dd8102f

Please sign in to comment.