(svn r1527) -Add: RCon (Remote Connection). A server can set:

'set rcon_pw <password>'
  Which enables rcon. A client can now do:
    'rcon <password> "<command>"'
  The command will be executed on the server. (guru3)
-Fix: 'kick 1' did crash dedicated servers
-Fix: server password is now correctly saved

  !!Warning!!: do not give your rcon password to people you do not thrust!
pull/155/head
truelight 20 years ago
parent 561ceeba0c
commit 27929d129b

@ -11,6 +11,8 @@
#include <string.h>
#include "console.h"
#include "network.h"
#include "network_data.h"
#include "network_server.h"
#ifdef WIN32
#include <windows.h>
@ -372,6 +374,12 @@ void IConsolePrint(uint16 color_code, const char* string)
char* i;
int j;
if (_redirect_console_to_client != 0) {
/* Redirect the string to the client */
SEND_COMMAND(PACKET_SERVER_RCON)(NetworkFindClientStateFromIndex(_redirect_console_to_client), color_code, string);
return;
}
if (_network_dedicated) {
printf("%s\n", string);
return;

@ -379,6 +379,18 @@ DEF_CONSOLE_CMD(ConBanList)
return NULL;
}
DEF_CONSOLE_CMD(ConRcon)
{
if (argc < 3) {
IConsolePrint(_iconsole_color_default, "Usage: rcon <password> <command>");
return NULL;
}
SEND_COMMAND(PACKET_CLIENT_RCON)(argv[1], argv[2]);
return NULL;
}
DEF_CONSOLE_CMD(ConStatus)
{
const char *status;
@ -425,7 +437,7 @@ DEF_CONSOLE_CMD(ConKick)
if (argc == 2) {
uint32 index = atoi(argv[1]);
if (index == NETWORK_SERVER_INDEX && !_network_dedicated) {
if (index == NETWORK_SERVER_INDEX) {
IConsolePrint(_iconsole_color_default, "Silly boy, you can not kick yourself!");
return NULL;
}
@ -900,13 +912,14 @@ DEF_CONSOLE_CMD(ConSet) {
if (argc == 3) {
// Change server password
if (strncmp(argv[2], "*", NETWORK_PASSWORD_LENGTH) == 0) {
_network_game_info.server_password[0] = '\0';
_network_server_password[0] = '\0';
_network_game_info.use_password = 0;
} else {
ttd_strlcpy(_network_game_info.server_password, argv[2], sizeof(_network_game_info.server_password));
ttd_strlcpy(_network_server_password, argv[2], sizeof(_network_server_password));
_network_game_info.use_password = 1;
}
IConsolePrintF(_iconsole_color_warning, "Game-password changed to '%s'", _network_game_info.server_password);
IConsolePrintF(_iconsole_color_warning, "Game-password changed to '%s'", _network_server_password);
ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_game_info.server_password));
} else {
IConsolePrintF(_iconsole_color_default, "Current game-password is set to '%s'", _network_game_info.server_password);
IConsolePrint(_iconsole_color_warning, "Usage: set server_pw \"<password>\". Use * as <password> to set no password.");
@ -914,6 +927,28 @@ DEF_CONSOLE_CMD(ConSet) {
return NULL;
}
// setting the rcon password
if ((strcmp(argv[1], "rcon_pw") == 0) || (strcmp(argv[1], "rcon_password") == 0)) {
if (!_network_server) {
IConsolePrintF(_iconsole_color_error, "You are not the server");
return NULL;
}
if (argc == 3) {
// Change server password
if (strncmp(argv[2], "*", NETWORK_PASSWORD_LENGTH) == 0) {
_network_rcon_password[0] = '\0';
} else {
ttd_strlcpy(_network_rcon_password, argv[2], sizeof(_network_rcon_password));
}
IConsolePrintF(_iconsole_color_warning, "Rcon-password changed to '%s'", _network_rcon_password);
ttd_strlcpy(_network_game_info.rcon_password, _network_rcon_password, sizeof(_network_game_info.rcon_password));
} else {
IConsolePrintF(_iconsole_color_default, "Current rcon-password is set to '%s'", _network_game_info.rcon_password);
IConsolePrint(_iconsole_color_warning, "Usage: set rcon_pw \"<password>\". Use * as <password> to disable rcon.");
}
return NULL;
}
// setting the company password
if ((strcmp(argv[1],"company_pw") == 0) || (strcmp(argv[1],"company_password") == 0)) {
if (!_networking) {
@ -1123,6 +1158,7 @@ DEF_CONSOLE_CMD(ConSet) {
IConsolePrint(_iconsole_color_error, " - autoclean_unprotected <months>");
IConsolePrint(_iconsole_color_error, " - company_pw \"<password>\"");
IConsolePrint(_iconsole_color_error, " - name \"<playername>\"");
IConsolePrint(_iconsole_color_error, " - rcon_pw \"<password>\"");
IConsolePrint(_iconsole_color_error, " - server_name \"<name>\"");
IConsolePrint(_iconsole_color_error, " - server_advertise on/off");
IConsolePrint(_iconsole_color_error, " - server_bind_ip <ip>");
@ -1229,6 +1265,9 @@ void IConsoleStdLibRegister(void)
IConsoleCmdHook("status", ICONSOLE_HOOK_ACCESS, ConCmdHookNoNetClient);
IConsoleCmdHook("resetengines", ICONSOLE_HOOK_ACCESS, ConCmdHookNoNetwork);
IConsoleCmdRegister("rcon", ConRcon);
IConsoleCmdHook("rcon", ICONSOLE_HOOK_ACCESS, ConCmdHookNeedNetwork);
IConsoleCmdRegister("ban", ConBan);
IConsoleCmdHook("ban", ICONSOLE_HOOK_ACCESS, ConCmdHookNoNetClient);
IConsoleCmdRegister("unban", ConUnBan);

@ -927,6 +927,8 @@ static void NetworkInitGameInfo(void)
NetworkClientInfo *ci;
ttd_strlcpy(_network_game_info.server_name, _network_server_name, sizeof(_network_game_info.server_name));
ttd_strlcpy(_network_game_info.server_password, _network_server_password, sizeof(_network_server_password));
ttd_strlcpy(_network_game_info.rcon_password, _network_rcon_password, sizeof(_network_rcon_password));
if (_network_game_info.server_name[0] == '\0')
snprintf(_network_game_info.server_name, sizeof(_network_game_info.server_name), "Unnamed Server");

@ -42,12 +42,15 @@
#define NETWORK_VEHICLE_TYPES 5
#define NETWORK_STATION_TYPES 5
#define NETWORK_NAME_LENGTH 80
#define NETWORK_HOSTNAME_LENGTH 80
#define NETWORK_REVISION_LENGTH 10
#define NETWORK_PASSWORD_LENGTH 20
#define NETWORK_PLAYERS_LENGTH 200
#define NETWORK_CLIENT_NAME_LENGTH 25
enum {
NETWORK_NAME_LENGTH = 80,
NETWORK_HOSTNAME_LENGTH = 80,
NETWORK_REVISION_LENGTH = 10,
NETWORK_PASSWORD_LENGTH = 20,
NETWORK_PLAYERS_LENGTH = 200,
NETWORK_CLIENT_NAME_LENGTH = 25,
NETWORK_RCONCOMMAND_LENGTH = 500,
};
// This is the struct used by both client and server
// some fields will be empty on the client (like game_password) by default
@ -71,6 +74,7 @@ typedef struct NetworkGameInfo {
uint16 map_height; // Map height
byte map_set; // Graphical set
bool dedicated; // Is this a dedicated server?
char rcon_password[NETWORK_PASSWORD_LENGTH]; // RCon password for the server. "" if rcon is disabled
} NetworkGameInfo;
typedef struct NetworkPlayerInfo {
@ -155,6 +159,10 @@ VARDEF uint32 _network_server_bind_ip;
VARDEF char _network_server_bind_ip_host[NETWORK_HOSTNAME_LENGTH];
VARDEF bool _is_network_server; // Does this client wants to be a network-server?
VARDEF char _network_server_name[NETWORK_NAME_LENGTH];
VARDEF char _network_server_password[NETWORK_PASSWORD_LENGTH];
VARDEF char _network_rcon_password[NETWORK_PASSWORD_LENGTH];
VARDEF uint16 _redirect_console_to_client;
VARDEF uint16 _network_sync_freq;
VARDEF uint8 _network_frame_freq;

@ -10,6 +10,7 @@
#include "gfx.h"
#include "window.h"
#include "settings.h"
#include "console.h"
// This file handles all the client-commands
@ -246,6 +247,14 @@ DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_QUIT)(const char *leavemsg)
NetworkSend_Packet(p, MY_CLIENT);
}
DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_RCON)(const char *pass, const char *command)
{
Packet *p = NetworkSend_Init(PACKET_CLIENT_RCON);
NetworkSend_string(p, pass);
NetworkSend_string(p, command);
NetworkSend_Packet(p, MY_CLIENT);
}
// **********
// Receiving functions
@ -741,6 +750,18 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEWGAME)
return NETWORK_RECV_STATUS_SERVER_ERROR;
}
DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_RCON)
{
char rcon_out[NETWORK_RCONCOMMAND_LENGTH];
uint16 color_code;
color_code = NetworkRecv_uint16(MY_CLIENT, p);
NetworkRecv_string(MY_CLIENT, p, rcon_out, sizeof(rcon_out));
IConsolePrint(color_code, rcon_out);
return NETWORK_RECV_STATUS_OKAY;
}
@ -782,6 +803,8 @@ static NetworkClientPacket* const _network_client_packet[] = {
RECEIVE_COMMAND(PACKET_SERVER_ERROR_QUIT),
RECEIVE_COMMAND(PACKET_SERVER_SHUTDOWN),
RECEIVE_COMMAND(PACKET_SERVER_NEWGAME),
RECEIVE_COMMAND(PACKET_SERVER_RCON),
NULL, /*PACKET_CLIENT_RCON,*/
};
// If this fails, check the array above with network_data.h

@ -13,6 +13,7 @@ DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_PASSWORD)(NetworkPasswordType type,
DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_PASSWORD)(const char *password);
DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_NAME)(const char *name);
DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_ACK);
DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_RCON)(const char *pass, const char *command);
NetworkRecvStatus NetworkClient_ReadPackets(NetworkClientState *cs);
void NetworkClient_Connected(void);

