Exemple #1
0
        public static Encryption CreateClientLogin(LoginEncryptionType type, uint seed, uint key1, uint key2)
        {
            IEncryptor encryptor;
            IDecryptor decryptor;

            switch (type)
            {
                case LoginEncryptionType.None:
                    NoEncryption encryption = new NoEncryption();
                    encryptor = encryption;
                    decryptor = encryption;
                    break;

                case LoginEncryptionType.Old:
                case LoginEncryptionType.Rare:
                    throw new Exception("Unsupported login encryption.");

                case LoginEncryptionType.New:
                    encryptor = new LoginEncryption(seed, key1, key2);
                    decryptor = new NoEncryption();
                    break;

                default:
                    throw new Exception("Internal error.");
            }

            return new Encryption(encryptor, decryptor);
        }
Exemple #2
0
        public static Encryption CreateClientLogin(LoginEncryptionType type, uint seed, uint key1, uint key2)
        {
            IEncryptor encryptor;
            IDecryptor decryptor;

            switch (type)
            {
            case LoginEncryptionType.None:
                NoEncryption encryption = new NoEncryption();
                encryptor = encryption;
                decryptor = encryption;
                break;

            case LoginEncryptionType.Old:
            case LoginEncryptionType.Rare:
                throw new Exception("Unsupported login encryption.");

            case LoginEncryptionType.New:
                encryptor = new LoginEncryption(seed, key1, key2);
                decryptor = new NoEncryption();
                break;

            default:
                throw new Exception("Internal error.");
            }

            return(new Encryption(encryptor, decryptor));
        }
Exemple #3
0
        public static EncryptionVersion FromLogin(LoginEncryptionType login)
        {
            switch (login)
            {
            case LoginEncryptionType.None:
                return(new EncryptionVersion());

            case LoginEncryptionType.Old:
                return(new EncryptionVersion(1, 25, 35));

            case LoginEncryptionType.Rare:
                return(new EncryptionVersion(1, 25, 36));

            case LoginEncryptionType.New:
                return(new EncryptionVersion(1, 25, 37));

            default:
                throw new Exception("Internal error.");
            }
        }
Exemple #4
0
        protected override bool OnClientMessage(byte[] data)
        {
            switch (phase)
            {
            case Phase.Seed:
                if (data.Length != 4)
                {
                    throw new SocketException("Error while initializing LoginSocket. Invalid seed lenght.", this, data);
                }

                // Seed comes in little endian and encryption alghortm expects it in little endian, so i keep it as it is.
                Seed = ByteConverter.LittleEndian.ToUInt32(data, 0);
                CommunicationManager.LoginSeed = Seed;

                SendToServer(data);
                phase = Phase.Keys;
                return(true);

            case Phase.Keys:
                if (data.Length != 62)
                {
                    throw new SocketException("Error while initializing LoginSocket. Invalid login packet lenght.", this, data);
                }


                // Detect and create client encryption
                uint key1;
                uint key2;
                LoginEncryptionType clientEnc = GetClientEncryption(data, out key1, out key2);
                ClientEncryption = Encryption.CreateServerLogin(clientEnc, Seed, key1, key2);


                // Read and create server encryption
                uint serverKey1;
                uint serverKey2;
                LoginEncryptionType serverEnc;


                int v = Int32.Parse(Core.LaunchData.ServerEncryption);

                switch (v)
                {
                case 0:
                    serverKey1 = 0;
                    serverKey2 = 0;
                    serverEnc  = LoginEncryptionType.None;
                    Trace.WriteLine("Using no server encryption.", "Communication");
                    break;

                case 1:
                    serverKey1 = key1;
                    serverKey2 = key2;
                    serverEnc  = clientEnc;
                    Trace.WriteLine(String.Format("Server key1: {1} key2: {2}", Seed.ToString("X"), serverKey1.ToString("X"), serverKey2.ToString("X")), "Communication");
                    break;

                default:
                    try {
                        serverKey1 = UInt32.Parse(Core.LaunchData.ServerKey1, System.Globalization.NumberStyles.HexNumber);
                        serverKey2 = UInt32.Parse(Core.LaunchData.ServerKey2, System.Globalization.NumberStyles.HexNumber);
                        serverEnc  = LoginEncryptionType.New;
                    }
                    catch (Exception e) {
                        throw new Exception("Error parsing server login keys.", e);
                    }
                    Trace.WriteLine(String.Format("Server key1: {1} key2: {2}", Seed.ToString("X"), serverKey1.ToString("X"), serverKey2.ToString("X")), "Communication");
                    break;
                }

                ServerEncryption = Encryption.CreateClientLogin(serverEnc, Seed, serverKey1, serverKey2);

                byte[] decrypted = ClientEncryption.Decrypt(data);

                // Save used account and password. They will be used to detect game encryprion.
                CommunicationManager.Username = ByteConverter.BigEndian.ToAsciiString(decrypted, 1, 30);
                CommunicationManager.Password = ByteConverter.BigEndian.ToAsciiString(decrypted, 31, 30);

                SendToServer(decrypted);

                // Zero password for security reasons
                for (int i = 31; i < 61; i++)
                {
                    decrypted[i] = 0;
                }

                Core.OnClientMessage(decrypted, CallbackResult.Sent);

                phase = Phase.Normal;
                return(true);
            }

            return(base.OnClientMessage(data));
        }