Example #1
0
        public bool fetchWordList(ref WorldList wl)
        {
            // Doesnt exist by default
            wl.setExistance(false);

            conn.Open();

            string sqlQuery = "SELECT * FROM users WHERE username='******' AND passwordmd5='"+wl.getPassword()+"' LIMIT 1;";
            queryExecuter= conn.CreateCommand();
            queryExecuter.CommandText = sqlQuery;
            dr= queryExecuter.ExecuteReader();

            while(dr.Read()){
                // Player is on the DB
                wl.setExistance(true);
                wl.setUserID((int) dr.GetDecimal(0));
                dr.GetBytes(5,0,wl.getPublicModulus(),0,96);
                dr.GetBytes(6,0,wl.getPrivateExponent(),0,96);
                wl.setTimeCreated((int)dr.GetDecimal(7));
            }

            dr.Close();

            // If doesnt exist... should not do more things
            if (!wl.getExistance()){
                String msg = "Player not found on DB with #"+wl.getUsername()+"# and #"+wl.getPassword()+"#";
                Output.WriteLine(msg);
                conn.Close();
                return false;
            }

            // If exist, get the player values

            // Count the values first

            int totalChars = 0;
            string sqlCount = "SELECT charId FROM characters WHERE userId='" + wl.getUserID() + "' AND is_deleted='0' ";
            queryExecuter= conn.CreateCommand();
            queryExecuter.CommandText = sqlCount;
            dr= queryExecuter.ExecuteReader();

            while (dr.Read()){
                totalChars++;
            }

            dr.Close();
            wl.getCharPack().setTotalChars(totalChars);

            // Prepare to read characters

            string sqlQueryForChars = "SELECT * FROM characters WHERE userId='" + wl.getUserID() + "' AND is_deleted='0' ";
            queryExecuter= conn.CreateCommand();
            queryExecuter.CommandText = sqlQueryForChars;
            dr= queryExecuter.ExecuteReader();

            // Read characters
            while(dr.Read()){

                //totalChars = (int) dr.GetDecimal(8);
                string charName = dr.GetString(4);
                int charId = (int)dr.GetDecimal(0);
                int status = (int)dr.GetDecimal(3);
                int worldId = (int)dr.GetDecimal(2);

                wl.getCharPack().addCharacter(charName,charId,status,worldId);

            }

            dr.Close();

            // Read worlds
            string sqlQueryForWorlds = "SELECT * FROM worlds ORDER BY worldId ASC";
            queryExecuter.CommandText = sqlQueryForWorlds;
            dr= queryExecuter.ExecuteReader();

            while (dr.Read()){

                string worldName = dr.GetString(1);

                int worldId = (int) dr.GetDecimal(0);
                int worldType = (int) dr.GetDecimal(2);
                int worldStatus = (int) dr.GetDecimal(3);
                int worldPopulation = (int) dr.GetDecimal(4);
                wl.getWorldPack().addWorld(worldName,worldId,worldStatus,worldType,worldPopulation);

            }

            dr.Close();

            conn.Close();

            return true;
        }
