Skip to content

Commit

Permalink
Merge pull request #219 from Blazam-App/SSL-Cert
Browse files Browse the repository at this point in the history
Service SSL Certificate Implementation
  • Loading branch information
jacobsen9026 committed Feb 11, 2024
2 parents 91d44f3 + 8bb9296 commit c60dc79
Show file tree
Hide file tree
Showing 22 changed files with 345 additions and 145 deletions.
4 changes: 2 additions & 2 deletions BLAZAM/App.razor
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@
base.OnInitialized();
try
{
var userTheme = currentUser.State.Preferences?.Theme;
var userTheme = currentUser.State?.Preferences?.Theme;
switch (userTheme)
{
case "Blue":
Expand All @@ -85,7 +85,7 @@


}
darkMode = currentUser.State.Preferences?.DarkMode == true;
darkMode = currentUser.State?.Preferences?.DarkMode == true;
}
catch(Exception ex)
{
Expand Down
2 changes: 1 addition & 1 deletion BLAZAM/BLAZAM.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<ServerGarbageCollection>false</ServerGarbageCollection>
<AssemblyVersion>0.8.8</AssemblyVersion>
<Version>2024.02.10.2119</Version>
<Version>2024.02.11.1907</Version>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<RootNamespace>BLAZAM</RootNamespace>
<GenerateDocumentationFile>False</GenerateDocumentationFile>
Expand Down
26 changes: 22 additions & 4 deletions BLAZAM/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
using System.Net;
using BLAZAM.Database.Context;
using System.Diagnostics;
using System.Security.Cryptography.X509Certificates;
using System.Net.WebSockets;
using BLAZAM.Database.Models;

namespace BLAZAM
{
Expand Down Expand Up @@ -78,6 +81,7 @@ public static void Main(string[] args)

builder.IntializeProperties();

_ = new Encryption(Configuration.GetValue<string>("EncryptionKey"));

//Setup host logging so it can catch the earliest logs possible

Expand Down Expand Up @@ -170,16 +174,30 @@ private static void SetupKestrel(WebApplicationBuilder builder)
var listeningAddress = Configuration.GetValue<string>("ListeningAddress");
var httpPort = Configuration.GetValue<int>("HTTPPort");
var httpsPort = Configuration.GetValue<int>("HTTPSPort");
AppSettings? dbSettings=null;
X509Certificate2? cert = null;
try
{
dbSettings = kestrelContext.AppSettings.FirstOrDefault();

var certBytes = dbSettings.SSLCertificateCipher.Decrypt<byte[]>();
cert = new X509Certificate2(certBytes);

}
catch (Exception ex)
{
Loggers.SystemLogger.Error("Error collecting SSL information {@Error}", ex);
}
builder.WebHost.UseKestrel(options =>
{
if (listeningAddress == "*")
{
options.ListenAnyIP(httpPort);
if (httpsPort != 0 && kestrelContext.AppSettings.FirstOrDefault()?.AppFQDN=="gsdfgfds")
if (httpsPort != 0 && dbSettings!=null && cert!=null && cert.HasPrivateKey)
{
options.ListenAnyIP(httpsPort, configure =>
{
configure.UseHttps();
configure.UseHttps(options=>options.ServerCertificate=cert);
});
}
}
Expand All @@ -189,11 +207,11 @@ private static void SetupKestrel(WebApplicationBuilder builder)
var ip = IPAddress.Parse(listeningAddress);
options.Listen(ip, httpPort);
if (httpsPort != 0 && kestrelContext.AppSettings.FirstOrDefault()?.AppFQDN == "gsdfgfds")
if (httpsPort != 0 && dbSettings != null && cert != null && cert.HasPrivateKey)
{
options.Listen(ip, httpsPort, configure =>
{
configure.UseHttps();
configure.UseHttps(options => options.ServerCertificate = cert);
});
}
}
Expand Down
146 changes: 89 additions & 57 deletions BLAZAMCommon/Data/WindowsImpersonation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,61 @@ namespace BLAZAM.Common.Data
{
public class WindowsImpersonation
{
static SafeAccessTokenHandle safeAccessTokenHandle;
SafeAccessTokenHandle safeAccessTokenHandle;

static WindowsImpersonationUser impersonationUser;
WindowsImpersonationUser impersonationUser;
private readonly WindowsIdentity ApplicationIdentity;


public static SafeAccessTokenHandle ImpersonatedToken
public SafeAccessTokenHandle ImpersonatedToken
{
get
{
//Use interactive logon

bool returnValue = LogonUser(impersonationUser.Username, impersonationUser.FQDN!=null?impersonationUser.FQDN:"", impersonationUser.Password.ToPlainText(),
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
out safeAccessTokenHandle);




if (false == returnValue)
var domain = impersonationUser.FQDN != null ? impersonationUser.FQDN : "";
var username = impersonationUser.Username;
var phPassword = Marshal.SecureStringToGlobalAllocUnicode(impersonationUser.Password);
bool returnValue = LogonUser(username,
domain,
phPassword,
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
out safeAccessTokenHandle);



Marshal.ZeroFreeGlobalAllocUnicode(phPassword);
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
Loggers.ActiveDirectryLogger.Warning("LogonUser failed with error code : {0}", ret);
var exception = new System.ComponentModel.Win32Exception(ret);
if (exception.NativeErrorCode == 1326)
{
int ret = Marshal.GetLastWin32Error();
Loggers.ActiveDirectryLogger.Warning("LogonUser failed with error code : {0}", ret);
var exception = new System.ComponentModel.Win32Exception(ret);
if (exception.NativeErrorCode == 1326)
{

throw new AuthenticationException(exception.Message);
}

throw new AuthenticationException(exception.Message);
}
}
return safeAccessTokenHandle;

}
}


const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_BATCH = 4;
const int LOGON32_LOGON_SERVICE = 5;
const int LOGON32_LOGON_UNLOCK = 7;
const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT50 = 3;
//This parameter causes LogonUser to create a primary token.
const int LOGON32_LOGON_INTERACTIVE = 2;

const int LOGON32_LOGON_NETWORK = 9;


[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool LogonUser(string lpszUsername, string lpszDomain, string lpszPassword,
public static extern bool LogonUser(string lpszUsername, string lpszDomain, IntPtr lpszPassword,
int dwLogonType, int dwLogonProvider, out SafeAccessTokenHandle phToken);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
Expand All @@ -61,75 +73,95 @@ public static SafeAccessTokenHandle ImpersonatedToken
public WindowsImpersonation(WindowsImpersonationUser user)
{
impersonationUser = user;
ApplicationIdentity = WindowsIdentity.GetCurrent();
}
public async Task<T?> RunAsync<T>(Func<T> task) => await Task.Run(() => Run<T>(task));
public T? Run<T>(Func<T> task)
{


T? result = default;

try
{
var impersonatedToken = ImpersonatedToken;
if (impersonatedToken == null || impersonatedToken.IsInvalid) throw new ApplicationException("The impersonation user is invalid. Check settings.");


if (impersonatedToken == null) throw new ApplicationException("The impersonation user is invalid. Check settings.");

//Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
// Check the identity.
Loggers.ActiveDirectryLogger.Information("Before impersonation: " + WindowsIdentity.GetCurrent().Name);


try
{

WindowsIdentity.RunImpersonated(
impersonatedToken,
() =>
{
// Check the identity.
Loggers.ActiveDirectryLogger.Information("During impersonation: " + WindowsIdentity.GetCurrent().Name);
result = task.Invoke();
}
);
WindowsIdentity.RunImpersonated(
impersonatedToken,
() =>
{
// Check the identity.
var impersonatedIdentity = WindowsIdentity.GetCurrent();
if (impersonatedIdentity.Name.Equals(ApplicationIdentity.Name))
{
Loggers.ActiveDirectryLogger.Error("Impersonation running as application identity");
}
Loggers.ActiveDirectryLogger.Information("During impersonation: " + WindowsIdentity.GetCurrent().Name);
result = task.Invoke();
}
);

}
catch (Exception ex)
{
Loggers.ActiveDirectryLogger.Error("Error running impersonated action " + impersonationUser.Username + " {@Error}", ex);
}
finally
{
impersonatedToken?.Close();
}
}
catch (Exception ex)
{
Loggers.ActiveDirectryLogger.Error("Error trying to impersonate " + impersonationUser.Username + " {@Error}", ex);
}

return result;
}
public async Task<string> RunProcess(string processPath, string arguments)
{


var output = "";
try {

var process = new Process
var output = "";
try
{
StartInfo = new ProcessStartInfo

var process = new Process
{
WorkingDirectory = "C:\\",
FileName = processPath,
Arguments = arguments,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
LoadUserProfile = true,
UserName = impersonationUser?.Username,
Domain = impersonationUser?.FQDN,
Password = impersonationUser?.Password,
}
StartInfo = new ProcessStartInfo
{
WorkingDirectory = "C:\\",
FileName = processPath,
Arguments = arguments,
RedirectStandardOutput = true,
UseShellExecute = false,
CreateNoWindow = true,
LoadUserProfile = true,
UserName = impersonationUser?.Username,
Domain = impersonationUser?.FQDN,
Password = impersonationUser?.Password,
}

};
};




process.Start();
process.Start();

// Reading the standard output stream of the process
output = await process.StandardOutput.ReadToEndAsync();
process.WaitForExit();
// Reading the standard output stream of the process
output = await process.StandardOutput.ReadToEndAsync();
process.WaitForExit();


}
Expand Down
6 changes: 5 additions & 1 deletion BLAZAMCommon/Helpers/EncryptionHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ namespace BLAZAM.Helpers
{
public static class EncryptionHelpers
{

public static T Decrypt<T>(this string input)
{
var str = Encryption.Instance.DecryptObject<T>(input);
return str == null ? default : str;

Check warning on line 15 in BLAZAMCommon/Helpers/EncryptionHelpers.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference return.

Check warning on line 15 in BLAZAMCommon/Helpers/EncryptionHelpers.cs

View workflow job for this annotation

GitHub Actions / build

Possible null reference return.
}
public static string Decrypt(this string input)
{
var str= Encryption.Instance.DecryptObject<string>(input);
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
name: "SSLCertificateCipher",
table: "AppSettings",
type: "longtext",
nullable: false)
nullable: true)
.Annotation("MySql:CharSet", "utf8mb4");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,6 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasColumnType("longtext");
b.Property<string>("SSLCertificateCipher")
.IsRequired()
.HasColumnType("longtext");
b.Property<string>("UpdateBranch")
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@ protected override void Up(MigrationBuilder migrationBuilder)
name: "SSLCertificateCipher",
table: "AppSettings",
type: "nvarchar(max)",
nullable: false,
defaultValue: "");
nullable: true);
}

/// <inheritdoc />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,6 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasColumnType("nvarchar(max)");
b.Property<string>("SSLCertificateCipher")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("UpdateBranch")
Expand Down
Loading

0 comments on commit c60dc79

Please sign in to comment.