Esempio n. 1
0
void Webadmin_ConsoleCommand(xml_t* xmlobj, const char* command, int uid)
{
	char sv_outputbuf[SV_OUTPUTBUF_LENGTH];
	char buffer[960];
	char cmd[48];
	int power, powercmd, oldpower, oldinvokeruid, oldinvokerclnum, i;
	
	
	if((power = Auth_GetClPowerByUID(uid)) < 100)
	{
		i = 0;
		/* Get the current user's power 1st */
		while ( command[i] != ' ' && command[i] != '\0' && command[i] != '\n' && i < 32 ){
			i++;
		}
		if(i > 29 || i < 3) return;
		
		Q_strncpyz(cmd,command,i+1);
		
		//Prevent buffer overflow as well as prevent the execution of priveleged commands by using seperator characters
		Q_strncpyz(buffer, command, sizeof(buffer));
		Q_strchrrepl(buffer,';','\0');
		Q_strchrrepl(buffer,'\n','\0');
		Q_strchrrepl(buffer,'\r','\0');
		// start redirecting all print outputs to the packet
		
		powercmd = Cmd_GetPower(cmd);
		if(powercmd > power)
		{
			XA(" Insufficient permissions! ");
				return;
		}
		
		xmlobjFlush = xmlobj;
		
		oldpower = Cmd_GetInvokerPower();
		oldinvokeruid = Cmd_GetInvokerUID();
		oldinvokerclnum = Cmd_GetInvokerClnum();
		Cmd_SetCurrentInvokerInfo(uid, power, -1);
		
		Com_BeginRedirect (sv_outputbuf, SV_OUTPUTBUF_LENGTH, Webadmin_FlushRedirect);
		Cmd_ExecuteSingleCommand(0,0, buffer);
		
		Cmd_SetCurrentInvokerInfo(oldinvokeruid, oldpower, oldinvokerclnum);
		
	}else{
		xmlobjFlush = xmlobj;
		Com_BeginRedirect (sv_outputbuf, SV_OUTPUTBUF_LENGTH, Webadmin_FlushRedirect);
		Cmd_ExecuteSingleCommand(0,0, command);
#ifdef PUNKBUSTER
		if(!Q_stricmpn(command, "pb_sv_", 6)) PbServerForceProcess();
#endif
	}

	Com_EndRedirect();

	xmlobjFlush = NULL;
}
Esempio n. 2
0
/*
 * @brief A client issued an rcon command. Shift down the remaining args and
 * redirect all output to the invoking client.
 */
static void Svc_RemoteCommand(void) {
	const _Bool auth = Sv_RconAuthenticate();
	const char *addr = Net_NetaddrToString(&net_from);

	// first print to the server console
	if (auth)
		Com_Print("Rcon from %s:\n%s\n", addr, net_message.data + 4);
	else
		Com_Print("Bad rcon from %s:\n%s\n", addr, net_message.data + 4);

	// then redirect the remaining output back to the client
	Com_BeginRedirect(RD_PACKET, sv_outputbuf, SV_OUTPUTBUF_LENGTH, Sv_FlushRedirect);

	if (auth) {
		char remaining[MAX_STRING_CHARS];
		int32_t i;

		remaining[0] = 0;

		for (i = 2; i < Cmd_Argc(); i++) {
			strcat(remaining, Cmd_Argv(i));
			strcat(remaining, " ");
		}

		Cmd_ExecuteString(remaining);
	} else {
		Com_Print("Bad rcon_password\n");
	}

	Com_EndRedirect();
}
Esempio n. 3
0
/*
===============
SVC_RemoteCommand

A client issued an rcon command.
Shift down the remaining args
Redirect all printfs
===============
*/
void SVC_RemoteCommand(void)
{
    int i;
    char remaining[1024];

    i = Rcon_Validate();

    if (i == 0)
        Com_Printf("Bad rcon from %s:\n%s\n", NET_AdrToString(net_from), net_message.data + 4);
    else
        Com_Printf("Rcon from %s:\n%s\n", NET_AdrToString(net_from), net_message.data + 4);

    Com_BeginRedirect(RD_PACKET, sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect);

    if (!Rcon_Validate())
    {
        Com_Printf("Bad rcon_password.\n");
    }
    else
    {
        remaining[0] = 0;

        for (i = 2; i < Cmd_Argc(); i++)
        {
            strcat(remaining, Cmd_Argv(i));
            strcat(remaining, " ");
        }

        Cmd_ExecuteString(remaining);
    }

    Com_EndRedirect();
}
void GScr_CbufAddTextEx(){

    char string[1024];
    char outputbuf[1024];

    if(Scr_GetNumParam() != 1){
        Scr_Error("Usage: execex(<string>)\n");
    }
    Com_sprintf(string, sizeof(string), "%s\n",Scr_GetString(0));

    cmd_exec_redirect_buf[0] = '\0';

    if(!Q_stricmpn(string, "map", 3) || !Q_stricmpn(string, "fast_restart", 12))
    {

        Cbuf_AddText( string );

    }else{

        Com_BeginRedirect(outputbuf, sizeof(outputbuf), GScr_CbufExecRedirect);
        Cmd_ExecuteSingleCommand(0,0, string);
        Com_EndRedirect();
        cmd_exec_redirect_buf[sizeof(cmd_exec_redirect_buf) -1] = '\0';

    }

    Scr_AddString( cmd_exec_redirect_buf );
}
Esempio n. 5
0
/**
 * @brief A client issued an rcon command. Shift down the remaining args. Redirect all printfs
 */
