Beispiel #1
0
        /// <summary>
        ///     Tries to authenticate a user with the provided user credentials and returns session data corresponding to a
        ///     successful login; fails if information provided is not enough or service is unavailable.
        /// </summary>
        /// <param name="credentials">The credentials to be used for login process.</param>
        /// <returns>Logged in session to be used with other classes</returns>
        /// <exception cref="ArgumentException">
        ///     Username and/or password is missing. - credentials
        ///     or
        ///     Two factor authentication code is required for login process to continue. - credentials
        ///     or
        ///     Email verification code is required for login process to continue. - credentials
        ///     or
        ///     Captcha is required for login process to continue. - credentials
        /// </exception>
        /// <exception cref="UserLoginException">
        ///     Raises when there is a problem with login process or there is a need for more information. Capture and decide if
        ///     you should repeat the process.
        /// </exception>
        public virtual async Task <WebSession> DoLogin(LoginCredentials credentials)
        {
            if (string.IsNullOrWhiteSpace(credentials.UserName) || string.IsNullOrWhiteSpace(credentials.Password))
            {
                throw new ArgumentException("Username and/or password is missing.", nameof(credentials));
            }

            if (RequiresTwoFactorAuthenticationCode &&
                string.IsNullOrWhiteSpace(credentials.TwoFactorAuthenticationCode))
            {
                throw new ArgumentException("Two factor authentication code is required for login process to continue.",
                                            nameof(credentials));
            }

            if (RequiresEmailVerification && string.IsNullOrWhiteSpace(credentials.EmailVerificationCode))
            {
                throw new ArgumentException("Email verification code is required for login process to continue.",
                                            nameof(credentials));
            }

            if (RequiresCaptchaCode && string.IsNullOrWhiteSpace(credentials.CaptchaCode))
            {
                throw new ArgumentException("Captcha is required for login process to continue.", nameof(credentials));
            }

            // Lock this instance
            await LockObject.WaitAsync().ConfigureAwait(false);

            try
            {
                // Retrieve guest cookies for login process if missing
                if (string.IsNullOrEmpty(SteamWebAccess?.Session?.SessionId))
                {
                    await GetGuestSession().ConfigureAwait(false);
                }

                var loginRequest = await ConstructLoginRequest(credentials).ConfigureAwait(false);

                var loginResponse = loginRequest != null
                    ? await OperationRetryHelper.Default
                                    .RetryOperationAsync(() => SteamWebAccess.FetchString(loginRequest)).ConfigureAwait(false)
                    : null;

                if (loginResponse == null)
                {
                    throw new UserLoginException(UserLoginErrorCode.GeneralFailure, this);
                }

                if (!await ProcessLoginResponse(loginResponse).ConfigureAwait(false))
                {
                    throw new UserLoginException(UserLoginErrorCode.BadCredentials, this);
                }

                var sessionData = SteamWebAccess.Session;
                ResetStates();
                return(sessionData);
            }
            finally
            {
                // Unlock this instance
                LockObject.Release();
            }
        }
