void GameEchoPing(session_node *s) { unsigned int token; if (!s || s->state != STATE_GAME || !s->game || s->game->game_state != GAME_NORMAL || s->conn.type == CONN_CONSOLE) { if (s) { s->secure_token = 0; s->sliding_token = NULL; } return; } // BP_PING is sign that client is still alive. // We return a BP_ECHO_PING in response. // We also take this opportunity to choose a new security token, // and tack it onto the BP_ECHO_PING. // // NOTE: This may be called anytime; the client can handle // unrequested BP_ECHO_PINGs to synchronize the security token. token = (s->seeds[0] & 0xFF); AddByteToPacket(BP_ECHO_PING); AddByteToPacket((unsigned char)(token ^ 0xED)); AddIntToPacket(GetSecurityRedbookID()); SendPacket(s->session_id); s->secure_token = token; s->sliding_token = GetSecurityRedbook(); }
void SecurePacketBufferList(int session_id, buffer_node *bl) { session_node *s = GetSessionByID(session_id); char* pRedbook; if (!session_id || !s || !s->account || !s->account->account_id || s->conn.type == CONN_CONSOLE) { //dprintf("SecurePacketBufferList cannot find session %i", session_id); return; } if (s->version_major < 4) { return; } if (bl == NULL || bl->buf == NULL) { // dprintf("SecurePacketBufferList can't use invalid buffer list"); return; } // dprintf("Securing msg %u with %u", (unsigned char)bl->buf[0], (unsigned char)(s->secure_token & 0xFF)); bl->buf[0] ^= (unsigned char)(s->secure_token & 0xFF); pRedbook = GetSecurityRedbook(); if (s->sliding_token && pRedbook) { if (s->sliding_token < pRedbook || s->sliding_token > pRedbook+strlen(pRedbook)) { lprintf("SecurePacketBufferList lost redbook on session %i account %i (%s), may break session\n", session_id, s->account->account_id, s->account->name); s->sliding_token = pRedbook; } s->secure_token += ((*s->sliding_token) & 0x7F); s->sliding_token++; if (*s->sliding_token == '\0') s->sliding_token = pRedbook; } }