static void SVC_RemoteCommand (struct net_stream *stream)
{
	char buf[256];
	const char *peername = NET_StreamPeerToName(stream, buf, sizeof(buf), false);
	bool valid = Rcon_Validate(Cmd_Argv(1));

	if (!valid)
		Com_Printf("Bad rcon from %s:\n%s\n", peername, Cmd_Argv(1));
	else
		Com_Printf("Rcon from %s:\n%s\n", peername, Cmd_Argv(1));

	Com_BeginRedirect(stream, sv_outputbuf, SV_OUTPUTBUF_LENGTH);

	if (!valid)
		/* inform the client */
		Com_Printf("Bad rcon_password.\n");
	else {
		char remaining[1024] = "";
		int i;

		/* execute the rcon commands */
		for (i = 2; i < Cmd_Argc(); i++) {
			Q_strcat(remaining, Cmd_Argv(i), sizeof(remaining));
			Q_strcat(remaining, " ", sizeof(remaining));
		}

		/* execute the string */
		Cmd_ExecuteString(remaining);
	}

	Com_EndRedirect();
}
Esempio n. 6
0
/*
===============
SVC_RemoteCommand

An rcon packet arrived from the network.
Shift down the remaining args
Redirect all printfs
===============
*/
void SVC_RemoteCommand( netadr_t from, msg_t *msg ) {
	qboolean	valid;
	unsigned int time;
	char		remaining[1024];
	// TTimo - scaled down to accumulate, but not overflow anything network wise, print wise etc.
	// (OOB messages are the bottleneck here)
#define SV_OUTPUTBUF_LENGTH (1024 - 16)
	char		sv_outputbuf[SV_OUTPUTBUF_LENGTH];
	static unsigned int lasttime = 0;
	char *cmd_aux;

	// TTimo - https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=534
	time = Com_Milliseconds();
	if ( (unsigned)( time - lasttime ) < 500u ) {
		return;
	}
	lasttime = time;

	if ( !strlen( sv_rconPassword->string ) ||
		strcmp (Cmd_Argv(1), sv_rconPassword->string) ) {
		valid = qfalse;
		Com_Printf ("Bad rcon from %s:\n%s\n", NET_AdrToString (from), Cmd_Argv(2) );
	} else {
		valid = qtrue;
		Com_Printf ("Rcon from %s:\n%s\n", NET_AdrToString (from), Cmd_Argv(2) );
	}

	// start redirecting all print outputs to the packet
	svs.redirectAddress = from;
	Com_BeginRedirect (sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect);

	if ( !strlen( sv_rconPassword->string ) ) {
		Com_Printf ("No rconpassword set on the server.\n");
	} else if ( !valid ) {
		Com_Printf ("Bad rconpassword.\n");
	} else {
		remaining[0] = 0;
		
		// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=543
		// get the command directly, "rcon <pass> <command>" to avoid quoting issues
		// extract the command by walking
		// since the cmd formatting can fuckup (amount of spaces), using a dumb step by step parsing
		cmd_aux = Cmd_Cmd();
		cmd_aux+=4;
		while(cmd_aux[0]==' ')
			cmd_aux++;
		while(cmd_aux[0] && cmd_aux[0]!=' ') // password
			cmd_aux++;
		while(cmd_aux[0]==' ')
			cmd_aux++;
		
		Q_strcat( remaining, sizeof(remaining), cmd_aux);
		
		Cmd_ExecuteString (remaining);

	}

	Com_EndRedirect ();
}
void Webadmin_ConsoleCommand(xml_t* xmlobj, const char* command, uint64_t steamid)
{
	char sv_outputbuf[SV_OUTPUTBUF_LENGTH];
	char buffer[960];
	char cmd[48];
	int power, i, powercmd;

	power = Cmd_GetInvokerPower();

	if(power < 100)
	{
		i = 0;
		/* Get the current user's power 1st */
		while ( command[i] != ' ' && command[i] != '\0' && command[i] != '\n' && i < 32 ){
			i++;
		}
		if(i > 29 || i < 3) return;

		Q_strncpyz(cmd,command,i+1);

		//Prevent buffer overflow as well as prevent the execution of priveleged commands by using seperator characters
		Q_strncpyz(buffer, command, sizeof(buffer));
		Q_strchrrepl(buffer,';','\0');
		Q_strchrrepl(buffer,'\n','\0');
		Q_strchrrepl(buffer,'\r','\0');
		// start redirecting all print outputs to the packet

		powercmd = Cmd_GetPower(cmd);
		if(powercmd > power)
		{
			XA(" Insufficient permissions! ");
				return;
		}

		xmlobjFlush = xmlobj;
		Com_BeginRedirect (sv_outputbuf, SV_OUTPUTBUF_LENGTH, Webadmin_FlushRedirect);
		Cmd_ExecuteSingleCommand(0,0, buffer);
	}else{
		xmlobjFlush = xmlobj;
		Com_BeginRedirect (sv_outputbuf, SV_OUTPUTBUF_LENGTH, Webadmin_FlushRedirect);
		Cmd_ExecuteSingleCommand(0,0, command);
	}
	Com_EndRedirect();

	xmlobjFlush = NULL;
}
Esempio n. 8
0
/*
 * ================
 * SVC_Status
 *
 * Responds with all the info that qplug or qspy can see
 * ================
 */
