From 6cd0dcc3bc3d2228f54ac496be0c6ca84c5c69cb Mon Sep 17 00:00:00 2001 From: Charles Lohr Date: Sun, 8 May 2005 04:42:33 +0000 Subject: [PATCH] Allow for a slightly smarter and more secure way for users to log onto SMOnline. --- stepmania/Docs/SMLanProtocol.txt | 7 +++++ stepmania/src/NetworkSyncManager.cpp | 39 ++++++++++++++++++++++++++- stepmania/src/NetworkSyncManager.h | 4 +++ stepmania/src/ScreenSMOnlineLogin.cpp | 38 ++++++-------------------- 4 files changed, 57 insertions(+), 31 deletions(-) diff --git a/stepmania/Docs/SMLanProtocol.txt b/stepmania/Docs/SMLanProtocol.txt index 189eea8100..ffbc2d3850 100644 --- a/stepmania/Docs/SMLanProtocol.txt +++ b/stepmania/Docs/SMLanProtocol.txt @@ -192,6 +192,7 @@ NOTE: Server responces always add 128, thus a server responce for no operation 1 Server protocol version //NOTE: if protocol version is 128+, then this server is an SMOnline server NT Server Name + 4 Random key ( at the moment only used for an alternate login method ) 003(131):Allow Start Desc: This will cause the client to start the game. @@ -336,9 +337,15 @@ Client SMOnline packets: 1 Player Number 1 Encryption text 0: MD5 hash + 1: MD5 ( MD5 hash + salt ) (salt is plain text, base 10 string ) NT Username NT Password + Note: The client is not permitted to use method (1) for authentication + if the salt it received from the server is 0 + + + 001: User asks to enter room Size: 1 Enter/Exit? diff --git a/stepmania/src/NetworkSyncManager.cpp b/stepmania/src/NetworkSyncManager.cpp index b3e3693281..19bd077493 100644 --- a/stepmania/src/NetworkSyncManager.cpp +++ b/stepmania/src/NetworkSyncManager.cpp @@ -3,6 +3,7 @@ #include "NetworkSyncServer.h" #include "LuaManager.h" #include "LuaFunctions.h" +#include "crypto/CryptMD5.h" NetworkSyncManager *NSMAN; @@ -24,6 +25,7 @@ void NetworkSyncManager::Update( float fDeltaTime ) { } bool NetworkSyncManager::ChangedScoreboard(int Column) { return false; } void NetworkSyncManager::SendChat(const CString& message) { } void NetworkSyncManager::SelectUserSong() { } +CString NetworkSyncManager::MD5Hex( CString &sInput ) { } #else #include "ezsockets.h" #include "ProfileManager.h" @@ -205,7 +207,7 @@ void NetworkSyncManager::PostStartUp(const CString& ServerIP) isSMOnline = true; m_ServerName = m_packet.ReadNT(); - + m_iSalt = m_packet.Read4(); LOG->Info("Server Version: %d %s", m_ServerVersion, m_ServerName.c_str()); } @@ -824,6 +826,41 @@ void PacketFunctions::ClearPacket() memset((void*)(&Data),0, NETMAXBUFFERSIZE); Position = 0; } + +CString NetworkSyncManager::MD5Hex( CString &sInput ) +{ + CString HashedName; + CString PreHashedName; + + unsigned char Output[16]; + const unsigned char *Input = (unsigned char *)sInput.c_str(); + + MD5Context BASE; + + memset(&BASE,0,sizeof(MD5Context)); + memset(&Output,0,16); + + MD5Init( &BASE ); + + MD5Update( &BASE, Input, sInput.length()); + + MD5Final( Output, &BASE ); + + for (int i = 0; i < 16; i++) + PreHashedName += ssprintf( "%2X", Output[i] ); + + //XXX: Yuck. Convert spaces to 0's better. (will fix soon) + for (int i = 0; i < 32; i++) + if ( PreHashedName.c_str()[i] == ' ' ) + HashedName += '0'; + else + if ( PreHashedName.c_str()[i]=='\0' ) + HashedName += ' '; + else + HashedName += PreHashedName.c_str()[i]; + + return HashedName; +} #endif LuaFunction_NoArgs( IsNetConnected, NSMAN->useSMserver ) diff --git a/stepmania/src/NetworkSyncManager.h b/stepmania/src/NetworkSyncManager.h index fae65e565d..2f4ef0665a 100644 --- a/stepmania/src/NetworkSyncManager.h +++ b/stepmania/src/NetworkSyncManager.h @@ -144,6 +144,9 @@ public: bool isLanServer; //Must be public for ScreenNetworkOptions StepManiaLanServer *LANserver; + int GetSMOnlineSalt() { return m_iSalt; } + + CString MD5Hex( CString & sInput ); private: #if !defined(WITHOUT_NETWORKING) @@ -160,6 +163,7 @@ private: int m_combo; int m_startupStatus; //Used to see if attempt was successful or not. + int m_iSalt; bool m_scoreboardchange[NUM_NSSB_CATEGORIES]; diff --git a/stepmania/src/ScreenSMOnlineLogin.cpp b/stepmania/src/ScreenSMOnlineLogin.cpp index 26fc3b3223..b81c5ff7a1 100644 --- a/stepmania/src/ScreenSMOnlineLogin.cpp +++ b/stepmania/src/ScreenSMOnlineLogin.cpp @@ -12,7 +12,6 @@ #include "GameState.h" #include "NetworkSyncManager.h" #include "ScreenTextEntry.h" -#include "crypto/CryptMD5.h" REGISTER_SCREEN_CLASS(ScreenSMOnlineLogin); @@ -185,41 +184,20 @@ CString ScreenSMOnlineLogin::GetSelectedProfileID() void ScreenSMOnlineLogin::SendLogin(CString sPassword) { CString PlayerName = GAMESTATE->GetPlayerDisplayName((PlayerNumber) m_iPlayer); - CString HashedName; - CString PreHashedName; - unsigned char Output[16]; - const unsigned char *Input = (unsigned char *)sPassword.c_str(); + CString HashedName = NSMAN->MD5Hex( sPassword ); - MD5Context BASE; - - memset(&BASE,0,sizeof(MD5Context)); - memset(&Output,0,16); - - MD5Init( &BASE ); - - - MD5Update( &BASE, Input, sPassword.length()); - - MD5Final( Output, &BASE ); - - for (int i = 0; i < 16; i++) - PreHashedName += ssprintf( "%2X", Output[i] ); - - //XXX: Yuck. Convert spaces to 0's better. (will fix soon) - for (int i = 0; i < 32; i++) - if ( PreHashedName.c_str()[i] == ' ' ) - HashedName += '0'; - else - if ( PreHashedName.c_str()[i]=='\0' ) - HashedName += ' '; - else - HashedName += PreHashedName.c_str()[i]; + int authMethod = 0; + if ( NSMAN->GetSMOnlineSalt() != 0 ) + { + authMethod = 1; + HashedName = NSMAN->MD5Hex( HashedName + ssprintf( "%d", NSMAN->GetSMOnlineSalt() ) ); + } NSMAN->m_SMOnlinePacket.ClearPacket(); NSMAN->m_SMOnlinePacket.Write1((uint8_t)0); //Login command NSMAN->m_SMOnlinePacket.Write1((uint8_t)m_iPlayer); //Player - NSMAN->m_SMOnlinePacket.Write1((uint8_t)0); //MD5 hash style + NSMAN->m_SMOnlinePacket.Write1((uint8_t)authMethod); //MD5 hash style NSMAN->m_SMOnlinePacket.WriteNT(PlayerName); NSMAN->m_SMOnlinePacket.WriteNT(HashedName); NSMAN->SendSMOnline( );