Add option to not send pre v25 init packet

The legacy init packet (pre v25) sends information about the client's
password that a server could use to log in to other servers if the
username and password are the same. All the other benefits of SRP of
protocol v25 are missed if the legacy init packet is still sent during
connection creation.

This patch adds an option to not send the v25 init packet. Not sending
the v25 packet means breaking compat with pre v25 servers, but as the
option is not enabled by default, no servers are affected unless the
user explicitly flips the switch. More than 90% of the servers on the
serverlist support post v25 protocols.

The patch also fixes a bug with greying out of non compliant servers
being done wrongly, the min and max params were mixed.
This commit is contained in:
est31 2016-03-14 10:18:29 +01:00
parent 2607b97b4f
commit af30183124
10 changed files with 71 additions and 24 deletions

@ -22,9 +22,14 @@ menudata = {}
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Local cached values -- Local cached values
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local min_supp_proto = core.get_min_supp_proto() local min_supp_proto
local max_supp_proto = core.get_max_supp_proto() local max_supp_proto
function common_update_cached_supp_proto()
min_supp_proto = core.get_min_supp_proto()
max_supp_proto = core.get_max_supp_proto()
end
common_update_cached_supp_proto()
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Menu helper functions -- Menu helper functions
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
@ -105,7 +110,7 @@ function render_favorite(spec,render_details)
end end
local details = "" local details = ""
local grey_out = not is_server_protocol_compat(spec.proto_max, spec.proto_min) local grey_out = not is_server_protocol_compat(spec.proto_min, spec.proto_max)
if spec.clients ~= nil and spec.clients_max ~= nil then if spec.clients ~= nil and spec.clients_max ~= nil then
local clients_color = '' local clients_color = ''

@ -17,6 +17,10 @@
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
local function get_formspec(tabview, name, tabdata) local function get_formspec(tabview, name, tabdata)
-- Update the cached supported proto info,
-- it may have changed after a change by the settings menu.
common_update_cached_supp_proto()
local render_details = core.is_yes(core.setting_getbool("public_serverlist")) local render_details = core.is_yes(core.setting_getbool("public_serverlist"))
local retval = local retval =

@ -232,6 +232,12 @@ address (Server address) string
# Note that the port field in the main menu overrides this setting. # Note that the port field in the main menu overrides this setting.
remote_port (Remote port) int 30000 1 65535 remote_port (Remote port) int 30000 1 65535
# Whether to support older servers before protocol version 25.
# Enable if you want to connect to 0.4.12 servers and before.
# Servers starting with 0.4.13 will work, 0.4.12-dev servers may work.
# Disabling this option will protect your password better.
send_pre_v25_init (Support older servers) bool true
# Save the map received by the client on disk. # Save the map received by the client on disk.
enable_local_map_saving (Saving map received from server) bool false enable_local_map_saving (Saving map received from server) bool false

@ -242,6 +242,13 @@
# type: int min: 1 max: 65535 # type: int min: 1 max: 65535
# remote_port = 30000 # remote_port = 30000
# Whether to support older servers before protocol version 25.
# Enable if you want to connect to 0.4.12 servers and before.
# Servers starting with 0.4.13 will work, 0.4.12-dev servers may work.
# Disabling this option will protect your password better.
# type: bool
# send_pre_v25_init = true
# Save the map received by the client on disk. # Save the map received by the client on disk.
# type: bool # type: bool
# enable_local_map_saving = false # enable_local_map_saving = false

