From ff02a4a8d415a343da550bc5394ddb57b9e04ee2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Domeradzki?= Date: Thu, 2 May 2024 21:54:54 +0200 Subject: [PATCH] Remove zxcvbn dependency Pushing external lib purely to save user's from eventual stupidity is just simply not worth the bytes in the final zip archive. --- ArchiSteamFarm.Tests/Utilities.cs | 82 ------------------- ArchiSteamFarm/ArchiSteamFarm.csproj | 1 - ArchiSteamFarm/Core/Utilities.cs | 38 --------- ArchiSteamFarm/Helpers/ArchiCryptoHelper.cs | 13 --- .../Localization/Strings.Designer.cs | 18 ---- ArchiSteamFarm/Localization/Strings.resx | 12 --- ArchiSteamFarm/Steam/Storage/BotConfig.cs | 24 ------ ArchiSteamFarm/Storage/GlobalConfig.cs | 15 ---- Directory.Packages.props | 1 - 9 files changed, 204 deletions(-) delete mode 100644 ArchiSteamFarm.Tests/Utilities.cs diff --git a/ArchiSteamFarm.Tests/Utilities.cs b/ArchiSteamFarm.Tests/Utilities.cs deleted file mode 100644 index 289d3114b..000000000 --- a/ArchiSteamFarm.Tests/Utilities.cs +++ /dev/null @@ -1,82 +0,0 @@ -// ---------------------------------------------------------------------------------------------- -// _ _ _ ____ _ _____ -// / \ _ __ ___ | |__ (_)/ ___| | |_ ___ __ _ _ __ ___ | ___|__ _ _ __ _ __ ___ -// / _ \ | '__|/ __|| '_ \ | |\___ \ | __|/ _ \ / _` || '_ ` _ \ | |_ / _` || '__|| '_ ` _ \ -// / ___ \ | | | (__ | | | || | ___) || |_| __/| (_| || | | | | || _|| (_| || | | | | | | | -// /_/ \_\|_| \___||_| |_||_||____/ \__|\___| \__,_||_| |_| |_||_| \__,_||_| |_| |_| |_| -// ---------------------------------------------------------------------------------------------- -// | -// Copyright 2015-2024 Łukasz "JustArchi" Domeradzki -// Contact: JustArchi@JustArchi.net -// | -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// | -// http://www.apache.org/licenses/LICENSE-2.0 -// | -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System; -using System.Collections.Generic; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using static ArchiSteamFarm.Core.Utilities; - -namespace ArchiSteamFarm.Tests; - -[TestClass] -#pragma warning disable CA1724 // We don't care about the potential conflict, as ASF class name has a priority -public sealed class Utilities { - [TestMethod] - public void AdditionallyForbiddenWordsWeakenPassphrases() => Assert.IsTrue(TestPasswordStrength("10charsasdf", new HashSet { "chars" }).IsWeak); - - [TestMethod] - public void ContextSpecificWordsWeakenPassphrases() => Assert.IsTrue(TestPasswordStrength("archisteamfarmpassword").IsWeak); - - [TestMethod] - public void EasyPasswordsHaveMeaningfulReason() { - (bool isWeak, string? reason) = TestPasswordStrength("CorrectHorse"); - - Assert.IsTrue(isWeak); - Assert.IsTrue(reason?.Contains("Capitalization doesn't help very much", StringComparison.OrdinalIgnoreCase)); - } - - [TestMethod] - public void LongPassphraseIsNotWeak() => Assert.IsFalse(TestPasswordStrength("10charsasdf").IsWeak); - - [TestMethod] - public void MemePasswordIsNotWeak() => Assert.IsFalse(TestPasswordStrength("correcthorsebatterystaple").IsWeak); - - [TestMethod] - public void RepeatedPasswordsHaveMeaningfulReason() { - (bool isWeak, string? reason) = TestPasswordStrength("abcabcabc"); - - Assert.IsTrue(isWeak); - Assert.IsTrue(reason?.Contains("Avoid repeated words and characters", StringComparison.OrdinalIgnoreCase)); - } - - [TestMethod] - public void RepetitiveCharactersWeakenPassphrases() => Assert.IsTrue(TestPasswordStrength("testaaaatest").IsWeak); - - [TestMethod] - public void SequentialCharactersWeakenPassphrases() => Assert.IsTrue(TestPasswordStrength("testabcdtest").IsWeak); - - [TestMethod] - public void SequentialDescendingCharactersWeakenPassphrases() => Assert.IsTrue(TestPasswordStrength("testdcbatest").IsWeak); - - [TestMethod] - public void ShortPassphraseIsWeak() => Assert.IsTrue(TestPasswordStrength("four").IsWeak); - - [TestMethod] - public void StraightRowsPasswordsHaveMeaningfulReason() { - (bool isWeak, string? reason) = TestPasswordStrength("`1234567890-="); - - Assert.IsTrue(isWeak); - Assert.IsTrue(reason?.Contains("Straight rows of keys are easy to guess", StringComparison.OrdinalIgnoreCase)); - } -} -#pragma warning restore CA1724 // We don't care about the potential conflict, as ASF class name has a priority diff --git a/ArchiSteamFarm/ArchiSteamFarm.csproj b/ArchiSteamFarm/ArchiSteamFarm.csproj index 5556a6295..e5db9bb50 100644 --- a/ArchiSteamFarm/ArchiSteamFarm.csproj +++ b/ArchiSteamFarm/ArchiSteamFarm.csproj @@ -25,7 +25,6 @@ - diff --git a/ArchiSteamFarm/Core/Utilities.cs b/ArchiSteamFarm/Core/Utilities.cs index 81fb09365..bdb52bc5f 100644 --- a/ArchiSteamFarm/Core/Utilities.cs +++ b/ArchiSteamFarm/Core/Utilities.cs @@ -45,7 +45,6 @@ using Humanizer.Localisation; using JetBrains.Annotations; using Microsoft.IdentityModel.JsonWebTokens; using SteamKit2; -using Zxcvbn; namespace ArchiSteamFarm.Core; @@ -57,9 +56,6 @@ public static class Utilities { private static readonly FrozenSet DirectorySeparators = new HashSet(2) { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }.ToFrozenSet(); - // normally we'd just use words like "steam" and "farm", but the library we're currently using is a bit iffy about banned words, so we need to also add combinations such as "steamfarm" - private static readonly FrozenSet ForbiddenPasswordPhrases = new HashSet(10, StringComparer.OrdinalIgnoreCase) { "archisteamfarm", "archi", "steam", "farm", "archisteam", "archifarm", "steamfarm", "asf", "asffarm", "password" }.ToFrozenSet(StringComparer.OrdinalIgnoreCase); - [PublicAPI] public static string GenerateChecksumFor(byte[] source) { ArgumentNullException.ThrowIfNull(source); @@ -293,40 +289,6 @@ public static class Utilities { ASF.ArchiLogger.LogGenericDebug($"{fileName} {progressPercentage}%..."); } - internal static (bool IsWeak, string? Reason) TestPasswordStrength(string password, IEnumerable? additionallyForbiddenPhrases = null) { - ArgumentException.ThrowIfNullOrEmpty(password); - - HashSet forbiddenPhrases = ForbiddenPasswordPhrases.ToHashSet(StringComparer.OrdinalIgnoreCase); - - if (additionallyForbiddenPhrases != null) { - forbiddenPhrases.UnionWith(additionallyForbiddenPhrases); - } - - Result result = Zxcvbn.Core.EvaluatePassword(password, forbiddenPhrases); - - IList? suggestions = result.Feedback.Suggestions; - - if (!string.IsNullOrEmpty(result.Feedback.Warning)) { - suggestions ??= new List(1); - - suggestions.Insert(0, result.Feedback.Warning); - } - - if (suggestions != null) { - for (byte i = 0; i < suggestions.Count; i++) { - string suggestion = suggestions[i]; - - if ((suggestion.Length == 0) || (suggestion[^1] == '.')) { - continue; - } - - suggestions[i] = $"{suggestion}."; - } - } - - return (result.Score < 4, suggestions is { Count: > 0 } ? string.Join(' ', suggestions.Where(static suggestion => suggestion.Length > 0)) : null); - } - internal static async Task UpdateCleanup(string targetDirectory) { ArgumentException.ThrowIfNullOrEmpty(targetDirectory); diff --git a/ArchiSteamFarm/Helpers/ArchiCryptoHelper.cs b/ArchiSteamFarm/Helpers/ArchiCryptoHelper.cs index f4013abe2..21891599e 100644 --- a/ArchiSteamFarm/Helpers/ArchiCryptoHelper.cs +++ b/ArchiSteamFarm/Helpers/ArchiCryptoHelper.cs @@ -22,7 +22,6 @@ // limitations under the License. using System; -using System.Collections.Frozen; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; @@ -47,8 +46,6 @@ public static class ArchiCryptoHelper { internal static bool HasDefaultCryptKey { get; private set; } = true; - private static readonly FrozenSet ForbiddenCryptKeyPhrases = new HashSet(3, StringComparer.OrdinalIgnoreCase) { "crypt", "key", "cryptkey" }.ToFrozenSet(StringComparer.OrdinalIgnoreCase); - private static IEnumerable SteamParentalCharacters => Enumerable.Range('0', 10).Select(static character => (byte) character); private static IEnumerable SteamParentalCodes { @@ -179,16 +176,6 @@ public static class ArchiCryptoHelper { return; } - Utilities.InBackground( - () => { - (bool isWeak, string? reason) = Utilities.TestPasswordStrength(key, ForbiddenCryptKeyPhrases); - - if (isWeak) { - ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningWeakCryptKey, reason)); - } - } - ); - byte[] encryptionKey = Encoding.UTF8.GetBytes(key); if (encryptionKey.Length < MinimumRecommendedCryptKeyBytes) { diff --git a/ArchiSteamFarm/Localization/Strings.Designer.cs b/ArchiSteamFarm/Localization/Strings.Designer.cs index 1bca714e0..0e855f8b5 100644 --- a/ArchiSteamFarm/Localization/Strings.Designer.cs +++ b/ArchiSteamFarm/Localization/Strings.Designer.cs @@ -1119,24 +1119,6 @@ namespace ArchiSteamFarm.Localization { } } - public static string WarningWeakIPCPassword { - get { - return ResourceManager.GetString("WarningWeakIPCPassword", resourceCulture); - } - } - - public static string WarningWeakSteamPassword { - get { - return ResourceManager.GetString("WarningWeakSteamPassword", resourceCulture); - } - } - - public static string WarningWeakCryptKey { - get { - return ResourceManager.GetString("WarningWeakCryptKey", resourceCulture); - } - } - public static string WarningTooShortCryptKey { get { return ResourceManager.GetString("WarningTooShortCryptKey", resourceCulture); diff --git a/ArchiSteamFarm/Localization/Strings.resx b/ArchiSteamFarm/Localization/Strings.resx index f73b2ac9a..c2ccda4b0 100644 --- a/ArchiSteamFarm/Localization/Strings.resx +++ b/ArchiSteamFarm/Localization/Strings.resx @@ -690,18 +690,6 @@ Process uptime: {1} {0} config file will be migrated to the latest syntax... {0} will be replaced with the relative path to the affected config file - - Your IPC password seems to be weak. Consider choosing a stronger one for increased security. Details: {0} - {0} will be replaced by additional details about the password being considered weak - - - Your Steam password for '{0}' seems to be weak. Consider choosing a stronger one for increased security. Details: {1} - {0} will be replaced by the affected bot name, {1} will be replaced by additional details about the password being considered weak - - - Your encryption key seems to be weak. Consider choosing a stronger one for increased security. Details: {0} - {0} will be replaced by additional details about the encryption key being considered weak - Your encryption key is too short. We recommend to use one that is at least {0} bytes (characters) long. {0} will be replaced by the number of bytes (characters) recommended diff --git a/ArchiSteamFarm/Steam/Storage/BotConfig.cs b/ArchiSteamFarm/Steam/Storage/BotConfig.cs index c2668f602..ad5a8220d 100644 --- a/ArchiSteamFarm/Steam/Storage/BotConfig.cs +++ b/ArchiSteamFarm/Steam/Storage/BotConfig.cs @@ -562,30 +562,6 @@ public sealed class BotConfig { return (null, null); } - string? decryptedSteamPassword = await botConfig.GetDecryptedSteamPassword().ConfigureAwait(false); - - if (!string.IsNullOrEmpty(decryptedSteamPassword)) { - HashSet disallowedValues = new(StringComparer.OrdinalIgnoreCase) { "account" }; - - if (!string.IsNullOrEmpty(botConfig.SteamLogin)) { - disallowedValues.Add(botConfig.SteamLogin); - } - - Utilities.InBackground( - () => { - (bool isWeak, string? reason) = Utilities.TestPasswordStrength(decryptedSteamPassword, disallowedValues); - - if (isWeak) { - if (string.IsNullOrEmpty(botName)) { - botName = Path.GetFileNameWithoutExtension(filePath); - } - - ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningWeakSteamPassword, botName, reason)); - } - } - ); - } - switch (botConfig.PasswordFormat) { case ArchiCryptoHelper.ECryptoMethod.AES when ArchiCryptoHelper.HasDefaultCryptKey: ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.WarningDefaultCryptKeyUsedForEncryption, botConfig.PasswordFormat, nameof(SteamPassword))); diff --git a/ArchiSteamFarm/Storage/GlobalConfig.cs b/ArchiSteamFarm/Storage/GlobalConfig.cs index dbb287872..2fae7c19c 100644 --- a/ArchiSteamFarm/Storage/GlobalConfig.cs +++ b/ArchiSteamFarm/Storage/GlobalConfig.cs @@ -22,7 +22,6 @@ // limitations under the License. using System; -using System.Collections.Frozen; using System.Collections.Generic; using System.Collections.Immutable; using System.ComponentModel.DataAnnotations; @@ -151,8 +150,6 @@ public sealed class GlobalConfig { [PublicAPI] public static readonly ImmutableHashSet DefaultPluginsUpdateList = []; - private static readonly FrozenSet ForbiddenIPCPasswordPhrases = new HashSet(5, StringComparer.OrdinalIgnoreCase) { "ipc", "api", "gui", "asf-ui", "asf-gui" }.ToFrozenSet(StringComparer.OrdinalIgnoreCase); - [JsonIgnore] [PublicAPI] public WebProxy? WebProxy { @@ -566,18 +563,6 @@ public sealed class GlobalConfig { if (globalConfig.IPC) { switch (globalConfig.IPCPasswordFormat) { - case ArchiCryptoHelper.EHashingMethod.PlainText when !string.IsNullOrEmpty(globalConfig.IPCPassword): - Utilities.InBackground( - () => { - (bool isWeak, string? reason) = Utilities.TestPasswordStrength(globalConfig.IPCPassword, ForbiddenIPCPasswordPhrases); - - if (isWeak) { - ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningWeakIPCPassword, reason)); - } - } - ); - - break; case ArchiCryptoHelper.EHashingMethod.Pbkdf2 when ArchiCryptoHelper.HasDefaultCryptKey: case ArchiCryptoHelper.EHashingMethod.SCrypt when ArchiCryptoHelper.HasDefaultCryptKey: ASF.ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningDefaultCryptKeyUsedForHashing, globalConfig.IPCPasswordFormat, nameof(IPCPassword))); diff --git a/Directory.Packages.props b/Directory.Packages.props index 75df57f37..3558ad2b9 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -22,6 +22,5 @@ -