From: <z-...@us...> - 2008-01-27 13:08:45
|
Revision: 7659 http://armagetronad.svn.sourceforge.net/armagetronad/?rev=7659&view=rev Author: z-man Date: 2008-01-27 05:02:50 -0800 (Sun, 27 Jan 2008) Log Message: ----------- Short network messages are now ignored and don't cause disconnection. Logins are secured with an additional random token, making it harder to inject fake login accept packets with a wrong IP to circumvent the anti-pharming code. Modified Paths: -------------- armagetronad/branches/0.2.8-auth/armagetronad/language/deutsch.txt armagetronad/branches/0.2.8-auth/armagetronad/language/english_base.txt armagetronad/branches/0.2.8-auth/armagetronad/language/french.txt armagetronad/branches/0.2.8-auth/armagetronad/language/spanish.txt armagetronad/branches/0.2.8-auth/armagetronad/src/network/nKrawall.cpp armagetronad/branches/0.2.8-auth/armagetronad/src/network/nKrawall.h armagetronad/branches/0.2.8-auth/armagetronad/src/network/nNetwork.cpp armagetronad/branches/0.2.8-auth/armagetronad/src/network/nNetwork.h Modified: armagetronad/branches/0.2.8-auth/armagetronad/language/deutsch.txt =================================================================== --- armagetronad/branches/0.2.8-auth/armagetronad/language/deutsch.txt 2008-01-27 12:23:59 UTC (rev 7658) +++ armagetronad/branches/0.2.8-auth/armagetronad/language/deutsch.txt 2008-01-27 13:02:50 UTC (rev 7659) @@ -2221,7 +2221,7 @@ network_warn_unknowndescriptor \n\n\nUnbekannte Nachricht (ID \1) erhalten.\n\nES IST RATSAM, EINE NEUE VERSION VON ARMAGETRON ZU BESORGEN!!!!\n network_error Netzwerkfehler.\n network_error_timeout Verbindung zu Benutzer \1 verloren.\n -network_error_shortmessage Benutzer \1 sendet eine unzul\xE4ssige (zu kurze) Nachricht. Er wird beseitigt.\n +network_error_shortmessage Benutzer \1 sendet eine unzul\xE4ssige (zu kurze) Nachricht.\n network_error_overflow Benutzer \1 kommt mit dem Netzwerkverkehr nicht hinterher.\n network_killuser Beseitige Benutzer \1, Ping \2.\n network_statistics1 Zeit: \1 Sekunden\n Modified: armagetronad/branches/0.2.8-auth/armagetronad/language/english_base.txt =================================================================== --- armagetronad/branches/0.2.8-auth/armagetronad/language/english_base.txt 2008-01-27 12:23:59 UTC (rev 7658) +++ armagetronad/branches/0.2.8-auth/armagetronad/language/english_base.txt 2008-01-27 13:02:50 UTC (rev 7659) @@ -2226,7 +2226,7 @@ network_warn_unknowndescriptor \n\n\nGot unknown nMessage with descriptor id \1 \n\nYOU SHOULD PROBABLY UPGRADE ARMAGETRON ADVANCED!!!!\n network_error Network error.\n network_error_timeout User \1 timed out.\n -network_error_shortmessage User \1's message was too short. Killing him.\n +network_error_shortmessage User \1's message was too short.\n network_error_overflow User \1 is unable to keep up with the network traffic.\n network_killuser Killing user \1, ping \2.\n network_statistics1 Time: \1 seconds\n Modified: armagetronad/branches/0.2.8-auth/armagetronad/language/french.txt =================================================================== --- armagetronad/branches/0.2.8-auth/armagetronad/language/french.txt 2008-01-27 12:23:59 UTC (rev 7658) +++ armagetronad/branches/0.2.8-auth/armagetronad/language/french.txt 2008-01-27 13:02:50 UTC (rev 7659) @@ -1963,7 +1963,7 @@ network_warn_unknowndescriptor \n\n\nMessage inconnu recu, avec l'ID \1 \n\nVOUS DEVEZ SANS DOUTE METTRE ARMAGETRON A JOUR!!!!\n network_error Erreur de reseau.\n network_error_timeout Le temps de l'utilisateur \1 est ecoule.\n -network_error_shortmessage Le message de l'utilisateur \1 est trop court. Destruction de celui-ci.\n +network_error_shortmessage Le message de l'utilisateur \1 est trop court.\n network_error_overflow L'utilisateur \1 ne sait pas suivre le trafic du reseau.\n network_killuser Fin de l'utilisateur \1, ping \2.\n network_statistics1 Duree: \1 secondes\n Modified: armagetronad/branches/0.2.8-auth/armagetronad/language/spanish.txt =================================================================== --- armagetronad/branches/0.2.8-auth/armagetronad/language/spanish.txt 2008-01-27 12:23:59 UTC (rev 7658) +++ armagetronad/branches/0.2.8-auth/armagetronad/language/spanish.txt 2008-01-27 13:02:50 UTC (rev 7659) @@ -2000,7 +2000,7 @@ network_warn_unknowndescriptor \n\n\nrecibido el nMessage desconocido con id \1 \n\nPROBABLEMENTE DEBAS ACTUALIZAR ARMAGETRON!!!!\n network_error Error de red.\n network_error_timeout El usuario \1 excedi\xF3 el tiempo.\n -network_error_shortmessage El mensaje del usuario \1 era muy corto. Elimin\xE1ndolo.\n +network_error_shortmessage El mensaje del usuario \1 era muy corto.\n network_error_overflow El usuario \1 no es capaz de mantener el tr\xE1fico de red.\n network_killuser Eliminando el usuario \1, ping \2.\n network_statistics1 Tiempo: \1 segundos\n Modified: armagetronad/branches/0.2.8-auth/armagetronad/src/network/nKrawall.cpp =================================================================== --- armagetronad/branches/0.2.8-auth/armagetronad/src/network/nKrawall.cpp 2008-01-27 12:23:59 UTC (rev 7658) +++ armagetronad/branches/0.2.8-auth/armagetronad/src/network/nKrawall.cpp 2008-01-27 13:02:50 UTC (rev 7659) @@ -440,8 +440,6 @@ -#ifdef KRAWALL_SERVER - // get a random salt value void nKrawall::RandomSalt(nSalt& salt) { @@ -452,6 +450,8 @@ // salt[i] = (int)(256.0 * rand() / (RAND_MAX + 1.0)); } +#ifdef KRAWALL_SERVER + #ifdef KRAWALL_SERVER_LEAGUE // called on the master server when the league message is received Modified: armagetronad/branches/0.2.8-auth/armagetronad/src/network/nKrawall.h =================================================================== --- armagetronad/branches/0.2.8-auth/armagetronad/src/network/nKrawall.h 2008-01-27 12:23:59 UTC (rev 7658) +++ armagetronad/branches/0.2.8-auth/armagetronad/src/network/nKrawall.h 2008-01-27 13:02:50 UTC (rev 7659) @@ -245,9 +245,9 @@ nScrambledPassword& dest); -#ifdef KRAWALL_SERVER // get a random salt value static void RandomSalt(nSalt& salt); +#ifdef KRAWALL_SERVER // check whether username's password, when run through ScrambleWithSalt( ScramblePassword(password), salt ), equals scrambledRemote. result.userName and result.authority need to be set by the caller, success and error are filled by this function, and authority may be modified. static void CheckScrambledPassword( nCheckResultBase & result, Modified: armagetronad/branches/0.2.8-auth/armagetronad/src/network/nNetwork.cpp =================================================================== --- armagetronad/branches/0.2.8-auth/armagetronad/src/network/nNetwork.cpp 2008-01-27 12:23:59 UTC (rev 7658) +++ armagetronad/branches/0.2.8-auth/armagetronad/src/network/nNetwork.cpp 2008-01-27 13:02:50 UTC (rev 7659) @@ -596,7 +596,10 @@ } #ifndef NOEXCEPT } - catch(nKillHim){ + catch(nIgnore const &){ + // well, do nothing. + } + catch(nKillHim const &){ // st_Breakpoint(); con << tOutput("$network_error"); sn_DisconnectUser(message.SenderID(), "$network_kill_error" ); @@ -1305,8 +1308,8 @@ o.SetTemplateParameter(1, senderID); o << "$network_error_shortmessage"; con << o; - sn_DisconnectUser(senderID, "$network_kill_error"); - nReadError(); + // sn_DisconnectUser(senderID, "$network_kill_error"); + nReadError( false ); } else x=data(readOut++); @@ -1320,6 +1323,11 @@ static bool login_failed=false; static bool login_succeeded=false; +// salt value sent as past login tokens. They are returned by +// the server as you sent them, and make sure you only accept +// the right answer. +static nKrawall::nSalt loginSalt; + static nHandler *real_req_info_handler=NULL; void req_info_handler(nMessage &m){ @@ -1427,10 +1435,8 @@ void login_accept_handler(nMessage &m){ if (sn_GetNetState()!=nSERVER && m.SenderID() == 0){ - login_succeeded=true; unsigned short id=0; m.Read(id); - sn_myNetID=id; // read or reset server version info if ( !m.End() ) @@ -1466,8 +1472,20 @@ { sn_myAddress = address; } + + // read salt reply and compare it to what we sent + nKrawall::nSalt replySalt; + nKrawall::ReadScrambledPassword( m, replySalt ); + if ( memcmp( &loginSalt,&replySalt, sizeof(replySalt) ) != 0 ) + { + nReadError( false ); + } } + // only now, login can be considered a success + login_succeeded=true; + sn_myNetID=id; + first_fill_ids(); } } @@ -1572,9 +1590,32 @@ static bool sn_lockOut028tTest = true; static tSettingItem< bool > sn_lockOut028TestConf( "NETWORK_LOCK_OUT_028_TEST", sn_lockOut028tTest ); -int login_handler(const nMessage &m, const nVersion& version, unsigned short rate, tString & supportedAuthenticationMethods ){ +int login_handler( nMessage &m, unsigned short rate ){ nCurrentSenderID senderID; + // read version and suppored authentication methods + nVersion version; + tString supportedAuthenticationMethods(""); + nKrawall::nSalt salt; // it's OK that this may stay uninitialized + if ( !m.End() ) + { + // read version + m >> version; + + // ok, clients that send a version do have at lesat basic authentication. + supportedAuthenticationMethods = "bmd5"; + } + if ( !m.End() ) + { + // read authentication methods + m >> supportedAuthenticationMethods; + } + if ( !m.End() ) + { + // also read a login salt, the client expects to get it returned verbatim + nKrawall::ReadScrambledPassword( m, salt ); + } + // don't accept logins in client mode if (sn_GetNetState() != nSERVER) return -1; @@ -1624,7 +1665,7 @@ // expire 0.2.8 test versions, they have a security flaw if ( sn_lockOut028tTest && version.Max() >= 5 && version.Max() <= 10 ) { - sn_DisconnectUser(m.SenderID(), "0.2.8_beta and 0.2.8.0_rc versions have a dangerous security flaw and are obsoleted, please upgrade to 0.2.8.0."); + sn_DisconnectUser(m.SenderID(), "0.2.8_beta and 0.2.8.0_rc versions have a dangerous security flaw and are obsoleted, please upgrade to 0.2.8.2.1."); } if (m.SenderID()!=MAXCLIENTS+1) @@ -1704,6 +1745,8 @@ rep->Write(new_id); (*rep) << sn_myVersion; (*rep) << peers[m.SenderID()].ToString(); + nKrawall::WriteScrambledPassword( salt, *rep ); + rep->Send(new_id, -killTimeout); nMessage::SendCollected( new_id ); @@ -1732,7 +1775,6 @@ void login_handler_1(nMessage& m) { - nVersion version; unsigned short rate; m.Read( rate ); @@ -1742,18 +1784,7 @@ m >> rem_bb; } - // clients this old don't support any authentication method. - tString supportedAuthenticationMethods(""); - if ( !m.End() ) - { - // version! - m >> version; - - // ok, clients that send a version do have authentication. - supportedAuthenticationMethods = "bmd5,"; - } - - login_handler( m, version, rate, supportedAuthenticationMethods ); + login_handler( m, rate ); } void login_handler_2(nMessage& m) @@ -1770,19 +1801,8 @@ m >> rem_bb; } - // read peer network protocol version - nVersion ver; - m >> ver; + int new_ID = login_handler( m, rate ); - // read peer supported authentication methods (fallback to broken md5) - tString supportedAuthenticationMethods("bmd5"); - if ( !m.End() ) - { - m >> supportedAuthenticationMethods; - } - - int new_ID = login_handler( m, ver , rate, supportedAuthenticationMethods ); - if ( new_ID > 0 ) { nMessage* m = tNEW( nMessage )( versionControl ); @@ -2363,7 +2383,7 @@ #ifndef NOEXCEPT } - catch(nKillHim) + catch(nKillHim const &) { con << "nKillHim signal caught.\n"; sn_DisconnectUser(peer, "$network_kill_error"); @@ -2629,12 +2649,6 @@ (*mess) << sn_bigBrotherString; big_brother=false; } - - // write our version - (*mess) << sn_MyVersion(); - - // write our supported authentication methods - (*mess) << nKrawall::nMethod::SupportedMethods(); } else { @@ -2651,11 +2665,19 @@ (*mess) << tString(""); } - (*mess) << sn_MyVersion(); - big_brother=false; } + // write our version + (*mess) << sn_MyVersion(); + + // write our supported authentication methods + (*mess) << nKrawall::nMethod::SupportedMethods(); + + // write a random salt + nKrawall::RandomSalt( loginSalt ); + nKrawall::WriteScrambledPassword( loginSalt, *mess ); + mess->ClearMessageID(); mess->SendImmediately(0,false); nMessage::SendCollected(0); @@ -2723,11 +2745,14 @@ } -void nReadError() +void nReadError( bool critical ) { // st_Breakpoint(); #ifndef NOEXCEPT - throw nKillHim(); + if ( critical ) + throw nKillHim(); + else + throw nIgnore(); #else con << "\nI told you not to use PGCC! Now we need to leave the\n" << "system in an undefined state. The progam will crash now.\n" @@ -3461,6 +3486,62 @@ // ******************************************************************************************* // * +// * nIgnore +// * +// ******************************************************************************************* +//! +//! +// ******************************************************************************************* + +nIgnore::nIgnore( void ) +{ +} + +// ******************************************************************************************* +// * +// * ~nIgnore +// * +// ******************************************************************************************* +//! +//! +// ******************************************************************************************* + +nIgnore::~nIgnore( void ) +{ +} + +// ******************************************************************************************* +// * +// * DoGetName +// * +// ******************************************************************************************* +//! +//! @return short name +//! +// ******************************************************************************************* + +tString nIgnore::DoGetName( void ) const +{ + return tString( "Packet ignore request" ); +} + +// ******************************************************************************************* +// * +// * DoGetDescription +// * +// ******************************************************************************************* +//! +//! @return description +//! +// ******************************************************************************************* + +tString nIgnore::DoGetDescription( void ) const +{ + return tString( "An error that should lead to the current message getting ingored was detected." ); +} + +// ******************************************************************************************* +// * // * nAverager // * // ******************************************************************************************* Modified: armagetronad/branches/0.2.8-auth/armagetronad/src/network/nNetwork.h =================================================================== --- armagetronad/branches/0.2.8-auth/armagetronad/src/network/nNetwork.h 2008-01-27 12:23:59 UTC (rev 7658) +++ armagetronad/branches/0.2.8-auth/armagetronad/src/network/nNetwork.h 2008-01-27 13:02:50 UTC (rev 7659) @@ -68,10 +68,9 @@ // rate control extern int sn_maxRateIn,sn_maxRateOut; -// exception that is thrown on any unexpected network error; -// causes the owner of the current nNetObject or the sender of -// the currently processed netmessage to be killed. - +//! exception that is thrown on any unexpected network error; +//! causes the owner of the current nNetObject or the sender of +//! the currently processed netmessage to be killed. class nKillHim: public tException { public: @@ -83,8 +82,21 @@ virtual tString DoGetDescription() const; //!< returns a detailed description }; +//! exception that is thrown on errors where it is safe to just ignore the +//! offending packet. +class nIgnore: public nKillHim +{ +public: + nIgnore(); + ~nIgnore(); + +private: + virtual tString DoGetName() const; //!< returns the name of the exception + virtual tString DoGetDescription() const; //!< returns a detailed description +}; + // call this function on any error occuring while reading a message: -void nReadError(); +void nReadError( bool critical = true ); #ifndef MAXCLIENTS #define MAXCLIENTS 16 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |