From 39e6b95c5e34547ba50edd17081b88ed5804c607 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Thu, 16 Oct 2008 23:53:38 +0000 Subject: [PATCH] avoid sending plaintext password on connect git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@3080 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/client.cpp | 34 +++++++++++++++++++--------------- source/src/clientgame.cpp | 8 ++++---- source/src/clients2c.cpp | 6 ++++-- source/src/editing.cpp | 10 +++++----- source/src/protos.h | 7 +++---- source/src/server.cpp | 30 +++++++++++++++++------------- source/src/serverbrowser.cpp | 2 +- 7 files changed, 53 insertions(+), 44 deletions(-) diff --git a/source/src/client.cpp b/source/src/client.cpp index a592f905..178574d6 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -49,13 +49,13 @@ void throttle() } string clientpassword = ""; -int claimadmin = 0; +int connectrole = CR_DEFAULT; void abortconnect() { if(!connpeer) return; clientpassword[0] = '\0'; - claimadmin = 0; + connectrole = CR_DEFAULT; if(connpeer->state!=ENET_PEER_STATE_DISCONNECTED) enet_peer_reset(connpeer); connpeer = NULL; #if 0 @@ -67,7 +67,7 @@ void abortconnect() #endif } -void connects(char *servername, char *serverport, char *password) +void connectserv_(const char *servername, const char *serverport = NULL, const char *password = NULL, int role = CR_DEFAULT) { if(connpeer) { @@ -75,6 +75,7 @@ void connects(char *servername, char *serverport, char *password) abortconnect(); } + connectrole = role; s_strcpy(clientpassword, password ? password : ""); ENetAddress address; @@ -90,7 +91,7 @@ void connects(char *servername, char *serverport, char *password) { conoutf("\f3could not resolve server %s", servername); clientpassword[0] = '\0'; - claimadmin = 0; + connectrole = CR_DEFAULT; return; } } @@ -114,20 +115,24 @@ void connects(char *servername, char *serverport, char *password) { conoutf("\f3could not connect to server"); clientpassword[0] = '\0'; - claimadmin = 0; + connectrole = CR_DEFAULT; } } +void connectserv(char *servername, char *serverport, char *password) +{ + connectserv_(servername, serverport, password); +} + void connectadmin(char *servername, char *serverport, char *password) { - if(!password) return; - claimadmin = 1; - connects(servername, serverport, password); + if(!password[0]) return; + connectserv_(servername, serverport, password, CR_ADMIN); } void lanconnect() { - connects(0); + connectserv_(NULL); } void disconnect(int onlyclean, int async) @@ -205,7 +210,7 @@ void echo(char *text) { conoutf("%s", text); } COMMAND(echo, ARG_CONC); COMMANDN(say, toserver, ARG_CONC); -COMMANDN(connect, connects, ARG_3STR); +COMMANDN(connect, connectserv, ARG_3STR); COMMAND(connectadmin, ARG_3STR); COMMAND(lanconnect, ARG_NONE); COMMANDN(disconnect, trydisconnect, ARG_NONE); @@ -378,10 +383,10 @@ void sendintro() ucharbuf p(packet->data, packet->dataLength); putint(p, SV_CONNECT); sendstring(player1->name, p); - sendstring(genpwdhash(player1->name, clientpassword, 0), p); - putint(p, claimadmin); + sendstring(genpwdhash(player1->name, clientpassword, sessionid), p); + putint(p, connectrole); clientpassword[0] = '\0'; - claimadmin = 0; + connectrole = CR_DEFAULT; putint(p, player1->nextprimweap->type); enet_packet_resize(packet, p.length()); sendpackettoserv(1, packet); @@ -414,8 +419,7 @@ void gets2c() // get updates from the server conoutf("connected to server"); throttle(); if(rate) setrate(rate); - if(editmode) toggleedit(); - sendintro(); + if(editmode) toggleedit(true); break; case ENET_EVENT_TYPE_RECEIVE: diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index 0a833384..021d25d3 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -160,7 +160,7 @@ void deathstate(playerent *pl) { showscores(showscoresondeath!=0); setscope(false); - if(editmode) toggleedit(); + if(editmode) toggleedit(true); } else pl->resetinterp(); } @@ -699,7 +699,7 @@ void startmap(const char *name, bool reset) // called just after a map load player1->frags = player1->flagscore = player1->deaths = player1->lifesequence = 0; loopv(players) if(players[i]) players[i]->frags = players[i]->flagscore = players[i]->deaths = players[i]->lifesequence = 0; - if(editmode) toggleedit(); + if(editmode) toggleedit(true); showscores(false); intermission = false; minutesremaining = -1; @@ -982,12 +982,12 @@ void whois(int cn) COMMAND(whois, ARG_1INT); -int setadminsalt = 0; +int sessionid = 0; void setadmin(char *claim, char *password) { if(!claim || !password) return; - else addmsg(SV_SETADMIN, "ris", atoi(claim), genpwdhash(player1->name, password, setadminsalt)); + else addmsg(SV_SETADMIN, "ris", atoi(claim), genpwdhash(player1->name, password, sessionid)); } COMMAND(setadmin, ARG_2STR); diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index e2167ddb..12859f6c 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -164,13 +164,15 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) case SV_INITS2C: // welcome messsage from the server { int mycn = getint(p), prot = getint(p); - setadminsalt = getint(p); if(prot!=PROTOCOL_VERSION) { conoutf("you are using a different game protocol (you: %d, server: %d)", PROTOCOL_VERSION, prot); disconnect(); return; } + sessionid = getint(p); + int oldcn = player1->clientnum; + if(oldcn < 0 && mycn >= 0) sendintro(); player1->clientnum = mycn; // we are now fully connected joining = getint(p); if(getint(p) > 0) conoutf("INFO: this server is password protected"); @@ -330,7 +332,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) case SV_SPAWNSTATE: { - if(editmode) toggleedit(); + if(editmode) toggleedit(true); showscores(false); setscope(false); player1->respawn(); diff --git a/source/src/editing.cpp b/source/src/editing.cpp index 742df7af..9256b99b 100644 --- a/source/src/editing.cpp +++ b/source/src/editing.cpp @@ -33,13 +33,13 @@ sqr rtex; VAR(editing, 1, 0, 0); -void toggleedit() +void toggleedit(bool force) { - if(player1->state==CS_DEAD) return; // do not allow dead players to edit to avoid state confusion - if(!editmode && !allowedittoggle()) return; // not in most multiplayer modes + if(player1->state==CS_DEAD) return; // do not allow dead players to edit to avoid state confusion + if(!force && !editmode && !allowedittoggle()) return; // not in most multiplayer modes if(!(editmode = !editmode)) { - entinmap(player1); // find spawn closest to current floating pos + entinmap(player1); // find spawn closest to current floating pos } else { @@ -51,7 +51,7 @@ void toggleedit() selset = false; editing = editmode ? 1 : 0; player1->state = editing ? CS_EDITING : CS_ALIVE; - addmsg(SV_EDITMODE, "ri", editing); + if(!force) addmsg(SV_EDITMODE, "ri", editing); } COMMANDN(edittoggle, toggleedit, ARG_NONE); diff --git a/source/src/protos.h b/source/src/protos.h index cabfcb6e..06140102 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -174,7 +174,7 @@ struct gmenu }; // serverbrowser -extern void addserver(char *servername, char *serverport); +extern void addserver(const char *servername, const char *serverport); extern char *getservername(int n); extern bool resolverwait(const char *name, ENetAddress *address); extern int connectwithtimeout(ENetSocket sock, const char *hostname, ENetAddress &remoteaddress); @@ -284,7 +284,6 @@ extern int renderwater(float hf, GLuint reflecttex, GLuint refracttex); extern void resetwater(); // client -extern void connects(char *servername, char *serverport = NULL, char *password = NULL); extern void abortconnect(); extern void disconnect(int onlyclean = 0, int async = 0); extern void cleanupclient(); @@ -309,7 +308,7 @@ extern void listdemos(); // clientgame extern flaginfo flaginfos[2]; -extern int setadminsalt; +extern int sessionid; extern bool autoteambalance; extern void updateworld(int curtime, int lastmillis); extern void resetmap(); @@ -465,7 +464,7 @@ extern void text_endcolumns(); // editing extern void cursorupdate(); -extern void toggleedit(); +extern void toggleedit(bool force = false); extern char *editinfo(); extern void editdrag(bool isdown); extern void setvdeltaxy(int delta, block &sel); diff --git a/source/src/server.cpp b/source/src/server.cpp index b7cca3de..e1df0563 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -2205,6 +2205,11 @@ void sendresume(client &c) NUMGUNS, c.state.mag); } +void sendinits2c(client &c) +{ + sendf(c.clientnum, 1, "ri6", SV_INITS2C, c.clientnum, PROTOCOL_VERSION, c.salt, 0, serverpassword[0] ? 1 : 0); +} + void welcomepacket(ucharbuf &p, int n, ENetPacket *packet) { #define CHECKSPACE(n) \ @@ -2218,20 +2223,17 @@ void welcomepacket(ucharbuf &p, int n, ENetPacket *packet) } \ } + if(!smapname[0] && configsets.length()) nextcfgset(false); + + client *c = valid_client(n) ? clients[n] : NULL; + int numcl = numclients(); + putint(p, SV_INITS2C); putint(p, n); putint(p, PROTOCOL_VERSION); - client *c = valid_client(n) ? clients[n] : NULL; - if(c) - { - c->salt = rand() * (servmillis % 999); - putint(p, c->salt); - } - else putint(p, 0); - if(!smapname[0] && configsets.length()) nextcfgset(false); - int numcl = numclients(); + putint(p, c ? c->salt : 0); putint(p, smapname[0] && !m_demo ? numcl : -1); - putint(p, serverpassword[0] ? 1 : 0); + putint(p, 0); if(smapname[0]) { putint(p, SV_MAPCHANGE); @@ -2390,15 +2392,15 @@ void process(ENetPacket *packet, int sender, int chan) // sender may be -1 s_strncpy(cl->name, text, MAXNAMELEN+1); getstring(text, p); - int cadm = getint(p); + int wantrole = getint(p); cl->state.nextprimary = getint(p); bool banned = isbanned(sender); bool srvfull = numnonlocalclients() > maxclients; bool srvprivate = mastermode == MM_PRIVATE; - if(checkadmin(cl->name, text, 0, &pd) && (!pd.denyadmin || (banned && !srvfull && !srvprivate))) // pass admins always through + if(checkadmin(cl->name, text, cl->salt, &pd) && (!pd.denyadmin || (banned && !srvfull && !srvprivate))) // pass admins always through { cl->isauthed = true; - if(!pd.denyadmin && cadm > 0) clientrole = CR_ADMIN; + if(!pd.denyadmin && wantrole == CR_ADMIN) clientrole = CR_ADMIN; if(banned) { loopv(bans) if(bans[i].address.host == cl->peer->address.host) { bans.remove(i); break; } // remove admin bans @@ -3170,9 +3172,11 @@ void serverslice(uint timeout) // main server update, called from cube main lo c.peer = event.peer; c.peer->data = (void *)(size_t)c.clientnum; c.connectmillis = servmillis; + c.salt = rand()*((servmillis%1000)+1); char hn[1024]; s_strcpy(c.hostname, (enet_address_get_host_ip(&c.peer->address, hn, sizeof(hn))==0) ? hn : "unknown"); logger->writeline(log::info,"[%s] client connected", c.hostname); + sendinits2c(c); break; } diff --git a/source/src/serverbrowser.cpp b/source/src/serverbrowser.cpp index 67ba3b32..57f5ff0a 100644 --- a/source/src/serverbrowser.cpp +++ b/source/src/serverbrowser.cpp @@ -323,7 +323,7 @@ static serverinfo *newserver(const char *name, uint ip = ENET_HOST_ANY, int port return si; } -void addserver(char *servername, char *serverport) +void addserver(const char *servername, const char *serverport) { int port = atoi(serverport); if(port == 0) port = CUBE_DEFAULT_SERVER_PORT;