Commands can now be locked out of remote sessions

Try using sos.shutdown remotely... it won't work.
😜
This commit is contained in:
Michael 2017-01-21 21:27:25 -05:00
parent 19b7f5b983
commit 2ce2214d5e
5 changed files with 158 additions and 97 deletions

View file

@ -326,16 +326,21 @@ Contents:
}
break;
case "trm_invcmd":
Console.WriteLine("Before arg check");
args = JsonConvert.DeserializeObject<Dictionary<string, object>>(msg.Contents);
if(args["guid"] != null && args["command"] != null)
{
Console.WriteLine("arg check finished");
string cmd = args["command"] as string;
string cGuid = args["guid"] as string;
Console.WriteLine("Before dispatch");
server.DispatchTo(new Guid(cGuid), new NetObject("trminvoke", new ServerMessage
{
Name = "trm_invokecommand",
GUID = "server",
Contents = cmd
}));
Console.WriteLine("After dispatch");
}
break;
case "usr_givecp":

View file

@ -253,10 +253,11 @@ namespace ShiftOS.WinForms.Applications
if (IsInRemoteSystem == true)
{
ServerManager.SendMessage("trm_invcmd", $@"{{
guid = ""{RemoteGuid}"",
command: ""{text4}""
}}");
ServerManager.SendMessage("trm_invcmd", JsonConvert.SerializeObject(new
{
guid = RemoteGuid,
command = text4
}));
}
else
{

View file

@ -28,39 +28,51 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ShiftOS.Engine {
public class Command : Attribute {
namespace ShiftOS.Engine
{
public class Command : Attribute
{
public string name;
public string description = "";
public string usage = "";
public bool hide = false;
public Command(string name) {
public Command(string name)
{
this.name = name;
}
public Command(string name, bool hide) {
public Command(string name, bool hide)
{
this.name = name;
this.hide = hide;
}
public Command(string name, string usage, string description) {
public Command(string name, string usage, string description)
{
this.name = name;
this.description = description;
this.usage = usage;
}
}
public class RequiresUpgradeAttribute : Attribute {
public class RequiresUpgradeAttribute : Attribute
{
public string Upgrade { get; set; }
public bool Installed {
get {
if (Upgrade.Contains(";")) {
public bool Installed
{
get
{
if (Upgrade.Contains(";"))
{
string[] split = Upgrade.Split(';');
foreach (var upg in split) {
foreach (var upg in split)
{
if (!Shiftorium.UpgradeInstalled(upg))
return false;
}
return true;
} else {
}
else
{
return Shiftorium.UpgradeInstalled(Upgrade);
}
}
@ -70,30 +82,36 @@ namespace ShiftOS.Engine {
/// Marks this Form or Command as dependant on this upgrade.
/// </summary>
/// <param name="upg">Upgrade ID - See 'shiftorium.json' in resources for all IDs and their metadata.</param>
public RequiresUpgradeAttribute(string upg) {
public RequiresUpgradeAttribute(string upg)
{
Upgrade = upg;
}
}
public class Namespace : Attribute {
public class Namespace : Attribute
{
public string name;
public bool hide;
public Namespace(string n) {
public Namespace(string n)
{
name = n;
}
public Namespace(string n, bool hide) {
public Namespace(string n, bool hide)
{
name = n;
this.hide = hide;
}
}
[AttributeUsage(AttributeTargets.Method)]
public class CommandObsolete : Attribute {
public class CommandObsolete : Attribute
{
public string reason;
public string newcommand;
public bool warn;
public CommandObsolete(string reason, string newcommand, bool warn) {
public CommandObsolete(string reason, string newcommand, bool warn)
{
this.reason = reason; // %n for newcommand
this.newcommand = newcommand;
this.warn = warn;
@ -101,17 +119,30 @@ namespace ShiftOS.Engine {
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class RequiresArgument : Attribute {
public class RequiresArgument : Attribute
{
public string argument;
public RequiresArgument(string argument) {
public RequiresArgument(string argument)
{
this.argument = argument;
}
public override object TypeId {
get {
public override object TypeId
{
get
{
return this;
}
}
}
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class RemoteLockAttribute : Attribute
{
/// <summary>
/// When used on a terminal command, it will prevent that command from being invoked by a remote user (over MUD terminal forwarding).
/// </summary>
public RemoteLockAttribute() { }
}
}

View file

@ -308,6 +308,7 @@ namespace ShiftOS.Engine
[Namespace("sos")]
public static class ShiftOSCommands
{
[RemoteLock]
[Command("shutdown")]
public static bool Shutdown()
{
@ -540,7 +541,7 @@ shiftorium.buy{{upgrade:""{upg.ID}""}}");
[RemoteLock]
[Command("list")]
public static bool List()
{
@ -553,6 +554,7 @@ shiftorium.buy{{upgrade:""{upg.ID}""}}");
return true;
}
[RemoteLock]
[Command("open")]
public static bool Open(Dictionary<string, object> args)
{

View file

@ -66,7 +66,7 @@ namespace ShiftOS.Engine
public static string LastCommand = "";
public static void InvokeCommand(string text)
public static void InvokeCommand(string text, bool isRemote = false)
{
try
{
@ -75,7 +75,7 @@ namespace ShiftOS.Engine
var args = GetArgs(ref text);
bool commandWasClient = RunClient(text, args);
bool commandWasClient = RunClient(text, args, isRemote);
if (!commandWasClient && !string.IsNullOrWhiteSpace(text))
{
@ -109,7 +109,21 @@ namespace ShiftOS.Engine
TerminalRequested?.Invoke();
}
public static bool RunClient(string text, Dictionary<string, object> args)
public static bool CanRunRemotely(MethodInfo mth, bool isRemote)
{
if (!isRemote)
return true;
foreach(var attr in mth.GetCustomAttributes(false))
{
if (attr is RemoteLockAttribute)
return false;
}
return true;
}
public static bool RunClient(string text, Dictionary<string, object> args, bool isRemote = false)
{
latestCommmand = text;
@ -136,97 +150,105 @@ namespace ShiftOS.Engine
{
if (Shiftorium.UpgradeAttributesUnlocked(method))
{
foreach (var ma in method.GetCustomAttributes(false))
if (CanRunRemotely(method, isRemote))
{
if (ma is Command)
foreach (var ma in method.GetCustomAttributes(false))
{
var cmd = ma as Command;
if (text.Split('.')[1] == cmd.name)
if (ma is Command)
{
var attr = method.GetCustomAttribute<CommandObsolete>();
if (attr != null)
var cmd = ma as Command;
if (text.Split('.')[1] == cmd.name)
{
string newcommand = attr.newcommand;
if (attr.warn)
var attr = method.GetCustomAttribute<CommandObsolete>();
if (attr != null)
{
Console.WriteLine(Localization.Parse((newcommand == "" ? "{ERROR}" : "{WARN}") + attr.reason, new Dictionary<string, string>() {
string newcommand = attr.newcommand;
if (attr.warn)
{
Console.WriteLine(Localization.Parse((newcommand == "" ? "{ERROR}" : "{WARN}") + attr.reason, new Dictionary<string, string>() {
{"%newcommand", newcommand}
}));
}
if (newcommand != "")
{
// redo the entire process running newcommand
return RunClient(newcommand, args);
}
}
var requiresArgs = method.GetCustomAttributes<RequiresArgument>();
bool error = false;
bool providedusage = false;
foreach (RequiresArgument argument in requiresArgs)
{
if (!args.ContainsKey(argument.argument))
{
if (!providedusage)
}
if (newcommand != "")
{
string usageparse = "{COMMAND_" + ns.name.ToUpper() + "_" + cmd.name.ToUpper() + "_USAGE}";
if (usageparse == Localization.Parse(usageparse))
usageparse = "";
else
usageparse = Shiftorium.UpgradeInstalled("help_usage") ? Localization.Parse("{ERROR}{USAGE}" + usageparse, new Dictionary<string, string>() {
// redo the entire process running newcommand
return RunClient(newcommand, args);
}
}
var requiresArgs = method.GetCustomAttributes<RequiresArgument>();
bool error = false;
bool providedusage = false;
foreach (RequiresArgument argument in requiresArgs)
{
if (!args.ContainsKey(argument.argument))
{
if (!providedusage)
{
string usageparse = "{COMMAND_" + ns.name.ToUpper() + "_" + cmd.name.ToUpper() + "_USAGE}";
if (usageparse == Localization.Parse(usageparse))
usageparse = "";
else
usageparse = Shiftorium.UpgradeInstalled("help_usage") ? Localization.Parse("{ERROR}{USAGE}" + usageparse, new Dictionary<string, string>() {
{"%ns", ns.name},
{"%cmd", cmd.name}
}) : "";
Console.WriteLine(usageparse);
Console.WriteLine(usageparse);
providedusage = true;
}
providedusage = true;
}
if (Shiftorium.UpgradeInstalled("help_usage"))
{
Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED}", new Dictionary<string, string>() {
if (Shiftorium.UpgradeInstalled("help_usage"))
{
Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED}", new Dictionary<string, string>() {
{"%argument", argument.argument}
}));
}
else
{
Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED_NO_USAGE}"));
}
}
else
{
Console.WriteLine(Localization.Parse("{ERROR_ARGUMENT_REQUIRED_NO_USAGE}"));
}
error = true;
error = true;
}
}
}
if (error)
{
throw new Exception("{ERROR_COMMAND_WRONG}");
}
if (error)
{
throw new Exception("{ERROR_COMMAND_WRONG}");
}
try
{
return (bool)method.Invoke(null, new[] { args });
}
catch (TargetInvocationException e)
{
Console.WriteLine(Localization.Parse("{ERROR_EXCEPTION_THROWN_IN_METHOD}"));
Console.WriteLine(e.InnerException.Message);
Console.WriteLine(e.InnerException.StackTrace);
return true;
}
catch
{
return (bool)method.Invoke(null, new object[] { });
try
{
return (bool)method.Invoke(null, new[] { args });
}
catch (TargetInvocationException e)
{
Console.WriteLine(Localization.Parse("{ERROR_EXCEPTION_THROWN_IN_METHOD}"));
Console.WriteLine(e.InnerException.Message);
Console.WriteLine(e.InnerException.StackTrace);
return true;
}
catch
{
return (bool)method.Invoke(null, new object[] { });
}
}
}
}
}
else
{
Console.WriteLine(text + " cannot be ran in a remote session");
return true;
}
}
}
}
@ -256,7 +278,7 @@ namespace ShiftOS.Engine
IsForwardingConsoleWrites = true;
if (TerminalBackend.InStory == false)
{
TerminalBackend.InvokeCommand(text3);
TerminalBackend.InvokeCommand(text3, true);
}
if (TerminalBackend.PrefixEnabled)
{