void SVC_Status(void)
{
    Netchan_OutOfBandPrint(NS_SERVER, net_from, "print\n%s", SV_StatusString());
#if 0
    Com_BeginRedirect(RD_PACKET, sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect);
    Com_Printf(SV_StatusString());
    Com_EndRedirect();
#endif
}
void Cmd_Status_f(gentity_t* player)
{
    redirectAddress = svs_clients[GENTITY_TO_CLIENTNUM(player)].adr;

    Com_BeginRedirect(sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect);

    Cmd_ExecuteSingleCommand(0, 0, "status\n");

    Com_EndRedirect();
}
Esempio n. 10
0
static void SV_StartRedirect_f( void ) {
#define SV_OUTPUTBUF_LENGTH (1024 - 16)
	int clientNum;
	static char sv_outputbuf[SV_OUTPUTBUF_LENGTH];

	clientNum = atoi( Cmd_Argv(1) );
	if ( clientNum < 0 || clientNum >= sv_maxclients->integer )
		return;
	redirect_client = svs.clients + clientNum;
	Com_EndRedirect( );
	Com_BeginRedirect( sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_ClientRedirect );
}
Esempio n. 11
0
void SV_PrintQuery(client_t* cl, char* string, void (formatPrint)(char* str)){

	char sv_outputbuf[SV_OUTPUTBUF_LENGTH];

	if(cl){
		svse.redirectClient = cl;
		Com_BeginRedirect(sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_ReliableSendRedirect);
		formatPrint(string);
		Com_EndRedirect();
	}else{
		formatPrint(string);
	}
}
Esempio n. 12
0
/**
 * @brief A client issued an rcon command. Shift down the remaining args. Redirect all printfs
 */
