Improve 2FA import process

This commit is contained in:
JustArchi
2018-12-26 16:56:28 +01:00
parent 05d7715ee8
commit 214dbaabcd
4 changed files with 116 additions and 59 deletions

View File

@@ -1450,7 +1450,45 @@ namespace ArchiSteamFarm {
ArchiLogger.LogGenericInfo(Strings.BotAuthenticatorConverting);
try {
MobileAuthenticator authenticator = JsonConvert.DeserializeObject<MobileAuthenticator>(await RuntimeCompatibility.File.ReadAllTextAsync(maFilePath).ConfigureAwait(false));
string json = await RuntimeCompatibility.File.ReadAllTextAsync(maFilePath).ConfigureAwait(false);
if (string.IsNullOrEmpty(json)) {
ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsEmpty, nameof(json)));
return;
}
MobileAuthenticator authenticator = JsonConvert.DeserializeObject<MobileAuthenticator>(json);
if (authenticator == null) {
ArchiLogger.LogNullError(nameof(authenticator));
return;
}
if (!authenticator.HasValidDeviceID) {
ArchiLogger.LogGenericWarning(Strings.BotAuthenticatorInvalidDeviceID);
if (string.IsNullOrEmpty(DeviceID)) {
string deviceID = Program.GetUserInput(ASF.EUserInputType.DeviceID, BotName);
if (string.IsNullOrEmpty(deviceID)) {
return;
}
SetUserInput(ASF.EUserInputType.DeviceID, deviceID);
}
if (!MobileAuthenticator.IsValidDeviceID(DeviceID)) {
ArchiLogger.LogGenericWarning(Strings.BotAuthenticatorInvalidDeviceID);
return;
}
authenticator.CorrectDeviceID(DeviceID);
}
authenticator.Init(this);
await BotDatabase.SetMobileAuthenticator(authenticator).ConfigureAwait(false);
File.Delete(maFilePath);
} catch (Exception e) {
@@ -1459,32 +1497,6 @@ namespace ArchiSteamFarm {
return;
}
if (BotDatabase.MobileAuthenticator == null) {
ArchiLogger.LogNullError(nameof(BotDatabase.MobileAuthenticator));
return;
}
BotDatabase.MobileAuthenticator.Init(this);
if (!BotDatabase.MobileAuthenticator.HasCorrectDeviceID) {
ArchiLogger.LogGenericWarning(Strings.BotAuthenticatorInvalidDeviceID);
if (string.IsNullOrEmpty(DeviceID)) {
string deviceID = Program.GetUserInput(ASF.EUserInputType.DeviceID, BotName);
if (string.IsNullOrEmpty(deviceID)) {
await BotDatabase.SetMobileAuthenticator().ConfigureAwait(false);
return;
}
SetUserInput(ASF.EUserInputType.DeviceID, deviceID);
}
await BotDatabase.CorrectMobileAuthenticatorDeviceID(DeviceID).ConfigureAwait(false);
}
ArchiLogger.LogGenericInfo(Strings.BotAuthenticatorImportFinished);
}

View File

