diff --git a/src/pc/lua/smlua_cobject_allowlist.c b/src/pc/lua/smlua_cobject_allowlist.c index 7b4ef0610..bd0a18a11 100644 --- a/src/pc/lua/smlua_cobject_allowlist.c +++ b/src/pc/lua/smlua_cobject_allowlist.c @@ -42,7 +42,7 @@ void smlua_cobject_allowlist_add(u16 lot, u64 pointer) { u16 m = smlua_lot_mapping(lot); if (sCachedAllowed[m] == pointer) { return; } sCachedAllowed[m] = pointer; - + struct CObjectAllowListNode* curNode = sAllowList[m]; struct CObjectAllowListNode* prevNode = NULL; while (curNode != NULL) { diff --git a/src/pc/network/packets/packet.c b/src/pc/network/packets/packet.c index d1179c065..5bbb0c4ef 100644 --- a/src/pc/network/packets/packet.c +++ b/src/pc/network/packets/packet.c @@ -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); +} diff --git a/src/pc/network/packets/packet.h b/src/pc/network/packets/packet.h index 64629e03e..80be440b9 100644 --- a/src/pc/network/packets/packet.h +++ b/src/pc/network/packets/packet.h @@ -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); diff --git a/src/pc/network/packets/packet_area_request.c b/src/pc/network/packets/packet_area_request.c index 44db627d3..17900e2aa 100644 --- a/src/pc/network/packets/packet_area_request.c +++ b/src/pc/network/packets/packet_area_request.c @@ -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); } diff --git a/src/pc/network/packets/packet_chat.c b/src/pc/network/packets/packet_chat.c index 56b2b9821..2f21cb22c 100644 --- a/src/pc/network/packets/packet_chat.c +++ b/src/pc/network/packets/packet_chat.c @@ -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 - */ } diff --git a/src/pc/network/packets/packet_leaving.c b/src/pc/network/packets/packet_leaving.c index b26c629c6..116e0d37e 100644 --- a/src/pc/network/packets/packet_leaving.c +++ b/src/pc/network/packets/packet_leaving.c @@ -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); } diff --git a/src/pc/network/packets/packet_level_area_inform.c b/src/pc/network/packets/packet_level_area_inform.c index f32af8ee8..59be29c6e 100644 --- a/src/pc/network/packets/packet_level_area_inform.c +++ b/src/pc/network/packets/packet_level_area_inform.c @@ -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); diff --git a/src/pc/network/packets/packet_level_area_request.c b/src/pc/network/packets/packet_level_area_request.c index 132dfd1db..5b55ba2ab 100644 --- a/src/pc/network/packets/packet_level_area_request.c +++ b/src/pc/network/packets/packet_level_area_request.c @@ -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); } diff --git a/src/pc/network/packets/packet_level_request.c b/src/pc/network/packets/packet_level_request.c index dee5c413b..bf5eec7ea 100644 --- a/src/pc/network/packets/packet_level_request.c +++ b/src/pc/network/packets/packet_level_request.c @@ -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); } diff --git a/src/pc/network/packets/packet_object.c b/src/pc/network/packets/packet_object.c index ffd4b787e..1391fc59d 100644 --- a/src/pc/network/packets/packet_object.c +++ b/src/pc/network/packets/packet_object.c @@ -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)); diff --git a/src/pc/network/packets/packet_player.c b/src/pc/network/packets/packet_player.c index 51deeadab..7b7f6098e 100644 --- a/src/pc/network/packets/packet_player.c +++ b/src/pc/network/packets/packet_player.c @@ -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; } diff --git a/src/pc/network/packets/packet_player_settings.c b/src/pc/network/packets/packet_player_settings.c index b98446977..cb684a9ad 100644 --- a/src/pc/network/packets/packet_player_settings.c +++ b/src/pc/network/packets/packet_player_settings.c @@ -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; diff --git a/src/pc/network/packets/packet_read_write.c b/src/pc/network/packets/packet_read_write.c index 18d3e9c9a..053303bde 100644 --- a/src/pc/network/packets/packet_read_write.c +++ b/src/pc/network/packets/packet_read_write.c @@ -164,7 +164,7 @@ u8 packet_initial_read(struct Packet* packet) { packet_read(packet, &packet->orderedGroupId, sizeof(u8)); packet_read(packet, &packet->orderedSeqId, sizeof(u8)); } - + // read location if (packet->levelAreaMustMatch) { packet_read(packet, &packet->courseNum, sizeof(u8)); diff --git a/src/pc/network/packets/packet_spawn_star.c b/src/pc/network/packets/packet_spawn_star.c index 8c6dc4512..b72c6317d 100644 --- a/src/pc/network/packets/packet_spawn_star.c +++ b/src/pc/network/packets/packet_spawn_star.c @@ -75,6 +75,12 @@ void network_receive_spawn_star_nle(struct Packet* p) { packet_read(p, &syncId, sizeof(u32)); packet_read(p, ¶ms, 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) { diff --git a/src/pc/network/packets/packet_sync_valid.c b/src/pc/network/packets/packet_sync_valid.c index 1a0446b64..e78bf73b0 100644 --- a/src/pc/network/packets/packet_sync_valid.c +++ b/src/pc/network/packets/packet_sync_valid.c @@ -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)) {