Add anti-spoofing

This commit is contained in:
MysterD 2022-03-02 00:01:41 -08:00
parent a1dbd4b268
commit 8bfadc95f1
15 changed files with 81 additions and 41 deletions

View file

@ -138,7 +138,7 @@ void packet_receive(struct Packet* p) {
struct NetworkPlayer* np = &gNetworkPlayers[p->localIndex];
for (int i = 0; i < MAX_RX_SEQ_IDS; i++) {
if (np->rxSeqIds[i] == p->seqId && np->rxPacketHash[i] == packetHash) {
LOG_INFO("received duplicate packet");
LOG_INFO("received duplicate packet %u", packetType);
return;
}
}
@ -180,3 +180,11 @@ void packet_receive(struct Packet* p) {
}
}
}
bool packet_spoofed(struct Packet* p, u8 globalIndex) {
if (gNetworkSystem->requireServerBroadcast) { return false; }
if (p->localIndex == UNKNOWN_LOCAL_INDEX) { return false; }
if (p->localIndex >= MAX_PLAYERS) { return true; }
return (gNetworkPlayers[p->localIndex].globalIndex != globalIndex);
}

View file

@ -131,6 +131,7 @@ struct LSTNetworkType {
// packet.c
void packet_process(struct Packet* p);
void packet_receive(struct Packet* packet);
bool packet_spoofed(struct Packet* p, u8 globalIndex);
// packet_read_write.c
void packet_init(struct Packet* packet, enum PacketType packetType, bool reliable, enum PacketLevelMatchType levelAreaMustMatch);

View file

@ -44,6 +44,12 @@ void network_receive_area_request(struct Packet* p) {
return;
}
// anti spoof
if (packet_spoofed(p, globalIndex)) {
LOG_ERROR("rx spoofed area request");
return;
}
// send area
network_send_area(toNp);
}

View file

@ -4,32 +4,6 @@
#include "pc/djui/djui.h"
#include "pc/debuglog.h"
#ifdef DEVELOPMENT
#include "behavior_table.h"
static void print_sync_object_table(void) {
LOG_INFO("Sync Object Table");
for (int i = 0; i < MAX_SYNC_OBJECTS; i++) {
if (gSyncObjects[i].o == NULL) { continue; }
u32 behaviorId = get_id_from_behavior(gSyncObjects[i].behavior);
LOG_INFO("%03d: %08X", i, behaviorId);
behaviorId = behaviorId; // suppress warning
}
LOG_INFO(" ");
}
static void print_network_player_table(void) {
LOG_INFO("Network Player Table");
LOG_INFO("%5s %5s %8s %8s %8s %8s %8s", "gID", "lID", "course", "act", "level", "area", "valid");
for (int i = 0; i < MAX_PLAYERS; i++) {
struct NetworkPlayer* np = &gNetworkPlayers[i];
if (!np->connected) { continue; }
LOG_INFO("%5d %5d %8d %8d %8d %8d %8d", np->globalIndex, np->localIndex, np->currCourseNum, np->currActNum, np->currLevelNum, np->currAreaIndex, np->currAreaSyncValid);
}
LOG_INFO(" ");
}
#endif
void network_send_chat(char* message, u8 globalIndex) {
u16 messageLength = strlen(message);
struct Packet p = { 0 };
@ -38,12 +12,6 @@ void network_send_chat(char* message, u8 globalIndex) {
packet_write(&p, &messageLength, sizeof(u16));
packet_write(&p, message, messageLength * sizeof(u8));
network_send(&p);
#ifdef DEVELOPMENT
print_network_player_table();
//reservation_area_debug();
//print_sync_object_table();
#endif
}
void network_receive_chat(struct Packet* p) {
@ -53,15 +21,16 @@ void network_receive_chat(struct Packet* p) {
packet_read(p, &globalIndex, sizeof(u8));
packet_read(p, &remoteMessageLength, sizeof(u16));
if (remoteMessageLength > 256) { remoteMessageLength = 255; }
if (remoteMessageLength >= 255) { remoteMessageLength = 255; }
packet_read(p, &remoteMessage, remoteMessageLength * sizeof(u8));
// anti spoof
if (packet_spoofed(p, globalIndex)) {
LOG_ERROR("rx spoofed chat");
return;
}
// add the message
djui_chat_message_create_from(globalIndex, remoteMessage);
LOG_INFO("rx chat: %s", remoteMessage);
/*
#ifdef DEVELOPMENT
print_network_player_table();
#endif
*/
}

View file

@ -37,6 +37,12 @@ void network_receive_leaving(struct Packet* p) {
u8 globalIndex = 0;
packet_read(p, &globalIndex, sizeof(u8));
// anti spoof
if (packet_spoofed(p, globalIndex)) {
LOG_ERROR("rx spoofed leaving");
return;
}
LOG_INFO("Received leaving event for %d", globalIndex);
network_player_disconnected(globalIndex);
}

View file

@ -66,6 +66,13 @@ void network_receive_level_area_inform(struct Packet* p) {
LOG_INFO("Received old level area inform seq: %d vs %d", sLevelAreaInformSeq[0][globalIndex], seq);
return;
}
// anti spoof
if (packet_spoofed(p, globalIndex)) {
LOG_ERROR("rx spoofed level area inform");
return;
}
sLevelAreaInformSeq[0][globalIndex] = seq;
network_player_update_course_level(np, courseNum, actNum, levelNum, areaIndex);

View file

@ -53,6 +53,12 @@ void network_receive_level_area_request(struct Packet* p) {
return;
}
// anti spoof
if (packet_spoofed(p, globalIndex)) {
LOG_ERROR("rx spoofed level area request");
return;
}
// send level area
network_send_level(toNp, true);
}

View file

@ -51,6 +51,12 @@ void network_receive_level_request(struct Packet* p) {
return;
}
// anti spoof
if (packet_spoofed(p, globalIndex)) {
LOG_ERROR("rx spoofed level request");
return;
}
// send level
network_send_level(toNp, false);
}

