Ejemplo n.º 1
0
        /// <summary>
        /// "login" packet. This is the response to the server's login challenge.
        /// </summary>
        private void OnReceive_Login(NetState ns, GsTcpReader reader)
        {
            string clientChallenge = reader.GetParameter("challenge"); // 32 chars ASCII upper/lower. Verifies server.
            string sessionToken    = reader.GetParameter("authtoken"); // identifies account DS wishes to log in with.
            string response        = reader.GetParameter("response");  // 128bit (as 32char hex) response LOGIN_CHALLENGE.
            string firewall        = reader.GetParameter("firewall");  // whether the client is behind a firewall.
            string port            = reader.GetParameter("port");      // port open on the device for communications.
            string product         = reader.GetParameter("productid"); // GameSpy-specific ID indicating the product attempting to connect to GameSpy.
            string gamename        = reader.GetParameter("gamename");  // GameSpy-specific name of the game
            // string nmspace = reader.GetParameter("nmspace"); // indicates presence of additional login parameters in this packet
            int seqNum = int.Parse(reader.GetParameter("id"));         // sequence ID of the previous LOGIN_CHALLENGE.
            // get account
            AccountRequestLogin info = new AccountRequestLogin(sessionToken);

            EventSink.InvokeAccountLogin(info);
            if (info.IsHandled && info.IsSuccess)
            {
                // verify client authentication:
                string verify = GsMd5Sum.HashChallenge(info.Account.GsLoginPassword, info.Account.GsLoginToken, clientChallenge, ns.GsServerChallenge);
                if (verify != response)
                {
                    throw new NetStateMsgException(ns, "sent incorrect LOGIN verification.", reader);
                }
                // client authenticated! Create server authentication proof and then login client:
                string proof = GsMd5Sum.HashChallenge(info.Account.GsLoginPassword, info.Account.GsLoginToken, ns.GsServerChallenge, clientChallenge);
                ns.Account = info.Account;
                ns.GenerateGamespySessionData();
                ns.Account.GenerateGamespyLoginData(info);
                Kernel.WriteLine(TypeName, $"{ns} logged in as '{ns.Account}'.");
                Send(ns, new GsSmsgLoggedIn(proof, ns, seqNum));
            }
            else if (info.IsHandled)
            {
                Send(ns, GsSmsgError.ErrFatalLoginFailed(seqNum));
                throw new NetStateMsgException(ns, $"sent wrong credentials: {info.FailReason}", reader);
            }
            else
            {
                Send(ns, GsSmsgError.ErrFatalDatabaseError(seqNum));
                throw new NetStateMsgException(ns, "sent Login; EventSink did not handle the message.", reader);
            }
        }