Merge branch 'master' into jgrpp

# Conflicts:
#	.github/workflows/release-windows.yml
#	src/autoreplace_gui.cpp
#	src/cargotype.cpp
#	src/company_base.h
#	src/company_cmd.cpp
#	src/company_gui.cpp
#	src/currency.h
#	src/date_gui.cpp
#	src/dropdown.cpp
#	src/dropdown_func.h
#	src/dropdown_type.h
#	src/game/game_gui.cpp
#	src/genworld.cpp
#	src/genworld_gui.cpp
#	src/ground_vehicle.hpp
#	src/group_gui.cpp
#	src/house.h
#	src/industry_gui.cpp
#	src/network/network_client.cpp
#	src/network/network_server.cpp
#	src/network/network_type.h
#	src/newgrf_class_func.h
#	src/newgrf_house.cpp
#	src/newgrf_roadstop.h
#	src/openttd.cpp
#	src/order_gui.cpp
#	src/saveload/saveload.cpp
#	src/saveload/saveload.h
#	src/screenshot_gui.cpp
#	src/settings_gui.cpp
#	src/settings_type.h
#	src/slider.cpp
#	src/smallmap_gui.cpp
#	src/station_cmd.cpp
#	src/stdafx.h
#	src/survey.cpp
#	src/tile_map.h
#	src/town_cmd.cpp
#	src/town_gui.cpp
#	src/vehicle.cpp
#	src/vehicle_gui.cpp
#	src/vehicle_gui_base.h
This commit is contained in:
Jonathan G Rennison
2024-05-28 19:48:40 +01:00
173 changed files with 2504 additions and 1971 deletions

View File

