Add separate network salt string for company passwords
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
#include "../error.h"
|
||||
#include "../core/checksum_func.hpp"
|
||||
#include "../string_func_extra.h"
|
||||
#include "../3rdparty/randombytes/randombytes.h"
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
@@ -62,6 +63,7 @@ bool _network_dedicated; ///< are we a dedicated server?
|
||||
bool _is_network_server; ///< Does this client wants to be a network-server?
|
||||
bool _network_settings_access; ///< Can this client change server settings?
|
||||
NetworkCompanyState *_network_company_states = nullptr; ///< Statistics about some companies.
|
||||
std::string _network_company_server_id; ///< Server ID string used for company passwords
|
||||
ClientID _network_own_client_id; ///< Our client identifier.
|
||||
ClientID _redirect_console_to_client; ///< If not invalid, redirect the console output to a client.
|
||||
uint8 _network_reconnect; ///< Reconnect timeout
|
||||
@@ -634,6 +636,7 @@ void NetworkClose(bool close_admins)
|
||||
|
||||
delete[] _network_company_states;
|
||||
_network_company_states = nullptr;
|
||||
_network_company_server_id.clear();
|
||||
|
||||
InitializeNetworkPools(close_admins);
|
||||
}
|
||||
@@ -917,6 +920,7 @@ bool NetworkServerStart()
|
||||
NetworkUDPServerListen();
|
||||
|
||||
_network_company_states = new NetworkCompanyState[MAX_COMPANIES];
|
||||
_network_company_server_id = NetworkGenerateRandomKeyString();
|
||||
_network_server = true;
|
||||
_networking = true;
|
||||
_frame_counter = 0;
|
||||
@@ -1257,6 +1261,26 @@ static void NetworkGenerateServerId()
|
||||
_settings_client.network.network_id = hex_output;
|
||||
}
|
||||
|
||||
std::string NetworkGenerateRandomKeyString()
|
||||
{
|
||||
uint8 key[16];
|
||||
char hex_output[16 * 2 + 1];
|
||||
|
||||
if (randombytes(key, 16) < 0) {
|
||||
/* Fallback poor-quality random */
|
||||
DEBUG(misc, 0, "High quality random source unavailable");
|
||||
for (int i = 0; i < 16; i++) {
|
||||
key[i] = (uint8)InteractiveRandom();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
seprintf(hex_output + i * 2, lastof(hex_output), "%02x", key[i]);
|
||||
}
|
||||
|
||||
return std::string(hex_output);
|
||||
}
|
||||
|
||||
class TCPNetworkDebugConnecter : TCPConnecter {
|
||||
private:
|
||||
std::string connection_string;
|
||||
|
@@ -374,8 +374,10 @@ static uint32 _server_password_game_seed;
|
||||
static uint32 _rcon_password_game_seed;
|
||||
/** One bit of 'entropy' used to generate a salt for the settings passwords. */
|
||||
static uint32 _settings_password_game_seed;
|
||||
/** The other bit of 'entropy' used to generate a salt for the company, server, rcon, and settings passwords. */
|
||||
/** The other bit of 'entropy' used to generate a salt for the server, rcon, and settings passwords. */
|
||||
static std::string _password_server_id;
|
||||
/** The other bit of 'entropy' used to generate a salt for the company passwords. */
|
||||
static std::string _company_password_server_id;
|
||||
|
||||
/** Maximum number of companies of the currently joined server. */
|
||||
static uint8 _network_server_max_companies;
|
||||
@@ -437,7 +439,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendGamePassword(const std::st
|
||||
NetworkRecvStatus ClientNetworkGameSocketHandler::SendCompanyPassword(const std::string &password)
|
||||
{
|
||||
Packet *p = new Packet(PACKET_CLIENT_COMPANY_PASSWORD, SHRT_MAX);
|
||||
p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _company_password_game_seed));
|
||||
p->Send_string(GenerateCompanyPasswordHash(password, _company_password_server_id, _company_password_game_seed));
|
||||
my_client->SendPacket(p);
|
||||
return NETWORK_RECV_STATUS_OKAY;
|
||||
}
|
||||
@@ -571,7 +573,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendSetPassword(const std::str
|
||||
{
|
||||
Packet *p = new Packet(PACKET_CLIENT_SET_PASSWORD, SHRT_MAX);
|
||||
|
||||
p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _company_password_game_seed));
|
||||
p->Send_string(GenerateCompanyPasswordHash(password, _company_password_server_id, _company_password_game_seed));
|
||||
my_client->SendPacket(p);
|
||||
return NETWORK_RECV_STATUS_OKAY;
|
||||
}
|
||||
@@ -623,7 +625,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendMove(CompanyID company, co
|
||||
{
|
||||
Packet *p = new Packet(PACKET_CLIENT_MOVE, SHRT_MAX);
|
||||
p->Send_uint8(company);
|
||||
p->Send_string(GenerateCompanyPasswordHash(password, _password_server_id, _company_password_game_seed));
|
||||
p->Send_string(GenerateCompanyPasswordHash(password, _company_password_server_id, _company_password_game_seed));
|
||||
my_client->SendPacket(p);
|
||||
return NETWORK_RECV_STATUS_OKAY;
|
||||
}
|
||||
@@ -828,7 +830,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_NEED_COMPANY_PA
|
||||
this->status = STATUS_AUTH_COMPANY;
|
||||
|
||||
_company_password_game_seed = p->Recv_uint32();
|
||||
_password_server_id = p->Recv_string(NETWORK_SERVER_ID_LENGTH);
|
||||
_company_password_server_id = p->Recv_string(NETWORK_SERVER_ID_LENGTH);
|
||||
if (this->HasClientQuit()) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
|
||||
|
||||
if (!_network_join.company_password.empty()) {
|
||||
@@ -853,6 +855,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_WELCOME(Packet
|
||||
_rcon_password_game_seed = p->Recv_uint32();
|
||||
_settings_password_game_seed = p->Recv_uint32();
|
||||
_password_server_id = p->Recv_string(NETWORK_SERVER_ID_LENGTH);
|
||||
_company_password_server_id = p->Recv_string(NETWORK_SERVER_ID_LENGTH);
|
||||
|
||||
/* Start receiving the map */
|
||||
return SendGetMap();
|
||||
|
@@ -25,6 +25,7 @@
|
||||
#include "../string_type.h"
|
||||
|
||||
extern NetworkCompanyState *_network_company_states;
|
||||
extern std::string _network_company_server_id;
|
||||
|
||||
extern ClientID _network_own_client_id;
|
||||
extern ClientID _redirect_console_to_client;
|
||||
|
@@ -131,6 +131,7 @@ uint NetworkCalculateLag(const NetworkClientSocket *cs);
|
||||
StringID GetNetworkErrorMsg(NetworkErrorCode err);
|
||||
bool NetworkMakeClientNameUnique(std::string &new_name);
|
||||
std::string GenerateCompanyPasswordHash(const std::string &password, const std::string &password_server_id, uint32 password_game_seed);
|
||||
std::string NetworkGenerateRandomKeyString();
|
||||
|
||||
std::string_view ParseCompanyFromConnectionString(const std::string &connection_string, CompanyID *company_id);
|
||||
NetworkAddress ParseConnectionString(const std::string &connection_string, uint16 default_port);
|
||||
|
@@ -490,7 +490,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedCompanyPassword()
|
||||
|
||||
Packet *p = new Packet(PACKET_SERVER_NEED_COMPANY_PASSWORD, SHRT_MAX);
|
||||
p->Send_uint32(_settings_game.game_creation.generation_seed);
|
||||
p->Send_string(_settings_client.network.network_id);
|
||||
p->Send_string(_network_company_server_id);
|
||||
this->SendPacket(p);
|
||||
return NETWORK_RECV_STATUS_OKAY;
|
||||
}
|
||||
@@ -516,6 +516,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome()
|
||||
p->Send_uint32(_settings_game.game_creation.generation_seed ^ this->rcon_hash_bits);
|
||||
p->Send_uint32(_settings_game.game_creation.generation_seed ^ this->settings_hash_bits);
|
||||
p->Send_string(_settings_client.network.network_id);
|
||||
p->Send_string(_network_company_server_id);
|
||||
this->SendPacket(p);
|
||||
|
||||
/* Transmit info about all the active clients */
|
||||
@@ -1825,7 +1826,7 @@ void NetworkServerSetCompanyPassword(CompanyID company_id, const std::string &pa
|
||||
if (already_hashed) {
|
||||
_network_company_states[company_id].password = password;
|
||||
} else {
|
||||
_network_company_states[company_id].password = GenerateCompanyPasswordHash(password, _settings_client.network.network_id, _settings_game.game_creation.generation_seed);
|
||||
_network_company_states[company_id].password = GenerateCompanyPasswordHash(password, _network_company_server_id, _settings_game.game_creation.generation_seed);
|
||||
}
|
||||
|
||||
NetworkServerUpdateCompanyPassworded(company_id, !_network_company_states[company_id].password.empty());
|
||||
|
Reference in New Issue
Block a user