diff options
author | est31 <MTest31@outlook.com> | 2015-04-12 04:49:13 +0200 |
---|---|---|
committer | est31 <MTest31@outlook.com> | 2015-05-11 18:40:27 +0200 |
commit | 82e35edff52d88dcd64a9bfc9d2c4c93f1341b78 (patch) | |
tree | bf55839e296c6d1cb9b7f81b8f5cf69e0492b4c0 /src/client.cpp | |
parent | 181f7baa453c58d4070de7196fd74663110946a8 (diff) | |
download | minetest-82e35edff52d88dcd64a9bfc9d2c4c93f1341b78.tar.gz minetest-82e35edff52d88dcd64a9bfc9d2c4c93f1341b78.tar.bz2 minetest-82e35edff52d88dcd64a9bfc9d2c4c93f1341b78.zip |
Make early protocol auth mechanism generic, and add SRP
Adds everything needed for SRP (and everything works too),
but still deactivated, as protocol v25 init packets aren't final yet.
Can be activated by changing the LATEST_PROTOCOL_VERSION header to 25
inside networkprotocol.h.
Diffstat (limited to 'src/client.cpp')
-rw-r--r-- | src/client.cpp | 134 |
1 files changed, 122 insertions, 12 deletions
diff --git a/src/client.cpp b/src/client.cpp index ceea56ba0..8cfcc85a7 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -22,10 +22,12 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <sstream> #include <IFileSystem.h> #include "jthread/jmutexautolock.h" +#include "util/auth.h" #include "util/directiontables.h" #include "util/pointedthing.h" #include "util/serialize.h" #include "util/string.h" +#include "util/srp.h" #include "client.h" #include "network/clientopcodes.h" #include "filesys.h" @@ -255,6 +257,8 @@ Client::Client( m_highlighted_pos(0,0,0), m_map_seed(0), m_password(password), + m_chosen_auth_mech(AUTH_MECHANISM_NONE), + m_auth_data(NULL), m_access_denied(false), m_itemdef_received(false), m_nodedef_received(false), @@ -404,10 +408,13 @@ void Client::step(float dtime) memset(pName, 0, PLAYERNAME_SIZE * sizeof(char)); memset(pPassword, 0, PASSWORD_SIZE * sizeof(char)); + std::string hashed_password = translatePassword(myplayer->getName(), m_password); snprintf(pName, PLAYERNAME_SIZE, "%s", myplayer->getName()); - snprintf(pPassword, PASSWORD_SIZE, "%s", m_password.c_str()); + snprintf(pPassword, PASSWORD_SIZE, "%s", hashed_password.c_str()); sendLegacyInit(pName, pPassword); + if (LATEST_PROTOCOL_VERSION >= 25) + sendInit(myplayer->getName()); } // Not connected, return @@ -943,6 +950,39 @@ void Client::interact(u8 action, const PointedThing& pointed) Send(&pkt); } +void Client::deleteAuthData() +{ + if (!m_auth_data) + return; + + switch (m_chosen_auth_mech) { + case AUTH_MECHANISM_FIRST_SRP: + break; + case AUTH_MECHANISM_SRP: + case AUTH_MECHANISM_LEGACY_PASSWORD: + srp_user_delete((SRPUser *) m_auth_data); + m_auth_data = NULL; + break; + case AUTH_MECHANISM_NONE: + break; + } +} + + +AuthMechanism Client::choseAuthMech(const u32 mechs) +{ + if (mechs & AUTH_MECHANISM_SRP) + return AUTH_MECHANISM_SRP; + + if (mechs & AUTH_MECHANISM_FIRST_SRP) + return AUTH_MECHANISM_FIRST_SRP; + + if (mechs & AUTH_MECHANISM_LEGACY_PASSWORD) + return AUTH_MECHANISM_LEGACY_PASSWORD; + + return AUTH_MECHANISM_NONE; +} + void Client::sendLegacyInit(const char* playerName, const char* playerPassword) { NetworkPacket pkt(TOSERVER_INIT_LEGACY, @@ -956,6 +996,70 @@ void Client::sendLegacyInit(const char* playerName, const char* playerPassword) Send(&pkt); } +void Client::sendInit(const std::string &playerName) +{ + NetworkPacket pkt(TOSERVER_INIT, 1 + 2 + 2 + (1 + playerName.size())); + + // TODO (later) actually send supported compression modes + pkt << (u8) SER_FMT_VER_HIGHEST_READ << (u8) 42; + pkt << (u16) CLIENT_PROTOCOL_VERSION_MIN << (u16) CLIENT_PROTOCOL_VERSION_MAX; + pkt << playerName; + + Send(&pkt); +} + +void Client::startAuth(AuthMechanism chosen_auth_mechanism) +{ + m_chosen_auth_mech = chosen_auth_mechanism; + + switch (chosen_auth_mechanism) { + case AUTH_MECHANISM_FIRST_SRP: { + // send srp verifier to server + NetworkPacket resp_pkt(TOSERVER_FIRST_SRP, 0); + char *salt, *bytes_v; + std::size_t len_salt, len_v; + salt = NULL; + getSRPVerifier(getPlayerName(), m_password, + &salt, &len_salt, &bytes_v, &len_v); + resp_pkt + << std::string((char*)salt, len_salt) + << std::string((char*)bytes_v, len_v) + << (u8)((m_password == "") ? 1 : 0); + free(salt); + free(bytes_v); + Send(&resp_pkt); + break; + } + case AUTH_MECHANISM_SRP: + case AUTH_MECHANISM_LEGACY_PASSWORD: { + u8 based_on = 1; + + if (chosen_auth_mechanism == AUTH_MECHANISM_LEGACY_PASSWORD) { + m_password = translatePassword(getPlayerName(), m_password); + based_on = 0; + } + + std::string playername_u = lowercase(getPlayerName()); + m_auth_data = srp_user_new(SRP_SHA256, SRP_NG_2048, + getPlayerName().c_str(), playername_u.c_str(), + (const unsigned char *) m_password.c_str(), + m_password.length(), NULL, NULL); + char *bytes_A = 0; + size_t len_A = 0; + srp_user_start_authentication((struct SRPUser *) m_auth_data, + NULL, NULL, 0, (unsigned char **) &bytes_A, &len_A); + + NetworkPacket resp_pkt(TOSERVER_SRP_BYTES_A, 0); + resp_pkt << std::string(bytes_A, len_A) << based_on; + free(bytes_A); + Send(&resp_pkt); + break; + } + case AUTH_MECHANISM_NONE: + break; // not handled in this method + } +} + void Client::sendDeletedBlocks(std::vector<v3s16> &blocks) { NetworkPacket pkt(TOSERVER_DELETEDBLOCKS, 1 + sizeof(v3s16) * blocks.size()); @@ -1066,24 +1170,30 @@ void Client::sendChangePassword(const std::string &oldpassword, const std::string &newpassword) { Player *player = m_env.getLocalPlayer(); - if(player == NULL) + if (player == NULL) return; std::string playername = player->getName(); - std::string oldpwd = translatePassword(playername, oldpassword); - std::string newpwd = translatePassword(playername, newpassword); + if (m_proto_ver >= 25) { + // get into sudo mode and then send new password to server + m_password = oldpassword; + m_new_password = newpassword; + startAuth(choseAuthMech(m_sudo_auth_methods)); + } else { + std::string oldpwd = translatePassword(playername, oldpassword); + std::string newpwd = translatePassword(playername, newpassword); - NetworkPacket pkt(TOSERVER_PASSWORD_LEGACY, 2 * PASSWORD_SIZE); + NetworkPacket pkt(TOSERVER_PASSWORD_LEGACY, 2 * PASSWORD_SIZE); - for(u8 i = 0; i < PASSWORD_SIZE; i++) { - pkt << (u8) (i < oldpwd.length() ? oldpwd[i] : 0); - } + for (u8 i = 0; i < PASSWORD_SIZE; i++) { + pkt << (u8) (i < oldpwd.length() ? oldpwd[i] : 0); + } - for(u8 i = 0; i < PASSWORD_SIZE; i++) { - pkt << (u8) (i < newpwd.length() ? newpwd[i] : 0); + for (u8 i = 0; i < PASSWORD_SIZE; i++) { + pkt << (u8) (i < newpwd.length() ? newpwd[i] : 0); + } + Send(&pkt); } - - Send(&pkt); } |