@@ -26,10 +26,9 @@
*/
enum PacketGameType : uint8_t {
/*
* These first four pair of packets (thus eight in
* total) must remain in this order for backward
* and forward compatibility between clients that
* are trying to join directly.
* These first ten packets must remain in this order for backward and forward compatibility
* between clients that are trying to join directly. These packets can be received and/or sent
* by the server before the server has processed the 'join' packet from the client.
*/
/* Packets sent by socket accepting code without ever constructing a client socket instance. */
@@ -48,6 +47,10 @@ enum PacketGameType : uint8_t {
PACKET_SERVER_GAME_INFO, ///< Information about the server.
PACKET_CLIENT_GAME_INFO, ///< Request information about the server.
/* A server quitting this game. */
PACKET_SERVER_NEWGAME, ///< The server is preparing to start a new game.
PACKET_SERVER_SHUTDOWN, ///< The server is shutting down.
/*
* Packets after here assume that the client
* and server are running the same version. As
@@ -127,10 +130,6 @@ enum PacketGameType : uint8_t {
PACKET_SERVER_COMPANY_UPDATE, ///< Information (password) of a company changed.
PACKET_SERVER_CONFIG_UPDATE, ///< Some network configuration important to the client changed.
/* A server quitting this game. */
PACKET_SERVER_NEWGAME, ///< The server is preparing to start a new game.
PACKET_SERVER_SHUTDOWN, ///< The server is shutting down.
/* A client quitting. */
PACKET_CLIENT_QUIT, ///< A client tells the server it is going to quit.
PACKET_SERVER_QUIT, ///< A server tells that a client has quit.
@@ -228,14 +227,14 @@ protected:
/**
* The client tells the server about the identity of the client:
* string Name of the client (max NETWORK_NAME_LENGTH).
* uint8_t ID of the company to play as (1..MAX_COMPANIES).
* uint8_t ID of the company to play as (1..MAX_COMPANIES, or COMPANY_SPECTATOR).
* @param p The packet that was just received.
*/
virtual NetworkRecvStatus Receive_CLIENT_IDENTIFY(Packet &p);
/**
* Indication to the client that it needs to authenticate:
* bool Whether to use the password in the key exchange.
* uint8_t The \c NetworkAuthenticationMethod to use.
* 32 * uint8_t Public key of the server.
* 24 * uint8_t Nonce for the key exchange.
* @param p The packet that was just received.
@@ -253,14 +252,16 @@ protected:
/**
* Send the response to the authentication request:
* 32 * uint8_t Public key of the client.
* 8 * uint8_t Random message that got encoded and signed.
* 16 * uint8_t Message authentication code.
* 8 * uint8_t Random message that got encoded and signed.
* @param p The packet that was just received.
*/
virtual NetworkRecvStatus Receive_CLIENT_AUTH_RESPONSE(Packet &p);
/**
* Indication to the client that authentication is complete and encryption has to be used from here on forward.
* The encryption uses the shared keys generated by the last AUTH_REQUEST key exchange.
* 24 * uint8_t Nonce for encrypted connection.
* @param p The packet that was just received.
*/
virtual NetworkRecvStatus Receive_SERVER_ENABLE_ENCRYPTION(Packet &p);
@@ -299,7 +300,6 @@ protected:
/**
* Request the map from the server.
* uint32_t NewGRF version (release versions of OpenTTD only).
* @param p The packet that was just received.
*/
virtual NetworkRecvStatus Receive_CLIENT_GETMAP(Packet &p);

View File

@@ -151,6 +151,57 @@ NetworkClientInfo::~NetworkClientInfo()
return nullptr;
}
/**
* Simple helper to find the location of the given authorized key in the authorized keys.
* @param authorized_keys The keys to look through.
* @param authorized_key The key to look for.
* @return The iterator to the location of the authorized key, or \c authorized_keys.end().
*/
static auto FindKey(auto *authorized_keys, std::string_view authorized_key)
{
return std::find_if(authorized_keys->begin(), authorized_keys->end(), [authorized_key](auto &value) { return StrEqualsIgnoreCase(value, authorized_key); });
}
/**
* Check whether the given key is contains in these authorized keys.
* @param key The key to look for.
* @return \c true when the key has been found, otherwise \c false.
*/
bool NetworkAuthorizedKeys::Contains(std::string_view key) const
{
return FindKey(this, key) != this->end();
}
/**
* Add the given key to the authorized keys, when it is not already contained.
* @param key The key to add.
* @return \c true when the key was added, \c false when the key already existed.
*/
bool NetworkAuthorizedKeys::Add(std::string_view key)
{
auto iter = FindKey(this, key);
if (iter != this->end()) return false;
this->emplace_back(key);
return true;
}
/**
* Remove the given key from the authorized keys, when it is exists.
* @param key The key to remove.
* @return \c true when the key was removed, \c false when the key did not exist.
*/
bool NetworkAuthorizedKeys::Remove(std::string_view key)
{
auto iter = FindKey(this, key);
if (iter == this->end()) return false;
this->erase(iter);
return true;
}
uint8_t NetworkSpectatorCount()
{
uint8_t count = 0;

View File

@@ -953,10 +953,12 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_AUTH_REQUEST(Pa
}
}
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ENABLE_ENCRYPTION(Packet &)
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ENABLE_ENCRYPTION(Packet &p)
{
if (this->status != STATUS_AUTH_GAME || this->authentication_handler == nullptr) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
if (!this->authentication_handler->ReceiveEnableEncryption(p)) return NETWORK_RECV_STATUS_MALFORMED_PACKET;
this->receive_encryption_handler = this->authentication_handler->CreateServerToClientEncryptionHandler();
this->send_encryption_handler = this->authentication_handler->CreateClientToServerEncryptionHandler();
this->authentication_handler = nullptr;

View File

@@ -183,14 +183,15 @@ X25519Nonce::~X25519Nonce()
* @param secret_key The secret key to use for this handler. Defaults to secure random data.
*/
X25519AuthenticationHandler::X25519AuthenticationHandler(const X25519SecretKey &secret_key) :
our_secret_key(secret_key), our_public_key(secret_key.CreatePublicKey()), nonce(X25519Nonce::CreateRandom())
our_secret_key(secret_key), our_public_key(secret_key.CreatePublicKey()),
key_exchange_nonce(X25519Nonce::CreateRandom()), encryption_nonce(X25519Nonce::CreateRandom())
{
}
/* virtual */ void X25519AuthenticationHandler::SendRequest(Packet &p)
{
p.Send_bytes(this->our_public_key);
p.Send_bytes(this->nonce);
p.Send_bytes(this->key_exchange_nonce);
}
/**
@@ -206,7 +207,7 @@ bool X25519AuthenticationHandler::ReceiveRequest(Packet &p)
}
p.Recv_bytes(this->peer_public_key);
p.Recv_bytes(this->nonce);
p.Recv_bytes(this->key_exchange_nonce);
return true;
}
@@ -228,7 +229,7 @@ bool X25519AuthenticationHandler::SendResponse(Packet &p, std::string_view deriv
RandomBytesWithFallback(message);
X25519Mac mac;
crypto_aead_lock(message.data(), mac.data(), this->derived_keys.ClientToServer().data(), nonce.data(),
crypto_aead_lock(message.data(), mac.data(), this->derived_keys.ClientToServer().data(), this->key_exchange_nonce.data(),
this->our_public_key.data(), this->our_public_key.size(), message.data(), message.size());
p.Send_bytes(this->our_public_key);
@@ -246,14 +247,33 @@ std::string X25519AuthenticationHandler::GetPeerPublicKey() const
return FormatArrayAsHex(this->peer_public_key);
}
/**
* Send the initial nonce for the encrypted connection.
* @param p The packet to send the data in.
*/
void X25519AuthenticationHandler::SendEnableEncryption(struct Packet &p) const
{
p.Send_bytes(this->encryption_nonce);
}
/**
* Receive the initial nonce for the encrypted connection.
* @param p The packet to read the data from.
* @return \c true when enough bytes could be read for the nonce, otherwise \c false.
*/
bool X25519AuthenticationHandler::ReceiveEnableEncryption(struct Packet &p)
{
return p.Recv_bytes(this->encryption_nonce) == this->encryption_nonce.size();
}
std::unique_ptr<NetworkEncryptionHandler> X25519AuthenticationHandler::CreateClientToServerEncryptionHandler() const
{
return std::make_unique<X25519EncryptionHandler>(this->derived_keys.ClientToServer(), this->nonce);
return std::make_unique<X25519EncryptionHandler>(this->derived_keys.ClientToServer(), this->encryption_nonce);
}
std::unique_ptr<NetworkEncryptionHandler> X25519AuthenticationHandler::CreateServerToClientEncryptionHandler() const
{
return std::make_unique<X25519EncryptionHandler>(this->derived_keys.ServerToClient(), this->nonce);
return std::make_unique<X25519EncryptionHandler>(this->derived_keys.ServerToClient(), this->encryption_nonce);
}
/**
@@ -283,7 +303,7 @@ NetworkAuthenticationServerHandler::ResponseResult X25519AuthenticationHandler::
return NetworkAuthenticationServerHandler::NOT_AUTHENTICATED;
}
if (crypto_aead_unlock(message.data(), mac.data(), this->derived_keys.ClientToServer().data(), nonce.data(),
if (crypto_aead_unlock(message.data(), mac.data(), this->derived_keys.ClientToServer().data(), this->key_exchange_nonce.data(),
this->peer_public_key.data(), this->peer_public_key.size(), message.data(), message.size()) != 0) {
/*
* The ciphertext and the message authentication code do not match with the encryption key.
@@ -424,14 +444,6 @@ void CombinedAuthenticationServerHandler::Add(CombinedAuthenticationServerHandle
this->SendResponse();
}
/* virtual */ bool NetworkAuthenticationDefaultAuthorizedKeyHandler::IsAllowed(std::string_view peer_public_key) const
{
for (const auto &allowed : *this->authorized_keys) {
if (StrEqualsIgnoreCase(allowed, peer_public_key)) return true;
}
return false;
}
/**
* Create a NetworkAuthenticationClientHandler.

View File

@@ -33,6 +33,8 @@
#ifndef NETWORK_CRYPTO_H
#define NETWORK_CRYPTO_H
#include "network_type.h"
/**
* Base class for handling the encryption (or decryption) of a network connection.
*/
@@ -158,16 +160,16 @@ public:
*/
class NetworkAuthenticationDefaultAuthorizedKeyHandler : public NetworkAuthenticationAuthorizedKeyHandler {
private:
const std::vector<std::string> *authorized_keys; ///< The authorized keys to check against.
const NetworkAuthorizedKeys *authorized_keys; ///< The authorized keys to check against.
public:
/**
* Create the handler that uses the given authorized keys to check against.
* @param authorized_keys The reference to the authorized keys to check against.
*/
NetworkAuthenticationDefaultAuthorizedKeyHandler(const std::vector<std::string> &authorized_keys) : authorized_keys(&authorized_keys) {}
NetworkAuthenticationDefaultAuthorizedKeyHandler(const NetworkAuthorizedKeys &authorized_keys) : authorized_keys(&authorized_keys) {}
bool CanBeUsed() const override { return !this->authorized_keys->empty(); }
bool IsAllowed(std::string_view peer_public_key) const override;
bool IsAllowed(std::string_view peer_public_key) const override { return authorized_keys->Contains(peer_public_key); }
};
@@ -240,6 +242,12 @@ public:
*/
virtual bool SendResponse(struct Packet &p) = 0;
/**
* Read the request to enable encryption from the server.
* @param p The request from the server.
*/
virtual bool ReceiveEnableEncryption(struct Packet &p) = 0;
static std::unique_ptr<NetworkAuthenticationClientHandler> Create(std::shared_ptr<NetworkAuthenticationPasswordRequestHandler> password_handler, std::string &secret_key, std::string &public_key);
};
@@ -268,6 +276,12 @@ public:
*/
virtual ResponseResult ReceiveResponse(struct Packet &p) = 0;
/**
* Create the request to enable encryption to the client.
* @param p The packet to write the enable encryption request to.
*/
virtual void SendEnableEncryption(struct Packet &p) = 0;
/**
* Checks whether this handler can be used with the current configuration.
* For example when there is no password, the handler cannot be used.

View File

@@ -105,10 +105,12 @@ class X25519AuthenticationHandler {
private:
X25519SecretKey our_secret_key; ///< The secret key used by us.
X25519PublicKey our_public_key; ///< The public key used by us.
X25519Nonce nonce; ///< The nonce to prevent replay attacks.
X25519Nonce key_exchange_nonce; ///< The nonce to prevent replay attacks of the key exchange.
X25519DerivedKeys derived_keys; ///< Keys derived from the authentication process.
X25519PublicKey peer_public_key; ///< The public key used by our peer.
X25519Nonce encryption_nonce; ///< The nonce to prevent replay attacks the encrypted connection.
protected:
X25519AuthenticationHandler(const X25519SecretKey &secret_key);
@@ -119,6 +121,8 @@ protected:
std::string GetPeerPublicKey() const;
void SendEnableEncryption(struct Packet &p) const;
bool ReceiveEnableEncryption(struct Packet &p);
std::unique_ptr<NetworkEncryptionHandler> CreateClientToServerEncryptionHandler() const;
std::unique_ptr<NetworkEncryptionHandler> CreateServerToClientEncryptionHandler() const;
};
@@ -142,6 +146,7 @@ public:
virtual std::string_view GetName() const override { return "X25519-KeyExchangeOnly-client"; }
virtual NetworkAuthenticationMethod GetAuthenticationMethod() const override { return NETWORK_AUTH_METHOD_X25519_KEY_EXCHANGE_ONLY; }
virtual bool ReceiveEnableEncryption(struct Packet &p) override { return this->X25519AuthenticationHandler::ReceiveEnableEncryption(p); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateClientToServerEncryptionHandler() const override { return this->X25519AuthenticationHandler::CreateClientToServerEncryptionHandler(); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateServerToClientEncryptionHandler() const override { return this->X25519AuthenticationHandler::CreateServerToClientEncryptionHandler(); }
};
@@ -167,6 +172,7 @@ public:
virtual bool CanBeUsed() const override { return true; }
virtual std::string GetPeerPublicKey() const override { return this->X25519AuthenticationHandler::GetPeerPublicKey(); }
virtual void SendEnableEncryption(struct Packet &p) override { this->X25519AuthenticationHandler::SendEnableEncryption(p); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateClientToServerEncryptionHandler() const override { return this->X25519AuthenticationHandler::CreateClientToServerEncryptionHandler(); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateServerToClientEncryptionHandler() const override { return this->X25519AuthenticationHandler::CreateServerToClientEncryptionHandler(); }
};
@@ -194,6 +200,7 @@ public:
virtual std::string_view GetName() const override { return "X25519-PAKE-client"; }
virtual NetworkAuthenticationMethod GetAuthenticationMethod() const override { return NETWORK_AUTH_METHOD_X25519_PAKE; }
virtual bool ReceiveEnableEncryption(struct Packet &p) override { return this->X25519AuthenticationHandler::ReceiveEnableEncryption(p); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateClientToServerEncryptionHandler() const override { return this->X25519AuthenticationHandler::CreateClientToServerEncryptionHandler(); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateServerToClientEncryptionHandler() const override { return this->X25519AuthenticationHandler::CreateServerToClientEncryptionHandler(); }
};
@@ -222,6 +229,7 @@ public:
virtual bool CanBeUsed() const override { return !this->password_provider->GetPassword().empty(); }
virtual std::string GetPeerPublicKey() const override { return this->X25519AuthenticationHandler::GetPeerPublicKey(); }
virtual void SendEnableEncryption(struct Packet &p) override { this->X25519AuthenticationHandler::SendEnableEncryption(p); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateClientToServerEncryptionHandler() const override { return this->X25519AuthenticationHandler::CreateClientToServerEncryptionHandler(); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateServerToClientEncryptionHandler() const override { return this->X25519AuthenticationHandler::CreateServerToClientEncryptionHandler(); }
};
@@ -247,6 +255,7 @@ public:
virtual std::string_view GetName() const override { return "X25519-AuthorizedKey-client"; }
virtual NetworkAuthenticationMethod GetAuthenticationMethod() const override { return NETWORK_AUTH_METHOD_X25519_AUTHORIZED_KEY; }
virtual bool ReceiveEnableEncryption(struct Packet &p) override { return this->X25519AuthenticationHandler::ReceiveEnableEncryption(p); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateClientToServerEncryptionHandler() const override { return this->X25519AuthenticationHandler::CreateClientToServerEncryptionHandler(); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateServerToClientEncryptionHandler() const override { return this->X25519AuthenticationHandler::CreateServerToClientEncryptionHandler(); }
@@ -278,6 +287,7 @@ public:
virtual bool CanBeUsed() const override { return this->authorized_key_handler->CanBeUsed(); }
virtual std::string GetPeerPublicKey() const override { return this->X25519AuthenticationHandler::GetPeerPublicKey(); }
virtual void SendEnableEncryption(struct Packet &p) override { this->X25519AuthenticationHandler::SendEnableEncryption(p); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateClientToServerEncryptionHandler() const override { return this->X25519AuthenticationHandler::CreateClientToServerEncryptionHandler(); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateServerToClientEncryptionHandler() const override { return this->X25519AuthenticationHandler::CreateServerToClientEncryptionHandler(); }
};
@@ -308,6 +318,7 @@ public:
virtual std::string_view GetName() const override;
virtual NetworkAuthenticationMethod GetAuthenticationMethod() const override;
virtual bool ReceiveEnableEncryption(struct Packet &p) override { return this->current_handler->ReceiveEnableEncryption(p); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateClientToServerEncryptionHandler() const override { return this->current_handler->CreateClientToServerEncryptionHandler(); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateServerToClientEncryptionHandler() const override { return this->current_handler->CreateServerToClientEncryptionHandler(); }
};
@@ -334,6 +345,7 @@ public:
virtual bool CanBeUsed() const override;
virtual std::string GetPeerPublicKey() const override { return this->handlers.back()->GetPeerPublicKey(); }
virtual void SendEnableEncryption(struct Packet &p) override { this->handlers.back()->SendEnableEncryption(p); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateClientToServerEncryptionHandler() const override { return this->handlers.back()->CreateClientToServerEncryptionHandler(); }
virtual std::unique_ptr<NetworkEncryptionHandler> CreateServerToClientEncryptionHandler() const override { return this->handlers.back()->CreateServerToClientEncryptionHandler(); }
};

View File

@@ -24,8 +24,8 @@
#include "network_udp.h"
#include "../window_func.h"
#include "../gfx_func.h"
#include "../widgets/dropdown_type.h"
#include "../widgets/dropdown_func.h"
#include "../dropdown_type.h"
#include "../dropdown_func.h"
#include "../querystring_gui.h"
#include "../sortlist_type.h"
#include "../company_func.h"

View File

@@ -316,7 +316,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvSta
/* Inform other clients of this... strange leaving ;) */
for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) {
if (new_cs->status > STATUS_AUTHORIZED && this != new_cs) {
if (new_cs->status >= STATUS_AUTHORIZED && this != new_cs) {
new_cs->SendErrorQuit(this->client_id, NETWORK_ERROR_CONNECTION_LOST);
}
}
@@ -443,7 +443,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode err
StringID strid = GetNetworkErrorMsg(error);
/* Only send when the current client was in game */
if (this->status > STATUS_AUTHORIZED) {
if (this->status >= STATUS_AUTHORIZED) {
char client_name[NETWORK_CLIENT_NAME_LENGTH];
this->GetClientName(client_name, lastof(client_name));
@@ -542,6 +542,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendEnableEncryption()
if (this->status != STATUS_AUTH_GAME) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET);
auto p = std::make_unique<Packet>(this, PACKET_SERVER_ENABLE_ENCRYPTION, TCP_MTU);
this->authentication_handler->SendEnableEncryption(*p);
this->SendPacket(std::move(p));
return NETWORK_RECV_STATUS_OKAY;
}
@@ -1038,7 +1039,8 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_IDENTIFY(Packet
DEBUG(desync, 1, "client: %s; client: %02x; company: %02x", debug_date_dumper().HexDate(), (int)ci->index, (int)ci->client_playas);
/* Make sure companies to which people try to join are not autocleaned */
if (Company::IsValidID(playas)) _network_company_states[playas].months_empty = 0;
Company *c = Company::GetIfValid(playas);
if (c != nullptr) c->months_empty = 0;
return this->SendNewGRFCheck();
}
@@ -1528,7 +1530,7 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co
} else {
/* Else find the client to send the message to */
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
if (cs->client_id == (ClientID)dest) {
if (cs->client_id == (ClientID)dest && cs->status >= ServerNetworkGameSocketHandler::STATUS_AUTHORIZED) {
cs->SendChat(action, from_id, false, msg, data);
break;
}
@@ -1545,7 +1547,7 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co
}
} else {
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
if (cs->client_id == from_id) {
if (cs->client_id == from_id && cs->status >= ServerNetworkGameSocketHandler::STATUS_AUTHORIZED) {
cs->SendChat(action, (ClientID)dest, true, msg, data);
break;
}
@@ -1560,7 +1562,7 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co
ci_to = nullptr;
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
ci = cs->GetInfo();
if (ci != nullptr && ci->client_playas == (CompanyID)dest) {
if (ci != nullptr && ci->client_playas == (CompanyID)dest && cs->status >= ServerNetworkGameSocketHandler::STATUS_AUTHORIZED) {
cs->SendChat(action, from_id, false, msg, data);
if (cs->client_id == from_id) show_local = false;
ci_to = ci; // Remember a client that is in the company for company-name
@@ -1592,7 +1594,7 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co
NetworkTextMessage(action, GetDrawStringCompanyColour(ci_own->client_playas), true, name, msg, data);
} else {
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
if (cs->client_id == from_id) {
if (cs->client_id == from_id && cs->status >= ServerNetworkGameSocketHandler::STATUS_AUTHORIZED) {
cs->SendChat(action, ci_to->client_id, true, msg, data);
}
}
@@ -1607,7 +1609,7 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co
case DESTTYPE_BROADCAST:
case DESTTYPE_BROADCAST_SS:
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
cs->SendChat(action, from_id, (desttype == DESTTYPE_BROADCAST_SS && from_id == cs->client_id), msg, data);
if (cs->status >= ServerNetworkGameSocketHandler::STATUS_AUTHORIZED) cs->SendChat(action, from_id, (desttype == DESTTYPE_BROADCAST_SS && from_id == cs->client_id), msg, data);
}
NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
@@ -1631,7 +1633,7 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co
void NetworkServerSendExternalChat(const std::string &source, TextColour colour, const std::string &user, const std::string &msg)
{
for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) {
cs->SendExternalChat(source, colour, user, msg);
if (cs->status >= ServerNetworkGameSocketHandler::STATUS_AUTHORIZED) cs->SendExternalChat(source, colour, user, msg);
}
NetworkTextMessage(NETWORK_ACTION_EXTERNAL_CHAT, colour, false, user, msg, {}, source.c_str());
}
@@ -1903,37 +1905,37 @@ static void NetworkAutoCleanCompanies()
}
/* Go through all the companies */
for (const Company *c : Company::Iterate()) {
for (Company *c : Company::Iterate()) {
/* Skip the non-active once */
if (c->is_ai) continue;
if (!HasBit(has_clients, c->index)) {
/* The company is empty for one month more */
_network_company_states[c->index].months_empty++;
if (c->months_empty != std::numeric_limits<decltype(c->months_empty)>::max()) c->months_empty++;
/* Is the company empty for autoclean_unprotected-months, and is there no protection? */
if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && _network_company_states[c->index].password.empty()) {
if (_settings_client.network.autoclean_unprotected != 0 && c->months_empty > _settings_client.network.autoclean_unprotected && _network_company_states[c->index].password.empty()) {
/* Shut the company down */
DoCommandP(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, CMD_COMPANY_CTRL);
IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no password", c->index + 1);
}
/* Is the company empty for autoclean_protected-months, and there is a protection? */
if (_settings_client.network.autoclean_protected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_protected && !_network_company_states[c->index].password.empty()) {
if (_settings_client.network.autoclean_protected != 0 && c->months_empty > _settings_client.network.autoclean_protected && !_network_company_states[c->index].password.empty()) {
/* Unprotect the company */
_network_company_states[c->index].password.clear();
IConsolePrintF(CC_DEFAULT, "Auto-removed protection from company #%d", c->index + 1);
_network_company_states[c->index].months_empty = 0;
c->months_empty = 0;
NetworkServerUpdateCompanyPassworded(c->index, false);
}
/* Is the company empty for autoclean_novehicles-months, and has no vehicles? */
if (_settings_client.network.autoclean_novehicles != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_novehicles && !HasBit(has_vehicles, c->index)) {
if (_settings_client.network.autoclean_novehicles != 0 && c->months_empty > _settings_client.network.autoclean_novehicles && !HasBit(has_vehicles, c->index)) {
/* Shut the company down */
DoCommandP(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, CMD_COMPANY_CTRL);
IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no vehicles", c->index + 1);
}
} else {
/* It is not empty, reset the date */
_network_company_states[c->index].months_empty = 0;
c->months_empty = 0;
}
}
}
@@ -2522,7 +2524,6 @@ void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci)
if (!_network_server) return;
_network_company_states[c->index].months_empty = 0;
_network_company_states[c->index].password.clear();
NetworkServerUpdateCompanyPassworded(c->index, false);

View File

@@ -73,7 +73,6 @@ struct NetworkCompanyStats {
/** Some state information of a company, especially for servers */
struct NetworkCompanyState {
std::string password; ///< The password for the company
uint16_t months_empty; ///< How many months the company is empty
};
struct NetworkClientInfo;
@@ -169,4 +168,17 @@ struct NetworkTextMessageData {
}
};
/**
* Simple helper to (more easily) manage authorized keys.
*
* The authorized keys are hexadecimal representations of their binary form.
* The authorized keys are case insensitive.
*/
class NetworkAuthorizedKeys : public std::vector<std::string> {
public:
bool Contains(std::string_view key) const;
bool Add(std::string_view key);
bool Remove(std::string_view key);
};
#endif /* NETWORK_TYPE_H */