@ -386,25 +386,30 @@ void Client::step(float dtime)
Player *myplayer = m_env.getLocalPlayer(); Player *myplayer = m_env.getLocalPlayer();
FATAL_ERROR_IF(myplayer == NULL, "Local player not found in environment."); FATAL_ERROR_IF(myplayer == NULL, "Local player not found in environment.");
// Send TOSERVER_INIT_LEGACY u16 proto_version_min = g_settings->getFlag("send_pre_v25_init") ?
// [0] u16 TOSERVER_INIT_LEGACY CLIENT_PROTOCOL_VERSION_MIN_LEGACY : CLIENT_PROTOCOL_VERSION_MIN;
// [2] u8 SER_FMT_VER_HIGHEST_READ
// [3] u8[20] player_name
// [23] u8[28] password (new in some version)
// [51] u16 minimum supported network protocol version (added sometime)
// [53] u16 maximum supported network protocol version (added later than the previous one)
char pName[PLAYERNAME_SIZE]; if (proto_version_min < 25) {
char pPassword[PASSWORD_SIZE]; // Send TOSERVER_INIT_LEGACY
memset(pName, 0, PLAYERNAME_SIZE * sizeof(char)); // [0] u16 TOSERVER_INIT_LEGACY
memset(pPassword, 0, PASSWORD_SIZE * sizeof(char)); // [2] u8 SER_FMT_VER_HIGHEST_READ
// [3] u8[20] player_name
// [23] u8[28] password (new in some version)
// [51] u16 minimum supported network protocol version (added sometime)
// [53] u16 maximum supported network protocol version (added later than the previous one)
std::string hashed_password = translate_password(myplayer->getName(), m_password); char pName[PLAYERNAME_SIZE];
snprintf(pName, PLAYERNAME_SIZE, "%s", myplayer->getName()); char pPassword[PASSWORD_SIZE];
snprintf(pPassword, PASSWORD_SIZE, "%s", hashed_password.c_str()); memset(pName, 0, PLAYERNAME_SIZE * sizeof(char));
memset(pPassword, 0, PASSWORD_SIZE * sizeof(char));
sendLegacyInit(pName, pPassword); std::string hashed_password = translate_password(myplayer->getName(), m_password);
if (LATEST_PROTOCOL_VERSION >= 25) snprintf(pName, PLAYERNAME_SIZE, "%s", myplayer->getName());
snprintf(pPassword, PASSWORD_SIZE, "%s", hashed_password.c_str());
sendLegacyInit(pName, pPassword);
}
if (CLIENT_PROTOCOL_VERSION_MAX >= 25)
sendInit(myplayer->getName()); sendInit(myplayer->getName());
} }
@ -1003,10 +1008,13 @@ void Client::sendLegacyInit(const char* playerName, const char* playerPassword)
NetworkPacket pkt(TOSERVER_INIT_LEGACY, NetworkPacket pkt(TOSERVER_INIT_LEGACY,
1 + PLAYERNAME_SIZE + PASSWORD_SIZE + 2 + 2); 1 + PLAYERNAME_SIZE + PASSWORD_SIZE + 2 + 2);
u16 proto_version_min = g_settings->getFlag("send_pre_v25_init") ?
CLIENT_PROTOCOL_VERSION_MIN_LEGACY : CLIENT_PROTOCOL_VERSION_MIN;
pkt << (u8) SER_FMT_VER_HIGHEST_READ; pkt << (u8) SER_FMT_VER_HIGHEST_READ;
pkt.putRawString(playerName,PLAYERNAME_SIZE); pkt.putRawString(playerName,PLAYERNAME_SIZE);
pkt.putRawString(playerPassword, PASSWORD_SIZE); pkt.putRawString(playerPassword, PASSWORD_SIZE);
pkt << (u16) CLIENT_PROTOCOL_VERSION_MIN << (u16) CLIENT_PROTOCOL_VERSION_MAX; pkt << (u16) proto_version_min << (u16) CLIENT_PROTOCOL_VERSION_MAX;
Send(&pkt); Send(&pkt);
} }
@ -1017,8 +1025,12 @@ void Client::sendInit(const std::string &playerName)
// we don't support network compression yet // we don't support network compression yet
u16 supp_comp_modes = NETPROTO_COMPRESSION_NONE; u16 supp_comp_modes = NETPROTO_COMPRESSION_NONE;
u16 proto_version_min = g_settings->getFlag("send_pre_v25_init") ?
CLIENT_PROTOCOL_VERSION_MIN_LEGACY : CLIENT_PROTOCOL_VERSION_MIN;
pkt << (u8) SER_FMT_VER_HIGHEST_READ << (u16) supp_comp_modes; pkt << (u8) SER_FMT_VER_HIGHEST_READ << (u16) supp_comp_modes;
pkt << (u16) CLIENT_PROTOCOL_VERSION_MIN << (u16) CLIENT_PROTOCOL_VERSION_MAX; pkt << (u16) proto_version_min << (u16) CLIENT_PROTOCOL_VERSION_MAX;
pkt << playerName; pkt << playerName;
Send(&pkt); Send(&pkt);

