diff --git a/src/network/core/tcp_game.h b/src/network/core/tcp_game.h index a678c247a2..9fefc3667f 100644 --- a/src/network/core/tcp_game.h +++ b/src/network/core/tcp_game.h @@ -35,8 +35,10 @@ enum { PACKET_CLIENT_COMPANY_INFO, PACKET_SERVER_COMPANY_INFO, PACKET_SERVER_CLIENT_INFO, - PACKET_SERVER_NEED_PASSWORD, - PACKET_CLIENT_PASSWORD, + PACKET_SERVER_NEED_GAME_PASSWORD, + PACKET_SERVER_NEED_COMPANY_PASSWORD, + PACKET_CLIENT_GAME_PASSWORD, + PACKET_CLIENT_COMPANY_PASSWORD, PACKET_SERVER_WELCOME, PACKET_CLIENT_GETMAP, PACKET_SERVER_WAIT, @@ -74,14 +76,15 @@ struct CommandPacket; /** Status of a client */ enum ClientStatus { - STATUS_INACTIVE, ///< The client is not connected nor active - STATUS_AUTHORIZING,///< The client is authorizing - STATUS_AUTH, ///< The client is authorized - STATUS_MAP_WAIT, ///< The client is waiting as someone else is downloading the map - STATUS_MAP, ///< The client is downloading the map - STATUS_DONE_MAP, ///< The client has downloaded the map - STATUS_PRE_ACTIVE, ///< The client is catching up the delayed frames - STATUS_ACTIVE, ///< The client is active within in the game + STATUS_INACTIVE, ///< The client is not connected nor active + STATUS_AUTH_GAME, ///< The client is authorizing with game (server) password + STATUS_AUTH_COMPANY, ///< The client is authorizing with company password + STATUS_AUTHORIZED, ///< The client is authorized + STATUS_MAP_WAIT, ///< The client is waiting as someone else is downloading the map + STATUS_MAP, ///< The client is downloading the map + STATUS_DONE_MAP, ///< The client has downloaded the map + STATUS_PRE_ACTIVE, ///< The client is catching up the delayed frames + STATUS_ACTIVE, ///< The client is active within in the game }; class NetworkClientSocket; diff --git a/src/network/network.cpp b/src/network/network.cpp index dd5bf2c8dc..0d1e84d788 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -452,7 +452,7 @@ static bool NetworkHasJoiningClient() { const NetworkClientSocket *cs; FOR_ALL_CLIENT_SOCKETS(cs) { - if (cs->status >= STATUS_AUTH && cs->status < STATUS_ACTIVE) return true; + if (cs->status >= STATUS_AUTHORIZED && cs->status < STATUS_ACTIVE) return true; } return false; @@ -548,7 +548,7 @@ NetworkRecvStatus NetworkCloseClient(NetworkClientSocket *cs, NetworkRecvStatus */ if (cs->sock == INVALID_SOCKET) return status; - if (status != NETWORK_RECV_STATUS_CONN_LOST && !cs->HasClientQuit() && _network_server && cs->status > STATUS_INACTIVE) { + if (status != NETWORK_RECV_STATUS_CONN_LOST && !cs->HasClientQuit() && _network_server && cs->status >= STATUS_AUTHORIZED) { /* We did not receive a leave message from this client... */ char client_name[NETWORK_CLIENT_NAME_LENGTH]; NetworkClientSocket *new_cs; @@ -559,7 +559,7 @@ NetworkRecvStatus NetworkCloseClient(NetworkClientSocket *cs, NetworkRecvStatus /* Inform other clients of this... strange leaving ;) */ FOR_ALL_CLIENT_SOCKETS(new_cs) { - if (new_cs->status > STATUS_AUTH && cs != new_cs) { + if (new_cs->status > STATUS_AUTHORIZED && cs != new_cs) { SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->client_id, NETWORK_ERROR_CONNECTION_LOST); } } @@ -569,7 +569,7 @@ NetworkRecvStatus NetworkCloseClient(NetworkClientSocket *cs, NetworkRecvStatus if (_network_server) { /* We just lost one client :( */ - if (cs->status >= STATUS_AUTH) _network_game_info.clients_on--; + if (cs->status >= STATUS_AUTHORIZED) _network_game_info.clients_on--; _network_clients_connected--; SetWindowDirty(WC_CLIENT_LIST, 0); diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index f20bafab73..65d7e3d14e 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -167,18 +167,32 @@ DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_NEWGRFS_CHECKED) return NETWORK_RECV_STATUS_OKAY; } -DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_PASSWORD)(NetworkPasswordType type, const char *password) +DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_GAME_PASSWORD)(const char *password) { /* - * Packet: CLIENT_PASSWORD + * Packet: CLIENT_GAME_PASSWORD * Function: Send a password to the server to authorize * Data: * uint8: NetworkPasswordType * String: Password */ - Packet *p = new Packet(PACKET_CLIENT_PASSWORD); - p->Send_uint8 (type); - p->Send_string(type == NETWORK_GAME_PASSWORD ? password : GenerateCompanyPasswordHash(password)); + Packet *p = new Packet(PACKET_CLIENT_GAME_PASSWORD); + p->Send_string(password); + MY_CLIENT->Send_Packet(p); + return NETWORK_RECV_STATUS_OKAY; +} + +DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_COMPANY_PASSWORD)(const char *password) +{ + /* + * Packet: CLIENT_COMPANY_PASSWORD + * Function: Send a password to the server to authorize + * Data: + * uint8: NetworkPasswordType + * String: Password + */ + Packet *p = new Packet(PACKET_CLIENT_COMPANY_PASSWORD); + p->Send_string(GenerateCompanyPasswordHash(password)); MY_CLIENT->Send_Packet(p); return NETWORK_RECV_STATUS_OKAY; } @@ -535,30 +549,32 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_CHECK_NEWGRFS) return ret; } -DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEED_PASSWORD) +DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEED_GAME_PASSWORD) { - NetworkPasswordType type = (NetworkPasswordType)p->Recv_uint8(); - const char *password = _network_join_server_password; - - switch (type) { - case NETWORK_COMPANY_PASSWORD: - /* Initialize the password hash salting variables. */ - _password_game_seed = p->Recv_uint32(); - p->Recv_string(_password_server_id, sizeof(_password_server_id)); - if (MY_CLIENT->HasClientQuit()) return NETWORK_RECV_STATUS_MALFORMED_PACKET; - password = _network_join_company_password; - /* FALL THROUGH */ - case NETWORK_GAME_PASSWORD: - if (StrEmpty(password)) { - ShowNetworkNeedPassword(type); - } else { - return SEND_COMMAND(PACKET_CLIENT_PASSWORD)(type, password); - } - return NETWORK_RECV_STATUS_OKAY; - - default: return NETWORK_RECV_STATUS_MALFORMED_PACKET; + if (!StrEmpty(password)) { + return SEND_COMMAND(PACKET_CLIENT_GAME_PASSWORD)(password); } + + ShowNetworkNeedPassword(NETWORK_GAME_PASSWORD); + + return NETWORK_RECV_STATUS_OKAY; +} + +DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_NEED_COMPANY_PASSWORD) +{ + _password_game_seed = p->Recv_uint32(); + p->Recv_string(_password_server_id, sizeof(_password_server_id)); + if (MY_CLIENT->HasClientQuit()) return NETWORK_RECV_STATUS_MALFORMED_PACKET; + + const char *password = _network_join_company_password; + if (!StrEmpty(password)) { + return SEND_COMMAND(PACKET_CLIENT_COMPANY_PASSWORD)(password); + } + + ShowNetworkNeedPassword(NETWORK_COMPANY_PASSWORD); + + return NETWORK_RECV_STATUS_OKAY; } DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_WELCOME) @@ -921,8 +937,10 @@ static NetworkClientPacket * const _network_client_packet[] = { NULL, // PACKET_CLIENT_COMPANY_INFO, RECEIVE_COMMAND(PACKET_SERVER_COMPANY_INFO), RECEIVE_COMMAND(PACKET_SERVER_CLIENT_INFO), - RECEIVE_COMMAND(PACKET_SERVER_NEED_PASSWORD), - NULL, // PACKET_CLIENT_PASSWORD, + RECEIVE_COMMAND(PACKET_SERVER_NEED_GAME_PASSWORD), + RECEIVE_COMMAND(PACKET_SERVER_NEED_COMPANY_PASSWORD), + NULL, // PACKET_CLIENT_GAME_PASSWORD, + NULL, // PACKET_CLIENT_COMPANY_PASSWORD, RECEIVE_COMMAND(PACKET_SERVER_WELCOME), NULL, // PACKET_CLIENT_GETMAP, RECEIVE_COMMAND(PACKET_SERVER_WAIT), diff --git a/src/network/network_client.h b/src/network/network_client.h index 17562fceca..88a02f0368 100644 --- a/src/network/network_client.h +++ b/src/network/network_client.h @@ -22,7 +22,8 @@ DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_COMMAND)(const CommandPacket *cp); DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_ERROR)(NetworkErrorCode errorno); DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_QUIT)(); DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_CHAT)(NetworkAction action, DestType desttype, int dest, const char *msg, int64 data); -DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_PASSWORD)(NetworkPasswordType type, const char *password); +DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_GAME_PASSWORD)(const char *password); +DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_COMPANY_PASSWORD)(const char *password); DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_PASSWORD)(const char *password); DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLIENT_SET_NAME)(const char *name); DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_ACK); diff --git a/src/network/network_gui.cpp b/src/network/network_gui.cpp index b151132439..4ac4204445 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -2116,23 +2116,6 @@ void ShowClientList() AllocateWindowDescFront(&_client_list_desc, 0); } - -static NetworkPasswordType pw_type; - - -void ShowNetworkNeedPassword(NetworkPasswordType npt) -{ - StringID caption; - - pw_type = npt; - switch (npt) { - default: NOT_REACHED(); - case NETWORK_GAME_PASSWORD: caption = STR_NETWORK_NEED_GAME_PASSWORD_CAPTION; break; - case NETWORK_COMPANY_PASSWORD: caption = STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION; break; - } - ShowQueryString(STR_EMPTY, caption, 20, 180, FindWindowById(WC_NETWORK_STATUS_WINDOW, 0), CS_ALPHANUMERAL, QSF_NONE); -} - /* Vars needed for the join-GUI */ NetworkJoinStatus _network_join_status; uint8 _network_join_waiting; @@ -2146,6 +2129,8 @@ enum NetworkJoinStatusWidgets { }; struct NetworkJoinStatusWindow : Window { + NetworkPasswordType password_type; + NetworkJoinStatusWindow(const WindowDesc *desc) : Window() { this->parent = FindWindowById(WC_NETWORK_WINDOW, 0); @@ -2225,8 +2210,13 @@ struct NetworkJoinStatusWindow : Window { if (StrEmpty(str)) { NetworkDisconnect(); ShowNetworkGameWindow(); - } else { - SEND_COMMAND(PACKET_CLIENT_PASSWORD)(pw_type, str); + return; + } + + switch (this->password_type) { + case NETWORK_GAME_PASSWORD: SEND_COMMAND(PACKET_CLIENT_GAME_PASSWORD) (str); break; + case NETWORK_COMPANY_PASSWORD: SEND_COMMAND(PACKET_CLIENT_COMPANY_PASSWORD)(str); break; + default: NOT_REACHED(); } } }; @@ -2257,6 +2247,21 @@ void ShowJoinStatusWindow() new NetworkJoinStatusWindow(&_network_join_status_window_desc); } +void ShowNetworkNeedPassword(NetworkPasswordType npt) +{ + NetworkJoinStatusWindow *w = (NetworkJoinStatusWindow *)FindWindowById(WC_NETWORK_STATUS_WINDOW, 0); + if (w == NULL) return; + w->password_type = npt; + + StringID caption; + switch (npt) { + default: NOT_REACHED(); + case NETWORK_GAME_PASSWORD: caption = STR_NETWORK_NEED_GAME_PASSWORD_CAPTION; break; + case NETWORK_COMPANY_PASSWORD: caption = STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION; break; + } + ShowQueryString(STR_EMPTY, caption, 20, 180, w, CS_ALPHANUMERAL, QSF_NONE); +} + /** Enum for NetworkGameWindow, referring to _network_game_window_widgets */ enum NetworkCompanyPasswordWindowWidgets { diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 2421ac31e1..eeae864c59 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -152,7 +152,7 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientSocket *cs, Netw GetString(str, strid, lastof(str)); /* Only send when the current client was in game */ - if (cs->status > STATUS_AUTH) { + if (cs->status > STATUS_AUTHORIZED) { NetworkClientSocket *new_cs; char client_name[NETWORK_CLIENT_NAME_LENGTH]; @@ -163,7 +163,7 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_ERROR)(NetworkClientSocket *cs, Netw NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, strid); FOR_ALL_CLIENT_SOCKETS(new_cs) { - if (new_cs->status > STATUS_AUTH && new_cs != cs) { + if (new_cs->status > STATUS_AUTHORIZED && new_cs != cs) { /* Some errors we filter to a more general error. Clients don't have to know the real * reason a joining failed. */ if (error == NETWORK_ERROR_NOT_AUTHORIZED || error == NETWORK_ERROR_NOT_EXPECTED || error == NETWORK_ERROR_WRONG_REVISION) @@ -209,22 +209,39 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_CHECK_NEWGRFS)(NetworkClientSocket * return NETWORK_RECV_STATUS_OKAY; } -DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_NEED_PASSWORD)(NetworkClientSocket *cs, NetworkPasswordType type) +DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_NEED_GAME_PASSWORD)(NetworkClientSocket *cs) { /* - * Packet: SERVER_NEED_PASSWORD - * Function: Indication to the client that the server needs a password - * Data: - * uint8: Type of password + * Packet: PACKET_SERVER_NEED_GAME_PASSWORD + * Function: Indication to the client that the server needs a game password */ - /* Invalid packet when status is AUTH or higher */ - if (cs->status >= STATUS_AUTH) return NetworkCloseClient(cs, NETWORK_RECV_STATUS_MALFORMED_PACKET); + /* Invalid packet when status is STATUS_AUTH_GAME or higher */ + if (cs->status >= STATUS_AUTH_GAME) return NetworkCloseClient(cs, NETWORK_RECV_STATUS_MALFORMED_PACKET); - cs->status = STATUS_AUTHORIZING; + cs->status = STATUS_AUTH_GAME; - Packet *p = new Packet(PACKET_SERVER_NEED_PASSWORD); - p->Send_uint8(type); + Packet *p = new Packet(PACKET_SERVER_NEED_GAME_PASSWORD); + cs->Send_Packet(p); + return NETWORK_RECV_STATUS_OKAY; +} + +DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SERVER_NEED_COMPANY_PASSWORD)(NetworkClientSocket *cs) +{ + /* + * Packet: PACKET_SERVER_NEED_COMPANY_PASSWORD + * Function: Indication to the client that the server needs a company password + * Data: + * uint32: Generation seed + * string: Network ID of the server + */ + + /* Invalid packet when status is STATUS_AUTH_COMPANY or higher */ + if (cs->status >= STATUS_AUTH_COMPANY) return NetworkCloseClient(cs, NETWORK_RECV_STATUS_MALFORMED_PACKET); + + cs->status = STATUS_AUTH_COMPANY; + + Packet *p = new Packet(PACKET_SERVER_NEED_COMPANY_PASSWORD); p->Send_uint32(_settings_game.game_creation.generation_seed); p->Send_string(_settings_client.network.network_id); cs->Send_Packet(p); @@ -244,9 +261,9 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WELCOME) NetworkClientSocket *new_cs; /* Invalid packet when status is AUTH or higher */ - if (cs->status >= STATUS_AUTH) return NetworkCloseClient(cs, NETWORK_RECV_STATUS_MALFORMED_PACKET); + if (cs->status >= STATUS_AUTHORIZED) return NetworkCloseClient(cs, NETWORK_RECV_STATUS_MALFORMED_PACKET); - cs->status = STATUS_AUTH; + cs->status = STATUS_AUTHORIZED; _network_game_info.clients_on++; p = new Packet(PACKET_SERVER_WELCOME); @@ -257,7 +274,7 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_WELCOME) /* Transmit info about all the active clients */ FOR_ALL_CLIENT_SOCKETS(new_cs) { - if (new_cs != cs && new_cs->status > STATUS_AUTH) + if (new_cs != cs && new_cs->status > STATUS_AUTHORIZED) SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(cs, new_cs->GetInfo()); } /* Also send the info of the server */ @@ -308,12 +325,12 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MAP) static FILE *file_pointer; static uint sent_packets; // How many packets we did send succecfully last time - if (cs->status < STATUS_AUTH) { + if (cs->status < STATUS_AUTHORIZED) { /* Illegal call, return error and ignore the packet */ return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED); } - if (cs->status == STATUS_AUTH) { + if (cs->status == STATUS_AUTHORIZED) { const char *filename = "network_server.tmp"; Packet *p; @@ -375,7 +392,7 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MAP) /* Check if we already have a new client to send the map to */ if (!new_map_client) { /* If not, this client will get the map */ - new_cs->status = STATUS_AUTH; + new_cs->status = STATUS_AUTHORIZED; new_map_client = true; SEND_COMMAND(PACKET_SERVER_MAP)(new_cs); } else { @@ -648,11 +665,11 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_NEWGRFS_CHECKED) /* We now want a password from the client else we do not allow him in! */ if (!StrEmpty(_settings_client.network.server_password)) { - return SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_GAME_PASSWORD); + return SEND_COMMAND(PACKET_SERVER_NEED_GAME_PASSWORD)(cs); } if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) { - return SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD); + return SEND_COMMAND(PACKET_SERVER_NEED_COMPANY_PASSWORD)(cs); } return SEND_COMMAND(PACKET_SERVER_WELCOME)(cs); @@ -729,42 +746,51 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_JOIN) return SEND_COMMAND(PACKET_SERVER_CHECK_NEWGRFS)(cs); } -DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD) +DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_GAME_PASSWORD) { - NetworkPasswordType type; - char password[NETWORK_PASSWORD_LENGTH]; - const NetworkClientInfo *ci; - - type = (NetworkPasswordType)p->Recv_uint8(); - p->Recv_string(password, sizeof(password)); - - if (cs->status == STATUS_AUTHORIZING && type == NETWORK_GAME_PASSWORD) { - /* Check game-password */ - if (strcmp(password, _settings_client.network.server_password) != 0) { - /* Password is invalid */ - return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD); - } - - ci = cs->GetInfo(); - - if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) { - return SEND_COMMAND(PACKET_SERVER_NEED_PASSWORD)(cs, NETWORK_COMPANY_PASSWORD); - } - - /* Valid password, allow user */ - return SEND_COMMAND(PACKET_SERVER_WELCOME)(cs); - } else if (cs->status == STATUS_AUTHORIZING && type == NETWORK_COMPANY_PASSWORD) { - ci = cs->GetInfo(); - - if (strcmp(password, _network_company_states[ci->client_playas].password) != 0) { - /* Password is invalid */ - return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD); - } - - return SEND_COMMAND(PACKET_SERVER_WELCOME)(cs); + if (cs->status != STATUS_AUTH_GAME) { + return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED); } - return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED); + char password[NETWORK_PASSWORD_LENGTH]; + p->Recv_string(password, sizeof(password)); + + /* Check game password. Allow joining if we cleared the password meanwhile */ + if (!StrEmpty(_settings_client.network.server_password) && + strcmp(password, _settings_client.network.server_password) != 0) { + /* Password is invalid */ + return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD); + } + + const NetworkClientInfo *ci = cs->GetInfo(); + if (Company::IsValidID(ci->client_playas) && !StrEmpty(_network_company_states[ci->client_playas].password)) { + return SEND_COMMAND(PACKET_SERVER_NEED_COMPANY_PASSWORD)(cs); + } + + /* Valid password, allow user */ + return SEND_COMMAND(PACKET_SERVER_WELCOME)(cs); +} + +DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_PASSWORD) +{ + if (cs->status != STATUS_AUTH_COMPANY) { + return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED); + } + + char password[NETWORK_PASSWORD_LENGTH]; + p->Recv_string(password, sizeof(password)); + + /* Check company password. Allow joining if we cleared the password meanwhile. + * Also, check the company is still valid - client could be moved to spectators + * in the middle of the authorization process */ + CompanyID playas = cs->GetInfo()->client_playas; + if (Company::IsValidID(playas) && !StrEmpty(_network_company_states[playas].password) && + strcmp(password, _network_company_states[playas].password) != 0) { + /* Password is invalid */ + return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_WRONG_PASSWORD); + } + + return SEND_COMMAND(PACKET_SERVER_WELCOME)(cs); } DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_GETMAP) @@ -792,7 +818,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_GETMAP) /* The client was never joined.. so this is impossible, right? * Ignore the packet, give the client a warning, and close his connection */ - if (cs->status < STATUS_AUTH || cs->HasClientQuit()) { + if (cs->status < STATUS_AUTHORIZED || cs->HasClientQuit()) { return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED); } @@ -833,7 +859,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_MAP_OK) cs->last_frame_server = _frame_counter; FOR_ALL_CLIENT_SOCKETS(new_cs) { - if (new_cs->status > STATUS_AUTH) { + if (new_cs->status > STATUS_AUTHORIZED) { SEND_COMMAND(PACKET_SERVER_CLIENT_INFO)(new_cs, cs->GetInfo()); SEND_COMMAND(PACKET_SERVER_JOIN)(new_cs, cs->client_id); } @@ -966,7 +992,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ERROR) NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, strid); FOR_ALL_CLIENT_SOCKETS(new_cs) { - if (new_cs->status > STATUS_AUTH) { + if (new_cs->status > STATUS_AUTHORIZED) { SEND_COMMAND(PACKET_SERVER_ERROR_QUIT)(new_cs, cs->client_id, errorno); } } @@ -993,7 +1019,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_QUIT) NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, STR_NETWORK_MESSAGE_CLIENT_LEAVING); FOR_ALL_CLIENT_SOCKETS(new_cs) { - if (new_cs->status > STATUS_AUTH) { + if (new_cs->status > STATUS_AUTHORIZED) { SEND_COMMAND(PACKET_SERVER_QUIT)(new_cs, cs->client_id); } } @@ -1004,7 +1030,7 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_QUIT) DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_ACK) { - if (cs->status < STATUS_AUTH) { + if (cs->status < STATUS_AUTHORIZED) { /* Illegal call, return error and ignore the packet */ return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED); } @@ -1131,7 +1157,7 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_CHAT) { - if (cs->status < STATUS_AUTH) { + if (cs->status < STATUS_AUTHORIZED) { /* Illegal call, return error and ignore the packet */ return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_AUTHORIZED); } @@ -1272,8 +1298,10 @@ static NetworkServerPacket * const _network_server_packet[] = { RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_INFO), NULL, // PACKET_SERVER_COMPANY_INFO, NULL, // PACKET_SERVER_CLIENT_INFO, - NULL, // PACKET_SERVER_NEED_PASSWORD, - RECEIVE_COMMAND(PACKET_CLIENT_PASSWORD), + NULL, // PACKET_SERVER_NEED_GAME_PASSWORD, + NULL, // PACKET_SERVER_NEED_COMPANY_PASSWORD, + RECEIVE_COMMAND(PACKET_CLIENT_GAME_PASSWORD), + RECEIVE_COMMAND(PACKET_CLIENT_COMPANY_PASSWORD), NULL, // PACKET_SERVER_WELCOME, RECEIVE_COMMAND(PACKET_CLIENT_GETMAP), NULL, // PACKET_SERVER_WAIT,