Feature: encrypt admin connection when using secure join

This commit is contained in:
Rubidium 2024-03-26 19:03:28 +01:00 committed by rubidium42
parent d3e37a251f
commit 4e026e448c
4 changed files with 27 additions and 0 deletions

View File

@ -94,6 +94,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet &p)
case ADMIN_PACKET_SERVER_RCON_END: return this->Receive_SERVER_RCON_END(p); case ADMIN_PACKET_SERVER_RCON_END: return this->Receive_SERVER_RCON_END(p);
case ADMIN_PACKET_SERVER_PONG: return this->Receive_SERVER_PONG(p); case ADMIN_PACKET_SERVER_PONG: return this->Receive_SERVER_PONG(p);
case ADMIN_PACKET_SERVER_AUTH_REQUEST: return this->Receive_SERVER_AUTH_REQUEST(p); case ADMIN_PACKET_SERVER_AUTH_REQUEST: return this->Receive_SERVER_AUTH_REQUEST(p);
case ADMIN_PACKET_SERVER_ENABLE_ENCRYPTION: return this->Receive_SERVER_ENABLE_ENCRYPTION(p);
default: default:
Debug(net, 0, "[tcp/admin] Received invalid packet type {} from '{}' ({})", type, this->admin_name, this->admin_version); Debug(net, 0, "[tcp/admin] Received invalid packet type {} from '{}' ({})", type, this->admin_name, this->admin_version);
@ -171,3 +172,4 @@ NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_CMD_LOGGING(Packet &
NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_RCON_END(Packet &) { return this->ReceiveInvalidPacket(ADMIN_PACKET_SERVER_RCON_END); } NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_RCON_END(Packet &) { return this->ReceiveInvalidPacket(ADMIN_PACKET_SERVER_RCON_END); }
NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_PONG(Packet &) { return this->ReceiveInvalidPacket(ADMIN_PACKET_SERVER_PONG); } NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_PONG(Packet &) { return this->ReceiveInvalidPacket(ADMIN_PACKET_SERVER_PONG); }
NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_AUTH_REQUEST(Packet &) { return this->ReceiveInvalidPacket(ADMIN_PACKET_SERVER_AUTH_REQUEST); } NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_AUTH_REQUEST(Packet &) { return this->ReceiveInvalidPacket(ADMIN_PACKET_SERVER_AUTH_REQUEST); }
NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_ENABLE_ENCRYPTION(Packet &) { return this->ReceiveInvalidPacket(ADMIN_PACKET_SERVER_ENABLE_ENCRYPTION); }

View File

@ -64,6 +64,7 @@ enum PacketAdminType : uint8_t {
ADMIN_PACKET_SERVER_PONG, ///< The server replies to a ping request from the admin. ADMIN_PACKET_SERVER_PONG, ///< The server replies to a ping request from the admin.
ADMIN_PACKET_SERVER_CMD_LOGGING, ///< The server gives the admin copies of incoming command packets. ADMIN_PACKET_SERVER_CMD_LOGGING, ///< The server gives the admin copies of incoming command packets.
ADMIN_PACKET_SERVER_AUTH_REQUEST, ///< The server gives the admin the used authentication method and required parameters. ADMIN_PACKET_SERVER_AUTH_REQUEST, ///< The server gives the admin the used authentication method and required parameters.
ADMIN_PACKET_SERVER_ENABLE_ENCRYPTION, ///< The server tells that authentication has completed and requests to enable encryption with the keys of the last \c ADMIN_PACKET_ADMIN_AUTH_RESPONSE.
INVALID_ADMIN_PACKET = 0xFF, ///< An invalid marker for admin packets. INVALID_ADMIN_PACKET = 0xFF, ///< An invalid marker for admin packets.
}; };
@ -513,6 +514,14 @@ protected:
*/ */
virtual NetworkRecvStatus Receive_SERVER_AUTH_REQUEST(Packet &p); virtual NetworkRecvStatus Receive_SERVER_AUTH_REQUEST(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);
/** /**
* Send a ping-reply (pong) to the admin that sent us the ping packet. * Send a ping-reply (pong) to the admin that sent us the ping packet.
* uint32_t Integer identifier - should be the same as read from the admins ping packet. * uint32_t Integer identifier - should be the same as read from the admins ping packet.

View File

@ -845,6 +845,17 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendAuthRequest()
return NETWORK_RECV_STATUS_OKAY; return NETWORK_RECV_STATUS_OKAY;
} }
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendEnableEncryption()
{
if (this->status != ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
auto p = std::make_unique<Packet>(this, ADMIN_PACKET_SERVER_ENABLE_ENCRYPTION);
this->authentication_handler->SendEnableEncryption(*p);
this->SendPacket(std::move(p));
return NETWORK_RECV_STATUS_OKAY;
}
NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_AUTH_RESPONSE(Packet &p) NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_AUTH_RESPONSE(Packet &p)
{ {
if (this->status != ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED); if (this->status != ADMIN_STATUS_AUTHENTICATE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
@ -853,6 +864,10 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_AUTH_RESPONSE(P
case NetworkAuthenticationServerHandler::AUTHENTICATED: case NetworkAuthenticationServerHandler::AUTHENTICATED:
Debug(net, 3, "[admin] '{}' ({}) authenticated", this->admin_name, this->admin_version); Debug(net, 3, "[admin] '{}' ({}) authenticated", this->admin_name, this->admin_version);
this->SendEnableEncryption();
this->receive_encryption_handler = this->authentication_handler->CreateClientToServerEncryptionHandler();
this->send_encryption_handler = this->authentication_handler->CreateServerToClientEncryptionHandler();
this->authentication_handler = nullptr; this->authentication_handler = nullptr;
return this->SendProtocol(); return this->SendProtocol();

View File

@ -41,6 +41,7 @@ protected:
NetworkRecvStatus SendProtocol(); NetworkRecvStatus SendProtocol();
NetworkRecvStatus SendPong(uint32_t d1); NetworkRecvStatus SendPong(uint32_t d1);
NetworkRecvStatus SendAuthRequest(); NetworkRecvStatus SendAuthRequest();
NetworkRecvStatus SendEnableEncryption();
public: public:
AdminUpdateFrequency update_frequency[ADMIN_UPDATE_END]; ///< Admin requested update intervals. AdminUpdateFrequency update_frequency[ADMIN_UPDATE_END]; ///< Admin requested update intervals.
std::chrono::steady_clock::time_point connect_time; ///< Time of connection. std::chrono::steady_clock::time_point connect_time; ///< Time of connection.