Example #2
0
        public byte[] processHandleAuthChallenge_Response(byte[] data, int maxBytes)
        {
            int blobSize = (int)data[4];

            byte[] encryptedBlob = new byte[blobSize];
            byte[] decryptedBlob = new byte[blobSize];

            ArrayUtils.copy(data, 6, encryptedBlob, 0, blobSize);

            // Reset IV to 0
            tf.setIV(blankIV);
            tf.decrypt(encryptedBlob, decryptedBlob);

            byte[] receivedMD5 = new byte[16];
            ArrayUtils.copy(decryptedBlob, 1, receivedMD5, 0, 16);


            // Security says that must be the same
            if (!ArrayUtils.equal(receivedMD5, md5edChallenge))
            {
                Output.WriteLine("The Md5 from client and Our Md5 are not same, aborting");
                Output.WriteLine("Decrypted (TF) blob:" + StringUtils.bytesToString(decryptedBlob));
                Output.WriteLine("Stored MD5ed Challenge:" + StringUtils.bytesToString(md5edChallenge));
                throw new AuthException("Md5 challenge differs");
            }

            // We take the pass from the decrypted Blob and subtract 1 byte, the ending "0"
            int passSize = ((int)decryptedBlob[23]) - 1;

            byte[] passwordB = new byte[passSize];
            ArrayUtils.copy(decryptedBlob, 25, passwordB, 0, passSize);

            Output.OptWriteLine("-> Password decrypted, size:" + passSize);

            // Set WorldList password
            wl.setPassword(StringUtils.bytesToString_NS(md5.digest(passwordB)));

            if (Store.dbManager.AuthDbHandler.fetchWordList(ref wl))
            {
                // Do calculations magic
                byte[] hexUserID = NumericalUtils.uint32ToByteArray((UInt32)wl.getUserID(), 1);

                byte[] nameH = new byte[33];

                string name = wl.getUsername();
                for (int i = 0; i < name.Length; i++)
                {
                    nameH[i] = (byte)name[i];
                }

                byte[] padding = new byte[4];                 // 4 empty byte ==> [0x00,0x00,0x00,0x00]

                // +10 mins from now, so 60secs per min
                byte[] expiredTime = TimeUtils.getUnixTime(60 * 10);

                byte[] padding2    = new byte[32];              // 32 empty byte ==> [0x00,0x00,0x00,0x00,...]
                byte[] pubModulusH = wl.getPublicModulus();
                byte[] createdTime = NumericalUtils.uint32ToByteArray((UInt32)wl.getTimeCreated(), 1);


                // Create signed data
                DynamicArray signedData = new DynamicArray();
                signedData.append(new byte[] { 0x01 });
                signedData.append(hexUserID);
                signedData.append(nameH);
                signedData.append(new byte[] { 0x00, 0x01 });
                signedData.append(padding);
                signedData.append(expiredTime);
                signedData.append(padding2);
                signedData.append(new byte[] { 0x00, 0x11 });
                signedData.append(pubModulusH);
                signedData.append(createdTime);

                byte[] md5FromStructure = md5.digest(signedData.getBytes());

                // Do MD5 to the signed data and RSA encrypt the result
                byte[] signature = rsa.signWithMD5(md5FromStructure);


                Output.OptWriteLine("-> Signing with RSA");

                // Do: privExp = Twofish(privExp)
                byte[] privExp = wl.getPrivateExponent();
                byte[] buffer  = new byte[privExp.Length];

                // We keep the Key from before this part
                // Set the challenge we saved before as IV
                tf.setIV(challenge);
                tf.encrypt(privExp, buffer);

                privExp = buffer;

                byte [] privExpSize = NumericalUtils.uint16ToByteArray((UInt16)privExp.Length, 1);

                // Calculate offsets
                int offsetAuthData      = 33 + wl.getCharPack().getPackLength() + wl.getWorldPack().getTotalSize();
                int offsetEncryptedData = offsetAuthData + signature.Length + signedData.getSize() + 2;
                int offsetCharData      = 33;
                int offsetServerData    = 33 + wl.getCharPack().getPackLength();
                int offsetUsernameLast  = offsetEncryptedData + 2 + privExp.Length;

                // Create the auth header

                DynamicArray authHeader = new DynamicArray();
                authHeader.append(new byte[] { 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 });
                authHeader.append(NumericalUtils.uint16ToByteArray((UInt16)offsetAuthData, 1));
                authHeader.append(NumericalUtils.uint16ToByteArray((UInt16)offsetEncryptedData, 1));
                authHeader.append(new byte[] { 0x1f, 0x00, 0x00, 0x00 });
                authHeader.append(NumericalUtils.uint16ToByteArray((UInt16)offsetCharData, 1));
                authHeader.append(new byte[] { 0x6E, 0xD1, 0x00, 0x00 });
                authHeader.append(NumericalUtils.uint32ToByteArray((UInt32)offsetServerData, 1));
                authHeader.append(NumericalUtils.uint32ToByteArray((UInt32)offsetUsernameLast, 1));

                byte [] usernameSize = NumericalUtils.uint16ToByteArray((UInt16)(name.Length + 1), 1);

                // Create the semiResponse (full data, except the total size)
                DynamicArray semiResponse = new DynamicArray();
                semiResponse.append(authHeader.getBytes());
                semiResponse.append(wl.getCharPack().getByteContents());
                semiResponse.append(wl.getWorldPack().getByteContents());
                semiResponse.append(new byte[] { 0x36, 0x01 });
                semiResponse.append(signature);
                semiResponse.append(signedData.getBytes());
                semiResponse.append(privExpSize);
                semiResponse.append(privExp);
                semiResponse.append(usernameSize);


                byte [] tempName = new byte[name.Length];

                for (int i = 0; i < name.Length; i++)
                {
                    tempName[i] = (byte)name[i];
                }

                semiResponse.append(tempName);
                semiResponse.append(new byte[] { 0x00 });

                int bigSize = semiResponse.getSize();
                bigSize += 0x8000;                // Add TCP Len Var

                byte [] finalSize = NumericalUtils.uint16ToByteArray((UInt16)bigSize, 0);

                // Create the finalResponse (full data, plus total size)
                DynamicArray finalResponse = new DynamicArray();
                finalResponse.append(finalSize);
                finalResponse.append(semiResponse.getBytes());


                Output.OptWriteLine("Sending world list.");
                status = -1;

                return(finalResponse.getBytes());
            }

            byte [] worldListPacket = { 0x00, 0x00 };

            status = -1;           // trick
            return(worldListPacket);
        }
