Add separate network salt string for company passwords

pull/352/head
Jonathan G Rennison 2 years ago
parent 00cfb00537
commit 26eca815d3

@ -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());

Loading…
Cancel
Save