mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-26 05:29:43 +00:00
agent production logging
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
@@ -19,11 +21,6 @@ namespace AutopilotMonitor.Agent.Core.Security
|
||||
/// <summary>
|
||||
/// Polls the certificate store until a valid MDM certificate is found or the timeout expires.
|
||||
/// </summary>
|
||||
/// <param name="thumbprint">Optional specific certificate thumbprint to wait for</param>
|
||||
/// <param name="timeoutMinutes">Maximum wait time in minutes (0 = wait indefinitely)</param>
|
||||
/// <param name="logger">Logger for status output</param>
|
||||
/// <param name="cancellationToken">Cancellation token for clean shutdown</param>
|
||||
/// <returns>The MDM certificate, or null if the timeout expired or was cancelled</returns>
|
||||
public static async Task<X509Certificate2> WaitForMdmCertificateAsync(
|
||||
string thumbprint = null,
|
||||
int timeoutMinutes = 480,
|
||||
@@ -39,30 +36,36 @@ namespace AutopilotMonitor.Agent.Core.Security
|
||||
|
||||
while (!cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
// Lightweight check: opens cert store, scans by issuer+EKU, closes — takes milliseconds
|
||||
var cert = CertificateHelper.FindMdmCertificate(thumbprint);
|
||||
var cert = CertificateHelper.FindMdmCertificate(thumbprint, logger);
|
||||
|
||||
if (cert != null && CertificateHelper.IsCertificateValid(cert))
|
||||
if (cert != null)
|
||||
{
|
||||
// No IsCertificateValid check here: freshly provisioned SCEP certs can have
|
||||
// a NotBefore slightly in the future due to clock skew between device and CA.
|
||||
// The cert existing in the store with correct issuer+EKU is sufficient.
|
||||
var elapsed = DateTime.UtcNow - startTime;
|
||||
logger?.Info($"Await-enrollment: MDM certificate found after {FormatElapsed(elapsed)} — Issuer={cert.Issuer}, Thumbprint={cert.Thumbprint}");
|
||||
logger?.Info($"Await-enrollment: MDM certificate found after {FormatElapsed(elapsed)} — " +
|
||||
$"Issuer={cert.Issuer}, Thumbprint={cert.Thumbprint}, " +
|
||||
$"Valid={cert.NotBefore:yyyy-MM-dd HH:mm:ss}..{cert.NotAfter:yyyy-MM-dd HH:mm:ss}");
|
||||
return cert;
|
||||
}
|
||||
|
||||
var totalElapsed = DateTime.UtcNow - startTime;
|
||||
|
||||
// Check timeout
|
||||
if (totalElapsed >= timeout)
|
||||
{
|
||||
logger?.Warning($"Await-enrollment: Timeout after {FormatElapsed(totalElapsed)} — no MDM certificate found");
|
||||
LogCertificateStoreDetails(logger);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Periodic status log (every 1 minute)
|
||||
// Periodic status with cert counts (every 1 minute)
|
||||
if (DateTime.UtcNow - lastLogTime >= LogInterval)
|
||||
{
|
||||
var remaining = timeout - totalElapsed;
|
||||
logger?.Info($"Await-enrollment: Waiting for MDM certificate... (elapsed: {FormatElapsed(totalElapsed)}, remaining: {FormatElapsed(remaining)})");
|
||||
var storeSummary = GetCertificateStoreSummary();
|
||||
logger?.Info($"Await-enrollment: Waiting for MDM certificate... " +
|
||||
$"(elapsed: {FormatElapsed(totalElapsed)}, remaining: {FormatElapsed(remaining)}, {storeSummary})");
|
||||
lastLogTime = DateTime.UtcNow;
|
||||
}
|
||||
|
||||
@@ -80,6 +83,79 @@ namespace AutopilotMonitor.Agent.Core.Security
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a short summary of cert counts per store, e.g. "LocalMachine=2, CurrentUser=0".
|
||||
/// </summary>
|
||||
private static string GetCertificateStoreSummary()
|
||||
{
|
||||
try
|
||||
{
|
||||
int lmCount = 0, cuCount = 0;
|
||||
|
||||
using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
|
||||
{
|
||||
store.Open(OpenFlags.ReadOnly);
|
||||
lmCount = store.Certificates.Count;
|
||||
}
|
||||
|
||||
using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
|
||||
{
|
||||
store.Open(OpenFlags.ReadOnly);
|
||||
cuCount = store.Certificates.Count;
|
||||
}
|
||||
|
||||
return $"certs in store: LM={lmCount}, CU={cuCount}";
|
||||
}
|
||||
catch
|
||||
{
|
||||
return "certs in store: unknown";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Full cert store dump — only on timeout to help diagnose why no MDM cert was matched.
|
||||
/// </summary>
|
||||
private static void LogCertificateStoreDetails(AgentLogger logger)
|
||||
{
|
||||
if (logger == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
var stores = new[]
|
||||
{
|
||||
new { Location = StoreLocation.LocalMachine, Name = StoreName.My },
|
||||
new { Location = StoreLocation.CurrentUser, Name = StoreName.My }
|
||||
};
|
||||
|
||||
foreach (var storeInfo in stores)
|
||||
{
|
||||
using (var store = new X509Store(storeInfo.Name, storeInfo.Location))
|
||||
{
|
||||
store.Open(OpenFlags.ReadOnly);
|
||||
var certs = store.Certificates.OfType<X509Certificate2>().ToList();
|
||||
|
||||
logger.Info($"Await-enrollment: {storeInfo.Location}\\{storeInfo.Name} — {certs.Count} certificate(s):");
|
||||
|
||||
foreach (var cert in certs)
|
||||
{
|
||||
var hasClientAuth = cert.Extensions
|
||||
.OfType<X509EnhancedKeyUsageExtension>()
|
||||
.Any(ext => ext.EnhancedKeyUsages
|
||||
.OfType<Oid>()
|
||||
.Any(oid => oid.Value == "1.3.6.1.5.5.7.3.2"));
|
||||
|
||||
logger.Info($" - Issuer={cert.Issuer}, Thumbprint={cert.Thumbprint}, " +
|
||||
$"ClientAuth={hasClientAuth}, Valid={cert.NotBefore:yyyy-MM-dd}..{cert.NotAfter:yyyy-MM-dd}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Warning($"Await-enrollment: Could not read certificate store: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private static string FormatElapsed(TimeSpan elapsed)
|
||||
{
|
||||
if (elapsed.TotalHours >= 1)
|
||||
|
||||
@@ -1 +1 @@
|
||||
391
|
||||
397
|
||||
|
||||
Reference in New Issue
Block a user