diff --git a/ArchiSteamFarm/Core/ASF.cs b/ArchiSteamFarm/Core/ASF.cs index ed937dfe5676d..033ec03d278e2 100644 --- a/ArchiSteamFarm/Core/ASF.cs +++ b/ArchiSteamFarm/Core/ASF.cs @@ -860,11 +860,16 @@ private static async Task UpdateAndRestart() { ArchiLogger.LogGenericInfo(Strings.FetchingChecksumFromRemoteServer); - string? remoteChecksum = await ArchiNet.FetchBuildChecksum(newVersion, SharedInfo.BuildInfo.Variant).ConfigureAwait(false); + // Keep short timeout allowed for this call, as we don't want to hold the flow for too long + using CancellationTokenSource archiNetCancellation = new(TimeSpan.FromSeconds(15)); + + string? remoteChecksum = await ArchiNet.FetchBuildChecksum(newVersion, SharedInfo.BuildInfo.Variant, archiNetCancellation.Token).ConfigureAwait(false); switch (remoteChecksum) { case null: // Timeout or error, refuse to update as a security measure + ArchiLogger.LogGenericWarning(Strings.ChecksumTimeout); + return (false, newVersion); case "": // Unknown checksum, release too new or actual malicious build published, no need to scare the user as it's 99.99% the first @@ -886,6 +891,7 @@ private static async Task UpdateAndRestart() { BinaryResponse? response; try { + // ReSharper disable once MethodSupportsCancellation - the token initialized above is not meant to be passed here response = await WebBrowser.UrlGetToBinary(binaryAsset.DownloadURL, progressReporter: progressReporter).ConfigureAwait(false); } finally { progressReporter.ProgressChanged -= onProgressChanged; diff --git a/ArchiSteamFarm/Core/ArchiNet.cs b/ArchiSteamFarm/Core/ArchiNet.cs index f884ecc2736d1..54f80985f6d30 100644 --- a/ArchiSteamFarm/Core/ArchiNet.cs +++ b/ArchiSteamFarm/Core/ArchiNet.cs @@ -55,7 +55,15 @@ internal static class ArchiNet { Uri request = new(URL, $"/Api/Checksum/{version}/{variant}"); - ObjectResponse>? response = await ASF.WebBrowser.UrlGetToJsonObject>(request, cancellationToken: cancellationToken).ConfigureAwait(false); + ObjectResponse>? response; + + try { + response = await ASF.WebBrowser.UrlGetToJsonObject>(request, cancellationToken: cancellationToken).ConfigureAwait(false); + } catch (OperationCanceledException e) { + ASF.ArchiLogger.LogGenericDebuggingException(e); + + return null; + } if (response?.Content == null) { return null; @@ -184,12 +192,14 @@ internal static class ArchiNet { Uri request = new(URL, "/Api/BadBots"); - ObjectResponse>>? response = null; + ObjectResponse>>? response; try { response = await ASF.WebBrowser.UrlGetToJsonObject>>(request, cancellationToken: cancellationToken).ConfigureAwait(false); } catch (OperationCanceledException e) { ASF.ArchiLogger.LogGenericDebuggingException(e); + + return (false, ASF.GlobalDatabase.CachedBadBots); } if (response?.Content?.Result == null) { diff --git a/ArchiSteamFarm/Localization/Strings.Designer.cs b/ArchiSteamFarm/Localization/Strings.Designer.cs index 11bcbf5e86f11..1bca714e0516e 100644 --- a/ArchiSteamFarm/Localization/Strings.Designer.cs +++ b/ArchiSteamFarm/Localization/Strings.Designer.cs @@ -1185,6 +1185,12 @@ public static string ChecksumMissing { } } + public static string ChecksumTimeout { + get { + return ResourceManager.GetString("ChecksumTimeout", resourceCulture); + } + } + public static string ChecksumWrong { get { return ResourceManager.GetString("ChecksumWrong", resourceCulture); diff --git a/ArchiSteamFarm/Localization/Strings.resx b/ArchiSteamFarm/Localization/Strings.resx index dc581dbb482a1..fbfd28d079be7 100644 --- a/ArchiSteamFarm/Localization/Strings.resx +++ b/ArchiSteamFarm/Localization/Strings.resx @@ -731,6 +731,9 @@ Process uptime: {1} Remote server doesn't know anything about the release we're updating to. This situation is possible if the release was published recently - refusing to proceed with the update procedure right away as an additional security measure. + + Failed to fetch checksum of the downloaded binary - refusing to proceed with the update procedure at this time as an additional security measure. + Remote server has replied with a different checksum, this might indicate corrupted download or MITM attack, refusing to proceed with the update procedure! diff --git a/ArchiSteamFarm/Steam/Exchange/Trading.cs b/ArchiSteamFarm/Steam/Exchange/Trading.cs index e7826129e171a..ec134f9d4cca3 100644 --- a/ArchiSteamFarm/Steam/Exchange/Trading.cs +++ b/ArchiSteamFarm/Steam/Exchange/Trading.cs @@ -396,10 +396,10 @@ private async Task ParseTrade(TradeOffer tradeOffer) { // Deny trades from bad steamIDs if user wishes to do so if (ASF.GlobalConfig?.FilterBadBots ?? GlobalConfig.DefaultFilterBadBots) { - // Allow no longer than 10 seconds timeout for BadBot call, as we don't want to hold the trade offer for too long - using CancellationTokenSource cts = new(TimeSpan.FromSeconds(10)); + // Keep short timeout allowed for this call, as we don't want to hold the flow for too long + using CancellationTokenSource archiNetCancellation = new(TimeSpan.FromSeconds(15)); - bool? isBadBot = await ArchiNet.IsBadBot(tradeOffer.OtherSteamID64, cts.Token).ConfigureAwait(false); + bool? isBadBot = await ArchiNet.IsBadBot(tradeOffer.OtherSteamID64, archiNetCancellation.Token).ConfigureAwait(false); if (isBadBot == true) { Bot.ArchiLogger.LogGenericDebug(string.Format(CultureInfo.CurrentCulture, Strings.BotTradeOfferResult, tradeOffer.TradeOfferID, ParseTradeResult.EResult.Blacklisted, $"{nameof(tradeOffer.OtherSteamID64)} {tradeOffer.OtherSteamID64}"));