mirror of
https://github.com/rmcrackan/Libation.git
synced 2026-05-08 23:54:10 -04:00
Merge pull request #1796 from rmcrackan/rmcrackan/1711-linux-safety
#1711 : Linux/Docker: the default in-progress download/decrypt folder…
This commit is contained in:
@@ -31,8 +31,19 @@ public abstract class AudibleFileStorage
|
||||
{
|
||||
try
|
||||
{
|
||||
return (DateTime.UtcNow - lastInProgressFail) < RetryInProgressInterval ? null
|
||||
: new DirectoryInfo(Configuration.Instance.InProgress).CreateSubdirectoryEx(subDirectory);
|
||||
if ((DateTime.UtcNow - lastInProgressFail) < RetryInProgressInterval)
|
||||
return null;
|
||||
|
||||
var parent = new DirectoryInfo(Configuration.Instance.InProgress);
|
||||
var dir = parent.CreateSubdirectoryEx(subDirectory);
|
||||
|
||||
// On Unix, lock down the parent and the subdir to the current user (0700).
|
||||
// Prevents other local users from reading partial downloads / decrypted artifacts
|
||||
// when InProgress lives on a world-traversable filesystem like /tmp.
|
||||
TrySetOwnerOnlyMode(parent.FullName);
|
||||
TrySetOwnerOnlyMode(dir.FullName);
|
||||
|
||||
return dir;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -42,6 +53,20 @@ public abstract class AudibleFileStorage
|
||||
}
|
||||
}
|
||||
|
||||
private static void TrySetOwnerOnlyMode(string path)
|
||||
{
|
||||
if (OperatingSystem.IsWindows())
|
||||
return;
|
||||
try
|
||||
{
|
||||
File.SetUnixFileMode(path, UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.UserExecute);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// best-effort. user may have intentionally set their own perms, or the FS may not support it.
|
||||
}
|
||||
}
|
||||
|
||||
public static LongPath? DownloadsInProgressDirectory => CreateInProgressDirectory("DownloadsInProgress")?.FullName;
|
||||
public static LongPath? DecryptInProgressDirectory => CreateInProgressDirectory("DecryptInProgress")?.FullName;
|
||||
|
||||
|
||||
@@ -13,7 +13,10 @@ public partial class Configuration
|
||||
public static string AppDir_Absolute => Path.GetFullPath(Path.Combine(ProcessDirectory, LibationFiles.LIBATION_FILES_KEY));
|
||||
public static string MyDocs => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), "Libation"));
|
||||
public static string MyMusic => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyMusic), "Libation"));
|
||||
public static string WinTemp => Path.GetFullPath(Path.Combine(Path.GetTempPath(), "Libation"));
|
||||
// Use a per-user subdir so we don't collide with -- or get blocked by -- another local
|
||||
// user's leftover dir on shared-/tmp systems (Linux). On Windows and macOS, GetTempPath
|
||||
// already returns a per-user location, so this is just a harmless extra path segment.
|
||||
public static string WinTemp => Path.GetFullPath(Path.Combine(Path.GetTempPath(), $"Libation-{Environment.UserName}"));
|
||||
public static string UserProfile => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Libation"));
|
||||
public static string LocalAppData => Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Libation"));
|
||||
|
||||
|
||||
@@ -62,8 +62,9 @@ public class Upgrader : UpgraderBase
|
||||
}
|
||||
|
||||
//Silently download the upgrade in the background, save it to a temp file.
|
||||
|
||||
var zipFile = Path.Combine(Path.GetTempPath(), Path.GetFileName(upgradeProperties.ZipUrl));
|
||||
var zipFile = GetUpgradeDownloadPath(upgradeProperties.ZipUrl);
|
||||
if (zipFile is null)
|
||||
return null;
|
||||
|
||||
Serilog.Log.Logger.Information($"Downloading {zipFile}");
|
||||
|
||||
@@ -103,6 +104,29 @@ public class Upgrader : UpgraderBase
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Allocate a fresh per-run temp directory for the upgrade zip and return the full path
|
||||
/// the zip should be downloaded to. Uses a random subdirectory name (and 0700 perms on
|
||||
/// Unix) so we never extract or execute from a predictable, shared-temp location.
|
||||
/// </summary>
|
||||
/// <returns>Destination path for the upgrade zip, or <c>null</c> if the temp directory
|
||||
/// could not be created (in which case the upgrade-failed event has already been raised).</returns>
|
||||
private string? GetUpgradeDownloadPath(string zipUrl)
|
||||
{
|
||||
try
|
||||
{
|
||||
var stagingDir = Directory.CreateTempSubdirectory("Libation-upgrade-").FullName;
|
||||
return Path.Combine(stagingDir, Path.GetFileName(zipUrl));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
var message = "Failed to create a temp directory for the upgrade download.";
|
||||
Serilog.Log.Logger.Error(ex, message);
|
||||
OnUpgradeFailed(message, ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MockUpgrader : UpgraderBase
|
||||
|
||||
Reference in New Issue
Block a user