summaryrefslogtreecommitdiff
path: root/src/map/clif.c
diff options
context:
space:
mode:
authorHaru <haru@dotalux.com>2013-08-01 18:14:36 +0200
committerHaru <haru@dotalux.com>2013-08-01 18:57:31 +0200
commit38b8bf02b69f3841fd496f8d628bf71040c99709 (patch)
tree4be62808f7696dbd706688f14be2994da09cdbe6 /src/map/clif.c
parent94502b74233035b07c8c73a1f991a17b7bf22c55 (diff)
downloadhercules-38b8bf02b69f3841fd496f8d628bf71040c99709.tar.gz
hercules-38b8bf02b69f3841fd496f8d628bf71040c99709.tar.bz2
hercules-38b8bf02b69f3841fd496f8d628bf71040c99709.tar.xz
hercules-38b8bf02b69f3841fd496f8d628bf71040c99709.zip
Improved packet obfuscation reliability
- Fixes bugreport:7607 http://hercules.ws/board/tracker/issue-7607-changing-emblem-with-packet-obfuscation-2-unknown-packet/ - Resolved unintended disconnections caused by invalid packets when obfuscation is enabled and a fragmented packet is received. - Improved packet parsing reliability when packet obfuscation is set to optional. Special thanks to serverkid for reporting the issue and Ind for figuring out the cause and suggesting a solution. Signed-off-by: Haru <haru@dotalux.com>
Diffstat (limited to 'src/map/clif.c')
-rw-r--r--src/map/clif.c58
1 files changed, 37 insertions, 21 deletions
diff --git a/src/map/clif.c b/src/map/clif.c
index 5110ca76b..2f63ec5c0 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -9209,8 +9209,11 @@ void clif_parse_WantToConnection(int fd, struct map_session_data* sd) {
CREATE(sd, TBL_PC, 1);
sd->fd = fd;
- sd->cryptKey = (( clif->cryptKey[0] * clif->cryptKey[1] ) + clif->cryptKey[2]) & 0xFFFFFFFF;
-
+
+ sd->cryptKey = (( ((( clif->cryptKey[0] * clif->cryptKey[1] ) + clif->cryptKey[2]) & 0xFFFFFFFF)
+ * clif->cryptKey[1] ) + clif->cryptKey[2]) & 0xFFFFFFFF;
+ sd->parse_cmd_func = clif->parse_cmd;
+
session[fd]->session_data = sd;
pc->setnewpc(sd, account_id, char_id, login_id1, client_tick, sex, fd);
@@ -17481,42 +17484,41 @@ void clif_cart_additem_ack(struct map_session_data *sd, int flag) {
/* */
unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) {
if( sd ) {
- sd->cryptKey = (( sd->cryptKey * clif->cryptKey[1] ) + clif->cryptKey[2]) & 0xFFFFFFFF;
return (cmd ^ ((sd->cryptKey >> 16) & 0x7FFF));
}
return (cmd ^ (((( clif->cryptKey[0] * clif->cryptKey[1] ) + clif->cryptKey[2]) >> 16) & 0x7FFF));
}
-unsigned short clif_parse_cmd_normal ( int fd, struct map_session_data *sd ) {
+unsigned short clif_parse_cmd_normal( int fd, struct map_session_data *sd ) {
unsigned short cmd = RFIFOW(fd,0);
+
// filter out invalid / unsupported packets
- if (cmd > MAX_PACKET_DB || packet_db[cmd].len == 0)
+ if( cmd > MAX_PACKET_DB || cmd < MIN_PACKET_DB || packet_db[cmd].len == 0 )
return 0;
return cmd;
}
-unsigned short clif_parse_cmd_optional ( int fd, struct map_session_data *sd ) {
+unsigned short clif_parse_cmd_decrypt( int fd, struct map_session_data *sd ) {
unsigned short cmd = RFIFOW(fd,0);
+ cmd = clif->decrypt_cmd(cmd, sd);
+
// filter out invalid / unsupported packets
- if (cmd > MAX_PACKET_DB || packet_db[cmd].len == 0) {
- cmd = clif->decrypt_cmd( cmd, sd );
- if( cmd > MAX_PACKET_DB || packet_db[cmd].len == 0 )
- return 0;
- RFIFOW(fd, 0) = cmd;
- }
+ if( cmd > MAX_PACKET_DB || cmd < MIN_PACKET_DB || packet_db[cmd].len == 0 )
+ return 0;
return cmd;
}
-unsigned short clif_parse_cmd_decrypt ( int fd, struct map_session_data *sd ) {
+unsigned short clif_parse_cmd_optional( int fd, struct map_session_data *sd ) {
unsigned short cmd = RFIFOW(fd,0);
- cmd = clif->decrypt_cmd( cmd, sd );
-
// filter out invalid / unsupported packets
- if (cmd > MAX_PACKET_DB || packet_db[cmd].len == 0 )
- return 0;
-
- RFIFOW(fd, 0) = cmd;
+ if( cmd > MAX_PACKET_DB || cmd < MIN_PACKET_DB || packet_db[cmd].len == 0 ) {
+ if( sd )
+ sd->parse_cmd_func = clif_parse_cmd_decrypt;
+ return clif_parse_cmd_decrypt(fd, sd);
+ } else if( sd ) {
+ sd->parse_cmd_func = clif_parse_cmd_normal;
+ }
return cmd;
}
@@ -17536,6 +17538,8 @@ int clif_parse(int fd) {
// begin main client packet processing loop
sd = (TBL_PC *)session[fd]->session_data;
+ unsigned short (*parse_cmd_func)(int fd, struct map_session_data *sd);
+
if (session[fd]->flag.eof) {
if (sd) {
if (sd->state.autotrade) {
@@ -17563,8 +17567,13 @@ int clif_parse(int fd) {
if (RFIFOREST(fd) < 2)
return 0;
- if( !( cmd = clif->parse_cmd(fd,sd) ) ) {
- ShowWarning("clif_parse: Received unsupported packet (packet 0x%04x, %d bytes received), disconnecting session #%d.\n", RFIFOW(fd,0), RFIFOREST(fd), fd);
+ if( sd )
+ parse_cmd_func = sd->parse_cmd_func;
+ else
+ parse_cmd_func = clif->parse_cmd;
+
+ if( !( cmd = parse_cmd_func(fd,sd) ) ) {
+ ShowWarning("clif_parse: Received unsupported packet (packet 0x%04x (0x%04x), %d bytes received), disconnecting session #%d.\n", cmd, RFIFOW(fd,0), RFIFOREST(fd), fd);
#ifdef DUMP_INVALID_PACKET
ShowDump(RFIFOP(fd,0), RFIFOREST(fd));
#endif
@@ -17593,6 +17602,13 @@ int clif_parse(int fd) {
if ((int)RFIFOREST(fd) < packet_len)
return 0; // not enough data received to form the packet
+ if( cmd != RFIFOW(fd, 0) ) {
+ RFIFOW(fd, 0) = cmd;
+ if( sd ) {
+ sd->cryptKey = (( sd->cryptKey * clif->cryptKey[1] ) + clif->cryptKey[2]) & 0xFFFFFFFF; // Update key for the next packet
+ }
+ }
+
if( packet_db[cmd].func == clif->pDebug )
packet_db[cmd].func(fd, sd);
else if( packet_db[cmd].func != NULL ) {