@ -160,6 +160,8 @@ typedef enum {
PACKET_SERVER_ERROR_QUIT,
PACKET_SERVER_SHUTDOWN,
PACKET_SERVER_NEWGAME,
PACKET_SERVER_RCON,
PACKET_CLIENT_RCON,
PACKET_END // Should ALWAYS be on the end of this list!! (period)
} PacketType;

@ -566,6 +566,15 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_NEWGAME)
NetworkSend_Packet(p, cs);
}
DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkClientState *cs, uint16 color, const char *command)
{
Packet *p = NetworkSend_Init(PACKET_SERVER_RCON);
NetworkSend_uint16(p, color);
NetworkSend_string(p, command);
NetworkSend_Packet(p, cs);
}
// **********
// Receiving functions
// DEF_SERVER_RECEIVE_COMMAND has parameter: NetworkClientState *cs, Packet *p
@ -1082,6 +1091,30 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_SET_NAME)
}
}
DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_RCON)
{
char pass[NETWORK_PASSWORD_LENGTH];
char command[NETWORK_RCONCOMMAND_LENGTH];
if (_network_game_info.rcon_password[0] == '\0')
return;
NetworkRecv_string(cs, p, pass, sizeof(pass));
NetworkRecv_string(cs, p, command, sizeof(command));
if (strncmp(pass, _network_game_info.rcon_password, sizeof(pass)) != 0) {
DEBUG(net, 0)("[RCon] Wrong password from client-id %d", cs->index);
return;
}
DEBUG(net, 0)("[RCon] Client-id %d executed: %s", cs->index, command);
_redirect_console_to_client = cs->index;
IConsoleCmdExec(command);
_redirect_console_to_client = 0;
return;
}
// The layout for the receive-functions by the server
typedef void NetworkServerPacket(NetworkClientState *cs, Packet *p);
@ -1121,6 +1154,8 @@ static NetworkServerPacket* const _network_server_packet[] = {
NULL, /*PACKET_SERVER_ERROR_QUIT,*/
NULL, /*PACKET_SERVER_SHUTDOWN,*/
NULL, /*PACKET_SERVER_NEWGAME,*/
NULL, /*PACKET_SERVER_RCON,*/
RECEIVE_COMMAND(PACKET_CLIENT_RCON),
};
// If this fails, check the array above with network_data.h

