Skip to content

Commit d94b167

Browse files
committed
Add [yet untested] code skeleton for secure settings
1 parent 38f323f commit d94b167

7 files changed

Lines changed: 242 additions & 8 deletions

File tree

cli-arguments.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
| `--help` | Opens this page | 3.2.0+ |
1313
| `--import-settings file` | Imports UniGetUI settings from json file _file_. The file must exist. The old settings will be lost* | 3.2.0+ |
1414
| `--export-settings file` | Exports UniGetUI settings to json file _file_. The file will be created or overwritten* | 3.2.0+ |
15-
| `--enable-setting key` | Enables the boolean setting _key_* | 3.2.0+ |
16-
| `--disable-setting key` | Disables the boolean setting _key_* | 3.2.0+ |
15+
| `--[enable\|disable]-setting key` | Enables/disables the boolean setting _key_* | 3.2.0+ |
1716
| `--set-setting-value key value` | Sets the value _value_ to the non-boolean setting _key_. To clear a non-boolean setting, `--disable-setting` can be used* | 3.2.0+ |
1817
| `--no-corrupt-dialog` | Will show a verbose error message (the error report) instead of a simplified message dialog | 3.2.1+ |
18+
| `--[enable\|disable]-secure-setting-for-user username key` | Enables/disables the given secure setting for the given username. Requires administrator rights. | 3.2.1+ |
19+
| `--[enable\|disable]-secure-setting key` | Enables/disables the given secure setting for current user. This will generate a UAC prompt | 3.2.1+ |
1920

2021

