diff --git a/SteamAccountDataFetcher/SteamAccountDataFetcher.csproj b/SteamAccountDataFetcher/SteamAccountDataFetcher.csproj
index 8a0e11e..25e52de 100644
--- a/SteamAccountDataFetcher/SteamAccountDataFetcher.csproj
+++ b/SteamAccountDataFetcher/SteamAccountDataFetcher.csproj
@@ -9,11 +9,11 @@
Andrii Lavrenko
Utility for collecting Steam account information
Andrii Lavrenko
- 2.0.0
+ 3.0.0
-
+
diff --git a/SteamAccountDataFetcher/SteamDataClient/AccountInfo.cs b/SteamAccountDataFetcher/SteamDataClient/AccountInfo.cs
index ff6821c..8ffa3ed 100644
--- a/SteamAccountDataFetcher/SteamDataClient/AccountInfo.cs
+++ b/SteamAccountDataFetcher/SteamDataClient/AccountInfo.cs
@@ -10,6 +10,7 @@ public class PackageInfo
public string Username { get; set; } = string.Empty;
public ulong SteamId { get; set; } = 0;
public List Packages { get; set; } = new();
+ public bool IsLocked { get; set; }
public bool IsLimited { get; set; }
public bool IsBanned { get; set; }
public string ApiKey { get; set; } = string.Empty;
diff --git a/SteamAccountDataFetcher/SteamDataClient/SteamTwoFactorGenerator.cs b/SteamAccountDataFetcher/SteamDataClient/AutoTwoFactorAuthenticator.cs
similarity index 79%
rename from SteamAccountDataFetcher/SteamDataClient/SteamTwoFactorGenerator.cs
rename to SteamAccountDataFetcher/SteamDataClient/AutoTwoFactorAuthenticator.cs
index 6cda007..5074318 100644
--- a/SteamAccountDataFetcher/SteamDataClient/SteamTwoFactorGenerator.cs
+++ b/SteamAccountDataFetcher/SteamDataClient/AutoTwoFactorAuthenticator.cs
@@ -1,11 +1,12 @@
using SteamKit2;
+using SteamKit2.Authentication;
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
namespace SteamAccountDataFetcher.SteamDataClient;
-internal class SteamTwoFactorGenerator
+public class AutoTwoFactorAuthenticator: IAuthenticator
{
private const string STEAM_TWO_FACTOR_SERVICE_INTERFACE = "ITwoFactorService";
private const string STEAM_QUERY_TIME_METHOD = "QueryTime";
@@ -16,20 +17,19 @@ internal class SteamTwoFactorGenerator
private static bool _aligned = false;
private Client _steamClient;
+ private string _sharedSecret;
- internal SteamTwoFactorGenerator(Client steamClient)
+ public AutoTwoFactorAuthenticator(Client steamClient, string sharedSecret)
{
_steamClient = steamClient;
+ _sharedSecret = sharedSecret;
}
- internal async Task GenerateSteamGuardCodeAsync(string sharedSecret)
+ public async Task GenerateSteamGuardCodeAsync()
{
- if (string.IsNullOrWhiteSpace(sharedSecret))
- return string.Empty;
-
long time = await GetSteamTimeAsync();
- string sharedSecretUnescaped = Regex.Unescape(sharedSecret);
+ string sharedSecretUnescaped = Regex.Unescape(_sharedSecret);
byte[] sharedSecretArray = Convert.FromBase64String(sharedSecretUnescaped);
byte[] timeArray = new byte[8];
@@ -88,4 +88,10 @@ private async Task AlignTimeAsync()
_aligned = true;
return;
}
+
+ public Task GetDeviceCodeAsync(bool previousCodeWasIncorrect) => GenerateSteamGuardCodeAsync();
+
+ public Task GetEmailCodeAsync(string email, bool previousCodeWasIncorrect) => throw new NotImplementedException();
+
+ public Task AcceptDeviceConfirmationAsync() => throw new NotImplementedException();
}
diff --git a/SteamAccountDataFetcher/SteamDataClient/Client.cs b/SteamAccountDataFetcher/SteamDataClient/Client.cs
index 3155371..03aeae9 100644
--- a/SteamAccountDataFetcher/SteamDataClient/Client.cs
+++ b/SteamAccountDataFetcher/SteamDataClient/Client.cs
@@ -1,12 +1,13 @@
using System.Runtime.CompilerServices;
using SteamKit2;
+using SteamKit2.Authentication;
namespace SteamAccountDataFetcher.SteamDataClient;
-internal class Client : IDisposable
+public class Client : IDisposable
{
private SteamClient _steamClient;
- private SteamTwoFactorGenerator _steamTwoFactorGenerator;
+ private AutoTwoFactorAuthenticator _autoTwoFactorAuthenticator;
private SteamWebClient _steamWebClient;
private CallbackManager _callbackManager;
private SteamUser _steamUser;
@@ -26,7 +27,8 @@ internal SteamID? SteamID
}
internal string Username { get; private set; }
internal string Password { get; private set; }
- private string SharedSecret { get; set; }
+ internal string AccessToken { get; private set; } = string.Empty;
+ internal string RefreshToken { get; private set; } = string.Empty;
private static uint _instance = 0;
private static DateTime _lastConnectionTime = DateTime.MinValue;
@@ -43,7 +45,6 @@ internal Client(string username, string password, string sharedSecret)
Username = username;
Password = password;
- SharedSecret = sharedSecret;
_responseAccountInfo = new()
{
@@ -74,13 +75,13 @@ internal Client(string username, string password, string sharedSecret)
_callbackManager.Subscribe(OnConnectedAsync);
_callbackManager.Subscribe(OnDisconnectedAsync);
- _callbackManager.Subscribe(OnLoggedOnAsync);
+ _callbackManager.Subscribe(OnLoggedOn);
_callbackManager.Subscribe(OnLoggedOffAsync);
_callbackManager.Subscribe(OnLicenseListAsync);
_callbackManager.Subscribe(OnIsLimitedAccount);
- _steamTwoFactorGenerator = new(this);
+ _autoTwoFactorAuthenticator = new(this, sharedSecret);
_steamWebClient = new(this);
}
@@ -117,12 +118,32 @@ internal async Task RunAsync()
private async Task LoginAsync()
{
- string twoFactorCode = await _steamTwoFactorGenerator.GenerateSteamGuardCodeAsync(SharedSecret);
- _steamUser.LogOn(new()
+ CredentialsAuthSession authSession = await _steamClient.Authentication.BeginAuthSessionViaCredentialsAsync(new()
{
Username = Username,
Password = Password,
- TwoFactorCode = twoFactorCode
+ Authenticator = _autoTwoFactorAuthenticator
+ });
+
+ AuthPollResult authPollResult;
+ try
+ {
+ authPollResult = await authSession.PollingWaitForResultAsync();
+ }
+ catch (AuthenticationException e)
+ {
+ Log($"Unable to authenticate user to Steam Client with error {e.Message}.", Logger.Level.Error);
+ _steamClient.Disconnect();
+ return;
+ }
+
+ AccessToken = authPollResult.AccessToken;
+ RefreshToken = authPollResult.RefreshToken;
+
+ _steamUser.LogOn(new()
+ {
+ Username = Username,
+ AccessToken = RefreshToken
});
}
@@ -170,7 +191,7 @@ private async void OnDisconnectedAsync(SteamClient.DisconnectedCallback callback
_steamClient.Connect();
}
- private async void OnLoggedOnAsync(SteamUser.LoggedOnCallback callback)
+ private void OnLoggedOn(SteamUser.LoggedOnCallback callback)
{
if (callback.Result != EResult.OK)
{
@@ -179,13 +200,6 @@ private async void OnLoggedOnAsync(SteamUser.LoggedOnCallback callback)
return;
}
- if (string.IsNullOrEmpty(callback.WebAPIUserNonce))
- {
- Log($"{nameof(callback.WebAPIUserNonce)} is empty.", Logger.Level.Error);
- _steamClient.Disconnect();
- return;
- }
-
if (callback.ClientSteamID == null)
{
Log($"{nameof(callback.ClientSteamID)} is empty.", Logger.Level.Error);
@@ -193,30 +207,18 @@ private async void OnLoggedOnAsync(SteamUser.LoggedOnCallback callback)
return;
}
_responseAccountInfo.SteamId = callback.ClientSteamID.ConvertToUInt64();
-
- Log("Logged into Steam. Log-in into Web Api.");
- var webLoginResult = await _steamWebClient.InitAsync(callback.WebAPIUserNonce);
- if (!webLoginResult)
- {
- Log("Unable to log-in into Web Api.", Logger.Level.Error);
- _steamClient.Disconnect();
- return;
- }
- Log("Logged into Web Api.");
+ _steamWebClient.InitAsync();
}
private async void OnIsLimitedAccount(DataFetcher.IsLimitedAccountCallback callback)
{
- if (callback.Locked)
- {
- Log("Account is locked.", Logger.Level.Error);
- _steamClient.Disconnect();
- return;
- }
-
+ _responseAccountInfo.IsLocked = callback.Locked;
_responseAccountInfo.IsBanned = callback.CommunityBanned;
_responseAccountInfo.IsLimited = callback.Limited;
+ if (callback.Locked)
+ Log("Account is locked.", Logger.Level.Warning);
+
if (callback.CommunityBanned)
Log("Account is banned.", Logger.Level.Warning);
diff --git a/SteamAccountDataFetcher/SteamDataClient/SteamWebClient.cs b/SteamAccountDataFetcher/SteamDataClient/SteamWebClient.cs
index deb843e..d82fec4 100644
--- a/SteamAccountDataFetcher/SteamDataClient/SteamWebClient.cs
+++ b/SteamAccountDataFetcher/SteamDataClient/SteamWebClient.cs
@@ -1,18 +1,12 @@
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
-using SteamKit2;
+using System.Web;
namespace SteamAccountDataFetcher.SteamDataClient;
internal class SteamWebClient: IDisposable
{
- private const string STEAM_USER_AUTH_INTERFACE = "ISteamUserAuth";
- private const string STEAM_COMMUNITY_SERVICE_INTERFACE = "ICommunityService";
-
- private const string STEAM_AUTH_USER_METHOD = "AuthenticateUser";
- private const string STEAM_GET_APPS_METHOD = "GetApps";
-
private static readonly Uri API_KEY_URI = new("https://steamcommunity.com/dev/apikey");
private static readonly Uri REGISTER_API_KEY_URI = new("https://steamcommunity.com/dev/registerkey");
private const string API_GROUP_KEY = "apiKey";
@@ -179,78 +173,23 @@ private string MatchApiKey(string html)
return apiKey;
}
- internal async Task InitAsync(string webApiUserNonce)
+ internal void InitAsync()
{
if (_steamClient.SteamID == null || !_steamClient.SteamID.IsValid || !_steamClient.SteamID.IsIndividualAccount)
{
- _steamClient.Log($"{nameof(_steamClient.SteamID)} is invalid.", Logger.Level.Error);
- return false;
+ var msg = $"{nameof(_steamClient.SteamID)} is invalid.";
+ _steamClient.Log(msg, Logger.Level.Error);
+ throw new InvalidOperationException(msg);
}
- if (string.IsNullOrEmpty(webApiUserNonce))
- {
- _steamClient.Log($"{nameof(webApiUserNonce)} is empty.", Logger.Level.Error);
- return false;
- }
-
- await RunOrSleep();
-
- var publicKey = KeyDictionary.GetPublicKey(EUniverse.Public);
- if (publicKey == null || publicKey.Length == 0)
+ if (string.IsNullOrEmpty(_steamClient.AccessToken))
{
- _steamClient.Log($"{nameof(KeyDictionary)} is empty.", Logger.Level.Error);
- return false;
+ var msg = $"{nameof(_steamClient.AccessToken)} is empty.";
+ _steamClient.Log(msg, Logger.Level.Error);
+ throw new InvalidOperationException(msg);
}
- var sessionKey = CryptoHelper.GenerateRandomBlock(32);
- byte[] encryptedSessionKey;
-
- using (RSACrypto rsa = new(publicKey))
- encryptedSessionKey = rsa.Encrypt(sessionKey);
-
- var loginKey = Encoding.UTF8.GetBytes(webApiUserNonce);
- var encryptedLoginKey = CryptoHelper.SymmetricEncrypt(loginKey, sessionKey);
-
- Dictionary postData = new(3, StringComparer.Ordinal)
- {
- { "encrypted_loginkey", encryptedLoginKey },
- { "sessionkey", encryptedSessionKey },
- { "steamid", _steamClient.SteamID.ConvertToUInt64() }
- };
-
- KeyValue response;
- using (var steamUserAuthInterface = _steamClient.SteamConfiguration.GetAsyncWebAPIInterface(STEAM_USER_AUTH_INTERFACE))
- {
- try
- {
- response = await steamUserAuthInterface.CallAsync(HttpMethod.Post, STEAM_AUTH_USER_METHOD, args: postData);
- }
- catch (HttpRequestException e)
- {
- _steamClient.Log($"Unable to authenticate user to web with status code {e.StatusCode}.", Logger.Level.Error);
- return (false);
- }
-
- if (response == null)
- {
- _steamClient.Log("Unable to authenticate user to web.", Logger.Level.Error);
- return false;
- }
- }
-
- string? steamLogin = response["token"].AsString();
- if (string.IsNullOrWhiteSpace(steamLogin))
- {
- _steamClient.Log($"{nameof(steamLogin)} is empty.", Logger.Level.Error);
- return false;
- }
-
- string? steamLoginSecure = response["tokensecure"].AsString();
- if (string.IsNullOrWhiteSpace(steamLoginSecure))
- {
- _steamClient.Log($"{nameof(steamLoginSecure)} is empty.", Logger.Level.Error);
- return false;
- }
+ string steamLoginSecure = HttpUtility.UrlEncode($"{_steamClient.SteamID.ConvertToUInt64()}||{_steamClient.AccessToken}");
Random rnd = new Random();
byte[] sessionBytes = new byte[12];
@@ -264,10 +203,6 @@ internal async Task InitAsync(string webApiUserNonce)
new Cookie("sessionid", SessionID, "/", ".steamcommunity.com"),
new Cookie("sessionid", SessionID, "/", ".help.steampowered.com"),
new Cookie("sessionid", SessionID, "/", ".store.steampowered.com"),
- new Cookie("steamLogin", steamLogin, "/", ".checkout.steampowered.com"),
- new Cookie("steamLogin", steamLogin, "/", ".steamcommunity.com"),
- new Cookie("steamLogin", steamLogin, "/", ".help.steampowered.com"),
- new Cookie("steamLogin", steamLogin, "/", ".store.steampowered.com"),
new Cookie("steamLoginSecure", steamLoginSecure, "/", ".checkout.steampowered.com"),
new Cookie("steamLoginSecure", steamLoginSecure, "/", ".steamcommunity.com"),
new Cookie("steamLoginSecure", steamLoginSecure, "/", ".help.steampowered.com"),
@@ -283,7 +218,7 @@ internal async Task InitAsync(string webApiUserNonce)
_httpClient = new HttpClient(httpClientHandler, true);
- return true;
+ return;
}
private async Task RunOrSleep()