diff --git a/src/DMAPI/tgs.dm b/src/DMAPI/tgs.dm
index 6e55567544..6645ce51ff 100644
--- a/src/DMAPI/tgs.dm
+++ b/src/DMAPI/tgs.dm
@@ -55,11 +55,16 @@
#define TGS_REBOOT_MODE_SHUTDOWN 1
#define TGS_REBOOT_MODE_RESTART 2
+#define TGS_SECURITY_TRUSTED 0
+#define TGS_SECURITY_SAFE 1
+#define TGS_SECURITY_ULTRASAFE 2
+
//REQUIRED HOOKS
//Call this somewhere in /world/New() that is always run
//event_handler: optional user defined event handler. The default behaviour is to broadcast the event in english to all connected admin channels
-/world/proc/TgsNew(datum/tgs_event_handler/event_handler)
+//minimum_required_security_level: The minimum required security level to run the game in which the DMAPI is integrated
+/world/proc/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE)
return
//Call this when your initializations are complete and your game is ready to play before any player interactions happen
@@ -155,6 +160,10 @@
/world/proc/TgsRevision()
return
+//Get the current BYOND security level
+/world/proc/TgsSecurityLevel()
+ return
+
//Gets a list of active `/datum/tgs_revision_information/test_merge`s
/world/proc/TgsTestMerges()
return
diff --git a/src/DMAPI/tgs/core/core.dm b/src/DMAPI/tgs/core/core.dm
index 1158fdbd34..e0495aba4e 100644
--- a/src/DMAPI/tgs/core/core.dm
+++ b/src/DMAPI/tgs/core/core.dm
@@ -1,4 +1,4 @@
-/world/TgsNew(datum/tgs_event_handler/event_handler)
+/world/TgsNew(datum/tgs_event_handler/event_handler, minimum_required_security_level = TGS_SECURITY_ULTRASAFE)
var/current_api = TGS_READ_GLOBAL(tgs)
if(current_api)
TGS_ERROR_LOG("TgsNew(): TGS API datum already set ([current_api])!")
@@ -18,7 +18,7 @@
TGS_WRITE_GLOBAL(tgs, new_api)
- var/result = new_api.OnWorldNew(event_handler ? event_handler : new /datum/tgs_event_handler/tgs_default)
+ var/result = new_api.OnWorldNew(event_handler ? event_handler : new /datum/tgs_event_handler/tgs_default, minimum_required_security_level)
if(!result || result == TGS_UNIMPLEMENTED)
TGS_WRITE_GLOBAL(tgs, null)
TGS_ERROR_LOG("Failed to activate API!")
@@ -127,6 +127,11 @@
if(api)
api.ChatPrivateMessage(message, user)
+/world/TgsSecurityLevel()
+ var/datum/tgs_api/api = TGS_READ_GLOBAL(tgs)
+ if(api)
+ api.SecurityLevel()
+
/*
The MIT License
diff --git a/src/DMAPI/tgs/core/datum.dm b/src/DMAPI/tgs/core/datum.dm
index f81569136c..b2f9b19cdd 100644
--- a/src/DMAPI/tgs/core/datum.dm
+++ b/src/DMAPI/tgs/core/datum.dm
@@ -46,6 +46,9 @@ TGS_PROTECT_DATUM(/datum/tgs_api)
/datum/tgs_api/proc/ChatPrivateMessage(message, admin_only)
return TGS_UNIMPLEMENTED
+/datum/tgs_api/proc/SecurityLevel()
+ return TGS_UNIMPLEMENTED
+
/*
The MIT License
diff --git a/src/DMAPI/tgs/v3210/api.dm b/src/DMAPI/tgs/v3210/api.dm
index 1c04be9212..63bc0beb2b 100644
--- a/src/DMAPI/tgs/v3210/api.dm
+++ b/src/DMAPI/tgs/v3210/api.dm
@@ -56,7 +56,7 @@
/datum/tgs_api/v3210/proc/file2list(filename)
return splittext(trim_left(trim_right(file2text(filename))), "\n")
-/datum/tgs_api/v3210/OnWorldNew(datum/tgs_event_handler/event_handler) //don't use event handling in this version
+/datum/tgs_api/v3210/OnWorldNew(datum/tgs_event_handler/event_handler, minimum_required_security_level) //don't use event handling in this version
. = FALSE
comms_key = world.params[SERVICE_WORLD_PARAM]
@@ -191,6 +191,9 @@
/datum/tgs_api/v3210/ChatPrivateMessage(message, datum/tgs_chat_user/user)
return TGS_UNIMPLEMENTED
+/datum/tgs_api/v3210/SecurityLevel()
+ return TGS_SECURITY_TRUSTED
+
#undef REBOOT_MODE_NORMAL
#undef REBOOT_MODE_HARD
#undef REBOOT_MODE_SHUTDOWN
diff --git a/src/DMAPI/tgs/v4/api.dm b/src/DMAPI/tgs/v4/api.dm
index 92251d1e43..b5bc692f11 100644
--- a/src/DMAPI/tgs/v4/api.dm
+++ b/src/DMAPI/tgs/v4/api.dm
@@ -32,6 +32,7 @@
var/chat_commands_json_path
var/server_commands_json_path
var/reboot_mode = TGS_REBOOT_MODE_NORMAL
+ var/security_level
var/list/intercepted_message_queue
@@ -48,7 +49,7 @@
/datum/tgs_api/v4/ApiVersion()
return "4.0.0.0"
-/datum/tgs_api/v4/OnWorldNew(datum/tgs_event_handler/event_handler)
+/datum/tgs_api/v4/OnWorldNew(datum/tgs_event_handler/event_handler, minimum_required_security_level)
json_path = world.params[TGS4_PARAM_INFO_JSON]
if(!json_path)
TGS_ERROR_LOG("Missing [TGS4_PARAM_INFO_JSON] world parameter!")
@@ -63,14 +64,14 @@
return
access_identifier = cached_json["accessIdentifier"]
- instance_name = text2num(cached_json["instanceName"])
server_commands_json_path = cached_json["serverCommandsJson"]
if(cached_json["apiValidateOnly"])
TGS_INFO_LOG("Validating API and exiting...")
- Export(TGS4_COMM_VALIDATE)
+ Export(TGS4_COMM_VALIDATE, list(TGS4_PARAMETER_DATA = "[minimum_required_security_level]"))
del(world)
+ security_level = cached_json["securityLevel"]
chat_channels_json_path = cached_json["chatChannelsJson"]
chat_commands_json_path = cached_json["chatCommandsJson"]
src.event_handler = event_handler
@@ -187,7 +188,7 @@
//request a new port
export_lock = FALSE
- var/list/new_port_json = Export(TGS4_COMM_NEW_PORT, list("current_port" = "[world.port]")) //stringify this on purpose
+ var/list/new_port_json = Export(TGS4_COMM_NEW_PORT, list(TGS4_PARAMETER_DATA = "[world.port]")) //stringify this on purpose
if(!new_port_json)
TGS_ERROR_LOG("No new port response from server![TGS4_PORT_CRITFAIL_MESSAGE]")
@@ -295,6 +296,9 @@
channel.custom_tag = channel_json["tag"]
return channel
+/datum/tgs_api/v4/SecurityLevel()
+ return security_level
+
/*
The MIT License
diff --git a/src/Tgstation.Server.Api/Models/DreamDaemon.cs b/src/Tgstation.Server.Api/Models/DreamDaemon.cs
index f78ffd2f15..ac982cf3d0 100644
--- a/src/Tgstation.Server.Api/Models/DreamDaemon.cs
+++ b/src/Tgstation.Server.Api/Models/DreamDaemon.cs
@@ -23,7 +23,7 @@ namespace Tgstation.Server.Api.Models
public bool? Running { get; set; }
///
- /// The current of
+ /// The current of . May be downgraded due to requirements of
///
public DreamDaemonSecurity? CurrentSecurity { get; set; }
diff --git a/src/Tgstation.Server.Api/Models/DreamMaker.cs b/src/Tgstation.Server.Api/Models/DreamMaker.cs
index 690cc90e09..bb821fdc63 100644
--- a/src/Tgstation.Server.Api/Models/DreamMaker.cs
+++ b/src/Tgstation.Server.Api/Models/DreamMaker.cs
@@ -17,5 +17,11 @@ namespace Tgstation.Server.Api.Models
///
[Required]
public ushort? ApiValidationPort { get; set; }
+
+ ///
+ /// The level used to validate the DMAPI
+ ///
+ [Required]
+ public DreamDaemonSecurity? ApiValidationSecurityLevel { get; set; }
}
}
diff --git a/src/Tgstation.Server.Api/Models/Internal/CompileJob.cs b/src/Tgstation.Server.Api/Models/Internal/CompileJob.cs
index bcd2801a51..e101ff7f23 100644
--- a/src/Tgstation.Server.Api/Models/Internal/CompileJob.cs
+++ b/src/Tgstation.Server.Api/Models/Internal/CompileJob.cs
@@ -1,4 +1,5 @@
using System;
+using System.ComponentModel.DataAnnotations;
namespace Tgstation.Server.Api.Models.Internal
{
@@ -26,5 +27,11 @@ namespace Tgstation.Server.Api.Models.Internal
/// The Game folder the results were compiled into
///
public Guid? DirectoryName { get; set; }
+
+ ///
+ /// The minimum required to run the 's output
+ ///
+ [Required]
+ public DreamDaemonSecurity? MinimumSecurityLevel { get; set; }
}
}
diff --git a/src/Tgstation.Server.Api/Rights/DreamMakerRights.cs b/src/Tgstation.Server.Api/Rights/DreamMakerRights.cs
index 0c4612b834..e9b04645f4 100644
--- a/src/Tgstation.Server.Api/Rights/DreamMakerRights.cs
+++ b/src/Tgstation.Server.Api/Rights/DreamMakerRights.cs
@@ -35,6 +35,10 @@ namespace Tgstation.Server.Api.Rights
///
/// User may list and read all s
///
- CompileJobs = 32
+ CompileJobs = 32,
+ ///
+ /// User may modify
+ ///
+ SetSecurityLevel = 64
}
}
diff --git a/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj b/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
index ea5523602b..d3a57d45bd 100644
--- a/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
+++ b/src/Tgstation.Server.Api/Tgstation.Server.Api.csproj
@@ -17,7 +17,7 @@
4.0.0.0json web api tgstation-server tgstation ss13 byondPrototype release
- 4.0.0.0-preview6003
+ 4.0.0.0-preview6004
diff --git a/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj b/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj
index 6bb5253884..97763f5f38 100644
--- a/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj
+++ b/src/Tgstation.Server.Client/Tgstation.Server.Client.csproj
@@ -3,7 +3,7 @@
netstandard2.0Full
- 4.0.0.0-preview9109
+ 4.0.0.0-preview9110trueCyberboss/tg/station 13
diff --git a/src/Tgstation.Server.Host/Components/Compiler/DmbFactory.cs b/src/Tgstation.Server.Host/Components/Compiler/DmbFactory.cs
index 0625499ac9..1c3a909b98 100644
--- a/src/Tgstation.Server.Host/Components/Compiler/DmbFactory.cs
+++ b/src/Tgstation.Server.Host/Components/Compiler/DmbFactory.cs
@@ -125,8 +125,6 @@ namespace Tgstation.Server.Host.Components.Compiler
if (job == null)
throw new ArgumentNullException(nameof(job));
- logger.LogTrace("Loading compile job {0}...", job.Id);
-
CompileJob finalCompileJob = null;
//now load the entire compile job tree
await databaseContextFactory.UseContext(async db => finalCompileJob = await db.CompileJobs.Where(x => x.Id == job.Id)
diff --git a/src/Tgstation.Server.Host/Components/Compiler/DreamMaker.cs b/src/Tgstation.Server.Host/Components/Compiler/DreamMaker.cs
index 15c46067f8..adaf2a55ef 100644
--- a/src/Tgstation.Server.Host/Components/Compiler/DreamMaker.cs
+++ b/src/Tgstation.Server.Host/Components/Compiler/DreamMaker.cs
@@ -125,8 +125,8 @@ namespace Tgstation.Server.Host.Components.Compiler
/// The current
/// The port to use for API validation
/// The for the operation
- /// A resulting in if the DMAPI was successfully validated, otherwise
- async Task VerifyApi(uint timeout, DreamDaemonSecurity securityLevel, Models.CompileJob job, IByondExecutableLock byondLock, ushort portToUse, CancellationToken cancellationToken)
+ /// A representing the running operation
+ async Task VerifyApi(uint timeout, DreamDaemonSecurity securityLevel, Models.CompileJob job, IByondExecutableLock byondLock, ushort portToUse, CancellationToken cancellationToken)
{
logger.LogTrace("Verifying DMAPI...");
var launchParameters = new DreamDaemonLaunchParameters
@@ -138,6 +138,8 @@ namespace Tgstation.Server.Host.Components.Compiler
};
var dirA = ioManager.ConcatPath(job.DirectoryName.ToString(), ADirectoryName);
+
+ job.MinimumSecurityLevel = securityLevel; //needed for the TempDmbProvider
var provider = new TemporaryDmbProvider(ioManager.ResolvePath(dirA), String.Concat(job.DmeName, DmbExtension), job);
var timeoutAt = DateTimeOffset.Now.AddSeconds(timeout);
@@ -154,15 +156,36 @@ namespace Tgstation.Server.Host.Components.Compiler
cancellationToken.ThrowIfCancellationRequested();
}
- if (!controller.Lifetime.IsCompleted)
+ if (controller.Lifetime.IsCompleted)
{
- logger.LogDebug("API validation timed out!");
- return false;
+ var validationStatus = controller.ApiValidationStatus;
+ logger.LogTrace("API validation status: {0}", validationStatus);
+ switch (validationStatus)
+ {
+ case ApiValidationStatus.RequiresUltrasafe:
+ job.MinimumSecurityLevel = DreamDaemonSecurity.Ultrasafe;
+ return;
+ case ApiValidationStatus.RequiresSafe:
+ if (securityLevel == DreamDaemonSecurity.Ultrasafe)
+ throw new JobException("This game must be run with at least the 'Safe' DreamDaemon security level!");
+ job.MinimumSecurityLevel = DreamDaemonSecurity.Safe;
+ return;
+ case ApiValidationStatus.RequiresTrusted:
+ if (securityLevel != DreamDaemonSecurity.Trusted)
+ throw new JobException("This game must be run with at least the 'Trusted' DreamDaemon security level!");
+ job.MinimumSecurityLevel = DreamDaemonSecurity.Trusted;
+ return;
+ case ApiValidationStatus.NeverValidated:
+ break;
+ case ApiValidationStatus.BadValidationRequest:
+ throw new JobException("Recieved an unrecognized API validation request from DreamDaemon!");
+ case ApiValidationStatus.UnaskedValidationRequest:
+ default:
+ throw new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, "Session controller returned unexpected ApiValidationStatus: {0}", validationStatus));
+ }
}
-
- var validated = controller.ApiValidated;
- logger.LogTrace("API valid: {0}", validated);
- return validated;
+
+ throw new JobException("DMAPI validation timed out!");
}
}
@@ -243,7 +266,7 @@ namespace Tgstation.Server.Host.Components.Compiler
}
///
- public async Task Compile(Models.RevisionInformation revisionInformation, Api.Models.DreamMaker dreamMakerSettings, DreamDaemonSecurity securityLevel, uint apiValidateTimeout, IRepository repository, CancellationToken cancellationToken)
+ public async Task Compile(Models.RevisionInformation revisionInformation, Api.Models.DreamMaker dreamMakerSettings, uint apiValidateTimeout, IRepository repository, CancellationToken cancellationToken)
{
if (revisionInformation == null)
throw new ArgumentNullException(nameof(revisionInformation));
@@ -254,8 +277,8 @@ namespace Tgstation.Server.Host.Components.Compiler
if (repository == null)
throw new ArgumentNullException(nameof(repository));
- if (securityLevel == DreamDaemonSecurity.Ultrasafe)
- throw new ArgumentOutOfRangeException(nameof(securityLevel), securityLevel, "Cannot compile with ultrasafe security!");
+ if (dreamMakerSettings.ApiValidationSecurityLevel == DreamDaemonSecurity.Ultrasafe)
+ throw new ArgumentOutOfRangeException(nameof(dreamMakerSettings), dreamMakerSettings, "Cannot compile with ultrasafe security!");
logger.LogTrace("Begin Compile");
@@ -356,13 +379,18 @@ namespace Tgstation.Server.Host.Components.Compiler
var exitCode = await RunDreamMaker(byondLock.DreamMakerPath, job, cancellationToken).ConfigureAwait(false);
- var apiValidated = exitCode == 0 && await VerifyApi(apiValidateTimeout, securityLevel, job, byondLock, dreamMakerSettings.ApiValidationPort.Value, cancellationToken).ConfigureAwait(false);
+ try
+ {
+ if (exitCode != 0)
+ throw new JobException(String.Format(CultureInfo.InvariantCulture, "DM exited with a non-zero code: {0}{1}{2}", exitCode, Environment.NewLine, job.Output));
- if (!apiValidated)
+ await VerifyApi(apiValidateTimeout, dreamMakerSettings.ApiValidationSecurityLevel.Value, job, byondLock, dreamMakerSettings.ApiValidationPort.Value, cancellationToken).ConfigureAwait(false);
+ }
+ catch (JobException)
{
//server never validated or compile failed
await eventConsumer.HandleEvent(EventType.CompileFailure, new List { resolvedGameDirectory, exitCode == 0 ? "1" : "0" }, cancellationToken).ConfigureAwait(false);
- throw new JobException(exitCode == 0 ? "Validation of the TGS api failed!" : String.Format(CultureInfo.InvariantCulture, "DM exited with a non-zero code: {0}{1}{2}", exitCode, Environment.NewLine, job.Output));
+ throw;
}
logger.LogTrace("Running post compile event...");
diff --git a/src/Tgstation.Server.Host/Components/Compiler/IDreamMaker.cs b/src/Tgstation.Server.Host/Components/Compiler/IDreamMaker.cs
index dce21e8194..83f83849fa 100644
--- a/src/Tgstation.Server.Host/Components/Compiler/IDreamMaker.cs
+++ b/src/Tgstation.Server.Host/Components/Compiler/IDreamMaker.cs
@@ -15,11 +15,10 @@ namespace Tgstation.Server.Host.Components.Compiler
///
/// The being compiled from the
/// The for the compile
- /// The level allowed for API validation
/// The time in seconds to wait while validating the API
/// The to copy from
/// The for the operation
/// A resulting in the partially populated for the operation. In particular, note the field will only have it's field populated
- Task Compile(Models.RevisionInformation revisionInformation, Api.Models.DreamMaker dreamMakerSettings, DreamDaemonSecurity securityLevel, uint apiValidateTimeout, IRepository repository, CancellationToken cancellationToken);
+ Task Compile(Models.RevisionInformation revisionInformation, Api.Models.DreamMaker dreamMakerSettings, uint apiValidateTimeout, IRepository repository, CancellationToken cancellationToken);
}
}
\ No newline at end of file
diff --git a/src/Tgstation.Server.Host/Components/Instance.cs b/src/Tgstation.Server.Host/Components/Instance.cs
index 8f7b0e7700..79faad2b45 100644
--- a/src/Tgstation.Server.Host/Components/Instance.cs
+++ b/src/Tgstation.Server.Host/Components/Instance.cs
@@ -132,7 +132,6 @@ namespace Tgstation.Server.Host.Components
var ddSettingsTask = databaseContext.DreamDaemonSettings.Where(x => x.InstanceId == metadata.Id).Select(x => new DreamDaemonSettings
{
StartupTimeout = x.StartupTimeout,
- SecurityLevel = x.SecurityLevel
}).FirstOrDefaultAsync(cancellationToken);
var dreamMakerSettings = await databaseContext.DreamMakerSettings.Where(x => x.InstanceId == metadata.Id).FirstAsync(cancellationToken).ConfigureAwait(false);
@@ -167,7 +166,7 @@ namespace Tgstation.Server.Host.Components
databaseContext.Instances.Attach(revInfo.Instance);
}
- compileJob = await DreamMaker.Compile(revInfo, dreamMakerSettings, ddSettings.SecurityLevel.Value, ddSettings.StartupTimeout.Value, repo, cancellationToken).ConfigureAwait(false);
+ compileJob = await DreamMaker.Compile(revInfo, dreamMakerSettings, ddSettings.StartupTimeout.Value, repo, cancellationToken).ConfigureAwait(false);
}
compileJob.Job = job;
diff --git a/src/Tgstation.Server.Host/Components/Interop/JsonFile.cs b/src/Tgstation.Server.Host/Components/Interop/JsonFile.cs
index 4c318c21c3..10eebe5c13 100644
--- a/src/Tgstation.Server.Host/Components/Interop/JsonFile.cs
+++ b/src/Tgstation.Server.Host/Components/Interop/JsonFile.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using Tgstation.Server.Api.Models;
using Tgstation.Server.Api.Models.Internal;
namespace Tgstation.Server.Host.Components.Interop
@@ -39,9 +40,14 @@ namespace Tgstation.Server.Host.Components.Interop
public string ServerCommandsJson { get; set; }
///
- /// The of the launch
+ /// The of the launch
///
- public RevisionInformation Revision { get; set; }
+ public Api.Models.Internal.RevisionInformation Revision { get; set; }
+
+ ///
+ /// The level of the launch
+ ///
+ public DreamDaemonSecurity SecurityLevel { get; set; }
///
/// The s in the launch
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/ApiValidationStatus.cs b/src/Tgstation.Server.Host/Components/Watchdog/ApiValidationStatus.cs
new file mode 100644
index 0000000000..46e282802d
--- /dev/null
+++ b/src/Tgstation.Server.Host/Components/Watchdog/ApiValidationStatus.cs
@@ -0,0 +1,33 @@
+namespace Tgstation.Server.Host.Components.Watchdog
+{
+ ///
+ /// Status of DMAPI validation
+ ///
+ enum ApiValidationStatus
+ {
+ ///
+ /// The DMAPI never contacted the server for validation
+ ///
+ NeverValidated,
+ ///
+ /// The server was contacted for validation but it was never requested
+ ///
+ UnaskedValidationRequest,
+ ///
+ /// The validation request was malformed
+ ///
+ BadValidationRequest,
+ ///
+ /// Valid API. The game must be run with a minimum security level of
+ ///
+ RequiresSafe,
+ ///
+ /// Valid API. The game must be run with a security level of
+ ///
+ RequiresTrusted,
+ ///
+ /// Valid API. The game must be run with a minimum security level of
+ ///
+ RequiresUltrasafe
+ }
+}
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/ISessionController.cs b/src/Tgstation.Server.Host/Components/Watchdog/ISessionController.cs
index 3f2e245eba..97e19b271d 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/ISessionController.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/ISessionController.cs
@@ -25,9 +25,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
bool TerminationWasRequested { get; }
///
- /// If the DMAPI was validated. This field may only be access once completes
+ /// The DMAPI
///
- bool ApiValidated { get; }
+ ApiValidationStatus ApiValidationStatus { get; }
///
/// The being used
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/ISessionControllerFactory.cs b/src/Tgstation.Server.Host/Components/Watchdog/ISessionControllerFactory.cs
index 645af10171..4873ce5b21 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/ISessionControllerFactory.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/ISessionControllerFactory.cs
@@ -13,7 +13,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
///
/// Create a from a freshly launch DreamDaemon instance
///
- /// The to use
+ /// The to use. will be updated with the minumum required security level for the launch
/// The to use
/// The current if any
/// If the of should be used
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs b/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs
index 6c8b65b05f..2002597284 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/IWatchdog.cs
@@ -56,7 +56,7 @@ namespace Tgstation.Server.Host.Components.Watchdog
///
/// Changes the . If currently triggers a graceful restart
///
- /// The new
+ /// The new . May be modified
/// The for the operation
/// A representing the running operation
Task ChangeSettings(DreamDaemonLaunchParameters launchParameters, CancellationToken cancellationToken);
diff --git a/src/Tgstation.Server.Host/Components/Watchdog/SessionController.cs b/src/Tgstation.Server.Host/Components/Watchdog/SessionController.cs
index 20b1115531..b71d7f0c62 100644
--- a/src/Tgstation.Server.Host/Components/Watchdog/SessionController.cs
+++ b/src/Tgstation.Server.Host/Components/Watchdog/SessionController.cs
@@ -29,13 +29,13 @@ namespace Tgstation.Server.Host.Components.Watchdog
}
///
- public bool ApiValidated
+ public ApiValidationStatus ApiValidationStatus
{
get
{
if (!Lifetime.IsCompleted)
throw new InvalidOperationException("ApiValidated cannot be checked while Lifetime is incomplete!");
- return apiValidated;
+ return apiValidationStatus;
}
}
@@ -126,6 +126,11 @@ namespace Tgstation.Server.Host.Components.Watchdog
///
readonly ILogger logger;
+ ///
+ /// The level the was launched with
+ ///
+ readonly DreamDaemonSecurity? launchSecurityLevel;
+
///
/// The waits on when DreamDaemon currently has it's ports closed
///
@@ -151,9 +156,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
bool disposed;
///
- /// If the DMAPI was validated
+ /// The for the
///
- bool apiValidated;
+ ApiValidationStatus apiValidationStatus;
///
/// If should be kept alive instead
@@ -171,8 +176,9 @@ namespace Tgstation.Server.Host.Components.Watchdog
/// The value of
/// The value of
/// The value of
+ /// The value of
/// The optional time to wait before failing the
- public SessionController(ReattachInformation reattachInformation, IProcess process, IByondExecutableLock byondLock, IByondTopicSender byondTopicSender, IJsonTrackingContext chatJsonTrackingContext, ICommContext interopContext, IChat chat, ILogger logger, uint? startupTimeout)
+ public SessionController(ReattachInformation reattachInformation, IProcess process, IByondExecutableLock byondLock, IByondTopicSender byondTopicSender, IJsonTrackingContext chatJsonTrackingContext, ICommContext interopContext, IChat chat, ILogger logger, DreamDaemonSecurity? launchSecurityLevel, uint? startupTimeout)
{
this.chatJsonTrackingContext = chatJsonTrackingContext; //null valid
this.reattachInformation = reattachInformation ?? throw new ArgumentNullException(nameof(reattachInformation));
@@ -183,11 +189,13 @@ namespace Tgstation.Server.Host.Components.Watchdog
this.chat = chat ?? throw new ArgumentNullException(nameof(chat));
this.logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ this.launchSecurityLevel = launchSecurityLevel;
+
interopContext.RegisterHandler(this);
portClosedForReboot = false;
disposed = false;
- apiValidated = false;
+ apiValidationStatus = ApiValidationStatus.NeverValidated;
released = false;
rebootTcs = new TaskCompletionSource