Skip to content

Commit

Permalink
Added new Cert Manager functionality and Removed depedency on Azure s…
Browse files Browse the repository at this point in the history
…torage. Also made publishednodes file handling more fualt tolerant and added ability to store encrypted password in publishednodes.json.
  • Loading branch information
barnstee committed Oct 7, 2024
1 parent 8ccad85 commit 6e09a19
Show file tree
Hide file tree
Showing 21 changed files with 213 additions and 655 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -354,3 +354,4 @@ MigrationBackup/
/pki
/store
/trustlist.zip
/customclientcert
164 changes: 0 additions & 164 deletions AzureFileStorage.cs

This file was deleted.

37 changes: 31 additions & 6 deletions Controllers/CertManagerController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ namespace Opc.Ua.Cloud.Publisher.Controllers
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.Extensions.Logging;
using Opc.Ua.Cloud.Publisher.Interfaces;
using Opc.Ua.Cloud.Publisher.Models;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

Expand All @@ -27,10 +30,10 @@ public CertManagerController(IUAApplication app, ILoggerFactory loggerFactory)

public IActionResult Index()
{
return LoadTrustlist();
return View("Index", new CertManagerModel() { Certs = new SelectList(LoadTrustlist()) });
}

private IActionResult LoadTrustlist()
private List<string> LoadTrustlist()
{
List<string> trustList = new();
CertificateTrustList ownTrustList = _app.UAApplicationInstance.ApplicationConfiguration.SecurityConfiguration.TrustedPeerCertificates;
Expand All @@ -39,7 +42,7 @@ private IActionResult LoadTrustlist()
trustList.Add(cert.Subject + " [" + cert.Thumbprint + "] ");
}

return View("Index", new SelectList(trustList));
return trustList;
}

[HttpPost]
Expand Down Expand Up @@ -68,12 +71,12 @@ public async Task<IActionResult> Load(IFormFile file)
// store in our own trust list
await _app.UAApplicationInstance.AddOwnCertificateToTrustedStoreAsync(certificate, CancellationToken.None).ConfigureAwait(false);

return LoadTrustlist();
return View("Index", new CertManagerModel() { Certs = new SelectList(LoadTrustlist()) });
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return View("Index", new SelectList(new List<string>() { ex.Message }));
return View("Index", new CertManagerModel() { Certs = new SelectList(new List<string>() { ex.Message }) });
}
}

