mirror of
https://github.com/JustArchiNET/ArchiSteamFarm
synced 2024-11-10 07:04:27 +00:00
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.
This commit is contained in:
parent
c8c35b5bf7
commit
ff02a4a8d4
9 changed files with 0 additions and 204 deletions
|
@ -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("10chars<!>asdf", new HashSet<string> { "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("10chars<!>asdf").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
|
|
@ -25,7 +25,6 @@
|
|||
<PackageReference Include="System.Composition" />
|
||||
<PackageReference Include="System.Linq.Async" />
|
||||
<PackageReference Include="System.Security.Cryptography.ProtectedData" />
|
||||
<PackageReference Include="zxcvbn-core" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -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<char> DirectorySeparators = new HashSet<char>(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<string> ForbiddenPasswordPhrases = new HashSet<string>(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<string>? additionallyForbiddenPhrases = null) {
|
||||
ArgumentException.ThrowIfNullOrEmpty(password);
|
||||
|
||||
HashSet<string> forbiddenPhrases = ForbiddenPasswordPhrases.ToHashSet(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
if (additionallyForbiddenPhrases != null) {
|
||||
forbiddenPhrases.UnionWith(additionallyForbiddenPhrases);
|
||||
}
|
||||
|
||||
Result result = Zxcvbn.Core.EvaluatePassword(password, forbiddenPhrases);
|
||||
|
||||
IList<string>? suggestions = result.Feedback.Suggestions;
|
||||
|
||||
if (!string.IsNullOrEmpty(result.Feedback.Warning)) {
|
||||
suggestions ??= new List<string>(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<bool> UpdateCleanup(string targetDirectory) {
|
||||
ArgumentException.ThrowIfNullOrEmpty(targetDirectory);
|
||||
|
||||
|
|
|
@ -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<string> ForbiddenCryptKeyPhrases = new HashSet<string>(3, StringComparer.OrdinalIgnoreCase) { "crypt", "key", "cryptkey" }.ToFrozenSet(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
private static IEnumerable<byte> SteamParentalCharacters => Enumerable.Range('0', 10).Select(static character => (byte) character);
|
||||
|
||||
private static IEnumerable<byte[]> 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) {
|
||||
|
|
18
ArchiSteamFarm/Localization/Strings.Designer.cs
generated
18
ArchiSteamFarm/Localization/Strings.Designer.cs
generated
|
@ -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);
|
||||
|
|
|
@ -690,18 +690,6 @@ Process uptime: {1}</value>
|
|||
<value>{0} config file will be migrated to the latest syntax...</value>
|
||||
<comment>{0} will be replaced with the relative path to the affected config file</comment>
|
||||
</data>
|
||||
<data name="WarningWeakIPCPassword" xml:space="preserve">
|
||||
<value>Your IPC password seems to be weak. Consider choosing a stronger one for increased security. Details: {0}</value>
|
||||
<comment>{0} will be replaced by additional details about the password being considered weak</comment>
|
||||
</data>
|
||||
<data name="WarningWeakSteamPassword" xml:space="preserve">
|
||||
<value>Your Steam password for '{0}' seems to be weak. Consider choosing a stronger one for increased security. Details: {1}</value>
|
||||
<comment>{0} will be replaced by the affected bot name, {1} will be replaced by additional details about the password being considered weak</comment>
|
||||
</data>
|
||||
<data name="WarningWeakCryptKey" xml:space="preserve">
|
||||
<value>Your encryption key seems to be weak. Consider choosing a stronger one for increased security. Details: {0}</value>
|
||||
<comment>{0} will be replaced by additional details about the encryption key being considered weak</comment>
|
||||
</data>
|
||||
<data name="WarningTooShortCryptKey" xml:space="preserve">
|
||||
<value>Your encryption key is too short. We recommend to use one that is at least {0} bytes (characters) long.</value>
|
||||
<comment>{0} will be replaced by the number of bytes (characters) recommended</comment>
|
||||
|
|
|
@ -562,30 +562,6 @@ public sealed class BotConfig {
|
|||
return (null, null);
|
||||
}
|
||||
|
||||
string? decryptedSteamPassword = await botConfig.GetDecryptedSteamPassword().ConfigureAwait(false);
|
||||
|
||||
if (!string.IsNullOrEmpty(decryptedSteamPassword)) {
|
||||
HashSet<string> 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)));
|
||||
|
|
|
@ -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<string> DefaultPluginsUpdateList = [];
|
||||
|
||||
private static readonly FrozenSet<string> ForbiddenIPCPasswordPhrases = new HashSet<string>(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)));
|
||||
|
|
|
@ -22,6 +22,5 @@
|
|||
<PackageVersion Include="System.Composition.AttributedModel" Version="8.0.0" />
|
||||
<PackageVersion Include="System.Linq.Async" Version="6.0.1" />
|
||||
<PackageVersion Include="System.Security.Cryptography.ProtectedData" Version="8.0.0" />
|
||||
<PackageVersion Include="zxcvbn-core" Version="7.0.92" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
Loading…
Reference in a new issue