diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-02-24 16:03:58 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-02-24 16:03:58 +0000 |
| commit | 4739966e14ca2df24d4f44fb814b6275b9bf2a3c (patch) | |
| tree | 2398dee3380dfa48582a71a4f2d4278448fa6cb8 /src/game/client/gc_hooks.cpp | |
| parent | 1ea859c431b33a384727c0016917dde15bceeff3 (diff) | |
| download | zcatch-4739966e14ca2df24d4f44fb814b6275b9bf2a3c.tar.gz zcatch-4739966e14ca2df24d4f44fb814b6275b9bf2a3c.zip | |
larger restructure to improve security
Diffstat (limited to 'src/game/client/gc_hooks.cpp')
| -rw-r--r-- | src/game/client/gc_hooks.cpp | 112 |
1 files changed, 85 insertions, 27 deletions
diff --git a/src/game/client/gc_hooks.cpp b/src/game/client/gc_hooks.cpp index a6391007..9292d08c 100644 --- a/src/game/client/gc_hooks.cpp +++ b/src/game/client/gc_hooks.cpp @@ -120,17 +120,17 @@ extern "C" void modc_predict() const void *data = snap_get_item(SNAP_CURRENT, i, &item); int client_id = item.id; - if(item.type == OBJTYPE_PLAYER_CHARACTER) + if(item.type == NETOBJTYPE_PLAYER_CHARACTER) { - const obj_player_character *character = (const obj_player_character *)data; + const NETOBJ_PLAYER_CHARACTER *character = (const NETOBJ_PLAYER_CHARACTER *)data; client_datas[client_id].predicted.world = &world; world.players[client_id] = &client_datas[client_id].predicted; client_datas[client_id].predicted.read(character); } - else if(item.type == OBJTYPE_PLAYER_INFO) + else if(item.type == NETOBJTYPE_PLAYER_INFO) { - const obj_player_info *info = (const obj_player_info *)data; + const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data; if(info->local) local_cid = client_id; } @@ -155,7 +155,7 @@ extern "C" void modc_predict() // apply player input int *input = client_get_input(tick); if(input) - world.players[c]->input = *((player_input*)input); + world.players[c]->input = *((NETOBJ_PLAYER_INPUT*)input); } world.players[c]->tick(); @@ -230,6 +230,23 @@ extern "C" void modc_newsnapshot() static int snapshot_count = 0; snapshot_count++; + // secure snapshot + { + int num = snap_num_items(SNAP_CURRENT); + for(int index = 0; index < num; index++) + { + SNAP_ITEM item; + void *data = snap_get_item(SNAP_CURRENT, index, &item); + if(netobj_secure(item.type, data, item.datasize) != 0) + { + if(config.debug) + dbg_msg("game", "invalidated %d %d (%s) %d", index, item.type, netobj_get_name(item.type), item.id); + snap_invalidate_item(SNAP_CURRENT, index); + } + } + } + + process_events(SNAP_CURRENT); if(config.dbg_stress) @@ -256,32 +273,32 @@ extern "C" void modc_newsnapshot() SNAP_ITEM item; const void *data = snap_get_item(SNAP_CURRENT, i, &item); - if(item.type == OBJTYPE_PLAYER_INFO) + if(item.type == NETOBJTYPE_PLAYER_INFO) { - const obj_player_info *info = (const obj_player_info *)data; + const NETOBJ_PLAYER_INFO *info = (const NETOBJ_PLAYER_INFO *)data; - client_datas[info->clientid].team = info->team; + client_datas[info->cid].team = info->team; if(info->local) { - local_info = info; - const void *data = snap_find_item(SNAP_CURRENT, OBJTYPE_PLAYER_CHARACTER, item.id); + netobjects.local_info = info; + const void *data = snap_find_item(SNAP_CURRENT, NETOBJTYPE_PLAYER_CHARACTER, item.id); if(data) { - local_character = (const obj_player_character *)data; - local_character_pos = vec2(local_character->x, local_character->y); + netobjects.local_character = (const NETOBJ_PLAYER_CHARACTER *)data; + local_character_pos = vec2(netobjects.local_character->x, netobjects.local_character->y); - const void *p = snap_find_item(SNAP_PREV, OBJTYPE_PLAYER_CHARACTER, item.id); + const void *p = snap_find_item(SNAP_PREV, NETOBJTYPE_PLAYER_CHARACTER, item.id); if(p) - local_prev_character = (obj_player_character *)p; + netobjects.local_prev_character = (NETOBJ_PLAYER_CHARACTER *)p; } } } - else if(item.type == OBJTYPE_GAME) - gameobj = (obj_game *)data; - else if(item.type == OBJTYPE_FLAG) + else if(item.type == NETOBJTYPE_GAME) + netobjects.gameobj = (NETOBJ_GAME *)data; + else if(item.type == NETOBJTYPE_FLAG) { - flags[item.id%2] = (const obj_flag *)data; + netobjects.flags[item.id%2] = (const NETOBJ_FLAG *)data; } } } @@ -394,7 +411,7 @@ extern "C" void modc_statechange(int state, int old) } } -obj_projectile extraproj_projectiles[MAX_EXTRA_PROJECTILES]; +NETOBJ_PROJECTILE extraproj_projectiles[MAX_EXTRA_PROJECTILES]; int extraproj_num; void extraproj_reset() @@ -409,6 +426,11 @@ extern "C" void modc_message(int msg) int cid = msg_unpack_int(); int team = msg_unpack_int(); const char *message = msg_unpack_string(); + + /* check for errors and invalid inputs */ + if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS) + return; + dbg_msg("message", "chat cid=%d team=%d msg='%s'", cid, team, message); chat_add_line(cid, team, message); @@ -423,10 +445,13 @@ extern "C" void modc_message(int msg) for(int k = 0; k < num; k++) { - obj_projectile proj; - for(unsigned i = 0; i < sizeof(obj_projectile)/sizeof(int); i++) + NETOBJ_PROJECTILE proj; + for(unsigned i = 0; i < sizeof(NETOBJ_PROJECTILE)/sizeof(int); i++) ((int *)&proj)[i] = msg_unpack_int(); + if(msg_unpack_error()) + return; + if(extraproj_num != MAX_EXTRA_PROJECTILES) { extraproj_projectiles[extraproj_num] = proj; @@ -440,6 +465,10 @@ extern "C" void modc_message(int msg) const char *name = msg_unpack_string(); const char *skinname = msg_unpack_string(); + /* check for errors and invalid inputs */ + if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS) + return; + strncpy(client_datas[cid].name, name, 64); strncpy(client_datas[cid].skin_name, skinname, 64); @@ -466,13 +495,24 @@ extern "C" void modc_message(int msg) } else if(msg == MSG_TUNE_PARAMS) { - int *params = (int *)&tuning; + // unpack the new tuning + tuning_params new_tuning; + int *params = (int *)&new_tuning; for(unsigned i = 0; i < sizeof(tuning_params)/sizeof(int); i++) params[i] = msg_unpack_int(); + + // check for unpacking errors + if(msg_unpack_error()) + return; + + // apply new tuning + tuning = new_tuning; } else if(msg == MSG_WEAPON_PICKUP) { int weapon = msg_unpack_int(); + if(msg_unpack_error()) + return; picked_up_weapon = weapon+1; } else if(msg == MSG_READY_TO_ENTER) @@ -481,23 +521,41 @@ extern "C" void modc_message(int msg) } else if(msg == MSG_KILLMSG) { + // unpack messages + killmsg msg; + msg.killer = msg_unpack_int(); + msg.victim = msg_unpack_int(); + msg.weapon = msg_unpack_int(); + msg.mode_special = msg_unpack_int(); + msg.tick = client_tick(); + + // check for unpacking errors + if(msg_unpack_error() || msg.killer >= MAX_CLIENTS || msg.victim >= MAX_CLIENTS || msg.weapon >= NUM_WEAPONS) + return; + + // add the message killmsg_current = (killmsg_current+1)%killmsg_max; - killmsgs[killmsg_current].killer = msg_unpack_int(); - killmsgs[killmsg_current].victim = msg_unpack_int(); - killmsgs[killmsg_current].weapon = msg_unpack_int(); - killmsgs[killmsg_current].mode_special = msg_unpack_int(); - killmsgs[killmsg_current].tick = client_tick(); + killmsgs[killmsg_current] = msg; } else if (msg == MSG_EMOTICON) { + // unpack int cid = msg_unpack_int(); int emoticon = msg_unpack_int(); + + // check for errors + if(msg_unpack_error() || cid < 0 || cid >= MAX_CLIENTS) + return; + + // apply client_datas[cid].emoticon = emoticon; client_datas[cid].emoticon_start = client_tick(); } else if(msg == MSG_SOUND_GLOBAL) { int soundid = msg_unpack_int(); + if(msg_unpack_error() || soundid < 0) + return; snd_play_random(CHN_GLOBAL, soundid, 1.0f, vec2(0,0)); } } |