Set the executable bit after unix static file writing

This commit is contained in:
Cyberboss
2018-08-14 13:53:45 -04:00
parent 076b733786
commit d36943512b
6 changed files with 68 additions and 3 deletions
@@ -77,6 +77,11 @@ namespace Tgstation.Server.Host.Components
/// </summary>
readonly IProcessExecutor processExecutor;
/// <summary>
/// The <see cref="IPostWriteHandler"/> for the <see cref="InstanceFactory"/>
/// </summary>
readonly IPostWriteHandler postWriteHandler;
/// <summary>
/// Construct an <see cref="InstanceFactory"/>
/// </summary>
@@ -92,7 +97,8 @@ namespace Tgstation.Server.Host.Components
/// <param name="byondInstaller">The value of <see cref="byondInstaller"/></param>
/// <param name="providerFactory">The value of <see cref="providerFactory"/></param>
/// <param name="processExecutor">The value of <see cref="processExecutor"/></param>
public InstanceFactory(IIOManager ioManager, IDatabaseContextFactory databaseContextFactory, IApplication application, ILoggerFactory loggerFactory, IByondTopicSender byondTopicSender, IServerControl serverUpdater, ICryptographySuite cryptographySuite, ISynchronousIOManager synchronousIOManager, ISymlinkFactory symlinkFactory, IByondInstaller byondInstaller, IProviderFactory providerFactory, IProcessExecutor processExecutor)
/// <param name="postWriteHandler">The value of <see cref="postWriteHandler"/></param>
public InstanceFactory(IIOManager ioManager, IDatabaseContextFactory databaseContextFactory, IApplication application, ILoggerFactory loggerFactory, IByondTopicSender byondTopicSender, IServerControl serverUpdater, ICryptographySuite cryptographySuite, ISynchronousIOManager synchronousIOManager, ISymlinkFactory symlinkFactory, IByondInstaller byondInstaller, IProviderFactory providerFactory, IProcessExecutor processExecutor, IPostWriteHandler postWriteHandler)
{
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
this.databaseContextFactory = databaseContextFactory ?? throw new ArgumentNullException(nameof(databaseContextFactory));
@@ -106,6 +112,7 @@ namespace Tgstation.Server.Host.Components
this.byondInstaller = byondInstaller ?? throw new ArgumentNullException(nameof(byondInstaller));
this.providerFactory = providerFactory ?? throw new ArgumentNullException(nameof(providerFactory));
this.processExecutor = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor));
this.postWriteHandler = postWriteHandler ?? throw new ArgumentNullException(nameof(postWriteHandler));
}
/// <inheritdoc />
@@ -120,7 +127,7 @@ namespace Tgstation.Server.Host.Components
var gameIoManager = new ResolvingIOManager(instanceIoManager, "Game");
var configurationIoManager = new ResolvingIOManager(instanceIoManager, "Configuration");
var configuration = new StaticFiles.Configuration(configurationIoManager, synchronousIOManager, symlinkFactory, processExecutor, loggerFactory.CreateLogger<StaticFiles.Configuration>());
var configuration = new StaticFiles.Configuration(configurationIoManager, synchronousIOManager, symlinkFactory, processExecutor, postWriteHandler, loggerFactory.CreateLogger<StaticFiles.Configuration>());
var eventConsumer = new EventConsumer(configuration);
var dmbFactory = new DmbFactory(databaseContextFactory, gameIoManager, loggerFactory.CreateLogger<DmbFactory>(), metadata.CloneMetadata());
@@ -54,6 +54,11 @@ namespace Tgstation.Server.Host.Components.StaticFiles
/// </summary>
readonly IProcessExecutor processExecutor;
/// <summary>
/// The <see cref="IPostWriteHandler"/> for <see cref="Configuration"/>
/// </summary>
readonly IPostWriteHandler postWriteHandler;
/// <summary>
/// The <see cref="ILogger"/> for <see cref="Configuration"/>
/// </summary>
@@ -71,13 +76,15 @@ namespace Tgstation.Server.Host.Components.StaticFiles
/// <param name="synchronousIOManager">The value of <see cref="synchronousIOManager"/></param>
/// <param name="symlinkFactory">The value of <see cref="symlinkFactory"/></param>
/// <param name="processExecutor">The value of <see cref="processExecutor"/></param>
/// <param name="postWriteHandler">The value of <see cref="postWriteHandler"/></param>
/// <param name="logger">The value of <see cref="logger"/></param>
public Configuration(IIOManager ioManager, ISynchronousIOManager synchronousIOManager, ISymlinkFactory symlinkFactory, IProcessExecutor processExecutor, ILogger<Configuration> logger)
public Configuration(IIOManager ioManager, ISynchronousIOManager synchronousIOManager, ISymlinkFactory symlinkFactory, IProcessExecutor processExecutor, IPostWriteHandler postWriteHandler, ILogger<Configuration> logger)
{
this.ioManager = ioManager ?? throw new ArgumentNullException(nameof(ioManager));
this.synchronousIOManager = synchronousIOManager ?? throw new ArgumentNullException(nameof(synchronousIOManager));
this.symlinkFactory = symlinkFactory ?? throw new ArgumentNullException(nameof(symlinkFactory));
this.processExecutor = processExecutor ?? throw new ArgumentNullException(nameof(processExecutor));
this.postWriteHandler = postWriteHandler ?? throw new ArgumentNullException(nameof(postWriteHandler));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
semaphore = new SemaphoreSlim(1);
@@ -259,6 +266,8 @@ namespace Tgstation.Server.Host.Components.StaticFiles
var success = synchronousIOManager.WriteFileChecked(path, data, previousHash, cancellationToken);
if (!success)
return;
if (data != null)
postWriteHandler.HandleWrite(path);
string sha1String;
#pragma warning disable CA5350 // Do not use insecure cryptographic algorithm SHA1.
using (var sha1 = new SHA1Managed())
@@ -0,0 +1,11 @@
namespace Tgstation.Server.Host.Components.StaticFiles
{
interface IPostWriteHandler
{
/// <summary>
/// For handling system specific necessities after a write
/// </summary>
/// <param name="filePath">The full path to the file that was written</param>
void HandleWrite(string filePath);
}
}
@@ -0,0 +1,25 @@
using Mono.Unix;
using Mono.Unix.Native;
namespace Tgstation.Server.Host.Components.StaticFiles
{
/// <summary>
/// <see cref="IPostWriteHandler"/> for POSIX systems
/// </summary>
sealed class PosixPostWriteHandler : IPostWriteHandler
{
/// <inheritdoc />
public void HandleWrite(string filePath)
{
//set executable bit every time, don't want people calling me when their uploaded "sl" binary doesn't work
if (Syscall.stat(filePath, out var stat) != 0)
throw new UnixIOException(Stdlib.GetLastError());
if (stat.st_mode.HasFlag(FilePermissions.S_IXUSR))
return;
if(Syscall.chmod(filePath, stat.st_mode | FilePermissions.S_IXUSR) != 0)
throw new UnixIOException(Stdlib.GetLastError());
}
}
}
@@ -0,0 +1,11 @@
namespace Tgstation.Server.Host.Components.StaticFiles
{
/// <summary>
/// <see cref="IPostWriteHandler"/> for Windows systems
/// </summary>
sealed class WindowsPostWriteHandler : IPostWriteHandler
{
/// <inheritdoc />
public void HandleWrite(string filePath) { }
}
}
@@ -190,12 +190,14 @@ namespace Tgstation.Server.Host.Core
services.AddSingleton<ISystemIdentityFactory, WindowsSystemIdentityFactory>();
services.AddSingleton<ISymlinkFactory, WindowsSymlinkFactory>();
services.AddSingleton<IByondInstaller, WindowsByondInstaller>();
services.AddSingleton<IPostWriteHandler, WindowsPostWriteHandler>();
}
else
{
services.AddSingleton<ISystemIdentityFactory, PosixSystemIdentityFactory>();
services.AddSingleton<ISymlinkFactory, PosixSymlinkFactory>();
services.AddSingleton<IByondInstaller, PosixByondInstaller>();
services.AddSingleton<IPostWriteHandler, PosixPostWriteHandler>();
}
services.AddSingleton<IProcessExecutor, ProcessExecutor>();