Exemplo n.º 1
0
        public PreLoginResponse PreLgoin()
        {
            this.header.FunctionName = "preLogin";
            this.request             = new PreLoginRequest();
            this.header.Request      = request;

            PreLoginResponse value = this.Request <PreLoginResponse>();

            return(value);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Generate authentication informations and store them in a serializable object to allow persistence
        /// </summary>
        /// <param name="email">email</param>
        /// <param name="password">password</param>
        /// <returns><see cref="AuthInfos" /> object containing encrypted data</returns>
        /// <exception cref="ArgumentNullException">email or password is null</exception>
        public AuthInfos GenerateAuthInfos(string email, string password)
        {
            if (string.IsNullOrEmpty(email))
            {
                throw new ArgumentNullException("email");
            }

            if (string.IsNullOrEmpty(password))
            {
                throw new ArgumentNullException("password");
            }

            // Prelogin to retrieve account version
            PreLoginRequest  preLoginRequest  = new PreLoginRequest(email);
            PreLoginResponse preLoginResponse = this.Request <PreLoginResponse>(preLoginRequest);

            if (preLoginResponse.Version == 2 && !string.IsNullOrEmpty(preLoginResponse.Salt))
            {
                // Mega uses a new way to hash password based on a salt sent by Mega during prelogin
                var       saltBytes     = preLoginResponse.Salt.FromBase64();
                var       passwordBytes = password.ToBytesPassword();
                const int Iterations    = 100000;

                var derivedKeyBytes = new byte[32];
                using (var hmac = new HMACSHA512())
                {
                    var pbkdf2 = new Pbkdf2(hmac, passwordBytes, saltBytes, Iterations);
                    derivedKeyBytes = pbkdf2.GetBytes(derivedKeyBytes.Length);
                }

                // Derived key contains master key (0-16) and password hash (16-32)
                return(new AuthInfos(
                           email,
                           derivedKeyBytes.Skip(16).ToArray().ToBase64(),
                           derivedKeyBytes.Take(16).ToArray()));
            }
            else if (preLoginResponse.Version == 1)
            {
                // Retrieve password as UTF8 byte array
                byte[] passwordBytes = password.ToBytesPassword();

                // Encrypt password to use password as key for the hash
                byte[] passwordAesKey = PrepareKey(passwordBytes);

                // Hash email and password to decrypt master key on Mega servers
                string hash = GenerateHash(email.ToLowerInvariant(), passwordAesKey);

                return(new AuthInfos(email, hash, passwordAesKey));
            }
            else
            {
                throw new NotSupportedException("Version of account not supported");
            }
        }
Exemplo n.º 3
0
        // Token: 0x06000932 RID: 2354 RVA: 0x0004B428 File Offset: 0x00049628
        public MegaApiClient.AuthInfos GenerateAuthInfos(string email, string password, string mfaKey = null)
        {
            if (string.IsNullOrEmpty(email))
            {
                throw new ArgumentNullException("email");
            }
            if (string.IsNullOrEmpty(password))
            {
                throw new ArgumentNullException("password");
            }
            PreLoginRequest  request          = new PreLoginRequest(email);
            PreLoginResponse preLoginResponse = this.Request <PreLoginResponse>(request, null);

            if (preLoginResponse.Version == 2 && !string.IsNullOrEmpty(preLoginResponse.Salt))
            {
                byte[] salt      = preLoginResponse.Salt.FromBase64();
                byte[] password2 = password.ToBytesPassword();
                byte[] array     = new byte[32];
                using (HMACSHA512 hmacsha = new HMACSHA512())
                {
                    array = new Pbkdf2(hmacsha, password2, salt, 100000).GetBytes(array.Length);
                }
                if (!string.IsNullOrEmpty(mfaKey))
                {
                    return(new MegaApiClient.AuthInfos(email, array.Skip(16).ToArray <byte>().ToBase64(), array.Take(16).ToArray <byte>(), mfaKey));
                }
                return(new MegaApiClient.AuthInfos(email, array.Skip(16).ToArray <byte>().ToBase64(), array.Take(16).ToArray <byte>(), null));
            }
            else
            {
                if (preLoginResponse.Version != 1)
                {
                    throw new NotSupportedException("Version of account not supported");
                }
                byte[] passwordAesKey = MegaApiClient.PrepareKey(password.ToBytesPassword());
                string hash           = MegaApiClient.GenerateHash(email.ToLowerInvariant(), passwordAesKey);
                if (!string.IsNullOrEmpty(mfaKey))
                {
                    return(new MegaApiClient.AuthInfos(email, hash, passwordAesKey, mfaKey));
                }
                return(new MegaApiClient.AuthInfos(email, hash, passwordAesKey, null));
            }
        }
Exemplo n.º 4
0
        public async Task Login(IUserConfiguration user = null)
        {
            var configuration = Api.Storage.Get();

            user = await ResolveUserConfiguration(user, configuration);

            var username = user?.Username;
            var password = user?.Password;

            if (string.IsNullOrEmpty(username) || string.IsNullOrEmpty(password))
            {
                return;
            }
            var token     = user.TwoFactorToken;
            var tokenType = "device_token";

            string           authHash = null;
            PreLoginResponse preLogin = null;

            while (true)
            {
                if (preLogin == null)
                {
                    preLogin = await Api.GetPreLogin(username);

                    authHash = null;
                }

                var    authParams = preLogin.Salt[0];
                int    iterations = authParams.Iterations;
                byte[] salt       = authParams.Salt_.ToByteArray();
                if (authHash == null)
                {
                    authHash = CryptoUtils.DeriveV1KeyHash(password, salt, iterations).Base64UrlEncode();
                }

                var command = new LoginCommand();
                command.username                 = username;
                command.authResponse             = authHash;
                command.include                  = new[] { "keys", "settings", "enforcements", "is_enterprise_admin" };
                command.twoFactorToken           = token;
                command.twoFactorType            = !string.IsNullOrEmpty(token) ? tokenType : null;
                command.deviceTokenExpiresInDays = !string.IsNullOrEmpty(token) && tokenType != "device_token" ? 9999 : (int?)null;

                var loginRs = await Api.ExecuteV2Command <LoginCommand, LoginResponse>(command);

                if (!loginRs.IsSuccess && loginRs.resultCode == "auth_failed") // invalid password
                {
                    throw new Exception("Invalid user name or password");
                }
                else
                {
                    if (!string.IsNullOrEmpty(loginRs.deviceToken))
                    {
                        token     = loginRs.deviceToken;
                        tokenType = "device_token";
                    }

                    SessionToken    = loginRs.sessionToken;
                    Username        = username;
                    accountSettings = loginRs.accountSettings;

                    if (loginRs.keys != null)
                    {
                        if (loginRs.keys.encryptedDataKey != null)
                        {
                            var key = CryptoUtils.DeriveKeyV2("data_key", password, salt, iterations);
                            DataKey = CryptoUtils.DecryptAesV2(loginRs.keys.encryptedDataKey.Base64UrlDecode(), key);
                        }
                        else
                        if (loginRs.keys.encryptionParams != null)
                        {
                            DataKey = CryptoUtils.DecryptEncryptionParams(password, loginRs.keys.encryptionParams.Base64UrlDecode());
                        }
                        else
                        {
                            throw new Exception("Missing data key");
                        }
                        if (loginRs.keys.encryptedPrivateKey != null)
                        {
                            privateKeyData = CryptoUtils.DecryptAesV1(loginRs.keys.encryptedPrivateKey.Base64UrlDecode(), DataKey);
                            privateKey     = null;
                        }
                    }
                    if (loginRs.IsSuccess)
                    {
                        EncryptedPassword = CryptoUtils.EncryptAesV2(Encoding.UTF8.GetBytes(password), DataKey);
                        TwoFactorToken    = token;
                        authResponse      = authHash;
                        IsEnterpriseAdmin = loginRs.isEnterpriseAdmin ?? false;
                        enforcements      = loginRs.enforcements;
                        StoreConfigurationIfChanged(configuration);
                        break;
                    }
                    switch (loginRs.resultCode)
                    {
                    case "need_totp":
                    case "invalid_device_token":
                    case "invalid_totp":
                        token = await Ui.GetTwoFactorCode();

                        if (!string.IsNullOrEmpty(token))
                        {
                            tokenType = "one_time";
                            continue;
                        }
                        break;

                    case "auth_expired":
                        await Ui.DisplayDialog(DialogType.Information, loginRs.message);

                        password = await this.ChangeMasterPassword(iterations);

                        if (!string.IsNullOrEmpty(password))
                        {
                            preLogin = null;
                            continue;
                        }
                        break;

                    case "auth_expired_transfer":
                        var shareAccountTo = loginRs.accountSettings.shareAccountTo;
                        if (await Ui.DisplayDialog(DialogType.Confirmation, "Do you accept Account Transfer policy?"))
                        {
                            await this.ShareAccount();

                            continue;
                        }
                        break;
                    }
                    throw new KeeperApiException(loginRs.resultCode, loginRs.message);
                }
            }
        }