// will still contain its IP address, so get the address...
InfoString_GetValue(cls.userinfo, "*ip", temp, sizeof(temp));
if (temp[0])
- {
- // clear the rcon password, to prevent vulnerability by stuffcmd-ing a setinfo command to change *ip, then reconnect
- if(!rcon_secure.integer)
- Cvar_SetQuick(&rcon_password, "");
CL_EstablishConnection(temp);
- }
else
Con_Printf("Reconnect to what server? (you have not connected to a server yet)\n");
return;
{
int i, j;
qboolean valid_colors;
+ const char *newNameSource;
char newName[sizeof(host_client->name)];
if (Cmd_Argc () == 1)
{
- Con_Printf("\"name\" is \"%s\"\n", cl_name.string);
+ Con_Printf("name: %s\n", cl_name.string);
return;
}
if (Cmd_Argc () == 2)
- strlcpy (newName, Cmd_Argv(1), sizeof (newName));
+ newNameSource = Cmd_Argv(1);
else
- strlcpy (newName, Cmd_Args(), sizeof (newName));
+ newNameSource = Cmd_Args();
+
+ strlcpy(newName, newNameSource, sizeof(newName));
if (cmd_source == src_command)
{
Cvar_Set ("_cl_name", newName);
+ if (strlen(newNameSource) >= sizeof(newName)) // overflowed
+ {
+ Con_Printf("Your name is longer than %i chars! It has been truncated.\n", (int) (sizeof(newName) - 1));
+ Con_Printf("name: %s\n", cl_name.string);
+ }
return;
}
Cvar_Set ("deathmatch", "1");
}
+/*
+=====================
+Host_PQRcon_f
+
+ProQuake rcon support
+=====================
+*/
+void Host_PQRcon_f (void)
+{
+ int i;
+ lhnetaddress_t to;
+ lhnetsocket_t *mysocket;
+ char peer_address[64];
+
+ if (!rcon_password.string || !rcon_password.string[0] || rcon_secure.integer)
+ {
+ Con_Printf ("You must set rcon_password before issuing an pqrcon command, and rcon_secure must be 0.\n");
+ return;
+ }
+
+ for (i = 0;rcon_password.string[i];i++)
+ {
+ if (ISWHITESPACE(rcon_password.string[i]))
+ {
+ Con_Printf("rcon_password is not allowed to have any whitespace.\n");
+ return;
+ }
+ }
+
+ if (cls.netcon)
+ {
+ InfoString_GetValue(cls.userinfo, "*ip", peer_address, sizeof(peer_address));
+ }
+ else
+ {
+ if (!rcon_address.string[0])
+ {
+ Con_Printf ("You must either be connected, or set the rcon_address cvar to issue rcon commands\n");
+ return;
+ }
+ strlcpy(peer_address, rcon_address.string, strlen(rcon_address.string)+1);
+ }
+ LHNETADDRESS_FromString(&to, peer_address, sv_netport.integer);
+ mysocket = NetConn_ChooseClientSocketForAddress(&to);
+ if (mysocket)
+ {
+ SZ_Clear(&net_message);
+ MSG_WriteLong (&net_message, 0);
+ MSG_WriteByte (&net_message, CCREQ_RCON);
+ MSG_WriteString (&net_message, rcon_password.string);
+ MSG_WriteString (&net_message, Cmd_Args());
+ *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK));
+ NetConn_Write(mysocket, net_message.data, net_message.cursize, &to);
+ SZ_Clear (&net_message);
+ }
+}
+
//=============================================================================
// QuakeWorld commands
{
char buf[1500];
char argbuf[1500];
- dpsnprintf(argbuf, sizeof(argbuf), "%ld %s", (long) time(NULL), Cmd_Args());
+ dpsnprintf(argbuf, sizeof(argbuf), "%ld.%06d %s", (long) time(NULL), (int) (rand() % 1000000), Cmd_Args());
memcpy(buf, "\377\377\377\377srcon HMAC-MD4 TIME ", 24);
if(HMAC_MDFOUR_16BYTES((unsigned char *) (buf + 24), (unsigned char *) argbuf, strlen(argbuf), (unsigned char *) rcon_password.string, strlen(rcon_password.string)))
{
in = Cmd_Argv(2);
out = send+4;
- send[0] = send[1] = send[2] = send[3] = 0xff;
+ send[0] = send[1] = send[2] = send[3] = -1;
l = (int)strlen (in);
for (i=0 ; i<l ; i++)
Cvar_RegisterVariable (&rcon_password);
Cvar_RegisterVariable (&rcon_address);
Cvar_RegisterVariable (&rcon_secure);
- Cmd_AddCommand ("rcon", Host_Rcon_f, "sends a command to the server console (if your rcon_password matches the server's rcon_password), or to the address specified by rcon_address when not connected (again rcon_password must match the server's)");
- Cmd_AddCommand ("srcon", Host_Rcon_f, "sends a command to the server console (if your rcon_password matches the server's rcon_password), or to the address specified by rcon_address when not connected (again rcon_password must match the server's); this always works as if rcon_secure is set");
+ Cmd_AddCommand ("rcon", Host_Rcon_f, "sends a command to the server console (if your rcon_password matches the server's rcon_password), or to the address specified by rcon_address when not connected (again rcon_password must match the server's); note: if rcon_secure is set, client and server clocks must be synced e.g. via NTP");
+ Cmd_AddCommand ("srcon", Host_Rcon_f, "sends a command to the server console (if your rcon_password matches the server's rcon_password), or to the address specified by rcon_address when not connected (again rcon_password must match the server's); this always works as if rcon_secure is set; note: client and server clocks must be synced e.g. via NTP");
+ Cmd_AddCommand ("pqrcon", Host_PQRcon_f, "sends a command to a proquake server console (if your rcon_password matches the server's rcon_password), or to the address specified by rcon_address when not connected (again rcon_password must match the server's)");
Cmd_AddCommand ("user", Host_User_f, "prints additional information about a player number or name on the scoreboard");
Cmd_AddCommand ("users", Host_Users_f, "prints additional information about all players on the scoreboard");
Cmd_AddCommand ("fullserverinfo", Host_FullServerinfo_f, "internal use only, sent by server to client to update client's local copy of serverinfo string");