summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorLoic Blot <loic.blot@unix-experience.fr>2015-03-13 16:35:21 +0100
committerLoic Blot <loic.blot@unix-experience.fr>2015-03-13 20:23:03 +0100
commit74d34da6cbb06a4d5659eb3287a87239c31da22c (patch)
tree639e35ad15a662006442431fdcc53b441f415e7f /src/network
parent9f3fc7201beedc66f974d54415b8e3fedb13ccb3 (diff)
downloadminetest-74d34da6cbb06a4d5659eb3287a87239c31da22c.tar.gz
minetest-74d34da6cbb06a4d5659eb3287a87239c31da22c.tar.bz2
minetest-74d34da6cbb06a4d5659eb3287a87239c31da22c.zip
Prepare Protocol v25 init & authentication.
* TOSERVER_INIT and TOCLIENT_INIT renamed to _LEGACY * TOSERVER_PASSWORD merged from dev-0.5, can use protocol v24 and v25 * TOCLIENT_ACCESS_DENIED merged from dev-0.5, can use protocol v24 and v25, with normalized strings an a custom id for custom errors * new TOSERVER_INIT packet only send MT version, supported compressions, protocols and serialization, this permit to rework everything later without break the _INIT packet * new TOSERVER_AUTH packet which auth the client * new TOCLIENT_HELLO packet which send server serialization version atm * new TOCLIENT_AUTH_ACCEPTED which is send when TOCLIENT_AUTH was okay. After this packet, the client load datas from servers, like after TOCLIENT_INIT_LEGACY packet
Diffstat (limited to 'src/network')
-rw-r--r--src/network/clientopcodes.cpp6
-rw-r--r--src/network/networkprotocol.h34
-rw-r--r--src/network/packethandlers/client.cpp58
-rw-r--r--src/network/packethandlers/server.cpp348
-rw-r--r--src/network/serveropcodes.cpp12
5 files changed, 400 insertions, 58 deletions
diff --git a/src/network/clientopcodes.cpp b/src/network/clientopcodes.cpp
index f236b6353..556e8d0c0 100644
--- a/src/network/clientopcodes.cpp
+++ b/src/network/clientopcodes.cpp
@@ -26,8 +26,8 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] =
{
null_command_handler, // 0x00 (never use this)
null_command_handler, // 0x01
- null_command_handler, // 0x02
- null_command_handler, // 0x03
+ { "TOCLIENT_HELLO", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_Hello }, // 0x02
+ { "TOCLIENT_AUTH_ACCEPT", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_AuthAccept }, // 0x03
null_command_handler, // 0x04
null_command_handler, // 0x05
null_command_handler, // 0x06
@@ -40,7 +40,7 @@ const ToClientCommandHandler toClientCommandTable[TOCLIENT_NUM_MSG_TYPES] =
null_command_handler, // 0x0D
null_command_handler, // 0x0E
null_command_handler, // 0x0F
- { "TOCLIENT_INIT", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_Init }, // 0x10
+ { "TOCLIENT_INIT", TOCLIENT_STATE_NOT_CONNECTED, &Client::handleCommand_InitLegacy }, // 0x10
null_command_handler,
null_command_handler,
null_command_handler,
diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h
index 1e0896ebf..599b70006 100644
--- a/src/network/networkprotocol.h
+++ b/src/network/networkprotocol.h
@@ -110,14 +110,21 @@ with this program; if not, write to the Free Software Foundation, Inc.,
ContentFeatures: change number of special tiles to 6 (CF_SPECIAL_COUNT)
PROTOCOL_VERSION 25:
Rename TOCLIENT_ACCESS_DENIED to TOCLIENT_ACCESS_DENIED_LEGAGY
- Rename TOCLIENT_DELETE_PARTICLESPAWNER to TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY
+ Rename TOCLIENT_DELETE_PARTICLESPAWNER to
+ TOCLIENT_DELETE_PARTICLESPAWNER_LEGACY
Rename TOSERVER_PASSWORD to TOSERVER_PASSWORD_LEGACY
Rename TOSERVER_INIT to TOSERVER_INIT_LEGACY
+ Rename TOCLIENT_INIT to TOCLIENT_INIT_LEGACY
Add TOCLIENT_ACCESS_DENIED new opcode (0x0A), using error codes
for standard error, keeping customisation possible. This
permit translation
Add TOCLIENT_DELETE_PARTICLESPAWNER (0x53), fixing the u16 read and
reading u32
+ Add TOSERVER_INIT new opcode (0x02) for client presentation to server
+ Add TOSERVER_AUTH new opcode (0x03) for client authentication
+ Add TOCLIENT_HELLO for presenting server to client after client
+ presentation
+ Add TOCLIENT_AUTH_ACCEPT to accept connexion from client
*/
#define LATEST_PROTOCOL_VERSION 24
@@ -143,6 +150,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
enum ToClientCommand
{
+ TOCLIENT_HELLO = 0x02,
+ TOCLIENT_AUTH_ACCEPT = 0x03,
TOCLIENT_ACCESS_DENIED = 0x0A,
/*
u16 command
@@ -150,7 +159,7 @@ enum ToClientCommand
wstring reason
*/
- TOCLIENT_INIT = 0x10,
+ TOCLIENT_INIT_LEGACY = 0x10,
/*
Server's reply to TOSERVER_INIT.
Sent second after connected.
@@ -585,17 +594,22 @@ enum ToClientCommand
enum ToServerCommand
{
- TOSERVER_INIT = 0x0F,
+ TOSERVER_INIT = 0x02,
/*
Sent first after connected.
[0] u16 TOSERVER_INIT
[2] u8 SER_FMT_VER_HIGHEST_READ
[3] u8 compression_modes
- [4] std::string player_name
- [4+*] std::string password (new in some version)
- [4+*+*] u16 minimum supported network protocol version (added sometime)
- [4+*+*+2] u16 maximum supported network protocol version (added later than the previous one)
+ */
+
+ TOSERVER_AUTH = 0x03,
+ /*
+ Sent first after presentation (INIT).
+ [0] std::string player_name
+ [0+*] std::string password (new in some version)
+ [0+*+*] u16 minimum supported network protocol version (added sometime)
+ [0+*+*+2] u16 maximum supported network protocol version (added later than the previous one)
*/
TOSERVER_INIT_LEGACY = 0x10,
@@ -856,8 +870,9 @@ enum AccessDeniedCode {
SERVER_ACCESSDENIED_TOO_MANY_USERS = 6,
SERVER_ACCESSDENIED_EMPTY_PASSWORD = 7,
SERVER_ACCESSDENIED_ALREADY_CONNECTED = 8,
- SERVER_ACCESSDENIED_CUSTOM_STRING = 9,
- SERVER_ACCESSDENIED_MAX = 10,
+ SERVER_ACCESSDENIED_SERVER_FAIL = 9,
+ SERVER_ACCESSDENIED_CUSTOM_STRING = 10,
+ SERVER_ACCESSDENIED_MAX = 11,
};
enum NetProtoCompressionMode {
@@ -874,6 +889,7 @@ const static std::wstring accessDeniedStrings[SERVER_ACCESSDENIED_MAX] = {
L"Too many users.",
L"Empty passwords are disallowed. Set a password and try again.",
L"Another client is connected with this name. If your client closed unexpectedly, try again in a minute.",
+ L"Server authenticator failed. Maybe the servers has some problems."
L"",
};
diff --git a/src/network/packethandlers/client.cpp b/src/network/packethandlers/client.cpp
index ae24157e0..838c85989 100644
--- a/src/network/packethandlers/client.cpp
+++ b/src/network/packethandlers/client.cpp
@@ -38,7 +38,7 @@ void Client::handleCommand_Deprecated(NetworkPacket* pkt)
<< pkt->getPeerId() << "!" << std::endl;
}
-void Client::handleCommand_Init(NetworkPacket* pkt)
+void Client::handleCommand_Hello(NetworkPacket* pkt)
{
if (pkt->getSize() < 1)
return;
@@ -46,11 +46,56 @@ void Client::handleCommand_Init(NetworkPacket* pkt)
u8 deployed;
*pkt >> deployed;
- infostream << "Client: TOCLIENT_INIT received with "
+ infostream << "Client: TOCLIENT_HELLO received with "
"deployed=" << ((int)deployed & 0xff) << std::endl;
if (!ser_ver_supported(deployed)) {
- infostream << "Client: TOCLIENT_INIT: Server sent "
+ infostream << "Client: TOCLIENT_HELLO: Server sent "
+ << "unsupported ser_fmt_ver"<< std::endl;
+ return;
+ }
+
+ m_server_ser_ver = deployed;
+
+ // @ TODO auth to server
+}
+
+void Client::handleCommand_AuthAccept(NetworkPacket* pkt)
+{
+ v3f playerpos;
+ *pkt >> playerpos >> m_map_seed >> m_recommended_send_interval;
+
+ playerpos -= v3f(0, BS / 2, 0);
+
+ // Set player position
+ Player *player = m_env.getLocalPlayer();
+ assert(player != NULL);
+ player->setPosition(playerpos);
+
+ infostream << "Client: received map seed: " << m_map_seed << std::endl;
+ infostream << "Client: received recommended send interval "
+ << m_recommended_send_interval<<std::endl;
+
+ // Reply to server
+ NetworkPacket* resp_pkt = new NetworkPacket(TOSERVER_INIT2, 0);
+ Send(resp_pkt);
+
+ m_state = LC_Init;
+}
+
+void Client::handleCommand_InitLegacy(NetworkPacket* pkt)
+{
+ if (pkt->getSize() < 1)
+ return;
+
+ u8 deployed;
+ *pkt >> deployed;
+
+ infostream << "Client: TOCLIENT_INIT_LEGACY received with "
+ "deployed=" << ((int)deployed & 0xff) << std::endl;
+
+ if (!ser_ver_supported(deployed)) {
+ infostream << "Client: TOCLIENT_INIT_LEGACY: Server sent "
<< "unsupported ser_fmt_ver"<< std::endl;
return;
}
@@ -98,10 +143,11 @@ void Client::handleCommand_AccessDenied(NetworkPacket* pkt)
m_access_denied_reason = L"Unknown";
if (pkt->getCommand() == TOCLIENT_ACCESS_DENIED) {
+ if (pkt->getSize() < 1)
+ return;
+
u8 denyCode = SERVER_ACCESSDENIED_UNEXPECTED_DATA;
- if(pkt->getSize() >= 1) {
- *pkt >> denyCode;
- }
+ *pkt >> denyCode;
if (denyCode == SERVER_ACCESSDENIED_CUSTOM_STRING) {
*pkt >> m_access_denied_reason;
}
diff --git a/src/network/packethandlers/server.cpp b/src/network/packethandlers/server.cpp
index 113ca6c8f..ee30dfd06 100644
--- a/src/network/packethandlers/server.cpp
+++ b/src/network/packethandlers/server.cpp
@@ -43,6 +43,283 @@ void Server::handleCommand_Deprecated(NetworkPacket* pkt)
<< " not supported anymore" << std::endl;
}
+void Server::handleCommand_Init(NetworkPacket* pkt)
+{
+
+ if(pkt->getSize() < 1)
+ return;
+
+ RemoteClient* client = getClient(pkt->getPeerId(), CS_Created);
+
+ std::string addr_s;
+ try {
+ Address address = getPeerAddress(pkt->getPeerId());
+ addr_s = address.serializeString();
+ }
+ catch (con::PeerNotFoundException &e) {
+ /*
+ * no peer for this packet found
+ * most common reason is peer timeout, e.g. peer didn't
+ * respond for some time, your server was overloaded or
+ * things like that.
+ */
+ infostream << "Server::ProcessData(): Canceling: peer "
+ << pkt->getPeerId() << " not found" << std::endl;
+ return;
+ }
+
+ // If net_proto_version is set, this client has already been handled
+ if (client->getState() > CS_Created) {
+ verbosestream << "Server: Ignoring multiple TOSERVER_INITs from "
+ << addr_s << " (peer_id=" << pkt->getPeerId() << ")" << std::endl;
+ return;
+ }
+
+ verbosestream << "Server: Got TOSERVER_INIT from " << addr_s << " (peer_id="
+ << pkt->getPeerId() << ")" << std::endl;
+
+ // Do not allow multiple players in simple singleplayer mode.
+ // This isn't a perfect way to do it, but will suffice for now
+ if (m_simple_singleplayer_mode && m_clients.getClientIDs().size() > 1) {
+ infostream << "Server: Not allowing another client (" << addr_s
+ << ") to connect in simple singleplayer mode" << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_SINGLEPLAYER);
+ return;
+ }
+
+ // First byte after command is maximum supported
+ // serialization version
+ u8 client_max;
+ u8 compression_modes;
+ u16 min_net_proto_version = 0;
+ u16 max_net_proto_version;
+
+ *pkt >> client_max >> compression_modes >> min_net_proto_version
+ >> max_net_proto_version;
+
+ u8 our_max = SER_FMT_VER_HIGHEST_READ;
+ // Use the highest version supported by both
+ int deployed = std::min(client_max, our_max);
+ // If it's lower than the lowest supported, give up.
+ if (deployed < SER_FMT_VER_LOWEST)
+ deployed = SER_FMT_VER_INVALID;
+
+ if (deployed == SER_FMT_VER_INVALID) {
+ actionstream << "Server: A mismatched client tried to connect from "
+ << addr_s << std::endl;
+ infostream<<"Server: Cannot negotiate serialization version with "
+ << addr_s << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_WRONG_VERSION);
+ return;
+ }
+
+ client->setPendingSerializationVersion(deployed);
+
+ /*
+ Read and check network protocol version
+ */
+
+ u16 net_proto_version = 0;
+
+ // Figure out a working version if it is possible at all
+ if (max_net_proto_version >= SERVER_PROTOCOL_VERSION_MIN ||
+ min_net_proto_version <= SERVER_PROTOCOL_VERSION_MAX) {
+ // If maximum is larger than our maximum, go with our maximum
+ if (max_net_proto_version > SERVER_PROTOCOL_VERSION_MAX)
+ net_proto_version = SERVER_PROTOCOL_VERSION_MAX;
+ // Else go with client's maximum
+ else
+ net_proto_version = max_net_proto_version;
+ }
+
+ verbosestream << "Server: " << addr_s << ": Protocol version: min: "
+ << min_net_proto_version << ", max: " << max_net_proto_version
+ << ", chosen: " << net_proto_version << std::endl;
+
+ client->net_proto_version = net_proto_version;
+
+ // On this handler protocol version 25 is required
+ if (net_proto_version < 25 ||
+ net_proto_version < SERVER_PROTOCOL_VERSION_MIN ||
+ net_proto_version > SERVER_PROTOCOL_VERSION_MAX) {
+ actionstream << "Server: A mismatched client tried to connect from "
+ << addr_s << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_WRONG_VERSION);
+ return;
+ }
+
+ if (g_settings->getBool("strict_protocol_version_checking")) {
+ if (net_proto_version != LATEST_PROTOCOL_VERSION) {
+ actionstream << "Server: A mismatched (strict) client tried to "
+ << "connect from " << addr_s << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_WRONG_VERSION);
+ return;
+ }
+ }
+
+ // @TODO: check if we support same modes, but not required now
+
+ client->setSupportedCompressionModes(compression_modes);
+
+ m_clients.event(pkt->getPeerId(), CSE_Init);
+}
+
+void Server::handleCommand_Auth(NetworkPacket* pkt)
+{
+ std::string addr_s;
+ try {
+ Address address = getPeerAddress(pkt->getPeerId());
+ addr_s = address.serializeString();
+ }
+ catch (con::PeerNotFoundException &e) {
+ /*
+ * no peer for this packet found
+ * most common reason is peer timeout, e.g. peer didn't
+ * respond for some time, your server was overloaded or
+ * things like that.
+ */
+ infostream << "Server::ProcessData(): Canceling: peer "
+ << pkt->getPeerId() << " not found" << std::endl;
+ return;
+ }
+
+ std::string playerName, playerPassword;
+
+ *pkt >> playerName >> playerPassword;
+
+ const char* playername = playerName.c_str();
+
+ if (playerName.size() > PLAYERNAME_SIZE) {
+ actionstream << "Server: Player with an too long name "
+ << "tried to connect from " << addr_s << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_WRONG_NAME);
+ return;
+ }
+
+ if (string_allowed(playerName, PLAYERNAME_ALLOWED_CHARS) == false) {
+ actionstream << "Server: Player with an invalid name "
+ << "tried to connect from " << addr_s << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_WRONG_CHARS_IN_NAME);
+ return;
+ }
+
+ if (!isSingleplayer() && strcasecmp(playername, "singleplayer") == 0) {
+ actionstream << "Server: Player with the name \"singleplayer\" "
+ << "tried to connect from " << addr_s << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_WRONG_NAME);
+ return;
+ }
+
+ {
+ std::string reason;
+ if(m_script->on_prejoinplayer(playername, addr_s, reason)) {
+ actionstream << "Server: Player with the name \"" << playerName << "\" "
+ << "tried to connect from " << addr_s << " "
+ << "but it was disallowed for the following reason: "
+ << reason << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_CUSTOM_STRING,
+ narrow_to_wide(reason.c_str()));
+ return;
+ }
+ }
+
+ if (playerPassword.size() > PASSWORD_SIZE) {
+ actionstream << "Server: Player with an too long password "
+ << "tried to connect from " << addr_s << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_WRONG_PASSWORD);
+ return;
+ }
+
+ infostream << "Server: New connection: \"" << playerName << "\" from "
+ << addr_s << " (peer_id=" << pkt->getPeerId() << ")" << std::endl;
+
+ if(!base64_is_valid(playerPassword)){
+ actionstream << "Server: " << playerName
+ << " supplied invalid password hash" << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_WRONG_PASSWORD);
+ return;
+ }
+
+ // Enforce user limit.
+ // Don't enforce for users that have some admin right
+ if (m_clients.getClientIDs(CS_Created).size() >= g_settings->getU16("max_users") &&
+ !checkPriv(playername, "server") &&
+ !checkPriv(playername, "ban") &&
+ !checkPriv(playername, "privs") &&
+ !checkPriv(playername, "password") &&
+ playername != g_settings->get("name")) {
+ actionstream << "Server: " << playername << " tried to join, but there"
+ << " are already max_users="
+ << g_settings->getU16("max_users") << " players." << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_TOO_MANY_USERS);
+ return;
+ }
+
+ std::string checkpwd; // Password hash to check against
+ bool has_auth = m_script->getAuth(playername, &checkpwd, NULL);
+
+ // If no authentication info exists for user, create it
+ if (!has_auth) {
+ if (!isSingleplayer() &&
+ g_settings->getBool("disallow_empty_password") &&
+ playerPassword.empty()) {
+ actionstream << "Server: " << playerName
+ << " supplied empty password" << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_EMPTY_PASSWORD);
+ return;
+ }
+ std::wstring raw_default_password =
+ narrow_to_wide(g_settings->get("default_password"));
+ std::string initial_password =
+ translatePassword(playername, raw_default_password);
+
+ // If default_password is empty, allow any initial password
+ if (raw_default_password.length() == 0)
+ initial_password = playerPassword.c_str();
+
+ m_script->createAuth(playername, initial_password);
+ }
+
+ has_auth = m_script->getAuth(playername, &checkpwd, NULL);
+
+ if(!has_auth) {
+ actionstream << "Server: " << playerName << " cannot be authenticated"
+ << " (auth handler does not work?)" << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_SERVER_FAIL);
+ return;
+ }
+
+ if(playerPassword.c_str() != checkpwd) {
+ actionstream << "Server: " << playerName << " supplied wrong password"
+ << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_WRONG_PASSWORD);
+ return;
+ }
+
+ RemotePlayer *player =
+ static_cast<RemotePlayer*>(m_env->getPlayer(playername));
+
+ if (player && player->peer_id != 0) {
+ errorstream << "Server: " << playername << ": Failed to emerge player"
+ << " (player allocated to an another client)" << std::endl;
+ DenyAccess(pkt->getPeerId(), SERVER_ACCESSDENIED_ALREADY_CONNECTED);
+ }
+
+ m_clients.setPlayerName(pkt->getPeerId(), playername);
+
+ /*
+ Answer with a TOCLIENT_INIT
+ */
+
+ NetworkPacket resp_pkt(TOCLIENT_AUTH_ACCEPT, 1 + 6 + 8 + 4, pkt->getPeerId());
+
+ resp_pkt << v3f(0,0,0) << (u64) m_env->getServerMap().getSeed()
+ << g_settings->getFloat("dedicated_server_step");
+
+ Send(&resp_pkt);
+ m_clients.event(pkt->getPeerId(), CSE_Init);
+}
+
void Server::handleCommand_Init_Legacy(NetworkPacket* pkt)
{
// [0] u8 SER_FMT_VER_HIGHEST_READ
@@ -86,7 +363,7 @@ void Server::handleCommand_Init_Legacy(NetworkPacket* pkt)
if (m_simple_singleplayer_mode && m_clients.getClientIDs().size() > 1) {
infostream << "Server: Not allowing another client (" << addr_s
<< ") to connect in simple singleplayer mode" << std::endl;
- DenyAccess(pkt->getPeerId(), L"Running in simple singleplayer mode.");
+ DenyAccess_Legacy(pkt->getPeerId(), L"Running in simple singleplayer mode.");
return;
}
@@ -108,7 +385,7 @@ void Server::handleCommand_Init_Legacy(NetworkPacket* pkt)
<< addr_s << std::endl;
infostream<<"Server: Cannot negotiate serialization version with "
<< addr_s << std::endl;
- DenyAccess(pkt->getPeerId(), std::wstring(
+ DenyAccess_Legacy(pkt->getPeerId(), std::wstring(
L"Your client's version is not supported.\n"
L"Server version is ")
+ narrow_to_wide(minetest_version_simple) + L"."
@@ -156,7 +433,7 @@ void Server::handleCommand_Init_Legacy(NetworkPacket* pkt)
net_proto_version > SERVER_PROTOCOL_VERSION_MAX) {
actionstream << "Server: A mismatched client tried to connect from "
<< addr_s << std::endl;
- DenyAccess(pkt->getPeerId(), std::wstring(
+ DenyAccess_Legacy(pkt->getPeerId(), std::wstring(
L"Your client's version is not supported.\n"
L"Server version is ")
+ narrow_to_wide(minetest_version_simple) + L",\n"
@@ -176,7 +453,7 @@ void Server::handleCommand_Init_Legacy(NetworkPacket* pkt)
if (net_proto_version != LATEST_PROTOCOL_VERSION) {
actionstream << "Server: A mismatched (strict) client tried to "
<< "connect from " << addr_s << std::endl;
- DenyAccess(pkt->getPeerId(), std::wstring(
+ DenyAccess_Legacy(pkt->getPeerId(), std::wstring(
L"Your client's version is not supported.\n"
L"Server version is ")
+ narrow_to_wide(minetest_version_simple) + L",\n"
@@ -205,7 +482,7 @@ void Server::handleCommand_Init_Legacy(NetworkPacket* pkt)
if (playername_length == PLAYERNAME_SIZE) {
actionstream << "Server: Player with name exceeding max length "
<< "tried to connect from " << addr_s << std::endl;
- DenyAccess(pkt->getPeerId(), L"Name too long");
+ DenyAccess_Legacy(pkt->getPeerId(), L"Name too long");
return;
}
@@ -213,21 +490,21 @@ void Server::handleCommand_Init_Legacy(NetworkPacket* pkt)
if (playername[0]=='\0') {
actionstream << "Server: Player with an empty name "
<< "tried to connect from " << addr_s << std::endl;
- DenyAccess(pkt->getPeerId(), L"Empty name");
+ DenyAccess_Legacy(pkt->getPeerId(), L"Empty name");
return;
}
if (string_allowed(playername, PLAYERNAME_ALLOWED_CHARS) == false) {
actionstream << "Server: Player with an invalid name "
<< "tried to connect from " << addr_s << std::endl;
- DenyAccess(pkt->getPeerId(), L"Name contains unallowed characters");
+ DenyAccess_Legacy(pkt->getPeerId(), L"Name contains unallowed characters");
return;
}
if (!isSingleplayer() && strcasecmp(playername, "singleplayer") == 0) {
actionstream << "Server: Player with the name \"singleplayer\" "
<< "tried to connect from " << addr_s << std::endl;
- DenyAccess(pkt->getPeerId(), L"Name is not allowed");
+ DenyAccess_Legacy(pkt->getPeerId(), L"Name is not allowed");
return;
}
@@ -238,7 +515,7 @@ void Server::handleCommand_Init_Legacy(NetworkPacket* pkt)
<< "tried to connect from " << addr_s << " "
<< "but it was disallowed for the following reason: "
<< reason << std::endl;
- DenyAccess(pkt->getPeerId(), narrow_to_wide(reason.c_str()));
+ DenyAccess_Legacy(pkt->getPeerId(), narrow_to_wide(reason.c_str()));
return;
}
}
@@ -262,7 +539,7 @@ void Server::handleCommand_Init_Legacy(NetworkPacket* pkt)
if (!base64_is_valid(given_password)) {
actionstream << "Server: " << playername
<< " supplied invalid password hash" << std::endl;
- DenyAccess(pkt->getPeerId(), L"Invalid password hash");
+ DenyAccess_Legacy(pkt->getPeerId(), L"Invalid password hash");
return;
}
@@ -277,7 +554,7 @@ void Server::handleCommand_Init_Legacy(NetworkPacket* pkt)
actionstream << "Server: " << playername << " tried to join, but there"
<< " are already max_users="
<< g_settings->getU16("max_users") << " players." << std::endl;
- DenyAccess(pkt->getPeerId(), L"Too many users.");
+ DenyAccess_Legacy(pkt->getPeerId(), L"Too many users.");
return;
}
@@ -291,7 +568,7 @@ void Server::handleCommand_Init_Legacy(NetworkPacket* pkt)
std::string(given_password) == "") {
actionstream << "Server: " << playername
<< " supplied empty password" << std::endl;
- DenyAccess(pkt->getPeerId(), L"Empty passwords are "
+ DenyAccess_Legacy(pkt->getPeerId(), L"Empty passwords are "
L"disallowed. Set a password and try again.");
return;
}
@@ -312,14 +589,14 @@ void Server::handleCommand_Init_Legacy(NetworkPacket* pkt)
if (!has_auth) {
actionstream << "Server: " << playername << " cannot be authenticated"
<< " (auth handler does not work?)" << std::endl;
- DenyAccess(pkt->getPeerId(), L"Not allowed to login");
+ DenyAccess_Legacy(pkt->getPeerId(), L"Not allowed to login");
return;
}
if (given_password != checkpwd) {
actionstream << "Server: " << playername << " supplied wrong password"
<< std::endl;
- DenyAccess(pkt->getPeerId(), L"Wrong password");
+ DenyAccess_Legacy(pkt->getPeerId(), L"Wrong password");
return;
}
@@ -329,7 +606,7 @@ void Server::handleCommand_Init_Legacy(NetworkPacket* pkt)
if (player && player->peer_id != 0) {
errorstream << "Server: " << playername << ": Failed to emerge player"
<< " (player allocated to an another client)" << std::endl;
- DenyAccess(pkt->getPeerId(), L"Another client is connected with this "
+ DenyAccess_Legacy(pkt->getPeerId(), L"Another client is connected with this "
L"name. If your client closed unexpectedly, try again in "
L"a minute.");
}
@@ -340,7 +617,7 @@ void Server::handleCommand_Init_Legacy(NetworkPacket* pkt)
Answer with a TOCLIENT_INIT
*/
- NetworkPacket* resp_pkt = new NetworkPacket(TOCLIENT_INIT, 1 + 6 + 8 + 4,
+ NetworkPacket* resp_pkt = new NetworkPacket(TOCLIENT_INIT_LEGACY, 1 + 6 + 8 + 4,
pkt->getPeerId());
*resp_pkt << (u8) deployed << (v3s16) floatToInt(v3f(0,0,0), BS)
@@ -942,33 +1219,36 @@ void Server::handleCommand_Breath(NetworkPacket* pkt)
SendPlayerBreath(pkt->getPeerId());
}
-void Server::handleCommand_Password_Legacy(NetworkPacket* pkt)
+void Server::handleCommand_Password(NetworkPacket* pkt)
{
- /*
- [0] u16 TOSERVER_PASSWORD
- [2] u8[28] old password
- [30] u8[28] new password
- */
-
errorstream << "PAssword packet size: " << pkt->getSize() << " size required: " << PASSWORD_SIZE * 2 << std::endl;
- if (pkt->getSize() != PASSWORD_SIZE * 2)
+ if ((pkt->getCommand() == TOSERVER_PASSWORD && pkt->getSize() < 4) ||
+ pkt->getSize() != PASSWORD_SIZE * 2)
return;
std::string oldpwd;
std::string newpwd;
- for (u16 i = 0; i < PASSWORD_SIZE - 1; i++) {
- char c = pkt->getChar(i);
- if (c == 0)
- break;
- oldpwd += c;
+ if (pkt->getCommand() == TOSERVER_PASSWORD) {
+ *pkt >> oldpwd >> newpwd;
}
+ // 13/03/15
+ // Protocol v24 compat. Please remove in 1 year after
+ // client convergence to 0.4.13/0.5.x
+ else {
+ for (u16 i = 0; i < PASSWORD_SIZE - 1; i++) {
+ char c = pkt->getChar(i);
+ if (c == 0)
+ break;
+ oldpwd += c;
+ }
- for (u16 i = 0; i < PASSWORD_SIZE - 1; i++) {
- char c = pkt->getChar(PASSWORD_SIZE + i);
- if (c == 0)
- break;
- newpwd += c;
+ for (u16 i = 0; i < PASSWORD_SIZE - 1; i++) {
+ char c = pkt->getChar(PASSWORD_SIZE + i);
+ if (c == 0)
+ break;
+ newpwd += c;
+ }
}
Player *player = m_env->getPlayer(pkt->getPeerId());
diff --git a/src/network/serveropcodes.cpp b/src/network/serveropcodes.cpp
index cecabf7a8..9c1da9ad1 100644
--- a/src/network/serveropcodes.cpp
+++ b/src/network/serveropcodes.cpp
@@ -26,8 +26,8 @@ const ToServerCommandHandler toServerCommandTable[TOSERVER_NUM_MSG_TYPES] =
{
null_command_handler, // 0x00 (never use this)
null_command_handler, // 0x01
- null_command_handler, // 0x02
- null_command_handler, // 0x03
+ { "TOSERVER_INIT", TOSERVER_STATE_NOT_CONNECTED, &Server::handleCommand_Init }, // 0x02
+ { "TOSERVER_AUTH", TOSERVER_STATE_NOT_CONNECTED, &Server::handleCommand_Auth }, // 0x03
null_command_handler, // 0x04
null_command_handler, // 0x05
null_command_handler, // 0x06
@@ -78,14 +78,14 @@ const ToServerCommandHandler toServerCommandTable[TOSERVER_NUM_MSG_TYPES] =
{ "TOSERVER_SIGNNODETEXT", TOSERVER_STATE_INGAME, &Server::handleCommand_Deprecated }, // 0x33
{ "TOSERVER_CLICK_ACTIVEOBJECT", TOSERVER_STATE_INGAME, &Server::handleCommand_Deprecated }, // 0x34
{ "TOSERVER_DAMAGE", TOSERVER_STATE_INGAME, &Server::handleCommand_Damage }, // 0x35
- { "TOSERVER_PASSWORD_LEGACY", TOSERVER_STATE_INGAME, &Server::handleCommand_Password_Legacy }, // 0x36
+ { "TOSERVER_PASSWORD_LEGACY", TOSERVER_STATE_INGAME, &Server::handleCommand_Password }, // 0x36
{ "TOSERVER_PLAYERITEM", TOSERVER_STATE_INGAME, &Server::handleCommand_PlayerItem }, // 0x37
{ "TOSERVER_RESPAWN", TOSERVER_STATE_INGAME, &Server::handleCommand_Respawn }, // 0x38
{ "TOSERVER_INTERACT", TOSERVER_STATE_INGAME, &Server::handleCommand_Interact }, // 0x39
{ "TOSERVER_REMOVED_SOUNDS", TOSERVER_STATE_INGAME, &Server::handleCommand_RemovedSounds }, // 0x3a
{ "TOSERVER_NODEMETA_FIELDS", TOSERVER_STATE_INGAME, &Server::handleCommand_NodeMetaFields }, // 0x3b
{ "TOSERVER_INVENTORY_FIELDS", TOSERVER_STATE_INGAME, &Server::handleCommand_InventoryFields }, // 0x3c
- null_command_handler, // 0x3d
+ { "TOSERVER_PASSWORD", TOSERVER_STATE_INGAME, &Server::handleCommand_Password }, // 0x3d
null_command_handler, // 0x3e
null_command_handler, // 0x3f
{ "TOSERVER_REQUEST_MEDIA", TOSERVER_STATE_STARTUP, &Server::handleCommand_RequestMedia }, // 0x40
@@ -100,8 +100,8 @@ const ClientCommandFactory clientCommandFactoryTable[TOCLIENT_NUM_MSG_TYPES] =
{
null_command_factory, // 0x00
null_command_factory, // 0x01
- null_command_factory, // 0x02
- null_command_factory, // 0x03
+ { "TOCLIENT_HELLO", 0, true }, // 0x02
+ { "TOCLIENT_AUTH_ACCEPT", 0, true }, // 0x03
null_command_factory, // 0x04
null_command_factory, // 0x05
null_command_factory, // 0x06