Exemplo n.º 1
0
        void ProcessRecieved(byte[] data, int ClientID)
        {
            int t;

            switch (data[0])
            {
            case 0x00:     //LOGIN
            {
                ColoredConsole.ConsoleWriteGreenWithOut("Recieved Logon Challenge!");
                int clientVersion = (((int)data[11]) * 256) + data[12];
                if (clientVersion == 55574)
                {
                    ColoredConsole.ConsoleWriteBlueWithOutAndWithDate("Cient version accepted: 2.0.0, ID = 56085!");
                }
                else
                {
                    ColoredConsole.ConsoleWriteErrorWithOne("Wrong client version {0}. Excpected is 2.0.0, ID = 56085!", clientVersion);
                    //return;
                }
                byte userlenght = data[33];
                username = new byte[userlenght];
                string usern = "";
                for (t = 0; t < userlenght; t++)
                {
                    username[t] = data[34 + t];
                    usern      += "" + (char)data[34 + t];
                    //ColoredConsole.ConsoleWriteGreenWithOne("{0}", "" + ((char)username[t]).ToString());
                }
                ColoredConsole.ConsoleWriteGreenWithOne("Recieved AUTH_CHALLENGE from user: {0}", usern);
                userNumber = World.FindUserByUsername(usern);
                if (userNumber == -1)
                {
                    SendToOneClient(new byte[] { 0x00, 0x00, 0x15 }, ClientID);
                    ColoredConsole.ConsoleWriteErrorWithOut("Wrong login.");
                    return;
                }
                string pass     = "******" + Database.Data.AccountArray.pass[userNumber];
                char[] passchar = pass.ToCharArray();
                byte[] passbyte = new byte[passchar.Length];
                int    ti       = 0;
                foreach (char c in passchar)
                {
                    passbyte[ti++] = (byte)c;
                }
                byte[] user = Concat(username, passbyte);
                SHA1   sha  = new SHA1CryptoServiceProvider();
                byte[] hash = sha.ComputeHash(user, 0, user.Length);
                byte[] res  = new Byte[hash.Length + salt.Length];
                t = 0;
                rand.NextBytes(salt);
                foreach (byte s in salt)
                {
                    res[t++] = s;
                }
                foreach (byte s in hash)
                {
                    res[t++] = s;
                }
                byte[] hash2 = sha.ComputeHash(res, 0, res.Length);
                byte[] x     = Reverse(hash2);

                rN = Reverse(N);
                rand.NextBytes(b);
                rb = Reverse(b);

                BigInteger bi  = new BigInteger(x);
                BigInteger bi2 = new BigInteger(rN);
                BigInteger g   = new BigInteger(new byte[] { 7 });
                v = g.modPow(bi, bi2);

                K     = new BigInteger(new Byte[] { 3 });
                temp1 = K * v;
                temp2 = g.modPow(new BigInteger(rb), new BigInteger(rN));
                temp3 = temp1 + temp2;
                B     = temp3 % new BigInteger(rN);
                byte[] pack = new byte[119];
                pack[0] = pack[1] = 0;
                byte[] tB = Reverse(B.getBytes());
                for (t = 0; t < tB.Length; t++)
                {
                    pack[3 + t] = tB[t];
                }
                pack[35] = 1;        // g_length
                pack[36] = 7;        // g
                pack[37] = 32;       // n_len
                for (t = 0; t < N.Length; t++)
                {
                    pack[38 + t] = N[t];
                }
                for (t = 0; t < salt.Length; t++)
                {
                    pack[70 + t] = salt[t];
                }
                //for( t = 0;t < 16;t++ )
                for (t = 0; t < 17; t++)
                {
                    pack[102 + t] = 0;
                }

                SendToOneClient(pack, ClientID);
                LoginAccount.user = usern;
                LoginAccount.pass = Database.Data.AccountArray.pass[userNumber];
                return;
            }

            case 0x01:     //LOGON PROOF
            {
                ColoredConsole.ConsoleWriteGreenWithOut("Logon proof!");
                //Console.WriteLine("Logon proof" );
                byte[] A = new byte[32];
                for (t = 0; t < 32; t++)
                {
                    A[t] = data[t + 1];
                }
                byte[] kM1 = new byte[20];
                for (t = 0; t < 20; t++)
                {
                    kM1[t] = data[t + 1 + 32];
                }

                //A = new byte[] { 0x23, 0x2f, 0xb1, 0xb8, 0x85, 0x29, 0x64, 0x3d, 0x95, 0xb8, 0xdc, 0xe7, 0x8f, 0x27, 0x50, 0xc7, 0x5b, 0x2d, 0xf3, 0x7a, 0xcb, 0xa8, 0x73, 0xeb, 0x31, 0x07, 0x38, 0x39, 0xed, 0xa0, 0x73, 0x8d };
                byte[] rA = Reverse(A);
                //	B = new BigInteger( new byte[] { 0x64, 0x5d, 0x1f, 0x78, 0x97, 0x30, 0x73, 0x70, 0x1e, 0x12, 0xbc, 0x98, 0xaa, 0x38, 0xea, 0x99, 0xb4, 0xbc, 0x43, 0x5c, 0x32, 0xe8, 0x44, 0x7c, 0x73, 0xab, 0x07, 0x7a, 0xe4, 0xd7, 0x59, 0x64 } );
                byte[] AB = Concat(A, Reverse(B.getBytes()));

                SHA1   shaM1 = new SHA1CryptoServiceProvider();
                byte[] U     = shaM1.ComputeHash(AB);
                //	U = new byte[] { 0x2f, 0x49, 0x69, 0xac, 0x9f, 0x38, 0x7f, 0xd6, 0x72, 0x23, 0x6f, 0x94, 0x91, 0xa5, 0x16, 0x77, 0x7c, 0xdd, 0xe1, 0xc1 };
                byte[] rU = Reverse(U);

                temp1 = v.modPow(new BigInteger(rU), new BigInteger(rN));
                temp2 = temp1 * new BigInteger(rA);
                temp3 = temp2.modPow(new BigInteger(rb), new BigInteger(rN));

                byte[] S1   = new byte[16];
                byte[] S2   = new byte[16];
                byte[] S    = new byte[32];
                byte[] temp = temp3.getBytes();

                /*	Console.WriteLine("temp");
                 *  HexViewer.View( temp, 0, temp.Length );
                 *  Console.WriteLine("temp1 {0}", temp1.ToHexString());
                 *  Console.WriteLine("temp2 {0}", temp2.ToHexString());
                 *  Console.WriteLine("temp3 {0}", temp3.ToHexString());*/
                Buffer.BlockCopy(temp, 0, S, 0, temp.Length);
                byte[] rS = Reverse(S);


                for (t = 0; t < 16; t++)
                {
                    S1[t] = rS[t * 2];
                    S2[t] = rS[(t * 2) + 1];
                }
                byte[] hashS1 = shaM1.ComputeHash(S1);
                byte[] hashS2 = shaM1.ComputeHash(S2);
                SS_Hashs[userNumber].SS_Hash = new byte[hashS1.Length + hashS2.Length];
                for (t = 0; t < hashS1.Length; t++)
                {
                    SS_Hashs[userNumber].SS_Hash[t * 2]       = hashS1[t];
                    SS_Hashs[userNumber].SS_Hash[(t * 2) + 1] = hashS2[t];
                }

                //	SS_Hash = new byte[] { 0x02, 0x61, 0xf4, 0xeb, 0x48, 0x91, 0xb6, 0x6a, 0x1a, 0x82, 0x6e, 0xb7, 0x79, 0x28, 0xd8, 0x64, 0xb7, 0xea, 0x14, 0x54, 0x38, 0xdb, 0x7c, 0xfd, 0x0d, 0x3d, 0x2f, 0xc0, 0x22, 0xce, 0xcc, 0x46, 0x83, 0x79, 0xf2, 0xc0, 0x87, 0x78, 0x7f, 0x14 };

                byte[] NHash    = shaM1.ComputeHash(N);
                byte[] GHash    = shaM1.ComputeHash(new byte[] { 7 });
                byte[] userHash = shaM1.ComputeHash(username);
                byte[] NG_Hash  = new byte[20];
                for (t = 0; t < 20; t++)
                {
                    NG_Hash[t] = (byte)(NHash[t] ^ GHash[t]);
                }
                byte[] Temp = Concat(NG_Hash, userHash);
                Temp = Concat(Temp, salt);
                Temp = Concat(Temp, A);
                Temp = Concat(Temp, B.getBytes());
                Temp = Concat(Temp, K.getBytes());        //SS_Hash );

                byte[] M1 = shaM1.ComputeHash(Temp);

                Temp = Concat(A, kM1);
                Temp = Concat(Temp, SS_Hashs[userNumber].SS_Hash);

                byte[] M2 = shaM1.ComputeHash(Temp);

                byte[] retur = new byte[M2.Length + 4 /*NG_Hash.Length */ + 2];
                //	byte []retur = new byte[ M2.Length + NG_Hash.Length + 2 ];
                retur[0] = 0x1;
                retur[1] = 0x0;
                for (t = 0; t < M2.Length; t++)
                {
                    retur[t + 2] = M2[t];
                }

                //for(t = 0;t < NG_Hash.Length;t++ )
                //	retur[ t + 2 + 20 ] = NG_Hash[ t ];

                //	set the account properties
                //Console.WriteLine("Logon proof for {0}", IP.ToString());
                LoginAccount.Ip   = IP;
                LoginAccount.Port = 0;
                LoginAccount.K    = SS_Hashs[userNumber].SS_Hash;

                SendToOneClient(retur, ClientID);
                return;
            }

            case 0x02:    //Reconnect challenge
            {
                ColoredConsole.ConsoleWriteGreenWithOut("Reconnect challenge!");
                byte[] packRecoChallenge = new byte[34];
                packRecoChallenge[0] = 0x02;
                packRecoChallenge[1] = 0x00;
                for (t = 0; t < 16; t++)
                {
                    packRecoChallenge[18 + t] = 0;
                }
                SendToOneClient(packRecoChallenge, ClientID);
                return;
            }

            case 0x03:    //Reconnect proof
            {
                ColoredConsole.ConsoleWriteGreenWithOut("Reconnect proof!");
                SendToOneClient(new byte[] { 0x03, 0x00 }, ClientID);
                return;
            }

            case 0x04:    //Update server
                //	Console.WriteLine( "Update server" );
                break;

            case 0x10:    //Realm List
                ColoredConsole.ConsoleWriteGreenWithOut("Client requested realmlist!");
                string ip      = World.DNS.AddressList[0].ToString();
                byte[] retData = new byte[25 + ip.Length + World.ServerName.Length + World.WorldPort.ToString().Length];
                int    offset  = 0;
                Converter.ToBytes((byte)0x10, retData, ref offset);
                Converter.ToBytes((byte)43, retData, ref offset);
                Converter.ToBytes(1 /*World.allConnectedChars.Count*/, retData, ref offset);
                Converter.ToBytes((byte)0, retData, ref offset);
                Converter.ToBytes(1, retData, ref offset);
                Converter.ToBytes((short)0, retData, ref offset);
                Converter.ToBytes(World.ServerName, retData, ref offset);
                Converter.ToBytes((byte)0, retData, ref offset);
                Converter.ToBytes(ip, retData, ref offset);
                Converter.ToBytes((byte)':', retData, ref offset);
                Converter.ToBytes(World.ServerPort.ToString(), retData, ref offset);
                Converter.ToBytes((byte)0, retData, ref offset);
                Converter.ToBytes(0, retData, ref offset);
                //	Converter.ToBytes( (short)0, retData, ref offset );//	cr erreir
                //Converter.ToBytes( (short)1, retData, ref offset );
                //Converter.ToBytes( (short)2, retData, ref offset );

                Converter.ToBytes((short)ClientsConnected, retData, ref offset);
                Converter.ToBytes((byte)0, retData, ref offset);
                Converter.ToBytes((short)1, retData, ref offset);
                int atlen = 1;
                offset -= 3;
                Converter.ToBytes(offset, retData, ref atlen);
                //Console.WriteLine("Connected player(s) {0}", ClientsConnected);
                /*	if ( World.allConnectedChars.Count < 3 )*/
                //Thread.Sleep( 500 );
                SendToOneClient(retData, ClientID);
                return;

            default:    //UNKNOWN OPCODE
            {
                ColoredConsole.ConsoleWriteErrorWithOne("Recieve unknown OPCode: {0}", data[0]);
                return;
            }
            }
        }