From 0fd0077befc5ac71c7491ac4a1decab11a551c0a Mon Sep 17 00:00:00 2001
From: Manti <67705577+mantikafasi@users.noreply.github.com>
Date: Tue, 13 Jun 2023 00:33:07 +0300
Subject: [PATCH] Add WebServer Support
---
Common/Config.cs | 3 +
MLock/App.xaml.cs | 18 +++++-
MLock/LockWindow.xaml.cs | 18 +++---
MLock/MLock.csproj | 4 +-
MLock/{ => Modules}/USB.cs | 0
MLock/Modules/WebServer.cs | 60 ++++++++++++++++++++
MLock/Utils.cs | 6 +-
MLockConfigurator/App.xaml.cs | 16 +++++-
MLockConfigurator/ConfiguratorWindow.xaml | 15 ++++-
MLockConfigurator/ConfiguratorWindow.xaml.cs | 17 +++++-
MLockConfigurator/Utils.cs | 14 ++---
README.md | 10 +++-
12 files changed, 153 insertions(+), 28 deletions(-)
rename MLock/{ => Modules}/USB.cs (100%)
create mode 100644 MLock/Modules/WebServer.cs
diff --git a/Common/Config.cs b/Common/Config.cs
index 6d43954..12ae3bb 100644
--- a/Common/Config.cs
+++ b/Common/Config.cs
@@ -18,5 +18,8 @@ public class Config
[DataMember(Name = "startLocked")] public bool StartLocked { get; set; }
[DataMember(Name = "enableBlur")] public bool BlurBackground { get; set; }
+ [DataMember(Name="enableWebServer")] public bool EnableWebServer { get; set;}
+ [DataMember (Name="webServerPassword")] public string WebServerPassword { get; set; }
+ [DataMember (Name="debug")] public bool Debug { get; set; } // this is only used to disable keyhook for testing
}
}
\ No newline at end of file
diff --git a/MLock/App.xaml.cs b/MLock/App.xaml.cs
index f20040b..0de212a 100644
--- a/MLock/App.xaml.cs
+++ b/MLock/App.xaml.cs
@@ -2,8 +2,11 @@
using System.Drawing;
using System.IO;
using System.Reflection;
+using System.Security.Principal;
+using System.Windows;
using System.Windows.Forms;
using Common;
+using MessageBox = System.Windows.MessageBox;
namespace MLock
{
@@ -14,6 +17,14 @@ public partial class App
public App()
{
+ var isAdmin = new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
+ if (!isAdmin)
+ {
+ MessageBox.Show("Please run MLock as administrator", "Admin Privileges Required", MessageBoxButton.OK,
+ MessageBoxImage.Warning);
+ Environment.Exit(0);
+ }
+
if (!ParseConfig()) Environment.Exit(0);
InitializeComponent();
@@ -54,7 +65,7 @@ public bool ParseConfig()
{
if (!File.Exists(MLOCK_DIR + "\\publicKey.xml"))
{
- System.Windows.MessageBox.Show(
+ MessageBox.Show(
"Public Key for USB Locking not found, please run the USB key generator and config installer first");
return false;
}
@@ -65,11 +76,12 @@ public bool ParseConfig()
if (Config.INSTANCE.EnablePasswordUnlocking &&
(Config.INSTANCE.Password == null || Config.INSTANCE.Password.Trim() == ""))
{
- System.Windows.MessageBox.Show("Password not set, please run the config installer first");
+ MessageBox.Show("Password not set, please run the config installer first");
return false;
}
- if (!Config.INSTANCE.EnablePasswordUnlocking && !Config.INSTANCE.EnableUSBUnlocking)
+ if (!Config.INSTANCE.EnablePasswordUnlocking && !Config.INSTANCE.EnableUSBUnlocking &&
+ !Config.INSTANCE.EnableWebServer)
{
MessageBox.Show("No unlocking methods enabled, please run the config installer first");
return false;
diff --git a/MLock/LockWindow.xaml.cs b/MLock/LockWindow.xaml.cs
index a151b2a..d02d683 100644
--- a/MLock/LockWindow.xaml.cs
+++ b/MLock/LockWindow.xaml.cs
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Threading;
+using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;
@@ -8,6 +9,7 @@
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using Common;
+using MLock.Modules;
namespace MLock
{
@@ -43,11 +45,10 @@ public MainWindow()
Events.LockApp += () =>
{
- var screenshot = Utils.Screenshot();
-
-
Dispatcher.Invoke(() =>
{
+ var screenshot = Utils.Screenshot();
+
var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(
screenshot.GetHbitmap(),
IntPtr.Zero,
@@ -62,17 +63,19 @@ public MainWindow()
Events.UnlockApp += () => { SetBlur(true); };
}
-
Native.SetKHookConfig(config);
- if (Config.INSTANCE.StartLocked) Events.Lock();
+ if (Config.INSTANCE.StartLocked && !Config.INSTANCE.EnableUSBUnlocking) // CheckUSBs method automaticly locks if no USBs are found
+ Events.Lock();
if (Config.INSTANCE.EnableUSBUnlocking)
{
USB.Initialize();
-
USB.CheckUSBs();
}
+
+ if (Config.INSTANCE.EnableWebServer)
+ Task.Run(() => new WebServer().Initialize());
}
private void SetPasswordText(string text)
@@ -132,7 +135,8 @@ public void OnLock()
return;
}
- Native.InstallKHook();
+ if (!Config.INSTANCE.Debug)
+ Native.InstallKHook();
Visibility = Visibility.Visible;
});
}
diff --git a/MLock/MLock.csproj b/MLock/MLock.csproj
index b701463..3bfc7de 100644
--- a/MLock/MLock.csproj
+++ b/MLock/MLock.csproj
@@ -78,7 +78,8 @@
Designer
-
+
+
MSBuild:Compile
@@ -123,5 +124,6 @@
Common
+
\ No newline at end of file
diff --git a/MLock/USB.cs b/MLock/Modules/USB.cs
similarity index 100%
rename from MLock/USB.cs
rename to MLock/Modules/USB.cs
diff --git a/MLock/Modules/WebServer.cs b/MLock/Modules/WebServer.cs
new file mode 100644
index 0000000..dbe0dc8
--- /dev/null
+++ b/MLock/Modules/WebServer.cs
@@ -0,0 +1,60 @@
+using System.Net;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Windows;
+using Common;
+
+namespace MLock.Modules
+{
+ internal class WebServer
+ {
+ private CancellationTokenSource cts;
+ private HttpListener listener;
+
+ public async Task Initialize()
+ {
+ listener = new HttpListener();
+ listener.Prefixes.Add("http://+:4444/");
+
+ listener.Start();
+
+ while (listener.IsListening)
+ {
+ var context = await listener.GetContextAsync();
+ ProcessRequest(context);
+ }
+
+ listener.Stop();
+ }
+
+ private void ProcessRequest(HttpListenerContext context)
+ {
+ var password = context.Request.QueryString.Get("password");
+ if (password == null || password != Config.INSTANCE.WebServerPassword)
+ {
+ context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
+ context.Response.Close();
+ return;
+ }
+
+ switch (context.Request.Url.AbsolutePath)
+ {
+ case "/lock":
+ Events.Lock();
+ break;
+ case "/unlock":
+ Events.Unlock();
+ break;
+ }
+
+ context.Response.StatusCode = (int)HttpStatusCode.OK;
+
+ context.Response.Close();
+ }
+
+ private void StopServer(object sender, RoutedEventArgs e) // I am guessing server gets closed automatically when the program closes
+ {
+ cts?.Cancel();
+ }
+ }
+}
\ No newline at end of file
diff --git a/MLock/Utils.cs b/MLock/Utils.cs
index b1a6e79..231f78b 100644
--- a/MLock/Utils.cs
+++ b/MLock/Utils.cs
@@ -39,8 +39,10 @@ public static Bitmap Screenshot()
var captureRectangle = Screen.PrimaryScreen.Bounds;
var captureBitmap = new Bitmap(captureRectangle.Width, captureRectangle.Height);
- var captureGraphics = Graphics.FromImage(captureBitmap);
- captureGraphics.CopyFromScreen(captureRectangle.Left, captureRectangle.Top, 0, 0, captureRectangle.Size);
+ using (var graphics = Graphics.FromImage(captureBitmap))
+ {
+ graphics.CopyFromScreen(captureRectangle.Left, captureRectangle.Top, 0, 0, captureRectangle.Size);
+ }
return captureBitmap;
}
diff --git a/MLockConfigurator/App.xaml.cs b/MLockConfigurator/App.xaml.cs
index d231b3c..6b7a16a 100644
--- a/MLockConfigurator/App.xaml.cs
+++ b/MLockConfigurator/App.xaml.cs
@@ -1,9 +1,23 @@
-namespace MLockUSBKeyGenerator
+using System.Windows;
+using System;
+
+namespace MLockUSBKeyGenerator
{
///
/// Interaction logic for App.xaml
///
public partial class App
{
+ public App()
+ {
+ if (!Utils.IsAdmin())
+ {
+ MessageBox.Show("Configurator requires administrative privileges to properly save the config file. Please run the program as an administrator.", "Admin Privileges Required", MessageBoxButton.OK, MessageBoxImage.Warning);
+ Environment.Exit(0);
+ return;
+ }
+
+ InitializeComponent();
+ }
}
}
\ No newline at end of file
diff --git a/MLockConfigurator/ConfiguratorWindow.xaml b/MLockConfigurator/ConfiguratorWindow.xaml
index 08a5b54..84af9ee 100644
--- a/MLockConfigurator/ConfiguratorWindow.xaml
+++ b/MLockConfigurator/ConfiguratorWindow.xaml
@@ -4,7 +4,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
- Title="MLock Config Generator" Height="400" Width="525">
+ Title="MLock Config Generator" Height="500" Width="525">
@@ -22,6 +22,19 @@
IsEnabled="{Binding EnablePasswordUnlocking}" />
+
+
+
+
+
+
+
+
+
+
diff --git a/MLockConfigurator/ConfiguratorWindow.xaml.cs b/MLockConfigurator/ConfiguratorWindow.xaml.cs
index 5d4e8ec..748e257 100644
--- a/MLockConfigurator/ConfiguratorWindow.xaml.cs
+++ b/MLockConfigurator/ConfiguratorWindow.xaml.cs
@@ -1,5 +1,6 @@
using System;
using System.IO;
+using System.Security.AccessControl;
using System.Windows;
using Common;
using Microsoft.Win32;
@@ -106,6 +107,14 @@ public void InstallConfigButton_Click(object sender, RoutedEventArgs e)
if (config.EnableUSBUnlocking && config.privateKey != null)
File.WriteAllText(MLOCK_DIR + "\\publicKey.xml", RSAUtils.GetPublicKey(config.privateKey));
+
+ // Make Config file only readable by admins
+ FileSecurity fileSecurity = File.GetAccessControl(MLOCK_DIR);
+ fileSecurity.SetAccessRuleProtection(true, false);
+ FileSystemAccessRule rule = new FileSystemAccessRule("Administrators", FileSystemRights.FullControl, AccessControlType.Allow);
+ fileSecurity.AddAccessRule(rule);
+ File.SetAccessControl(MLOCK_DIR, fileSecurity);
+
MessageBox.Show("Config installed successfully");
}
}
@@ -142,7 +151,13 @@ public bool ValidateConfig()
return false;
}
- if (!config.EnablePasswordUnlocking && !config.EnableUSBUnlocking)
+ if (Config.INSTANCE.EnableWebServer && Config.INSTANCE.WebServerPassword.Trim() == "")
+ {
+ MessageBox.Show("WebServer password not set");
+ return false;
+ }
+
+ if (!config.EnablePasswordUnlocking && !config.EnableUSBUnlocking && !config.EnableWebServer)
{
MessageBox.Show("No unlocking methods enabled, select one first");
return false;
diff --git a/MLockConfigurator/Utils.cs b/MLockConfigurator/Utils.cs
index 61c7a9c..92090a4 100644
--- a/MLockConfigurator/Utils.cs
+++ b/MLockConfigurator/Utils.cs
@@ -39,17 +39,13 @@ public static bool IsTaskInstalled()
return TaskService.Instance.RootFolder.Tasks.Any(task => task.Name == "MLockTask");
}
- public static void InstallTask()
+ public static bool IsAdmin()
{
- var isAdmin = new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
-
- if (!isAdmin)
- {
- MessageBox.Show("To Install task, please run Configurator as admin");
- // Instead of this I can make it start a CMD process as admin and copy file but better do in code i think
- return;
- }
+ return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
+ }
+ public static void InstallTask()
+ {
var td = TaskService.Instance.NewTask();
td.RegistrationInfo.Description = "Starts MLock";
td.Principal.RunLevel = TaskRunLevel.Highest;
diff --git a/README.md b/README.md
index 7a394e3..e8527de 100644
--- a/README.md
+++ b/README.md
@@ -23,10 +23,14 @@ https://github.com/mantikafasi/MLock/assets/67705577/7440eb07-5159-47ea-a202-524
Incase you get locked out, from different account with admin permissions you can delete config.json inside C:/Users/YourUser/AppData/Roaming/MLock
+## Notes
+- Currently passwords are stored as plaintext in config.json, so any user with admin permissions can see your password.
+- WebServer doesnt use https, so if someone is sniffing your network they can see your password.
+
## TODO
-- [ ] Add more unlock methods (Like from mobile app)
-- [ ] Design a better UI (current one is terrible)
-- [ ] Add option to configurator to run program at startup
+- [x] Add more unlock methods (Like from mobile app)
+- [x] Design a better UI (current one is terrible)
+- [x] Add option to configurator to run program at startup
- [ ] Add github actions to create releases automatically
- [ ] Maybe add option to remove sound when locked
- [ ] Log Failures to file