Beispiel #2
0
        protected virtual async Task <SteamWebAccessRequest> ConstructLoginRequest(LoginCredentials credentials)
        {
            // Get a RSA public key for password encryption
            var serverResponse = await SteamWebAccess.FetchString(
                new SteamWebAccessRequest(
                    WebLoginRSAUrl,
                    SteamWebAccessRequestMethod.Post,
                    new QueryStringBuilder
            {
                { "donotcache", (DateTime.UtcNow - Epoch).TotalMilliseconds },
                { "username", credentials.UserName }
            }
                    )
                ).ConfigureAwait(false);

            if (string.IsNullOrWhiteSpace(serverResponse) ||
                serverResponse.Contains("<BODY>\nAn error occurred while processing your request."))
            {
                throw new UserLoginException(UserLoginErrorCode.GeneralFailure, this);
            }

            var rsaResponse = JsonConvert.DeserializeObject <RSAResponse>(serverResponse);

            if (rsaResponse?.Success != true)
            {
                throw new UserLoginException(UserLoginErrorCode.BadRSAResponse, this);
            }

            // Sleep for a bit to give Steam a chance to catch up??
            await Task.Delay(350).ConfigureAwait(false);

            string encryptedPassword;

            using (var rsaEncrypt = new RSACryptoServiceProvider())
            {
                rsaEncrypt.ImportParameters(new RSAParameters
                {
                    Exponent = HexStringToByteArray(rsaResponse.Exponent),
                    Modulus  = HexStringToByteArray(rsaResponse.Modulus)
                });

                encryptedPassword =
                    Convert.ToBase64String(
                        rsaEncrypt.Encrypt(
                            Encoding.UTF8.GetBytes(credentials.Password)
                            , false)
                        );
            }

            return(new SteamWebAccessRequest(
                       WebLoginUrl,
                       SteamWebAccessRequestMethod.Post,
                       new QueryStringBuilder
            {
                { "donotcache", (DateTime.UtcNow - Epoch).TotalMilliseconds },
                { "rsatimestamp", rsaResponse.Timestamp },
                { "password", encryptedPassword },
                { "username", credentials.UserName },
                { "twofactorcode", credentials.TwoFactorAuthenticationCode ?? "" },
                { "emailauth", RequiresEmailVerification ? (credentials.EmailVerificationCode ?? "") : "" },
                { "loginfriendlyname", "" },
                { "captchagid", RequiresCaptchaCode ? (CaptchaGID ?? "-1") : "-1" },
                { "captcha_text", RequiresCaptchaCode ? (credentials.CaptchaCode ?? "") : "" },
                {
                    "emailsteamid",
                    RequiresTwoFactorAuthenticationCode || RequiresEmailVerification
                            ? (SteamId?.ToString() ?? "")
                            : ""
                },
                { "rsatimestamp", rsaResponse.Timestamp },
                { "remember_login", "true" }
            }
                       ));
        }
Beispiel #3
0
        public static async Task Login()
        {
            var username = "******";
            var password = "******";

            var loginCredentials = new LoginCredentials(username, password);
            var webLogin         = new WebLogin();

            while (true)
            {
                try
                {
                    var session = await webLogin.DoLogin(loginCredentials);

                    if (session?.HasEnoughInfo() == true)
                    {
                        // Login complete, serialize session or create an instance of SteamWebAccess

                        return;
                    }
                }
                catch (UserLoginException e)
                {
                    switch (e.ErrorCode)
                    {
                    case UserLoginErrorCode.GeneralFailure:

                        throw;

                    case UserLoginErrorCode.BadRSAResponse:

                        throw;

                    case UserLoginErrorCode.BadCredentials:

                        throw;

                    case UserLoginErrorCode.TooManyFailedLoginAttempts:

                        throw;

                    case UserLoginErrorCode.NeedsCaptchaCode:
                        // Should download the captcha image and fill the CaptchaCode property of LoginCredentials and try again
                        var captchaImage = await e.UserLogin.DownloadCaptchaImage();

                        loginCredentials.CaptchaCode = "CAPTCHA CODE";

                        break;

                    case UserLoginErrorCode.NeedsTwoFactorAuthenticationCode:
                        // This account has a mobile authenticator associated with it
                        // Should fill the TwoFactorAuthenticationCode property of LoginCredentials and try again
                        loginCredentials.TwoFactorAuthenticationCode = "AUTHENTICATOR 2FA CODE";

                        break;

                    case UserLoginErrorCode.NeedsEmailVerificationCode:
                        // This account uses Steam Guard for added security
                        // Should fill the EmailVerificationCode property of LoginCredentials and try again
                        loginCredentials.EmailVerificationCode = "EMAIL VERIFICATION CODE";

                        break;
                    }
                }
            }
        }