@ -184,6 +184,8 @@ void set_default_settings(Settings *settings)
settings->setDefault("minimap_shape_round", "true"); settings->setDefault("minimap_shape_round", "true");
settings->setDefault("minimap_double_scan_height", "true"); settings->setDefault("minimap_double_scan_height", "true");
settings->setDefault("send_pre_v25_init", "true");
settings->setDefault("curl_timeout", "5000"); settings->setDefault("curl_timeout", "5000");
settings->setDefault("curl_parallel_limit", "8"); settings->setDefault("curl_parallel_limit", "8");
settings->setDefault("curl_file_download_timeout", "300000"); settings->setDefault("curl_file_download_timeout", "300000");

@ -145,7 +145,10 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#define SERVER_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION #define SERVER_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION
// Client's supported network protocol range // Client's supported network protocol range
#define CLIENT_PROTOCOL_VERSION_MIN 13 // The minimal version depends on whether
// send_pre_v25_init is enabled or not
#define CLIENT_PROTOCOL_VERSION_MIN 25
#define CLIENT_PROTOCOL_VERSION_MIN_LEGACY 13
#define CLIENT_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION #define CLIENT_PROTOCOL_VERSION_MAX LATEST_PROTOCOL_VERSION
// Constant that differentiates the protocol from random data and other protocols // Constant that differentiates the protocol from random data and other protocols

@ -1095,7 +1095,9 @@ int ModApiMainMenu::l_get_screen_info(lua_State *L)
/******************************************************************************/ /******************************************************************************/
int ModApiMainMenu::l_get_min_supp_proto(lua_State *L) int ModApiMainMenu::l_get_min_supp_proto(lua_State *L)
{ {
lua_pushinteger(L, CLIENT_PROTOCOL_VERSION_MIN); u16 proto_version_min = g_settings->getFlag("send_pre_v25_init") ?
CLIENT_PROTOCOL_VERSION_MIN_LEGACY : CLIENT_PROTOCOL_VERSION_MIN;
lua_pushinteger(L, proto_version_min);
return 1; return 1;
} }

@ -69,8 +69,12 @@ std::vector<ServerListSpec> getLocal()
std::vector<ServerListSpec> getOnline() std::vector<ServerListSpec> getOnline()
{ {
std::ostringstream geturl; std::ostringstream geturl;
u16 proto_version_min = g_settings->getFlag("send_pre_v25_init") ?
CLIENT_PROTOCOL_VERSION_MIN_LEGACY : CLIENT_PROTOCOL_VERSION_MIN;
geturl << g_settings->get("serverlist_url") << geturl << g_settings->get("serverlist_url") <<
"/list?proto_version_min=" << CLIENT_PROTOCOL_VERSION_MIN << "/list?proto_version_min=" << proto_version_min <<
"&proto_version_max=" << CLIENT_PROTOCOL_VERSION_MAX; "&proto_version_max=" << CLIENT_PROTOCOL_VERSION_MAX;
Json::Value root = fetchJsonValue(geturl.str(), NULL); Json::Value root = fetchJsonValue(geturl.str(), NULL);

@ -98,6 +98,8 @@ fake_function() {
gettext("Address to connect to.\nLeave this blank to start a local server.\nNote that the address field in the main menu overrides this setting."); gettext("Address to connect to.\nLeave this blank to start a local server.\nNote that the address field in the main menu overrides this setting.");
gettext("Remote port"); gettext("Remote port");
gettext("Port to connect to (UDP).\nNote that the port field in the main menu overrides this setting."); gettext("Port to connect to (UDP).\nNote that the port field in the main menu overrides this setting.");
gettext("Support older servers");
gettext("Whether to support older servers before protocol version 25.\nEnable if you want to connect to 0.4.12 servers and before.\nServers starting with 0.4.13 will work, 0.4.12-dev servers may work.\nDisabling this option will protect your password better.");
gettext("Saving map received from server"); gettext("Saving map received from server");
gettext("Save the map received by the client on disk."); gettext("Save the map received by the client on disk.");
gettext("Connect to external media server"); gettext("Connect to external media server");