From: Rudolf Polzer Date: Sat, 28 Aug 2010 17:51:10 +0000 (+0200) Subject: make the cryptographic ID known to race and ipban X-Git-Tag: xonotic-v0.1.0preview~321 X-Git-Url: https://de.git.xonotic.org/?a=commitdiff_plain;h=62b04471b783985495eb0455883329cd41817344;p=xonotic%2Fxonotic-data.pk3dir.git make the cryptographic ID known to race and ipban --- diff --git a/defaultXonotic.cfg b/defaultXonotic.cfg index 34b4c889b..2b6395660 100644 --- a/defaultXonotic.cfg +++ b/defaultXonotic.cfg @@ -1258,6 +1258,7 @@ set cl_gravity 800 "but ignored anyway" set g_ban_default_bantime 5400 "90 minutes" set g_ban_default_masksize 3 "whole 255.255.255.0 networks (set to 4 for single IPs); when UID support is compiled in, masksize 0 means banning by UID" set g_banned_list "" "format: IP remainingtime IP remainingtime ..." +set g_banned_list_idmode "1" "when set, the IP banning system always uses the ID over the IP address (so a user in a banned IP range can connect if they have a valid signed ID)" alias bans "sv_cmd bans" alias ban "sv_cmd ban $*" // usage: ban address(maybe incomplete, like 1.2.3) bantime(seconds) alias kickban "sv_cmd kickban $*" // usage: kickban # playerno bantime(seconds) masksize(bytes) diff --git a/qcsrc/client/Main.qc b/qcsrc/client/Main.qc index 2fc1ce308..320ed9472 100644 --- a/qcsrc/client/Main.qc +++ b/qcsrc/client/Main.qc @@ -148,23 +148,6 @@ void CSQC_Init(void) } Tuba_Precache(); -#ifdef UID - { - // find the user ID - string uid; - registercvar("_cl_userid", "", CVAR_SAVE); - uid = cvar_string("_cl_userid"); - if(strlen(uid) < 16) - { - uid = ""; - for(i = 0; i < 4; ++i) - uid = strcat(uid, substring(ftos(floor(10000 + random() * 10000)), 1, -1)); - } - cvar_set("_cl_userid", uid); - localcmd(strcat("\ncmd uid ", uid, "\n")); - } -#endif - get_mi_min_max_texcoords(1); // try the CLEVER way first minimapname = strcat("gfx/", mi_shortname, "_radar.tga"); shortmapname = mi_shortname; diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index f08ef5f53..21ab80f2f 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -1386,10 +1386,6 @@ Called when a client connects to the server string ColoredTeamName(float t); void DecodeLevelParms (void); //void dom_player_join_team(entity pl); -#ifdef UID -.float uid_kicktime; -.string uid; -#endif void ClientConnect (void) { float t; @@ -1567,12 +1563,6 @@ void ClientConnect (void) else self.hitplotfh = -1; -#ifdef UID - if(clienttype(self) == CLIENTTYPE_REAL) - if not(self.uid) - self.uid_kicktime = time + 60; -#endif - if(g_race || g_cts) { string rr; if(g_cts) @@ -2903,16 +2893,6 @@ void PlayerPostThink (void) self.stat_count -= 1; } -#ifdef UID - if(self.uid_kicktime) - if(time > self.uid_kicktime) - { - bprint("^3", self.netname, "^3 was kicked for missing UID.\n"); - dropclient(self); - return; - } -#endif - if(sv_maxidle && frametime) { // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero). diff --git a/qcsrc/server/clientcommands.qc b/qcsrc/server/clientcommands.qc index 171906428..a9fd886bf 100644 --- a/qcsrc/server/clientcommands.qc +++ b/qcsrc/server/clientcommands.qc @@ -182,16 +182,6 @@ void SV_ParseClientCommand(string s) { tokens = tokenize_console(s); } GetCvars(1); -#ifdef UID - } else if(cmd == "uid") { - if not(self.uid) - { - self.uid = strzone(argv(1)); - self.uid_kicktime = 0; - print("Client ", etos(self), " has UID ", self.uid, "\n"); - Ban_MaybeEnforceBan(self); - } -#endif } else if(cmd == "sentcvar") { // new system if(tokens == 2) // undefined cvar: use the default value on the server then { diff --git a/qcsrc/server/extensions.qh b/qcsrc/server/extensions.qh index 18119546c..ac7748372 100644 --- a/qcsrc/server/extensions.qh +++ b/qcsrc/server/extensions.qh @@ -1,60 +1,60 @@ -//DarkPlaces supported extension list, draft version 1.04 - -//things that don't have extensions yet: -.float disableclientprediction; - -//definitions that id Software left out: -//these are passed as the 'nomonsters' parameter to traceline/tracebox (yes really this was supported in all quake engines, nomonsters is misnamed) -float MOVE_NORMAL = 0; // same as FALSE -float MOVE_NOMONSTERS = 1; // same as TRUE -float MOVE_MISSILE = 2; // save as movement with .movetype == MOVETYPE_FLYMISSILE - -//checkextension function -//idea: expected by almost everyone -//darkplaces implementation: LordHavoc -float(string s) checkextension = #99; -//description: -//check if (cvar("pr_checkextension")) before calling this, this is the only -//guaranteed extension to be present in the extension system, it allows you -//to check if an extension is available, by name, to check for an extension -//use code like this: -//// (it is recommended this code be placed in worldspawn or a worldspawn called function somewhere) -//if (cvar("pr_checkextension")) -//if (checkextension("DP_SV_SETCOLOR")) -// ext_setcolor = TRUE; -//from then on you can check ext_setcolor to know if that extension is available - -//BX_WAL_SUPPORT -//idea: id Software -//darkplaces implementation: LordHavoc -//description: -//indicates the engine supports .wal textures for filenames in the textures/ directory -//(note: DarkPlaces has supported this since 2001 or 2002, but did not advertise it as an extension, then I noticed Betwix was advertising it and added the extension accordingly) - -//DP_BUTTONCHAT -//idea: Vermeulen -//darkplaces implementation: LordHavoc -//field definitions: -.float buttonchat; -//description: -//true if the player is currently chatting (in messagemode, menus or console) - -//DP_BUTTONUSE -//idea: id Software -//darkplaces implementation: LordHavoc -//field definitions: -.float buttonuse; -//client console commands: -//+use -//-use -//description: -//made +use and -use commands work, they now control the .buttonuse field (.button1 was used by many mods for other purposes). - -//DP_CL_LOADSKY -//idea: Nehahra, LordHavoc -//darkplaces implementation: LordHavoc -//client console commands: + //DarkPlaces supported extension list, draft version 1.04 + + //things that don't have extensions yet: + .float disableclientprediction; + + //definitions that id Software left out: + //these are passed as the 'nomonsters' parameter to traceline/tracebox (yes really this was supported in all quake engines, nomonsters is misnamed) + float MOVE_NORMAL = 0; // same as FALSE + float MOVE_NOMONSTERS = 1; // same as TRUE + float MOVE_MISSILE = 2; // save as movement with .movetype == MOVETYPE_FLYMISSILE + + //checkextension function + //idea: expected by almost everyone + //darkplaces implementation: LordHavoc + float(string s) checkextension = #99; + //description: + //check if (cvar("pr_checkextension")) before calling this, this is the only + //guaranteed extension to be present in the extension system, it allows you + //to check if an extension is available, by name, to check for an extension + //use code like this: + //// (it is recommended this code be placed in worldspawn or a worldspawn called function somewhere) + //if (cvar("pr_checkextension")) + //if (checkextension("DP_SV_SETCOLOR")) + // ext_setcolor = TRUE; + //from then on you can check ext_setcolor to know if that extension is available + + //BX_WAL_SUPPORT + //idea: id Software + //darkplaces implementation: LordHavoc + //description: + //indicates the engine supports .wal textures for filenames in the textures/ directory + //(note: DarkPlaces has supported this since 2001 or 2002, but did not advertise it as an extension, then I noticed Betwix was advertising it and added the extension accordingly) + + //DP_BUTTONCHAT + //idea: Vermeulen + //darkplaces implementation: LordHavoc + //field definitions: + .float buttonchat; + //description: + //true if the player is currently chatting (in messagemode, menus or console) + + //DP_BUTTONUSE + //idea: id Software + //darkplaces implementation: LordHavoc + //field definitions: + .float buttonuse; + //client console commands: + //+use + //-use + //description: + //made +use and -use commands work, they now control the .buttonuse field (.button1 was used by many mods for other purposes). + + //DP_CL_LOADSKY + //idea: Nehahra, LordHavoc + //darkplaces implementation: LordHavoc + //client console commands: //"loadsky" (parameters: "basename", example: "mtnsun_" would load "mtnsun_up.tga" and "mtnsun_rt.tga" and similar names, use "" to revert to quake sky, note: this is the same as Quake2 skybox naming) //description: //sets global skybox for the map for this client (can be stuffed to a client by QC), does not hurt much to repeatedly execute this command, please don't use this in mods if it can be avoided (only if changing skybox is REALLY needed, otherwise please use DP_GFX_SKYBOX). @@ -2309,3 +2309,15 @@ float JOINTTYPE_HINGE2 = 5; // hinge2; uses origin (anchor), angles (axis1), vel //description: //various physics properties can be defined in an entity and are executed via //ODE + +//DP_CRYPTO +//idea: divVerent +//darkplaces implementation: divVerent +//field definitions: (SVQC) +.string crypto_keyfp; // fingerprint of CA key the player used to authenticate, or string_null if not verified +.string crypto_mykeyfp; // fingerprint of CA key the server used to authenticate to the player, or string_null if not verified +.string crypto_idfp; // fingerprint of ID used by the player entity, or string_null if not identified +.string crypto_encryptmethod; // the string "AES128" if encrypting, and string_null if plaintext +.string crypto_signmethod; // the string "HMAC-SHA256" if signing, and string_null if plaintext +// there is no field crypto_myidfp, as that info contains no additional information the QC may have a use for +//description: diff --git a/qcsrc/server/ipban.qc b/qcsrc/server/ipban.qc index ebc58cea7..f74262a10 100644 --- a/qcsrc/server/ipban.qc +++ b/qcsrc/server/ipban.qc @@ -160,12 +160,15 @@ void OnlineBanList_URI_Get_Callback(float id, float status, string data) continue; l = strlen(ip); - for(j = 0; j < l; ++j) - if(strstrofs("0123456789.", substring(ip, j, 1), 0) == -1) - { - print("Invalid character ", substring(ip, j, 1), " in IP address ", ip, ". Skipping this ban.\n"); - goto skip; - } + if(l != 44) // length 44 is a cryptographic ID + { + for(j = 0; j < l; ++j) + if(strstrofs("0123456789.", substring(ip, j, 1), 0) == -1) + { + print("Invalid character ", substring(ip, j, 1), " in IP address ", ip, ". Skipping this ban.\n"); + goto skip; + } + } if(cvar("g_ban_sync_trusted_servers_verify")) if((strstrofs(strcat(";", OnlineBanList_Servers, ";"), strcat(";", serverip, ";"), 0) == -1)) @@ -243,9 +246,7 @@ string ban_ip1; string ban_ip2; string ban_ip3; string ban_ip4; -#ifdef UID -string ban_uid; -#endif +string ban_idfp; void Ban_SaveBans() { @@ -335,28 +336,37 @@ float Ban_GetClientIP(entity client) float i1, i2, i3, i4; string s; - s = client.netaddress; - - i1 = strstrofs(s, ".", 0); - if(i1 < 0) - return FALSE; - i2 = strstrofs(s, ".", i1 + 1); - if(i2 < 0) - return FALSE; - i3 = strstrofs(s, ".", i2 + 1); - if(i3 < 0) - return FALSE; - i4 = strstrofs(s, ".", i3 + 1); - if(i4 >= 0) - return FALSE; - - ban_ip1 = substring(s, 0, i1); - ban_ip2 = substring(s, 0, i2); - ban_ip3 = substring(s, 0, i3); - ban_ip4 = strcat1(s); -#ifdef UID - ban_uid = client.uid; -#endif + if(client.crypto_keyfp) + ban_idfp = client.crypto_idfp; + else + ban_idfp = string_null; + + if(cvar("g_banned_list_idmode") && ban_idfp) + { + ban_ip1 = ban_ip2 = ban_ip3 = ban_ip4 = ban_idfp; + } + else + { + s = client.netaddress; + + i1 = strstrofs(s, ".", 0); + if(i1 < 0) + return FALSE; + i2 = strstrofs(s, ".", i1 + 1); + if(i2 < 0) + return FALSE; + i3 = strstrofs(s, ".", i2 + 1); + if(i3 < 0) + return FALSE; + i4 = strstrofs(s, ".", i3 + 1); + if(i4 >= 0) + return FALSE; + + ban_ip1 = substring(s, 0, i1); + ban_ip2 = substring(s, 0, i2); + ban_ip3 = substring(s, 0, i3); + ban_ip4 = strcat1(s); + } return TRUE; } @@ -388,9 +398,7 @@ float Ban_IsClientBanned(entity client, float idx) if(ban_ip2 == s) return TRUE; if(ban_ip3 == s) return TRUE; if(ban_ip4 == s) return TRUE; -#ifdef UID - if(ban_uid == s) return TRUE; -#endif + if(ban_idfp == s) return TRUE; } return FALSE; } @@ -535,11 +543,9 @@ void Ban_KickBanClient(entity client, float bantime, float masksize, string reas default: Ban_Insert(ban_ip4, bantime, reason, 1); break; -#ifdef UID case 0: - Ban_Insert(ban_uid, bantime, reason, 1); + Ban_Insert(ban_idfp, bantime, reason, 1); break; -#endif } /* * not needed, as we enforce the ban in Ban_Insert anyway diff --git a/qcsrc/server/race.qc b/qcsrc/server/race.qc index 4dff570d3..1c79c575f 100644 --- a/qcsrc/server/race.qc +++ b/qcsrc/server/race.qc @@ -101,9 +101,7 @@ void race_InitSpectator() string rr; float grecordtime[RANKINGS_CNT]; string grecordholder[RANKINGS_CNT]; -#ifdef UID string grecorduid[RANKINGS_CNT]; -#endif float worst_time; // last ranked time float have_recs; // have we already read the records from the database before? float race_GetTime(float pos) { @@ -117,15 +115,11 @@ float race_GetTime(float pos) { for(i=0;i=0;--i) - if(grecorduid[i] == myuid) - return i+1; + if(myuid) + { + for (i=RANKINGS_CNT-1;i>=0;--i) + if(grecorduid[i] == myuid) + return i+1; + } for (i=RANKINGS_CNT-1;i>=0;--i) if(grecordholder[i] == net_name) return i+1; @@ -224,11 +220,7 @@ string race_PlaceName(float pos) { void race_SetTime(entity e, float t, float match_rec) { float pos, prevpos; pos = race_GetPos(t); -#ifdef UID - prevpos = race_CheckUID(e.uid, e.netname); -#else - prevpos = race_CheckName(e.netname); -#endif + prevpos = race_CheckUID(e.crypto_idfp, e.netname); float oldrec; string recorddifference; @@ -254,37 +246,29 @@ void race_SetTime(entity e, float t, float match_rec) { for (i=prevpos-1;i>pos-1;--i) { db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), ftos(grecordtime[i-1])); db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), grecordholder[i-1]); -#ifdef UID - db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(i)), grecorduid[i-1]); -#endif + db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), grecorduid[i-1]); grecordtime[i] = grecordtime[i-1]; if (grecordholder[i]) strunzone(grecordholder[i]); grecordholder[i] = strzone(grecordholder[i-1]); -#ifdef UID if (grecorduid[i]) strunzone(grecorduid[i]); grecorduid[i] = strzone(grecorduid[i-1]); -#endif } } else { // player has no ranked record yet for (i=RANKINGS_CNT-1;i>pos-1;--i) { db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), ftos(grecordtime[i-1])); db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), grecordholder[i-1]); -#ifdef UID - db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(i)), grecorduid[i-1]); -#endif + db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), grecorduid[i-1]); grecordtime[i] = grecordtime[i-1]; if (grecordholder[i]) strunzone(grecordholder[i]); grecordholder[i] = strzone(grecordholder[i-1]); -#ifdef UID if (grecorduid[i]) strunzone(grecorduid[i]); grecorduid[i] = strzone(grecorduid[i-1]); -#endif } } @@ -292,39 +276,31 @@ void race_SetTime(entity e, float t, float match_rec) { if (pos == 1) { db_put(ServerProgsDB, strcat(GetMapname(), rr, "time"), ftos(t)); db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname"), e.netname); -#ifdef UID - db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid"), e.uid); -#endif + db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp"), e.crypto_idfp); grecordtime[0] = t; if (grecordholder[0]) strunzone(grecordholder[0]); grecordholder[0] = strzone(e.netname); -#ifdef UID if (grecorduid[0]) strunzone(grecorduid[0]); - grecorduid[0] = strzone(e.uid); -#endif + grecorduid[0] = strzone(e.crypto_idfp); write_recordmarker(e, time - TIME_DECODE(t), TIME_DECODE(t)); race_send_recordtime(MSG_ALL); } else { db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(pos-1)), ftos(t)); db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(pos-1)), e.netname); -#ifdef UID - db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(pos-1)), e.uid); -#endif + db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(pos-1)), e.crypto_idfp); grecordtime[pos-1] = t; if (grecordholder[pos-1]) strunzone(grecordholder[pos-1]); grecordholder[pos-1] = strzone(e.netname); -#ifdef UID if (grecorduid[pos-1]) strunzone(grecorduid[pos-1]); - grecorduid[pos-1] = strzone(e.uid); -#endif + grecorduid[pos-1] = strzone(e.crypto_idfp); } if (pos == RANKINGS_CNT) @@ -368,53 +344,41 @@ void race_DeleteTime(float pos) { if (i == 0) { db_put(ServerProgsDB, strcat(GetMapname(), rr, "time"), ftos(grecordtime[1])); db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname"), grecordholder[1]); -#ifdef UID - db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid"), grecorduid[1]); -#endif + db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp"), grecorduid[1]); grecordtime[0] = grecordtime[1]; if (grecordholder[i]) strunzone(grecordholder[0]); grecordholder[0] = strzone(grecordholder[1]); -#ifdef UID if (grecorduid[i]) strunzone(grecorduid[0]); grecorduid[0] = strzone(grecorduid[1]); -#endif } else if (i == RANKINGS_CNT-1) { db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), string_null); db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), string_null); -#ifdef UID - db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(i)), string_null); -#endif + db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), string_null); grecordtime[i] = 0; if (grecordholder[i]) strunzone(grecordholder[i]); grecordholder[i] = string_null; -#ifdef UID if (grecorduid[i]) strunzone(grecorduid[i]); grecorduid[i] = string_null; -#endif } else { db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), ftos(grecordtime[i+1])); db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), grecordholder[i+1]); -#ifdef UID - db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(i)), grecorduid[i+1]); -#endif + db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), grecorduid[i+1]); grecordtime[i] = grecordtime[i+1]; if (grecordholder[i]) strunzone(grecordholder[i]); grecordholder[i] = strzone(grecordholder[i+1]); -#ifdef UID if (grecorduid[i]) strunzone(grecorduid[i]); grecorduid[i] = strzone(grecorduid[i+1]); -#endif } }