From 59f4e5291192d918f06fe0b2f86c462441c9e204 Mon Sep 17 00:00:00 2001 From: havoc Date: Thu, 18 Nov 2010 01:44:07 +0000 Subject: [PATCH] added server support for proquake rcon when running quake protocol git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10603 d7cf8633-e32d-0410-b094-e92efae38249 --- console.c | 23 +++++++++++++++++++++-- console.h | 2 +- netconn.c | 29 ++++++++++++++++++++++++----- 3 files changed, 46 insertions(+), 8 deletions(-) diff --git a/console.c b/console.c index 7c0499ad..4421def8 100644 --- a/console.c +++ b/console.c @@ -93,6 +93,7 @@ lhnetsocket_t *rcon_redirect_sock = NULL; lhnetaddress_t *rcon_redirect_dest = NULL; int rcon_redirect_bufferpos = 0; char rcon_redirect_buffer[1400]; +qboolean rcon_redirect_proquakeprotocol = false; // generic functions for console buffers @@ -885,20 +886,38 @@ static char qfont_table[256] = { 'x', 'y', 'z', '{', '|', '}', '~', '<' }; -void Con_Rcon_Redirect_Init(lhnetsocket_t *sock, lhnetaddress_t *dest) +void Con_Rcon_Redirect_Init(lhnetsocket_t *sock, lhnetaddress_t *dest, qboolean proquakeprotocol) { rcon_redirect_sock = sock; rcon_redirect_dest = dest; - memcpy(rcon_redirect_buffer, "\377\377\377\377n", 5); // QW rcon print + rcon_redirect_proquakeprotocol = proquakeprotocol; + if (rcon_redirect_proquakeprotocol) + { + // reserve space for the packet header + rcon_redirect_buffer[0] = 0; + rcon_redirect_buffer[1] = 0; + rcon_redirect_buffer[2] = 0; + rcon_redirect_buffer[3] = 0; + // this is a reply to a CCREQ_RCON + rcon_redirect_buffer[4] = CCREP_RCON; + } + else + memcpy(rcon_redirect_buffer, "\377\377\377\377n", 5); // QW rcon print rcon_redirect_bufferpos = 5; } void Con_Rcon_Redirect_Flush(void) { rcon_redirect_buffer[rcon_redirect_bufferpos] = 0; + if (rcon_redirect_proquakeprotocol) + { + // update the length in the packet header + StoreBigLong((unsigned char *)rcon_redirect_buffer, NETFLAG_CTL | (rcon_redirect_bufferpos & NETFLAG_LENGTH_MASK)); + } NetConn_WriteString(rcon_redirect_sock, rcon_redirect_buffer, rcon_redirect_dest); memcpy(rcon_redirect_buffer, "\377\377\377\377n", 5); // QW rcon print rcon_redirect_bufferpos = 5; + rcon_redirect_proquakeprotocol = false; } void Con_Rcon_Redirect_End(void) diff --git a/console.h b/console.h index f86ae155..8b2d7680 100644 --- a/console.h +++ b/console.h @@ -28,7 +28,7 @@ extern int con_totallines; extern int con_backscroll; extern qboolean con_initialized; -void Con_Rcon_Redirect_Init(lhnetsocket_t *sock, lhnetaddress_t *dest); +void Con_Rcon_Redirect_Init(lhnetsocket_t *sock, lhnetaddress_t *dest, qboolean proquakeprotocol); void Con_Rcon_Redirect_End(void); void Con_Rcon_Redirect_Abort(void); diff --git a/netconn.c b/netconn.c index dde22c22..2c1d03ee 100755 --- a/netconn.c +++ b/netconn.c @@ -2636,7 +2636,7 @@ allow: return va("%srcon", restricted ? "restricted " : ""); } -void RCon_Execute(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, const char *addressstring2, const char *userlevel, const char *s, const char *endpos) +void RCon_Execute(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, const char *addressstring2, const char *userlevel, const char *s, const char *endpos, qboolean proquakeprotocol) { if(userlevel) { @@ -2653,7 +2653,7 @@ void RCon_Execute(lhnetsocket_t *mysocket, lhnetaddress_t *peeraddress, const ch Con_Printf("\n"); if (!host_client || !host_client->netconnection || LHNETADDRESS_GetAddressType(&host_client->netconnection->peeraddress) != LHNETADDRESSTYPE_LOOP) - Con_Rcon_Redirect_Init(mysocket, peeraddress); + Con_Rcon_Redirect_Init(mysocket, peeraddress, proquakeprotocol); while(s != endpos) { size_t l = strlen(s); @@ -2973,7 +2973,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat ++s; userlevel = RCon_Authenticate(peeraddress, password, s, endpos, hmac_mdfour_time_matching, timeval, endpos - timeval - 1); // not including the appended \0 into the HMAC - RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos); + RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos, false); return true; } if (length >= 42 && !memcmp(string, "srcon HMAC-MD4 CHALLENGE ", 25)) @@ -2988,7 +2988,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat ++s; userlevel = RCon_Authenticate(peeraddress, password, s, endpos, hmac_mdfour_challenge_matching, challenge, endpos - challenge - 1); // not including the appended \0 into the HMAC - RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos); + RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos, false); return true; } if (length >= 5 && !memcmp(string, "rcon ", 5)) @@ -3010,7 +3010,7 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat if (!ISWHITESPACE(password[0])) { const char *userlevel = RCon_Authenticate(peeraddress, password, s, endpos, plaintext_matching, NULL, 0); - RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos); + RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos, false); } return true; } @@ -3260,6 +3260,25 @@ static int NetConn_ServerParsePacket(lhnetsocket_t *mysocket, unsigned char *dat SZ_Clear(&net_message); } break; + case CCREQ_RCON: + if (developer_extra.integer) + Con_DPrintf("Datagram_ParseConnectionless: received CCREQ_RCON from %s.\n", addressstring2); + if (sv.active && !rcon_secure.integer) + { + char password[2048]; + char cmd[2048]; + char *s; + char *endpos; + const char *userlevel; + strlcpy(password, MSG_ReadString(), sizeof(password)); + strlcpy(cmd, MSG_ReadString(), sizeof(cmd)); + s = cmd; + endpos = cmd + strlen(cmd) + 1; // one behind the NUL, so adding strlen+1 will eventually reach it + userlevel = RCon_Authenticate(peeraddress, password, s, endpos, plaintext_matching, NULL, 0); + RCon_Execute(mysocket, peeraddress, addressstring2, userlevel, s, endpos, true); + return true; + } + break; default: break; } -- 2.39.2