mirror of
https://github.com/JustArchiNET/ArchiSteamFarm
synced 2024-11-10 15:14:41 +00:00
Refuse to run as root without explicit ignore (#2427)
* Refuse to run as root without explicit ignore * Apply feedback * Detect docker a bit better * Guard more OS parts behind ifdefs * Fix warnings * Further fixes
This commit is contained in:
parent
cfe88d59ec
commit
bfbeb91633
6 changed files with 100 additions and 17 deletions
|
@ -114,7 +114,7 @@ namespace ArchiSteamFarm.Core {
|
|||
}
|
||||
|
||||
if (!PluginsCore.InitPlugins()) {
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
await Task.Delay(SharedInfo.InformationDelay).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
WebBrowser = new WebBrowser(ArchiLogger, GlobalConfig.WebProxy, true);
|
||||
|
@ -170,11 +170,11 @@ namespace ArchiSteamFarm.Core {
|
|||
|
||||
if (Program.RestartAllowed && GlobalConfig.AutoRestart) {
|
||||
ArchiLogger.LogGenericInfo(Strings.Restarting);
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
await Task.Delay(SharedInfo.ShortInformationDelay).ConfigureAwait(false);
|
||||
await Program.Restart().ConfigureAwait(false);
|
||||
} else {
|
||||
ArchiLogger.LogGenericInfo(Strings.Exiting);
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
await Task.Delay(SharedInfo.ShortInformationDelay).ConfigureAwait(false);
|
||||
await Program.Exit().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ namespace ArchiSteamFarm.Core {
|
|||
|
||||
if (!updateOverride && (GlobalConfig.UpdatePeriod == 0)) {
|
||||
ArchiLogger.LogGenericInfo(Strings.UpdateNewVersionAvailable);
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
await Task.Delay(SharedInfo.ShortInformationDelay).ConfigureAwait(false);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -314,6 +314,7 @@ namespace ArchiSteamFarm.Core {
|
|||
return null;
|
||||
}
|
||||
|
||||
#if TARGET_GENERIC || !TARGET_WINDOWS
|
||||
if (OperatingSystem.IsFreeBSD() || OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) {
|
||||
string executable = Path.Combine(SharedInfo.HomeDirectory, SharedInfo.AssemblyName);
|
||||
|
||||
|
@ -321,6 +322,7 @@ namespace ArchiSteamFarm.Core {
|
|||
OS.UnixSetFileAccess(executable, OS.EUnixPermission.Combined755);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ArchiLogger.LogGenericInfo(Strings.UpdateFinished);
|
||||
|
||||
|
@ -840,8 +842,6 @@ namespace ArchiSteamFarm.Core {
|
|||
} catch (Exception e) {
|
||||
ArchiLogger.LogGenericWarningException(e);
|
||||
ArchiLogger.LogGenericWarning(Strings.BotSteamDirectoryInitializationFailed);
|
||||
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -862,7 +862,7 @@ namespace ArchiSteamFarm.Core {
|
|||
return;
|
||||
case > MaximumRecommendedBotsCount:
|
||||
ArchiLogger.LogGenericWarning(string.Format(CultureInfo.CurrentCulture, Strings.WarningExcessiveBotsCount, MaximumRecommendedBotsCount));
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
await Task.Delay(SharedInfo.InformationDelay).ConfigureAwait(false);
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -901,7 +901,7 @@ namespace ArchiSteamFarm.Core {
|
|||
if (SharedInfo.Version >= newVersion) {
|
||||
if (SharedInfo.Version > newVersion) {
|
||||
ArchiLogger.LogGenericWarning(Strings.WarningPreReleaseVersion);
|
||||
await Task.Delay(15 * 1000).ConfigureAwait(false);
|
||||
await Task.Delay(SharedInfo.InformationDelay).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return;
|
||||
|
|
|
@ -31,6 +31,7 @@ using System.Globalization;
|
|||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Principal;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
|
@ -94,6 +95,7 @@ namespace ArchiSteamFarm.Core {
|
|||
private static string? BackingVersion;
|
||||
private static Mutex? SingleInstance;
|
||||
|
||||
#if TARGET_GENERIC || TARGET_WINDOWS
|
||||
internal static void CoreInit(bool systemRequired) {
|
||||
if (OperatingSystem.IsWindows()) {
|
||||
if (systemRequired) {
|
||||
|
@ -114,6 +116,9 @@ namespace ArchiSteamFarm.Core {
|
|||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
internal static void CoreInit(bool _) { }
|
||||
#endif
|
||||
|
||||
internal static string GetOsResourceName(string objectName) {
|
||||
if (string.IsNullOrEmpty(objectName)) {
|
||||
|
@ -142,6 +147,32 @@ namespace ArchiSteamFarm.Core {
|
|||
}
|
||||
}
|
||||
|
||||
internal static bool IsRunningAsRoot() {
|
||||
#if TARGET_GENERIC || TARGET_WINDOWS
|
||||
if (OperatingSystem.IsWindows()) {
|
||||
using WindowsIdentity identity = WindowsIdentity.GetCurrent();
|
||||
|
||||
return new WindowsPrincipal(identity).IsInRole(WindowsBuiltInRole.Administrator);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TARGET_GENERIC || !TARGET_WINDOWS
|
||||
if (OperatingSystem.IsFreeBSD() || OperatingSystem.IsLinux() || OperatingSystem.IsMacOS()) {
|
||||
return NativeMethods.GetEUID() == 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
// We can't determine whether user is running as root or not, so fallback to that not happening
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static bool IsRunningInDocker() =>
|
||||
#if ASF_VARIANT_DOCKER
|
||||
true;
|
||||
#else
|
||||
Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER") == "true";
|
||||
#endif
|
||||
|
||||
internal static async Task<bool> RegisterProcess() {
|
||||
if (SingleInstance != null) {
|
||||
return false;
|
||||
|
@ -182,6 +213,7 @@ namespace ArchiSteamFarm.Core {
|
|||
return true;
|
||||
}
|
||||
|
||||
#if TARGET_GENERIC || !TARGET_WINDOWS
|
||||
[SupportedOSPlatform("FreeBSD")]
|
||||
[SupportedOSPlatform("Linux")]
|
||||
[SupportedOSPlatform("MacOS")]
|
||||
|
@ -205,6 +237,7 @@ namespace ArchiSteamFarm.Core {
|
|||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, Marshal.GetLastWin32Error()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
internal static void UnregisterProcess() {
|
||||
if (SingleInstance == null) {
|
||||
|
@ -248,6 +281,7 @@ namespace ArchiSteamFarm.Core {
|
|||
#endif
|
||||
}
|
||||
|
||||
#if TARGET_GENERIC || TARGET_WINDOWS
|
||||
[SupportedOSPlatform("Windows")]
|
||||
private static void WindowsDisableQuickEditMode() {
|
||||
if (!OperatingSystem.IsWindows()) {
|
||||
|
@ -285,7 +319,9 @@ namespace ArchiSteamFarm.Core {
|
|||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.WarningFailedWithError, result));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if TARGET_GENERIC || !TARGET_WINDOWS
|
||||
[Flags]
|
||||
[SupportedOSPlatform("FreeBSD")]
|
||||
[SupportedOSPlatform("Linux")]
|
||||
|
@ -303,8 +339,10 @@ namespace ArchiSteamFarm.Core {
|
|||
Combined755 = UserRead | UserWrite | UserExecute | GroupRead | GroupExecute | OtherRead | OtherExecute,
|
||||
Combined777 = UserRead | UserWrite | UserExecute | GroupRead | GroupWrite | GroupExecute | OtherRead | OtherWrite | OtherExecute
|
||||
}
|
||||
#endif
|
||||
|
||||
private static class NativeMethods {
|
||||
#if TARGET_GENERIC || TARGET_WINDOWS
|
||||
[SupportedOSPlatform("Windows")]
|
||||
internal const EExecutionState AwakeExecutionState = EExecutionState.SystemRequired | EExecutionState.AwayModeRequired | EExecutionState.Continuous;
|
||||
|
||||
|
@ -313,7 +351,9 @@ namespace ArchiSteamFarm.Core {
|
|||
|
||||
[SupportedOSPlatform("Windows")]
|
||||
internal const sbyte StandardInputHandle = -10;
|
||||
#endif
|
||||
|
||||
#if TARGET_GENERIC || !TARGET_WINDOWS
|
||||
#pragma warning disable CA2101 // False positive, we can't use unicode charset on Unix, and it uses UTF-8 by default anyway
|
||||
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
||||
[DllImport("libc", EntryPoint = "chmod", SetLastError = true)]
|
||||
|
@ -322,12 +362,25 @@ namespace ArchiSteamFarm.Core {
|
|||
[SupportedOSPlatform("MacOS")]
|
||||
internal static extern int Chmod(string path, int mode);
|
||||
#pragma warning restore CA2101 // False positive, we can't use unicode charset on Unix, and it uses UTF-8 by default anyway
|
||||
#endif
|
||||
|
||||
#if TARGET_GENERIC || TARGET_WINDOWS
|
||||
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
||||
[DllImport("kernel32.dll")]
|
||||
[SupportedOSPlatform("Windows")]
|
||||
internal static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
|
||||
#endif
|
||||
|
||||
#if TARGET_GENERIC || !TARGET_WINDOWS
|
||||
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
||||
[DllImport("libc", EntryPoint = "geteuid", SetLastError = true)]
|
||||
[SupportedOSPlatform("FreeBSD")]
|
||||
[SupportedOSPlatform("Linux")]
|
||||
[SupportedOSPlatform("MacOS")]
|
||||
internal static extern uint GetEUID();
|
||||
#endif
|
||||
|
||||
#if TARGET_GENERIC || TARGET_WINDOWS
|
||||
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
|
||||
[DllImport("kernel32.dll")]
|
||||
[SupportedOSPlatform("Windows")]
|
||||
|
@ -351,6 +404,7 @@ namespace ArchiSteamFarm.Core {
|
|||
AwayModeRequired = 0x00000040,
|
||||
Continuous = 0x80000000
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
12
ArchiSteamFarm/Localization/Strings.Designer.cs
generated
12
ArchiSteamFarm/Localization/Strings.Designer.cs
generated
|
@ -1166,5 +1166,17 @@ namespace ArchiSteamFarm.Localization {
|
|||
return ResourceManager.GetString("WarningDefaultCryptKeyUsedForEncryption", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string WarningRunningAsRoot {
|
||||
get {
|
||||
return ResourceManager.GetString("WarningRunningAsRoot", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string WarningRunningInUnsupportedEnvironment {
|
||||
get {
|
||||
return ResourceManager.GetString("WarningRunningInUnsupportedEnvironment", resourceCulture);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -723,4 +723,10 @@ Process uptime: {1}</value>
|
|||
<value>You're using {0} setting of {1} property, but you didn't provide a custom --cryptkey. This entirely defeats the protection, as ASF is forced to use its own (known) key. You should provide a custom --cryptkey for making use of the security benefit offered by this setting.</value>
|
||||
<comment>{0} will be replaced by the name of a particular setting (e.g. "AES"), {1} will be replaced by the name of the property (e.g. "SteamPassword")</comment>
|
||||
</data>
|
||||
<data name="WarningRunningAsRoot" xml:space="preserve">
|
||||
<value>You're attempting to run ASF as the administrator (root). This causes a significant security risk to your machine, and as ASF does not require root access for its operation, we do not support this scenario. Supply --ignore-unsupported-environment argument if you really know what you're doing.</value>
|
||||
</data>
|
||||
<data name="WarningRunningInUnsupportedEnvironment" xml:space="preserve">
|
||||
<value>You're running ASF in unsupported environment, supplying --ignore-unsupported-environment argument. Please note that we do not offer any kind of support for this scenario and you're doing it entirely at your own risk. You've been warned.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -193,7 +193,7 @@ namespace ArchiSteamFarm {
|
|||
|
||||
if (!uniqueInstance) {
|
||||
ASF.ArchiLogger.LogGenericError(Strings.ErrorSingleInstanceRequired);
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
await Task.Delay(SharedInfo.InformationDelay).ConfigureAwait(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -210,10 +210,19 @@ namespace ArchiSteamFarm {
|
|||
ASF.ArchiLogger.LogGenericInfo(copyright!);
|
||||
}
|
||||
|
||||
if (!IgnoreUnsupportedEnvironment) {
|
||||
if (IgnoreUnsupportedEnvironment) {
|
||||
ASF.ArchiLogger.LogGenericWarning(Strings.WarningRunningInUnsupportedEnvironment);
|
||||
} else {
|
||||
if (!OS.VerifyEnvironment()) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.WarningUnsupportedEnvironment, SharedInfo.BuildInfo.Variant, OS.Version));
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
await Task.Delay(SharedInfo.InformationDelay).ConfigureAwait(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!OS.IsRunningInDocker() && OS.IsRunningAsRoot()) {
|
||||
ASF.ArchiLogger.LogGenericError(Strings.WarningRunningAsRoot);
|
||||
await Task.Delay(SharedInfo.InformationDelay).ConfigureAwait(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -221,7 +230,7 @@ namespace ArchiSteamFarm {
|
|||
|
||||
if (!Directory.Exists(SharedInfo.ConfigDirectory)) {
|
||||
ASF.ArchiLogger.LogGenericError(Strings.ErrorConfigDirectoryNotFound);
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
await Task.Delay(SharedInfo.InformationDelay).ConfigureAwait(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -245,7 +254,7 @@ namespace ArchiSteamFarm {
|
|||
|
||||
if (globalConfig == null) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorGlobalConfigNotLoaded, globalConfigFile));
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
await Task.Delay(SharedInfo.ShortInformationDelay).ConfigureAwait(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -348,16 +357,16 @@ namespace ArchiSteamFarm {
|
|||
|
||||
if (!File.Exists(globalDatabaseFile)) {
|
||||
ASF.ArchiLogger.LogGenericInfo(Strings.Welcome);
|
||||
await Task.Delay(10000).ConfigureAwait(false);
|
||||
await Task.Delay(SharedInfo.InformationDelay).ConfigureAwait(false);
|
||||
ASF.ArchiLogger.LogGenericWarning(Strings.WarningPrivacyPolicy);
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
await Task.Delay(SharedInfo.ShortInformationDelay).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
GlobalDatabase? globalDatabase = await GlobalDatabase.CreateOrLoad(globalDatabaseFile).ConfigureAwait(false);
|
||||
|
||||
if (globalDatabase == null) {
|
||||
ASF.ArchiLogger.LogGenericError(string.Format(CultureInfo.CurrentCulture, Strings.ErrorDatabaseInvalid, globalDatabaseFile));
|
||||
await Task.Delay(5000).ConfigureAwait(false);
|
||||
await Task.Delay(SharedInfo.ShortInformationDelay).ConfigureAwait(false);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ namespace ArchiSteamFarm {
|
|||
internal const string GithubRepo = "JustArchiNET/" + AssemblyName;
|
||||
internal const string GlobalConfigFileName = ASF + JsonConfigExtension;
|
||||
internal const string GlobalDatabaseFileName = ASF + DatabaseExtension;
|
||||
internal const ushort InformationDelay = 10000;
|
||||
internal const string IPCConfigExtension = ".config";
|
||||
internal const string IPCConfigFile = nameof(IPC) + IPCConfigExtension;
|
||||
internal const string JsonConfigExtension = ".json";
|
||||
|
@ -54,12 +55,13 @@ namespace ArchiSteamFarm {
|
|||
internal const string KeysUnusedExtension = ".unused";
|
||||
internal const string KeysUsedExtension = ".used";
|
||||
internal const string LicenseName = "Apache 2.0";
|
||||
internal const string LicenseURL = "http://www.apache.org/licenses/LICENSE-2.0";
|
||||
internal const string LicenseURL = "https://www.apache.org/licenses/LICENSE-2.0";
|
||||
internal const string LogFile = "log.txt";
|
||||
internal const string MobileAuthenticatorExtension = ".maFile";
|
||||
internal const string PluginsDirectory = "plugins";
|
||||
internal const string ProjectURL = "https://github.com/" + GithubRepo;
|
||||
internal const string SentryHashExtension = ".bin";
|
||||
internal const ushort ShortInformationDelay = InformationDelay / 2;
|
||||
internal const string StatisticsServer = "asf.justarchi.net";
|
||||
internal const string UlongCompatibilityStringPrefix = "s_";
|
||||
internal const string UpdateDirectory = "_old";
|
||||
|
|
Loading…
Reference in a new issue