diff --git a/src/network/core/tcp_game.h b/src/network/core/tcp_game.h --- 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, @@ -75,7 +77,8 @@ 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_GAME, ///< The client is authorizing with game (server) password + STATUS_AUTH_COMPANY, ///< The client is authorizing with company password 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 diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp --- a/src/network/network_client.cpp +++ b/src/network/network_client.cpp @@ -167,18 +167,32 @@ DEF_CLIENT_SEND_COMMAND(PACKET_CLIENT_NE 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 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; + if (!StrEmpty(password)) { + return SEND_COMMAND(PACKET_CLIENT_GAME_PASSWORD)(password); + } - const char *password = _network_join_server_password; + ShowNetworkNeedPassword(NETWORK_GAME_PASSWORD); + + return NETWORK_RECV_STATUS_OKAY; +} - 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; +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; - default: 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 _netw 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 --- a/src/network/network_client.h +++ b/src/network/network_client.h @@ -22,7 +22,8 @@ DEF_CLIENT_SEND_COMMAND_PARAM(PACKET_CLI 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 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.cpp @@ -2210,8 +2210,13 @@ struct NetworkJoinStatusWindow : Window if (StrEmpty(str)) { NetworkDisconnect(); ShowNetworkGameWindow(); - } else { - SEND_COMMAND(PACKET_CLIENT_PASSWORD)(this->password_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(); } } }; diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -209,22 +209,39 @@ DEF_SERVER_SEND_COMMAND_PARAM(PACKET_SER 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_AUTH_GAME; + + Packet *p = new Packet(PACKET_SERVER_NEED_GAME_PASSWORD); + cs->Send_Packet(p); + return NETWORK_RECV_STATUS_OKAY; +} - cs->status = STATUS_AUTHORIZING; +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 + */ - Packet *p = new Packet(PACKET_SERVER_NEED_PASSWORD); - p->Send_uint8(type); + /* 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); @@ -647,11 +664,11 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT /* 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); @@ -728,42 +745,47 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT 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; + if (cs->status != STATUS_AUTH_GAME) { + return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED); + } + 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(); + /* 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); + } - 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); + 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); } - return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_NOT_EXPECTED); + /* 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 */ + const NetworkClientInfo *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); } DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_GETMAP) @@ -1271,8 +1293,10 @@ static NetworkServerPacket * const _netw 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,