2122
\*After modifying the settings, you must ensure that any running instance of UniGetUI is restarted for the changes to take effect
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using System.Diagnostics;
2+
using UniGetUI.Core.Data;
3+
using UniGetUI.Core.Tools;
4+
5+
namespace UniGetUI.Core.SettingsEngine.SecureSettings;
6+
7+
public static class SecureSettings
8+
{
9+
public static class Args
10+
{
11+
public const string ENABLE_FOR_USER = "--enable-secure-setting-for-user";
12+
public const string DISABLE_FOR_USER = "--disable-secure-setting-for-user";
13+
}
14+
15+
public static bool Get(string setting)
16+
{
17+
string purifiedUser = CoreTools.MakeValidFileName(Environment.UserName);
18+
string purifiedSetting = CoreTools.MakeValidFileName(setting);
19+
20+
var appData = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
21+
var settingsLocation = Path.Join(appData, "UniGetUI\\SecureSettings", purifiedUser);
22+
var settingFile = Path.Join(settingsLocation, purifiedSetting);
23+
24+
if (!Directory.Exists(settingsLocation))
25+
return false;
26+
27+
return File.Exists(settingFile);
28+
}
29+
30+
public static async Task<bool> TrySet(string setting, bool enabled)
31+
{
32+
string purifiedUser = CoreTools.MakeValidFileName(Environment.UserName);
33+
string purifiedSetting = CoreTools.MakeValidFileName(setting);
34+
35+
using Process p = new Process();
36+
p.StartInfo = new()
37+
{
38+
UseShellExecute = false,
39+
CreateNoWindow = true,
40+
FileName = CoreData.UniGetUIExecutableFile,
41+
ArgumentList =
42+
{
43+
enabled? Args.ENABLE_FOR_USER: Args.DISABLE_FOR_USER,
44+
purifiedUser,
45+
purifiedSetting
46+
}
47+
};
48+
49+
p.Start();
50+
await p.WaitForExitAsync();
51+
return p.ExitCode is 0;
52+
}
53+
54+
public static int ApplyForUser(string username, string setting, bool enable)
55+
{
56+
try
57+
{
58+
string purifiedUser = CoreTools.MakeValidFileName(username);
59+
string purifiedSetting = CoreTools.MakeValidFileName(setting);
60+
61+
var appData = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
62+
var settingsLocation = Path.Join(appData, "UniGetUI\\SecureSettings", purifiedUser);
63+
var settingFile = Path.Join(settingsLocation, purifiedSetting);
64+
65+
if (!Directory.Exists(settingsLocation))
66+
{
67+
Directory.CreateDirectory(settingsLocation);
68+
}
69+
70+
if (enable)
71+
{
72+
File.WriteAllText(settingFile, "");
73+
}
74+
else
75+
{
76+
if (File.Exists(settingFile))
77+
{
78+
File.Delete(settingFile);
79+
}
80+
}
81+
82+
return 0;
83+
}
84+
catch (Exception ex)
85+
{
86+
Console.WriteLine(ex);
87+
return -1;
88+
}
89+
}
90+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<ItemGroup>
3+
<ProjectReference Include="..\UniGetUI.Core.Data\UniGetUI.Core.Tools.csproj" />
4+
<ProjectReference Include="..\UniGetUI.Core.Tools\UniGetUI.Core.Tools.csproj" />
5+
</ItemGroup>
6+
7+
<ItemGroup>
8+
<Compile Include="..\SharedAssemblyInfo.cs" Link="SharedAssemblyInfo.cs" />
9+
</ItemGroup>
10+
</Project>

src/UniGetUI.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{015B44EE
105105
EndProject
106106
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniGetUI.PackageEngine.Serializable.Tests", "UniGetUI.PackageEngine.Serializable.Tests\UniGetUI.PackageEngine.Serializable.Tests.csproj", "{F1610A61-5444-4C11-9447-13CCA327887E}"
107107
EndProject
108+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UniGetUI.Core.SecureSettings", "UniGetUI.Core.SecureSettings\UniGetUI.Core.SecureSettings.csproj", "{B0E59327-933E-4DB0-BD2D-FB16EB9B4194}"
109+
EndProject
108110
Global
109111
GlobalSection(SolutionConfigurationPlatforms) = preSolution
110112
Debug|x64 = Debug|x64
@@ -271,6 +273,10 @@ Global
271273
{F1610A61-5444-4C11-9447-13CCA327887E}.Debug|x64.Build.0 = Debug|x64
272274
{F1610A61-5444-4C11-9447-13CCA327887E}.Release|x64.ActiveCfg = Release|x64
273275
{F1610A61-5444-4C11-9447-13CCA327887E}.Release|x64.Build.0 = Release|x64
276+
{B0E59327-933E-4DB0-BD2D-FB16EB9B4194}.Debug|x64.ActiveCfg = Debug|x64
277+
{B0E59327-933E-4DB0-BD2D-FB16EB9B4194}.Debug|x64.Build.0 = Debug|x64
278+
{B0E59327-933E-4DB0-BD2D-FB16EB9B4194}.Release|x64.ActiveCfg = Release|x64
279+
{B0E59327-933E-4DB0-BD2D-FB16EB9B4194}.Release|x64.Build.0 = Release|x64
274280
EndGlobalSection
275281
GlobalSection(SolutionProperties) = preSolution
276282
HideSolutionNode = FALSE
@@ -319,6 +325,7 @@ Global
319325
{3C8BF564-B4B5-44A7-9D8C-102C2F820EAF} = {8CF74C87-534F-4017-A4ED-F2918025E31A}
320326
{015B44EE-32AE-4105-9016-49140743CAF9} = {7940E867-EEBA-4AFD-9904-1536F003239C}
321327
{F1610A61-5444-4C11-9447-13CCA327887E} = {015B44EE-32AE-4105-9016-49140743CAF9}
328+
{B0E59327-933E-4DB0-BD2D-FB16EB9B4194} = {E05D1183-D360-4AFE-8968-314A34FAD3B2}
322329
EndGlobalSection
323330
GlobalSection(ExtensibilityGlobals) = postSolution
324331
SolutionGuid = {D044BB14-0B37-47E5-A579-8B30FCBA1F9F}

src/UniGetUI/CLIHandler.cs

Lines changed: 111 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using UniGetUI.Core.Logging;
22
using UniGetUI.Core.SettingsEngine;
3+
using UniGetUI.Core.SettingsEngine.SecureSettings;
34

45
namespace UniGetUI;
56

@@ -19,10 +20,16 @@ public static class CLIHandler
1920
public const string DISABLE_SETTING = "--disable-setting";
2021
public const string SET_SETTING_VAL = "--set-setting-value";
2122

23+
public const string ENABLE_SECURE_SETTING = "--enable-secure-setting";
24+
public const string DISABLE_SECURE_SETTING = "--disable-secure-setting";
25+
public const string ENABLE_SECURE_SETTING_FOR_USER = SecureSettings.Args.ENABLE_FOR_USER;
26+
public const string DISABLE_SECURE_SETTING_FOR_USER = SecureSettings.Args.DISABLE_FOR_USER;
27+
2228

2329
private enum HRESULT
2430
{
25-
SUCCESS = 0x00000000,
31+
SUCCESS = 0,
32+
STATUS_FAILED = -1,
2633
STATUS_INVALID_PARAMETER = -1073741811,
2734
STATUS_NO_SUCH_FILE = -1073741809,
2835
}
@@ -48,7 +55,7 @@ public static int ImportSettings()
4855
if (filePos +1 >= args.Count)
4956
return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (import settings requires "--import-settings file")
5057

51-
var file = args[filePos + 1].Replace("\"", "").Replace("\'", "");
58+
var file = args[filePos + 1].Trim('"').Trim('\'');
5259
if (!File.Exists(file))
5360
return (int)HRESULT.STATUS_NO_SUCH_FILE; // The given file does not exist
5461

@@ -75,7 +82,7 @@ public static int ExportSettings()
7582
if (filePos +1 >= args.Count)
7683
return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file")
7784

78-
var file = args[filePos + 1].Replace("\"", "").Replace("\'", "");
85+
var file = args[filePos + 1].Trim('"').Trim('\'');
7986

8087
try
8188
{
@@ -100,7 +107,7 @@ public static int EnableSetting()
100107
if (basePos +1 >= args.Count)
101108
return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file")
102109

103-
var setting = args[basePos + 1].Replace("\"", "").Replace("\'", "");
110+
var setting = args[basePos + 1].Trim('"').Trim('\'');
104111

105112
try
106113
{
@@ -125,7 +132,7 @@ public static int DisableSetting()
125132
if (basePos +1 >= args.Count)
126133
return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file")
127134

128-
var setting = args[basePos + 1].Replace("\"", "").Replace("\'", "");
135+
var setting = args[basePos + 1].Trim('"').Trim('\'');
129136

130137
try
131138
{
@@ -150,7 +157,7 @@ public static int SetSettingsValue()
150157
if (basePos +2 >= args.Count)
151158
return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file")
152159

153-
var setting = args[basePos + 1].Replace("\"", "").Replace("\'", "");
160+
var setting = args[basePos + 1].Trim('"').Trim('\'');
154161
var value = args[basePos + 2];
155162

156163
try
@@ -230,4 +237,102 @@ public static int UninstallUniGetUI()
230237
// There is currently no uninstall logic. However, this needs to be maintained, or otherwhise UniGetUI will launch on uninstall
231238
return 0;
232239
}
240+
241+
public static int EnableSecureSetting()
242+
{
243+
var args = Environment.GetCommandLineArgs().ToList();
244+
245+
var basePos = args.IndexOf(ENABLE_SECURE_SETTING);
246+
if (basePos < 0)
247+
return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater was not found
248+
249+
if (basePos +1 >= args.Count)
250+
return (int)HRESULT.STATUS_INVALID_PARAMETER; // The file parameter does not exist (export settings requires "--export-settings file")
251+
252+
var setting = args[basePos + 1].Trim('"').Trim('\'');
253+
254+
try
255+
{
256+
bool success = SecureSettings.TrySet(setting, true).GetAwaiter().GetResult();
257+
if (!success) return (int)HRESULT.STATUS_FAILED;
258+
else return (int)HRESULT.SUCCESS;
259+
}
260+
catch (Exception ex)
261+
{
262+
return ex.HResult;
263+
}
264+
}
265+
266+
public static int DisableSecureSetting()
267+
{
268+
var args = Environment.GetCommandLineArgs().ToList();
269+
270+
var basePos = args.IndexOf(DISABLE_SECURE_SETTING);
271+
if (basePos < 0)
272+
return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater was not found
273+
274+
if (basePos +1 >= args.Count)
275+
return (int)HRESULT.STATUS_INVALID_PARAMETER; // The first positional argument does not exist
276+
277+
var setting = args[basePos + 1].Trim('"').Trim('\'');
278+
279+
try
280+
{
281+
bool success = SecureSettings.TrySet(setting, false).GetAwaiter().GetResult();
282+
if (!success) return (int)HRESULT.STATUS_FAILED;
283+
else return (int)HRESULT.SUCCESS;
284+
}
285+
catch (Exception ex)
286+
{
287+
return ex.HResult;
288+
}
289+
}
290+
291+
public static int EnableSecureSettingForUser()
292+
{
293+
var args = Environment.GetCommandLineArgs().ToList();
294+
295+
var basePos = args.IndexOf(ENABLE_SECURE_SETTING);
296+
if (basePos < 0)
297+
return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater was not found
298+
299+
if (basePos +2 >= args.Count)
300+
return (int)HRESULT.STATUS_INVALID_PARAMETER; // The required parameters do not exist
301+
302+
var user = args[basePos + 1].Trim('"').Trim('\'');
303+
var setting = args[basePos + 2].Trim('"').Trim('\'');
304+
305+
try
306+
{
307+
return SecureSettings.ApplyForUser(user, setting, true);
308+
}
309+
catch (Exception ex)
310+
{
311+
return ex.HResult;
312+
}
313+
}
314+
315+
public static int DisableSecureSettingForUser()
316+
{
317+
var args = Environment.GetCommandLineArgs().ToList();
318+
319+
var basePos = args.IndexOf(ENABLE_SECURE_SETTING);
320+
if (basePos < 0)
321+
return (int)HRESULT.STATUS_INVALID_PARAMETER; // The base paramater was not found
322+
323+
if (basePos +2 >= args.Count)
324+
return (int)HRESULT.STATUS_INVALID_PARAMETER; // The required parameters do not exist
325+
326+
var user = args[basePos + 1].Trim('"').Trim('\'');
327+
var setting = args[basePos + 2].Trim('"').Trim('\'');
328+
329+
try
330+
{
331+
return SecureSettings.ApplyForUser(user, setting, false);
332+
}
333+
catch (Exception ex)
334+
{
335+
return ex.HResult;
336+
}
337+
}
233338
}

src/UniGetUI/EntryPoint.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,26 @@ private static void Main(string[] args)
5555
int ret = CLIHandler.SetSettingsValue();
5656
Environment.Exit(ret);
5757
}
58+
else if (args.Contains(CLIHandler.ENABLE_SECURE_SETTING))
59+
{
60+
int ret = CLIHandler.EnableSecureSetting();
61+
Environment.Exit(ret);
62+
}
63+
else if (args.Contains(CLIHandler.DISABLE_SECURE_SETTING))
64+
{
65+
int ret = CLIHandler.DisableSecureSetting();
66+
Environment.Exit(ret);
67+
}
68+
else if (args.Contains(CLIHandler.ENABLE_SECURE_SETTING_FOR_USER))
69+
{
70+
int ret = CLIHandler.EnableSecureSettingForUser();
71+
Environment.Exit(ret);
72+
}
73+
else if (args.Contains(CLIHandler.DISABLE_SECURE_SETTING_FOR_USER))
74+
{
75+
int ret = CLIHandler.DisableSecureSettingForUser();
76+
Environment.Exit(ret);
77+
}
5878
else
5979
{
6080
CoreData.WasDaemon = CoreData.IsDaemon = args.Contains(CLIHandler.DAEMON);

src/UniGetUI/UniGetUI.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@
270270
<ProjectReference Include="..\UniGetUI.Core.IconStore\UniGetUI.Core.IconEngine.csproj" />
271271
<ProjectReference Include="..\UniGetUI.Core.LanguageEngine\UniGetUI.Core.LanguageEngine.csproj" />
272272
<ProjectReference Include="..\UniGetUI.Core.Logger\UniGetUI.Core.Logging.csproj" />
273+
<ProjectReference Include="..\UniGetUI.Core.SecureSettings\UniGetUI.Core.SecureSettings.csproj" />
273274
<ProjectReference Include="..\UniGetUI.Core.Settings\UniGetUI.Core.Settings.csproj" />
274275
<ProjectReference Include="..\UniGetUI.Core.Tools\UniGetUI.Core.Tools.csproj" />
275276
<ProjectReference Include="..\UniGetUI.Interface.BackgroundApi\UniGetUI.Interface.BackgroundApi.csproj" />

0 commit comments

Comments
 (0)