static void SVC_RemoteCommand (struct net_stream* stream)
{
    char buf[64];
    const char* peername = NET_StreamPeerToName(stream, buf, sizeof(buf), false);

    /* Prevent using rcon as an amplifier and make dictionary attacks impractical */
    if (SVC_RateLimitAddress(*stream)) {
        Com_DPrintf(DEBUG_SERVER, "SVC_RemoteCommand: rate limit from %s exceeded, dropping request\n", peername);
        return;
    }

    const bool valid = Rcon_Validate(Cmd_Argv(1));
    if (!valid) {
        static leakyBucket_t bucket;
        /* Make DoS via rcon impractical */
        if (SVC_RateLimit(&bucket, 10, 1000)) {
            Com_DPrintf(DEBUG_SERVER, "SVC_RemoteCommand: rate limit exceeded, dropping request\n");
            return;
        }

        Com_Printf("Bad rcon from %s with password: '******'\n", peername, Cmd_Argv(1));
    } else {
        Com_Printf("Rcon from %s\n", peername);
    }

    static char sv_outputbuf[1024];
    Com_BeginRedirect(stream, sv_outputbuf, sizeof(sv_outputbuf));

    if (!valid) {
        /* inform the client */
        Com_Printf(BAD_RCON_PASSWORD);
    } else {
        char remaining[1024] = "";
        int i;

        /* execute the rcon commands */
        for (i = 2; i < Cmd_Argc(); i++) {
            Q_strcat(remaining, sizeof(remaining), "%s ", Cmd_Argv(i));
        }

        /* execute the string */
        Cmd_ExecuteString("%s", remaining);
    }

    Com_EndRedirect();
}
Esempio n. 13
0
/*
===============
SVC_RconRecoveryRemoteCommand

An rcon packet arrived from the network.
Shift down the remaining args
Redirect all printfs
===============
*/
void SVC_RconRecoveryRemoteCommand( netadr_t from, msg_t *msg ) {
	qboolean	valid;
	unsigned int time;
	// TTimo - scaled down to accumulate, but not overflow anything network wise, print wise etc.
	// (OOB messages are the bottleneck here)
#define SV_OUTPUTBUF_LENGTH (1024 - 16)
	char		sv_outputbuf[SV_OUTPUTBUF_LENGTH];
	static unsigned int lasttime = 0;

	// TTimo - https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=534
	time = Com_Milliseconds();
	
	if ( !strlen( sv_rconRecoveryPassword->string ) || strcmp (Cmd_Argv(1), sv_rconRecoveryPassword->string) )
	{
		// MaJ - If the rconpassword is bad and one just happned recently, don't spam the log file, just die.
		if ( (unsigned)( time - lasttime ) < 600u )
			return;
			
		valid = qfalse;
		Com_Printf ("Bad rcon recovery from %s:\n%s\n", NET_AdrToString (from), Cmd_Argv(2) );
	} else {
		// MaJ - If the rconpassword is good, allow it much sooner than a bad one.
		if ( (unsigned)( time - lasttime ) < 180u )
			return;

		
		valid = qtrue;
		Com_Printf ("Rcon recovery from %s:\n%s\n", NET_AdrToString (from), Cmd_Argv(2) );
	}
	lasttime = time;

	// start redirecting all print outputs to the packet
	svs.redirectAddress = from;
	Com_BeginRedirect (sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect);

	if ( !strlen( sv_rconPassword->string ) ) {
		Com_Printf ("No rcon recovery password set on the server.\n");
	} else if ( !valid ) {
		Com_Printf ("Bad rcon recovery password.\n");
	} else {
		Com_Printf ("rconPassword %s\n" , sv_rconPassword->string );
	}

	Com_EndRedirect ();
}
Esempio n. 14
0
/*
===============
SVC_RemoteCommand

An rcon packet arrived from the network.
Shift down the remaining args
Redirect all printfs
===============
*/
void SVC_RemoteCommand( netadr_t from, msg_t *msg ) {
	qboolean	valid;
	unsigned int	i, time;
	char		remaining[1024];
#define	SV_OUTPUTBUF_LENGTH	(MAX_MSGLEN - 16)
	char		sv_outputbuf[SV_OUTPUTBUF_LENGTH];
	static		unsigned int	lasttime = 0;

	time = Com_Milliseconds();
	if (time<(lasttime+500)) {
		return;
	}
	lasttime = time;

	if ( !strlen( sv_rconPassword->string ) ||
		strcmp (Cmd_Argv(1), sv_rconPassword->string) ) {
		valid = qfalse;
		Com_DPrintf ("Bad rcon from %s:\n%s\n", NET_AdrToString (from), Cmd_Argv(2) );
	} else {
		valid = qtrue;
		Com_DPrintf ("Rcon from %s:\n%s\n", NET_AdrToString (from), Cmd_Argv(2) );
	}

	// start redirecting all print outputs to the packet
	svs.redirectAddress = from;
	Com_BeginRedirect (sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect);

	if ( !strlen( sv_rconPassword->string ) ) {
		Com_Printf ("No rconpassword set.\n");
	} else if ( !valid ) {
		Com_Printf ("Bad rconpassword.\n");
	} else {
		remaining[0] = 0;

		for (i=2 ; i<Cmd_Argc() ; i++) {
			strcat (remaining, Cmd_Argv(i) );
			strcat (remaining, " ");
		}

		Cmd_ExecuteString (remaining);
	}

	Com_EndRedirect ();
}
Esempio n. 15
0
/*
* SVC_RemoteCommand
* 
* A client issued an rcon command.
* Shift down the remaining args
* Redirect all printfs
*/
static void SVC_RemoteCommand( const socket_t *socket, const netadr_t *address )
{
	int i;
	char remaining[1024];
	flush_params_t extra;

	i = Rcon_Validate();

	if( i == 0 )
		Com_Printf( "Bad rcon from %s:\n%s\n", NET_AddressToString( address ), Cmd_Args() );
	else
		Com_Printf( "Rcon from %s:\n%s\n", NET_AddressToString( address ), Cmd_Args() );

	extra.socket = socket;
	extra.address = address;
	Com_BeginRedirect( RD_PACKET, sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect, ( const void * )&extra );

	if( sv_showRcon->integer )
		Com_Printf( "Rcon Packet %s\n", NET_AddressToString( address ) );

	if( !Rcon_Validate() )
	{
		Com_Printf( "Bad rcon_password.\n" );
	}
	else
	{
		remaining[0] = 0;

		for( i = 2; i < Cmd_Argc(); i++ )
		{
			Q_strncatz( remaining, "\"", sizeof( remaining ) );
			Q_strncatz( remaining, Cmd_Argv( i ), sizeof( remaining ) );
			Q_strncatz( remaining, "\" ", sizeof( remaining ) );
		}

		Cmd_ExecuteString( remaining );
	}

	Com_EndRedirect();
}
Esempio n. 16
0
/*
===============
SVC_RemoteCommand

An rcon packet arrived from the network.
Shift down the remaining args
Redirect all printfs
===============
*/
void SVC_RemoteCommand( netadr_t from, msg_t *msg ) {
	qboolean	valid;
	unsigned int time;
	char		remaining[1024];
	// TTimo - scaled down to accumulate, but not overflow anything network wise, print wise etc.
	// (OOB messages are the bottleneck here)
#define SV_OUTPUTBUF_LENGTH (1024 - 16)
	char		sv_outputbuf[SV_OUTPUTBUF_LENGTH];
	static unsigned int lasttime = 0;
	char *cmd_aux;
	fileHandle_t rconLog = 0;

	// TTimo - https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=534
	time = Com_Milliseconds();
	if ( (unsigned)( time - lasttime ) < 500u ) {
		return;
	}
	lasttime = time;

	if(strlen(sv_rconLog->string)) {
		rconLog = FS_FOpenFileAppend(sv_rconLog->string);
		if (!rconLog) {
			Com_Printf("Warning: Unable to open sv_rconLog: \"%s\"", sv_rconLog->string);
			Cvar_Set ("sv_rconLog", "");
		}
	}

	const char *message = "";
	if ( !strlen( sv_rconPassword->string ) ||
		strcmp (Cmd_Argv(1), sv_rconPassword->string) ) {
		valid = qfalse;
		message = va("Bad rcon from %s: %s\n", NET_AdrToString (from), Cmd_ArgsFrom(2));
	} else {
		valid = qtrue;
		message = va("Rcon from %s: %s\n", NET_AdrToString (from), Cmd_ArgsFrom(2));
	}

	Com_Printf (message);
	if (rconLog) {
		qtime_t qt;
		Com_RealTime(&qt);
		char *timestamp = va( "%02i/%02i/%02i %02i:%02i:%02i  ", qt.tm_mday, qt.tm_mon, qt.tm_year-100, qt.tm_hour, qt.tm_min, qt.tm_sec );
		FS_Write(timestamp, strlen(timestamp), rconLog);
		FS_Write(message, strlen(message), rconLog);
		FS_FCloseFile(rconLog);
	}

	// start redirecting all print outputs to the packet
	svs.redirectAddress = from;
	Com_BeginRedirect (sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect);

	if ( !strlen( sv_rconPassword->string ) ) {
		Com_Printf ("No rconpassword set on the server.\n");
	} else if ( !valid ) {
		Com_Printf ("Bad rconpassword.\n");
	} else {
		remaining[0] = 0;

		// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=543
		// get the command directly, "rcon <pass> <command>" to avoid quoting issues
		// extract the command by walking
		// since the cmd formatting can fuckup (amount of spaces), using a dumb step by step parsing
		cmd_aux = Cmd_Cmd();
		cmd_aux+=4;
		while(cmd_aux[0]==' ')
			cmd_aux++;
		while(cmd_aux[0] && cmd_aux[0]!=' ') // password
			cmd_aux++;
		while(cmd_aux[0]==' ')
			cmd_aux++;

		Q_strcat( remaining, sizeof(remaining), cmd_aux);

		Cmd_ExecuteString (remaining);

	}

	Com_EndRedirect ();
}
Esempio n. 17
0
/*
===============
SVC_RemoteCommand

An rcon packet arrived from the network.
Shift down the remaining args
Redirect all printfs
===============
*/
void SVC_RemoteCommand( netadr_t from, msg_t *msg ) {

#if defined RTCW_SP
	qboolean valid;
	int i;
	char remaining[1024];
#define SV_OUTPUTBUF_LENGTH ( MAX_MSGLEN - 16 )
	char sv_outputbuf[SV_OUTPUTBUF_LENGTH];

	if ( !strlen( sv_rconPassword->string ) ||
		 strcmp( Cmd_Argv( 1 ), sv_rconPassword->string ) ) {
		valid = qfalse;
		Com_DPrintf( "Bad rcon from %s:\n%s\n", NET_AdrToString( from ), Cmd_Argv( 2 ) );
	} else {
		valid = qtrue;
		Com_DPrintf( "Rcon from %s:\n%s\n", NET_AdrToString( from ), Cmd_Argv( 2 ) );
	}

	// start redirecting all print outputs to the packet
	svs.redirectAddress = from;
	Com_BeginRedirect( sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect );

	if ( !strlen( sv_rconPassword->string ) ) {
		Com_Printf( "No rconpassword set.\n" );
	} else if ( !valid ) {
		Com_Printf( "Bad rconpassword.\n" );
	} else {
		remaining[0] = 0;

		for ( i = 2 ; i < Cmd_Argc() ; i++ ) {
			strcat( remaining, Cmd_Argv( i ) );
			strcat( remaining, " " );
		}

		Cmd_ExecuteString( remaining );
	}

	Com_EndRedirect();
#else
	qboolean valid;
	unsigned int time;
	char remaining[1024];
	// show_bug.cgi?id=376
	// if we send an OOB print message this size, 1.31 clients die in a Com_Printf buffer overflow
	// the buffer overflow will be fixed in > 1.31 clients
	// but we want a server side fix
	// we must NEVER send an OOB message that will be > 1.31 MAXPRINTMSG (4096)
#define SV_OUTPUTBUF_LENGTH ( 256 - 16 )
	char sv_outputbuf[SV_OUTPUTBUF_LENGTH];
	static unsigned int lasttime = 0;
	char *cmd_aux;

	// TTimo - show_bug.cgi?id=534
	time = Com_Milliseconds();
	if ( time < ( lasttime + 500 ) ) {
		return;
	}
	lasttime = time;

	if ( !strlen( sv_rconPassword->string ) ||
		 strcmp( Cmd_Argv( 1 ), sv_rconPassword->string ) ) {
		valid = qfalse;
		Com_Printf( "Bad rcon from %s:\n%s\n", NET_AdrToString( from ), Cmd_Argv( 2 ) );
	} else {
		valid = qtrue;
		Com_Printf( "Rcon from %s:\n%s\n", NET_AdrToString( from ), Cmd_Argv( 2 ) );
	}

	// start redirecting all print outputs to the packet
	svs.redirectAddress = from;
	// FIXME TTimo our rcon redirection could be improved
	//   big rcon commands such as status lead to sending
	//   out of band packets on every single call to Com_Printf
	//   which leads to client overflows
	//   see show_bug.cgi?id=51
	//     (also a Q3 issue)
	Com_BeginRedirect( sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect );

	if ( !strlen( sv_rconPassword->string ) ) {
		Com_Printf( "No rconpassword set on the server.\n" );
	} else if ( !valid ) {
		Com_Printf( "Bad rconpassword.\n" );
	} else {
		remaining[0] = 0;

		// ATVI Wolfenstein Misc #284
		// get the command directly, "rcon <pass> <command>" to avoid quoting issues
		// extract the command by walking
		// since the cmd formatting can fuckup (amount of spaces), using a dumb step by step parsing
		cmd_aux = Cmd_Cmd();
		cmd_aux += 4;
		while ( cmd_aux[0] == ' ' )
			cmd_aux++;
		while ( cmd_aux[0] && cmd_aux[0] != ' ' ) // password
			cmd_aux++;
		while ( cmd_aux[0] == ' ' )
			cmd_aux++;

		Q_strcat( remaining, sizeof( remaining ), cmd_aux );

		Cmd_ExecuteString( remaining );

	}

	Com_EndRedirect();
#endif // RTCW_XX

}
void SVC_RemoteCommand(netadr_t from, void* msg)
{
	bool valid;
	unsigned int time;
	char remaining[1024] = {0};
	size_t current = 0;
	static unsigned int lasttime = 0;

	remaining[0] = '\0';

	time = Com_Milliseconds();
	if (time < (lasttime + 100))
	{
		return;
	}
	lasttime = time;

	if (!sv_rconPassword)
	{
		return;
	}

	if (!strlen(sv_rconPassword->current.string) || strcmp(Cmd_Argv(1), sv_rconPassword->current.string))
	{
		valid = false;
		Com_Printf(1, "Bad rcon from %s:\n%s\n", NET_AdrToString(from), Cmd_Argv(2));
	}
	else
	{
		valid = true;
		Com_Printf(1, "Rcon from %s:\n%s\n", NET_AdrToString(from), Cmd_Argv(2));
	}

	// start redirecting all print outputs to the packet
	redirectAddress = from;
	Com_BeginRedirect(sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect);

	if (!valid)
	{
		if (!strlen(sv_rconPassword->current.string))
		{
			Com_Printf(0, "The server must set 'rcon_password' for clients to use 'rcon'.\n");
		}
		else
		{
			Com_Printf(0, "Invalid password.\n");
		}
	}
	else
	{
		remaining[0] = 0;

		if (Cmd_Argc() > 2)
		{
			for (int i = 2; i < Cmd_Argc(); i++)
			{
				current = Com_AddToString(Cmd_Argv(i), remaining, current, sizeof(remaining), true);
				current = Com_AddToString(" ", remaining, current, sizeof(remaining), false);
			}
		}
		else
		{
			memset(remaining, 0, sizeof(remaining));
			strncpy(remaining, Cmd_Argv(2), sizeof(remaining) - 1);
		}

		Cmd_ExecuteSingleCommand(0, 0, remaining);
	}

	Com_EndRedirect();

	if (strlen(remaining) > 0)
	{
		Com_Printf(0, "handled rcon: %s\n", remaining);
	}
}
Esempio n. 19
0
qboolean SV_ExecuteRemoteCmd(int clientnum, const char *msg){
	char sv_outputbuf[SV_OUTPUTBUF_LENGTH];
	char cmd[30];
	char buffer[256];
	char *printPtr;
	int i = 0;
	int j = 0;
	int powercmd;
	int power;
	client_t *cl;

        if(!cmdSystemInitialized){
            SV_SendServerCommand(redirectClient, "e \"Error: Remote control system is not initialized\n\"");
            Com_Printf("Error: Remote control system is not initialized\n");
            return qfalse;
        }


	if(clientnum < 0 || clientnum > 63) return qfalse;
	cl = &svs.clients[clientnum];
	redirectClient = cl;

	while ( msg[i] != ' ' && msg[i] != '\0' && msg[i] != '\n' && i < 32 ){
		i++;
	}
	
	if(i > 29 || i < 3) return qfalse;

	Q_strncpyz(cmd,msg,i+1);


	//Prevent buffer overflow as well as prevent the execution of priveleged commands by using seperator characters
	Q_strncpyz(buffer,msg,256);
	Q_strchrrepl(buffer,';','\0');
	Q_strchrrepl(buffer,'\n','\0');
	Q_strchrrepl(buffer,'\r','\0');
	// start redirecting all print outputs to the packet

    power = SV_RemoteCmdGetClPower(cl);
    powercmd = Cmd_GetPower(cmd);
	
    if(!Q_stricmpn(cmd,"auth",4)){
       printPtr = cmd;
        
    }else{
	    printPtr = buffer;
    }

	if(powercmd == -1){
            SV_SendServerCommand(redirectClient, "e \"^5Command^2: %s\n^3Command execution failed - Invalid command invoked - Type ^2$cmdlist ^3to get a list of all available commands\"", printPtr);
            return qfalse;
	}
	if(powercmd > power){
            SV_SendServerCommand(redirectClient, "e \"^5Command^2: %s\n^3Command execution failed - Insufficient power to execute this command.\n^3You need at least ^6%i ^3powerpoints to invoke this command.\n^3Type ^2$cmdlist ^3to get a list of all available commands\"",
            printPtr, powercmd);
	    return qtrue;
	}
	Com_Printf( "Command execution: %s   Invoked by: %s   InvokerUID: %i Power: %i\n", printPtr, cl->name, cl->uid, power);

	Com_BeginRedirect(sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_ReliableSendRedirect);

	i = cmdInvoker.currentCmdPower;
	cmdInvoker.currentCmdPower = power;
	cmdInvoker.authserver = qfalse;

	j = cmdInvoker.currentCmdInvoker;
	cmdInvoker.currentCmdInvoker = cl->uid;

	cmdInvoker.clientnum = clientnum;

	Cmd_ExecuteSingleCommand( 0, 0, buffer );
#ifdef PUNKBUSTER
	if(!Q_stricmpn(buffer, "pb_sv_", 6)) PbServerForceProcess();
#endif
	SV_SendServerCommand(redirectClient, "e \"^5Command^2: %s\"", buffer);

	cmdInvoker.currentCmdPower = i;
	cmdInvoker.currentCmdInvoker = j;
	cmdInvoker.clientnum = -1;

	Com_EndRedirect();
	return qtrue;
}
Esempio n. 20
0
qboolean SV_ExecuteRemoteCmd(int clientnum, const char *msg){
	char sv_outputbuf[SV_OUTPUTBUF_LENGTH];
	char cmd[30];
	char buffer[256];
	char *printPtr;
	int i = 0;
	int j = 0;
	int powercmd;
	int power;
	client_t *cl;
	qboolean critcmd;

	if(clientnum < 0 || clientnum > 63) return qfalse;
	cl = &svs.clients[clientnum];
	redirectClient = cl;

	while ( msg[i] != ' ' && msg[i] != '\0' && msg[i] != '\n' && i < 32 ){
		i++;
	}
	
	if(i > 29 || i < 3) return qfalse;

	Q_strncpyz(cmd,msg,i+1);


	if(!Q_stricmpn(cmd, "auth", 4)){
		if(!Q_stricmp(cmd, "authChangePassword"))
		{
			Q_strncpyz(cmd, "changePassword", sizeof(cmd));
		}
		else if(!Q_stricmp(cmd, "authSetAdmin"))
		{
			Q_strncpyz(cmd, "AdminAddAdminWithPassword", sizeof(cmd));
		}
		else if(!Q_stricmp(cmd, "authUnsetAdmin"))
		{
			Q_strncpyz(cmd, "AdminRemoveAdmin", sizeof(cmd));
		}
		else if(!Q_stricmp(cmd, "authListAdmins"))
		{
			Q_strncpyz(cmd, "adminListAdmins", sizeof(cmd));
		}
	}else if(!Q_stricmp(cmd, "cmdpowerlist")){
		Q_strncpyz(cmd, "AdminListCommands", sizeof(cmd));
	}else if(!Q_stricmp(cmd, "setCmdMinPower")){
		Q_strncpyz(cmd, "AdminChangeCommandPower", sizeof(cmd));
	}

	//Prevent buffer overflow as well as prevent the execution of priveleged commands by using seperator characters
	Q_strncpyz(buffer,msg,256);
	Q_strchrrepl(buffer,';','\0');
	Q_strchrrepl(buffer,'\n','\0');
	Q_strchrrepl(buffer,'\r','\0');
	// start redirecting all print outputs to the packet

	power = Auth_GetClPower(cl);
	powercmd = Cmd_GetPower(cmd);

    if(strstr(cmd, "password"))
    {
            printPtr = "hiddencmd";
            critcmd = qtrue;
    }else{
	    printPtr = buffer;
            critcmd = qfalse;
    }

	if(powercmd == -1){
            SV_SendServerCommand(redirectClient, "e \"^5Command^2: %s\n^3Command execution failed - Invalid command invoked - Type ^2$cmdlist ^3to get a list of all available commands\"", printPtr);
            return qfalse;
	}
	if(powercmd > power){
            SV_SendServerCommand(redirectClient, "e \"^5Command^2: %s\n^3Command execution failed - Insufficient power to execute this command.\n^3You need at least ^6%i ^3powerpoints to invoke this command.\n^3Type ^2$cmdlist ^3to get a list of all available commands\"",
            printPtr, powercmd);
	    return qtrue;
	}
	Com_Printf( "Command execution: %s   Invoked by: %s   InvokerUID: %i Power: %i\n", printPtr, cl->name, cl->uid, power);

	Com_BeginRedirect(sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_ReliableSendRedirect);

	i = Cmd_GetInvokerUID();
	j = Cmd_GetInvokerPower();

	Cmd_SetCurrentInvokerInfo(cl->uid, power, clientnum);
	
	Cmd_ExecuteSingleCommand( 0, 0, buffer );
#ifdef PUNKBUSTER
	if(!Q_stricmpn(buffer, "pb_sv_", 6)) PbServerForceProcess();
#endif

	if(!critcmd)
	{
		SV_SendServerCommand(redirectClient, "e \"^5Command^2: %s\"", buffer);
	}
	Cmd_SetCurrentInvokerInfo(i, j, -1);

	Com_EndRedirect();
	return qtrue;
}
qboolean HL2Rcon_SourceRconEvent(netadr_t *from, msg_t *msg, int connectionId){

//    int packetlen;
    int packettype;
    int type;
    int8_t team;
    int8_t clientnum;
    int32_t *updatelen;
    char* command;
    char* chatline;
    char sv_outputbuf[HL2RCON_SOURCEOUTPUTBUF_LENGTH];
    msg_t msg2;
    byte data[20000];
	char stringbuf[8 * MAX_STRING_CHARS];

    MSG_BeginReading(msg);

    while(msg->readcount < msg->cursize)
    {
	//packetlen = 
	MSG_ReadLong(msg);

	if(connectionId < 0 || connectionId >= MAX_RCONUSERS)
		return qtrue;

	rconUser_t* user;
	user = &sourceRcon.activeRconUsers[connectionId];

	user->lastpacketid = MSG_ReadLong(msg);

	packettype = MSG_ReadLong(msg);
	
	switch(packettype)
	{
		case SERVERDATA_GETSTATUS:
		//status request
		    //Pop the end of body byte
		    MSG_ReadByte(msg);

		    MSG_Init(&msg2, data, sizeof(data));
		    MSG_WriteLong(&msg2, 0); //writing 0 for now
		    MSG_WriteLong(&msg2, user->lastpacketid); // ID
		    MSG_WriteLong(&msg2, SERVERDATA_STATUSRESPONSE); // Type: status response
		    SV_WriteRconStatus(&msg2);
		    MSG_WriteByte(&msg2, 0);

		    //Adjust the length
		    updatelen = (int32_t*)msg2.data;
		    *updatelen = msg2.cursize - 4;
		    NET_SendData(from->sock, &msg2);
		    break;

		case SERVERDATA_EXECCOMMAND:

		    command = MSG_ReadString(msg, stringbuf, sizeof(stringbuf));

		    //Pop the end of body byte
		    MSG_ReadByte(msg);

		    Com_Printf("Rcon from: %s command: %s\n", NET_AdrToString(from), command);

		    sourceRcon.redirectUser = connectionId+1;
		    HL2Rcon_ExecuteConsoleCommand(command, user->uid);
		    sourceRcon.redirectUser = 0;
		    break;

		case SERVERDATA_TURNONSTREAM:

		    type = MSG_ReadByte(msg);

		    //Pop the end of body byte
		    MSG_ReadByte(msg);

		    sourceRcon.redirectUser = connectionId+1;
		    Com_BeginRedirect (sv_outputbuf, sizeof(sv_outputbuf), HL2Rcon_SourceRconFlushRedirect);
		    HL2Rcon_SourceRconStreaming_enable( type, user->uid );
		    Com_EndRedirect ();
		    sourceRcon.redirectUser = 0;
		    break;

		case SERVERDATA_SAY:
		    clientnum = MSG_ReadByte(msg); // -1 if Team or for all is used
		    team = MSG_ReadByte(msg); // teamnumber or -1 if it is for all team or clientnum is set
		    chatline = MSG_ReadString(msg, stringbuf, sizeof(stringbuf));

		    //Pop the end of body byte
		    MSG_ReadByte(msg);

		    sourceRcon.redirectUser = connectionId+1;
		    HL2Rcon_SayToPlayers(clientnum, team, chatline);
		    sourceRcon.redirectUser = 0;
		    break;

		default:
		//Not a source rcon packet
		Com_Printf("Not a valid source rcon packet from: %s received. Type: %d - Closing connection\n", NET_AdrToString(from), packettype);
		return qtrue;
	}
    }
    return qfalse;
}
Esempio n. 22
0
/*
===============
SVC_RemoteCommand

An rcon packet arrived from the network.
Shift down the remaining args
Redirect all printfs
===============
*/
void SVC_RemoteCommand(netadr_t from, msg_t * msg) {
	bool        valid;
	unsigned int    time;
	char            remaining[1024];

	// show_bug.cgi?id=376
	// if we send an OOB print message this size, 1.31 clients die in a Com_Printf buffer overflow
	// the buffer overflow will be fixed in > 1.31 clients
	// but we want a server side fix
	// we must NEVER send an OOB message that will be > 1.31 MAXPRINTMSG (4096)
#define SV_OUTPUTBUF_LENGTH ( 256 - 16 )
	char            sv_outputbuf[SV_OUTPUTBUF_LENGTH], *cmd_aux;
	static unsigned int lasttime = 0;

	// TTimo - show_bug.cgi?id=534
    time = Com_Milliseconds();

	// Do we have a whitelist for rcon?
	if(sv_WhiteListRcon->string && *sv_WhiteListRcon->string) {
		// Prevent use of rcon from addresses that have not been whitelisted
		if(!SV_IsRconWhitelisted(&from))
		{
			Com_Printf( "SVC_RemoteCommand: attempt from %s who is not whitelisted\n", NET_AdrToString( from ) );
			NET_OutOfBandPrint(NS_SERVER, from, "print\nClient not found whitelist data.\n");
			SV_DropClientsByAddress(&from, "Client tried to access to RCON password.");
			return;
		}
	}

    if ( !strlen( sv_rconPassword->string ) || strcmp (Cmd_Argv(1), sv_rconPassword->string) ) {
        // MaJ - If the rconpassword is bad and one just happned recently, don't spam the log file, just die.
        if ( (unsigned)( time - lasttime ) < 500u ) {
			return;
        }
        valid = false;
        Com_Printf ("Bad rcon from %s:\n%s\n", NET_AdrToString (from), Cmd_Argv(2) );
    } else {
        // MaJ - If the rconpassword is good, allow it much sooner than a bad one.
        if ( (unsigned)( time - lasttime ) < 200u ) {
			return;
        }
        valid = true;
        Com_Printf ("Rcon from %s:\n%s\n", NET_AdrToString (from), Cmd_Argv(2) );
    }
    lasttime = time;

	// start redirecting all print outputs to the packet
	svs.redirectAddress = from;
	// FIXME TTimo our rcon redirection could be improved
	//   big rcon commands such as status lead to sending
	//   out of band packets on every single call to Com_Printf
	//   which leads to client overflows
	//   see show_bug.cgi?id=51
	//     (also a Q3 issue)
	Com_BeginRedirect(sv_outputbuf, SV_OUTPUTBUF_LENGTH, SV_FlushRedirect);

	if(!strlen(sv_rconPassword->string)) {
		Com_Printf("No rconpassword set on the server.\n");
	} else if(!valid) {
		Com_Printf("Bad rconpassword.\n");
	} else {
		remaining[0] = 0;

		// ATVI Wolfenstein Misc #284
		// get the command directly, "rcon <pass> <command>" to avoid quoting issues
		// extract the command by walking
		// since the cmd formatting can fuckup (amount of spaces), using a dumb step by step parsing
		cmd_aux = Cmd_Cmd();
		cmd_aux += 4;
		while(cmd_aux[0] == ' ') {
			cmd_aux++;
		}
		while(cmd_aux[0] && cmd_aux[0] != ' ') { // password
			cmd_aux++;
		}
		while(cmd_aux[0] == ' ') {
			cmd_aux++;
		}

		Q_strcat(remaining, sizeof(remaining), cmd_aux);

		Cmd_ExecuteString(remaining);

	}

	Com_EndRedirect();
}