Example #3
0
        public bool fetchWordList(ref WorldList wl)
        {
            // Doesnt exist by default
            wl.setExistance(false);

            conn.Open();

            string sqlQuery = "SELECT * FROM users WHERE username='******' AND passwordmd5='" + wl.getPassword() + "' LIMIT 1;";

            queryExecuter             = conn.CreateCommand();
            queryExecuter.CommandText = sqlQuery;
            dr = queryExecuter.ExecuteReader();



            while (dr.Read())
            {
                // Player is on the DB
                wl.setExistance(true);
                wl.setUserID((int)dr.GetDecimal(0));
                dr.GetBytes(5, 0, wl.getPublicModulus(), 0, 96);
                dr.GetBytes(6, 0, wl.getPrivateExponent(), 0, 96);
                wl.setTimeCreated((int)dr.GetDecimal(7));
            }



            dr.Close();

            // If doesnt exist... should not do more things
            if (!wl.getExistance())
            {
                String msg = "Player not found on DB with #" + wl.getUsername() + "# and #" + wl.getPassword() + "#";
                Output.WriteLine(msg);
                conn.Close();
                return(false);
            }

            // If exist, get the player values


            // Count the values first

            int    totalChars = 0;
            string sqlCount   = "SELECT charId FROM characters WHERE userId='" + wl.getUserID() + "' AND is_deleted='0' ";

            queryExecuter             = conn.CreateCommand();
            queryExecuter.CommandText = sqlCount;
            dr = queryExecuter.ExecuteReader();

            while (dr.Read())
            {
                totalChars++;
            }

            dr.Close();
            wl.getCharPack().setTotalChars(totalChars);

            // Prepare to read characters

            string sqlQueryForChars = "SELECT * FROM characters WHERE userId='" + wl.getUserID() + "' AND is_deleted='0' ";

            queryExecuter             = conn.CreateCommand();
            queryExecuter.CommandText = sqlQueryForChars;
            dr = queryExecuter.ExecuteReader();

            // Read characters
            while (dr.Read())
            {
                //totalChars = (int) dr.GetDecimal(8);
                string charName = dr.GetString(4);
                int    charId   = (int)dr.GetDecimal(0);
                int    status   = (int)dr.GetDecimal(3);
                int    worldId  = (int)dr.GetDecimal(2);

                wl.getCharPack().addCharacter(charName, charId, status, worldId);
            }

            dr.Close();


            // Read worlds
            string sqlQueryForWorlds = "SELECT * FROM worlds ORDER BY worldId ASC";

            queryExecuter.CommandText = sqlQueryForWorlds;
            dr = queryExecuter.ExecuteReader();

            while (dr.Read())
            {
                string worldName = dr.GetString(1);

                int worldId         = (int)dr.GetDecimal(0);
                int worldType       = (int)dr.GetDecimal(2);
                int worldStatus     = (int)dr.GetDecimal(3);
                int worldPopulation = (int)dr.GetDecimal(4);
                wl.getWorldPack().addWorld(worldName, worldId, worldStatus, worldType, worldPopulation);
            }

            dr.Close();

            conn.Close();

            return(true);
        }