@@ -137,18 +137,6 @@ namespace ArchiSteamFarm {
}
}
internal async Task CorrectMobileAuthenticatorDeviceID(string deviceID) {
if (string.IsNullOrEmpty(deviceID) || (MobileAuthenticator == null)) {
ASF.ArchiLogger.LogNullError(nameof(deviceID) + " || " + nameof(MobileAuthenticator));
return;
}
if (MobileAuthenticator.CorrectDeviceID(deviceID)) {
await Save().ConfigureAwait(false);
}
}
internal static async Task<BotDatabase> CreateOrLoad(string filePath) {
if (string.IsNullOrEmpty(filePath)) {
ASF.ArchiLogger.LogNullError(nameof(filePath));

View File

@@ -45,8 +45,7 @@ namespace ArchiSteamFarm {
private static DateTime LastSteamTimeCheck;
private static int? SteamTimeDifference;
// "ERROR" is being used by SteamDesktopAuthenticator
internal bool HasCorrectDeviceID => !string.IsNullOrEmpty(DeviceID) && !DeviceID.Equals("ERROR");
internal bool HasValidDeviceID => !string.IsNullOrEmpty(DeviceID) && IsValidDeviceID(DeviceID);
#pragma warning disable 649
[JsonProperty(PropertyName = "identity_secret", Required = Required.Always)]
@@ -65,20 +64,20 @@ namespace ArchiSteamFarm {
private MobileAuthenticator() { }
internal bool CorrectDeviceID(string deviceID) {
internal void CorrectDeviceID(string deviceID) {
if (string.IsNullOrEmpty(deviceID)) {
Bot.ArchiLogger.LogNullError(nameof(deviceID));
return false;
return;
}
if (!string.IsNullOrEmpty(DeviceID) && DeviceID.Equals(deviceID)) {
return false;
if (!IsValidDeviceID(deviceID)) {
Bot.ArchiLogger.LogGenericError(string.Format(Strings.ErrorIsInvalid, nameof(deviceID)));
return;
}
DeviceID = deviceID;
return true;
}
internal async Task<string> GenerateToken() {
@@ -100,7 +99,7 @@ namespace ArchiSteamFarm {
return null;
}
if (!HasCorrectDeviceID) {
if (!HasValidDeviceID) {
Bot.ArchiLogger.LogGenericError(Strings.ErrorMobileAuthenticatorInvalidDeviceID);
return null;
@@ -128,7 +127,7 @@ namespace ArchiSteamFarm {
}
internal async Task<HashSet<Confirmation>> GetConfirmations(Steam.ConfirmationDetails.EType acceptedType = Steam.ConfirmationDetails.EType.Unknown) {
if (!HasCorrectDeviceID) {
if (!HasValidDeviceID) {
Bot.ArchiLogger.LogGenericError(Strings.ErrorMobileAuthenticatorInvalidDeviceID);
return null;
@@ -228,7 +227,7 @@ namespace ArchiSteamFarm {
return false;
}
if (!HasCorrectDeviceID) {
if (!HasValidDeviceID) {
Bot.ArchiLogger.LogGenericError(Strings.ErrorMobileAuthenticatorInvalidDeviceID);
return false;
@@ -278,6 +277,26 @@ namespace ArchiSteamFarm {
internal void Init(Bot bot) => Bot = bot ?? throw new ArgumentNullException(nameof(bot));
internal static bool IsValidDeviceID(string deviceID) {
if (string.IsNullOrEmpty(deviceID)) {
ASF.ArchiLogger.LogNullError(nameof(deviceID));
return false;
}
// To the best of my knowledge, Steam uses android identifier even on iOS and other devices right now
// If we ever need to correct this, we also need to clean up other places
const string deviceIdentifier = "android:";
if (!deviceID.StartsWith(deviceIdentifier, StringComparison.Ordinal) || (deviceID.Length != deviceIdentifier.Length + 36)) {
return false;
}
string hash = deviceID.Substring(deviceIdentifier.Length).Replace("-", "");
return (hash.Length == 32) && Utilities.IsValidHexadecimalString(hash);
}
private string GenerateConfirmationHash(uint time, string tag = null) {
if (time == 0) {
Bot.ArchiLogger.LogNullError(nameof(time));

View File

@@ -180,17 +180,55 @@ namespace ArchiSteamFarm {
return false;
}
const byte split = 16;
for (byte i = 0; i < text.Length; i += split) {
string textPart = string.Join("", text.Skip(i).Take(split));
if (!ulong.TryParse(textPart, NumberStyles.HexNumber, null, out _)) {
return false;
}
if (text.Length % 2 != 0) {
return false;
}
return true;
// ulong is 64-bits wide, each hexadecimal character is 4-bits wide, so we split each 16
const byte split = 16;
string lastHex;
if (text.Length >= split) {
StringBuilder hex = new StringBuilder(split);
foreach (char character in text) {
hex.Append(character);
if (hex.Length < split) {
continue;
}
if (!ulong.TryParse(hex.ToString(), NumberStyles.HexNumber, null, out _)) {
return false;
}
hex.Clear();
}
if (hex.Length == 0) {
return true;
}
lastHex = hex.ToString();
} else {
lastHex = text;
}
switch (lastHex.Length) {
case 2:
return byte.TryParse(lastHex, NumberStyles.HexNumber, null, out _);
case 4:
return ushort.TryParse(lastHex, NumberStyles.HexNumber, null, out _);
case 8:
return uint.TryParse(lastHex, NumberStyles.HexNumber, null, out _);
default:
return false;
}
}
internal static int RandomNext() {