Expand All @@ -97,7 +100,29 @@ public ActionResult DownloadTrustlist()
catch (Exception ex)
{
_logger.LogError(ex.Message);
return View("Index", new SelectList(new List<string>() { ex.Message }));
return View("Index", new CertManagerModel() { Certs = new SelectList(new List<string>() { ex.Message }) });
}
}
[HttpPost]
public ActionResult EncryptString(string plainTextString)
{
try
{
X509Certificate2 cert = _app.IssuerCert;
using RSA rsa = cert.GetRSAPublicKey();
if (!string.IsNullOrEmpty(plainTextString) && (rsa != null))
{
return View("Index", new CertManagerModel() { Encrypt = Convert.ToBase64String(rsa.Encrypt(Encoding.UTF8.GetBytes(plainTextString), RSAEncryptionPadding.Pkcs1)), Certs = new SelectList(LoadTrustlist()) });
}
else
{
throw new Exception("Encryption failed");
}
}
catch (Exception ex)
{
_logger.LogError(ex.Message);
return View("Index", new CertManagerModel() { Certs = new SelectList(new List<string>() { ex.Message }) });
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions Controllers/ConfigController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,13 @@ public async Task<ActionResult> LocalCertOpen(IFormFile file)

// update cert file hash and expiry
X509Certificate2 cert = new X509Certificate2(filePath);
Settings.Instance.UACertThumbprint = cert.Thumbprint;
Settings.Instance.UACertExpiry = cert.NotAfter;
Settings.Instance.MQTTClientCertThumbprint = cert.Thumbprint;
Settings.Instance.MQTTClientCertExpiry = cert.NotAfter;
}
catch (Exception ex)
{
Settings.Instance.UACertThumbprint = ex.Message;
Settings.Instance.UACertExpiry = DateTime.MinValue;
Settings.Instance.MQTTClientCertThumbprint = ex.Message;
Settings.Instance.MQTTClientCertExpiry = DateTime.MinValue;
}

return View("Index", Settings.Instance);
Expand Down
17 changes: 6 additions & 11 deletions Controllers/PublishedController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,22 @@ namespace Opc.Ua.Cloud.Publisher.Controllers
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;

public class PublishedController : Controller
{
private readonly ILogger _logger;
private readonly IPublishedNodesFileHandler _publishedNodesFileHandler;
private readonly IUAClient _uaclient;
private readonly IFileStorage _storage;

public PublishedController(
ILoggerFactory loggerFactory,
IPublishedNodesFileHandler publishedNodesFileHandler,
IUAClient client,
IFileStorage storage)
IUAClient client)
{
_logger = loggerFactory.CreateLogger("PublishedController");
_publishedNodesFileHandler = publishedNodesFileHandler;
_uaclient = client;
_storage = storage;
}

public IActionResult Index()
Expand Down Expand Up @@ -89,25 +87,22 @@ public IActionResult LoadPersisted()
{
try
{
string persistencyFilePath = _storage.FindFileAsync(Path.Combine(Directory.GetCurrentDirectory(), "settings"), "persistency.json").GetAwaiter().GetResult();
byte[] persistencyFile = _storage.LoadFileAsync(persistencyFilePath).GetAwaiter().GetResult();
byte[] persistencyFile = System.IO.File.ReadAllBytes(Path.Combine(Directory.GetCurrentDirectory(), "settings", "persistency.json"));
if (persistencyFile == null)
{
// no file persisted yet
_logger.LogInformation("Persistency file not found.");
throw new Exception("Persistency file not found.");
}
else
{
_logger.LogInformation($"Parsing persistency file...");
_publishedNodesFileHandler.ParseFile(persistencyFile);
_logger.LogInformation("Persistency file parsed successfully.");
_ = Task.Run(() => _publishedNodesFileHandler.ParseFile(persistencyFile));
}

return View("Index", GeneratePublishedNodesArray());
}
catch (Exception ex)
{
_logger.LogError(ex, "Persistency file not loaded!");
_logger.LogError(ex.Message);
return View("Index", new string[] { "Error: " + ex.Message });
}
}
Expand Down
3 changes: 0 additions & 3 deletions Diagnostics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ private void Clear()
{
Info.PublisherStartTime = DateTime.UtcNow;
Info.ConnectedToBroker = false;
Info.ConnectedToCloudStorage = false;
Info.NumberOfOpcSessionsConnected = 0;
Info.NumberOfOpcSubscriptionsConnected = 0;
Info.NumberOfOpcMonitoredItemsMonitored = 0;
Expand Down Expand Up @@ -98,7 +97,6 @@ public async Task RunAsync(CancellationToken cancellationToken = default)

_hubClient.AddOrUpdateTableEntry("Publisher Start Time", Info.PublisherStartTime.ToString());
_hubClient.AddOrUpdateTableEntry("Connected to broker(s)", Info.ConnectedToBroker.ToString());
_hubClient.AddOrUpdateTableEntry("Connected to cloud storage/OneLake", Info.ConnectedToCloudStorage.ToString());
_hubClient.AddOrUpdateTableEntry("OPC UA sessions", Info.NumberOfOpcSessionsConnected.ToString());
_hubClient.AddOrUpdateTableEntry("OPC UA subscriptions", Info.NumberOfOpcSubscriptionsConnected.ToString());
_hubClient.AddOrUpdateTableEntry("OPC UA monitored items", Info.NumberOfOpcMonitoredItemsMonitored.ToString());
Expand Down Expand Up @@ -131,7 +129,6 @@ public async Task RunAsync(CancellationToken cancellationToken = default)
if (ticks % 10 == 0)
{
DiagnosticsSend("ConnectedToBroker", new DataValue(Info.ConnectedToBroker));
DiagnosticsSend("ConnectedToCloudStorage", new DataValue(Info.ConnectedToCloudStorage));
DiagnosticsSend("NumOpcSessions", new DataValue(Info.NumberOfOpcSessionsConnected));
DiagnosticsSend("NumOpcSubscriptions", new DataValue(Info.NumberOfOpcSubscriptionsConnected));
DiagnosticsSend("NumOpcMonitoredItems", new DataValue(Info.NumberOfOpcMonitoredItemsMonitored));
Expand Down
15 changes: 0 additions & 15 deletions Interfaces/IFileStorage.cs

This file was deleted.

Loading

0 comments on commit 6e09a19

Please sign in to comment.