]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - netconn.c
independent volume control for the 8 entity channels
[xonotic/darkplaces.git] / netconn.c
index 27f16c1d8c5f21f6547e733b2c08689a7a3111ba..d114d7c2008a0a28c0cc60e716f5de1d80fe47fc 100755 (executable)
--- a/netconn.c
+++ b/netconn.c
@@ -38,7 +38,7 @@ static cvar_t sv_masters [] =
        {CVAR_SAVE, "sv_master4", "", "user-chosen master server 4"},
        {0, "sv_masterextra1", "ghdigital.com", "default master server 1 (admin: LordHavoc)"}, // admin: LordHavoc
        {0, "sv_masterextra2", "dpmaster.deathmask.net", "default master server 2 (admin: Willis)"}, // admin: Willis
-       {0, "sv_masterextra3", "excalibur.nvg.ntnu.no", "default master server 3 (admin: tChr)"}, // admin: tChr
+       {0, "sv_masterextra3", "dpmaster.tchr.no", "default master server 3 (admin: tChr)"}, // admin: tChr
        {0, NULL, NULL, NULL}
 };
 
@@ -327,11 +327,11 @@ static void ServerList_ViewList_Insert( serverlist_entry_t *entry )
 
        // FIXME: change this to be more readable (...)
        // now check whether it passes through the masks
-       for( start = 0 ; serverlist_andmasks[start].active && start < SERVERLIST_ANDMASKCOUNT ; start++ )
+       for( start = 0 ; start < SERVERLIST_ANDMASKCOUNT && serverlist_andmasks[start].active; start++ )
                if( !_ServerList_Entry_Mask( &serverlist_andmasks[start], &entry->info ) )
                        return;
 
-       for( start = 0 ; serverlist_ormasks[start].active && start < SERVERLIST_ORMASKCOUNT ; start++ )
+       for( start = 0 ; start < SERVERLIST_ORMASKCOUNT && serverlist_ormasks[start].active ; start++ )
                if( _ServerList_Entry_Mask( &serverlist_ormasks[start], &entry->info ) )
                        break;
        if( start == SERVERLIST_ORMASKCOUNT || (start > 0 && !serverlist_ormasks[start].active) )
@@ -433,7 +433,7 @@ static void _ServerList_Test(void)
                serverlist_cache[serverlist_cachecount].info.ping = 1000 + 1024 - i;
                dpsnprintf( serverlist_cache[serverlist_cachecount].info.name, sizeof(serverlist_cache[serverlist_cachecount].info.name), "Black's ServerList Test %i", i );
                serverlist_cache[serverlist_cachecount].finished = true;
-               sprintf( serverlist_cache[serverlist_cachecount].line1, "%i %s", serverlist_cache[serverlist_cachecount].info.ping, serverlist_cache[serverlist_cachecount].info.name );
+               dpsnprintf( serverlist_cache[serverlist_cachecount].line1, sizeof(serverlist_cache[serverlist_cachecount].info.line1), "%i %s", serverlist_cache[serverlist_cachecount].info.ping, serverlist_cache[serverlist_cachecount].info.name );
                ServerList_ViewList_Insert( &serverlist_cache[serverlist_cachecount] );
                serverlist_cachecount++;
        }
@@ -1975,38 +1975,61 @@ void NetConn_ClearConnectFlood(lhnetaddress_t *peeraddress)
        }
 }
 
-qboolean RCon_Authenticate(const char *password, const char *s, const char *endpos)
+// returns a string describing the user level, or NULL for auth failure
+const char *RCon_Authenticate(const char *password, const char *s, const char *endpos)
 {
        const char *text;
+       qboolean hasquotes;
 
        if(!strcmp(rcon_password.string, password))
-               return true;
+               return "rcon";
        
        if(strcmp(rcon_restricted_password.string, password))
-               return false;
+               return NULL;
 
        for(text = s; text != endpos; ++text)
                if(*text > 0 && (*text < ' ' || *text == ';'))
-                       return false; // block possible exploits against the parser/alias expansion
+                       return NULL; // block possible exploits against the parser/alias expansion
 
        while(s != endpos)
        {
                size_t l = strlen(s);
                if(l)
                {
-                       text = s;
-
-                       if (!COM_ParseToken_Console(&text))
-                               return false;
-
-                       // com_token now contains the command
-                       if(!strstr(va(" %s ", rcon_restricted_commands.string), va(" %s ", com_token)))
-                               return false;
+                       hasquotes = (strchr(s, '"') != NULL);
+                       // sorry, we can't allow these substrings in wildcard expressions,
+                       // as they can mess with the argument counts
+                       text = rcon_restricted_commands.string;
+                       while(COM_ParseToken_Console(&text))
+                       {
+                               // com_token now contains a pattern to check for...
+                               if(strchr(com_token, '*') || strchr(com_token, '?')) // wildcard expression, * can only match a SINGLE argument
+                               {
+                                       if(!hasquotes)
+                                               if(matchpattern_with_separator(s, com_token, true, " ", true)) // note how we excluded tab, newline etc. above
+                                                       goto match;
+                               }
+                               else if(strchr(com_token, ' ')) // multi-arg expression? must match in whole
+                               {
+                                       if(!strcmp(com_token, s))
+                                               goto match;
+                               }
+                               else // single-arg expression? must match the beginning of the command
+                               {
+                                       if(!strcmp(com_token, s))
+                                               goto match;
+                                       if(!memcmp(va("%s ", com_token), s, strlen(com_token) + 1))
+                                               goto match;
+                               }
+                       }
+                       // if we got here, nothing matched!
+                       return NULL;
                }
+match:
                s += l + 1;
        }
 
-       return true;
+       return "restricted rcon";
 }
 
 extern void SV_SendServerinfo (client_t *client);
@@ -2201,11 +2224,12 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                        password[i] = 0;
                        if (password[0] > ' ')
                        {
-                               if (RCon_Authenticate(password, s, endpos))
+                               const char *userlevel = RCon_Authenticate(password, s, endpos);
+                               if(userlevel)
                                {
                                        // looks like a legitimate rcon command with the correct password
                                        char *s_ptr = s;
-                                       Con_Printf("server received rcon command from %s:\n", host_client ? host_client->name : addressstring2);
+                                       Con_Printf("server received %s command from %s: ", userlevel, host_client ? host_client->name : addressstring2);
                                        while(s_ptr != endpos)
                                        {
                                                size_t l = strlen(s_ptr);
@@ -2220,7 +2244,12 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat
                                        {
                                                size_t l = strlen(s);
                                                if(l)
+                                               {
+                                                       client_t *host_client_save = host_client;
                                                        Cmd_ExecuteString(s, src_command);
+                                                       host_client = host_client_save;
+                                                       // in case it is a command that changes host_client (like restart)
+                                               }
                                                s += l + 1;
                                        }
                                        rcon_redirect_buffer[rcon_redirect_bufferpos] = 0;