@ -8,6 +8,7 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR_QUIT)(NetworkClientState *cs,
DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientState *cs, NetworkErrorCode error);
DEF_SERVER_SEND_COMMAND(PACKET_SERVER_SHUTDOWN);
DEF_SERVER_SEND_COMMAND(PACKET_SERVER_NEWGAME);
DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_RCON)(NetworkClientState *cs, uint16 color, const char *command);
bool NetworkFindName(char new_name[NETWORK_NAME_LENGTH]);
void NetworkServer_HandleChat(NetworkAction action, DestType desttype, int dest, const char *msg, uint16 from_index);

@ -759,7 +759,8 @@ static const SettingDesc network_settings[] = {
{"server_advertise",SDT_BOOL, (void*)false, &_network_advertise, NULL},
{"lan_internet", SDT_UINT8, (void*)0, &_network_lan_internet, NULL},
{"player_name", SDT_STRINGBUF | (lengthof(_network_player_name) << 16), NULL, &_network_player_name, NULL},
{"server_password", SDT_STRINGBUF | (lengthof(_network_game_info.server_password) << 16), NULL, &_network_game_info.server_password, NULL},
{"server_password", SDT_STRINGBUF | (lengthof(_network_server_password) << 16), NULL, &_network_server_password, NULL},
{"rcon_password", SDT_STRINGBUF | (lengthof(_network_rcon_password) << 16), NULL, &_network_rcon_password, NULL},
{"server_name", SDT_STRINGBUF | (lengthof(_network_server_name) << 16), NULL, &_network_server_name, NULL},
{"connect_to_ip", SDT_STRINGBUF | (lengthof(_network_default_ip) << 16), NULL, &_network_default_ip, NULL},
{"network_id", SDT_STRINGBUF | (lengthof(_network_unique_id) << 16), NULL, &_network_unique_id, NULL},

Loading…
Cancel
Save