View file

@ -294,6 +294,12 @@ static struct SyncObject* packet_read_object_header(struct Packet* p, u8* fromLo
struct NetworkPlayer* np = network_player_from_global_index(fromGlobalIndex);
*fromLocalIndex = (np != NULL) ? np->localIndex : p->localIndex;
// anti spoof
if (packet_spoofed(p, fromGlobalIndex)) {
LOG_ERROR("rx spoofed object");
return NULL;
}
// get sync ID, sanity check
u32 syncId = 0;
packet_read(p, &syncId, sizeof(u32));

View file

@ -13,6 +13,7 @@
#include "game/mario_misc.h"
#include "pc/configfile.h"
#include "pc/djui/djui.h"
#include "pc/debuglog.h"
#pragma pack(1)
struct PacketPlayerData {
@ -206,6 +207,12 @@ void network_receive_player(struct Packet* p) {
struct NetworkPlayer* np = network_player_from_global_index(globalIndex);
if (np == NULL || np->localIndex == UNKNOWN_LOCAL_INDEX || !np->connected) { return; }
// anti spoof
if (packet_spoofed(p, globalIndex)) {
LOG_ERROR("rx spoofed player");
return;
}
// prevent receiving a packet about our player
if (gNetworkPlayerLocal && globalIndex == gNetworkPlayerLocal->globalIndex) { return; }

View file

@ -36,6 +36,12 @@ void network_receive_player_settings(struct Packet* p) {
return;
}
// anti spoof
if (packet_spoofed(p, globalId)) {
LOG_ERROR("rx spoofed player settings");
return;
}
struct NetworkPlayer* np = network_player_from_global_index(globalId);
snprintf(np->name, MAX_PLAYER_STRING, "%s", playerName);
np->modelIndex = playerModel;

View file

@ -75,6 +75,12 @@ void network_receive_spawn_star_nle(struct Packet* p) {
packet_read(p, &syncId, sizeof(u32));
packet_read(p, &params, sizeof(u32));
// anti spoof
if (packet_spoofed(p, globalIndex)) {
LOG_ERROR("rx spoofed star");
return;
}
// grab network player first
struct Object* object = NULL;
if (globalIndex != UNKNOWN_GLOBAL_INDEX) {

View file

@ -41,6 +41,12 @@ void network_receive_sync_valid(struct Packet* p) {
packet_read(p, &areaIndex, sizeof(s16));
packet_read(p, &fromGlobalIndex, sizeof(u8));
// anti spoof
if (packet_spoofed(p, fromGlobalIndex)) {
LOG_ERROR("rx spoofed sync valid");
return;
}
if (gNetworkType != NT_SERVER) {
extern s16 gCurrCourseNum, gCurrActStarNum, gCurrLevelNum, gCurrAreaIndex;
if (courseNum != gCurrCourseNum || actNum != gCurrActStarNum || levelNum != gCurrLevelNum || (areaIndex != gCurrAreaIndex && areaIndex != -1)) {