Initial commit: IT Nexus Web-App
This commit is contained in:
195
agent-cs/AgentWorker.cs
Normal file
195
agent-cs/AgentWorker.cs
Normal file
@@ -0,0 +1,195 @@
|
||||
using ITNexusAgent.Models;
|
||||
using ITNexusAgent.Services;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace ITNexusAgent;
|
||||
|
||||
public class AgentWorker
|
||||
{
|
||||
private const string Version = "2.0.0";
|
||||
private const string DataDir = @"C:\ProgramData\IT Nexus Agent";
|
||||
private const string ConfigPath = @"C:\ProgramData\IT Nexus Agent\config.json";
|
||||
private const string StatusPath = @"C:\ProgramData\IT Nexus Agent\status.json";
|
||||
private const string LogPath = @"C:\ProgramData\IT Nexus Agent\agent.log";
|
||||
|
||||
private readonly CancellationToken _ct;
|
||||
private AgentConfig? _config;
|
||||
private ApiService? _api;
|
||||
private NotificationService? _notifier;
|
||||
private string _exePath = "";
|
||||
|
||||
public AgentWorker(CancellationToken ct) => _ct = ct;
|
||||
|
||||
public async Task RunAsync()
|
||||
{
|
||||
_exePath = System.Diagnostics.Process.GetCurrentProcess().MainModule!.FileName;
|
||||
Directory.CreateDirectory(DataDir);
|
||||
|
||||
if (!File.Exists(ConfigPath))
|
||||
{
|
||||
Log("ERROR: config.json nicht gefunden");
|
||||
return;
|
||||
}
|
||||
|
||||
SecureConfigFile(ConfigPath);
|
||||
|
||||
_config = AgentConfig.Load(ConfigPath);
|
||||
_api = new ApiService(_config.ServerUrl, _config.AgentKey);
|
||||
_notifier = new NotificationService(_exePath, DataDir);
|
||||
|
||||
Log($"Agent v{Version} gestartet");
|
||||
|
||||
while (!_ct.IsCancellationRequested)
|
||||
{
|
||||
await RunCycleAsync();
|
||||
await Task.Delay(TimeSpan.FromMinutes(1), _ct).ContinueWith(_ => { });
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RunCycleAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
Log("Sammle Systemdaten...");
|
||||
var payload = CollectData();
|
||||
var response = await _api!.CheckinAsync(payload);
|
||||
|
||||
Log($"OK: Checkin erfolgreich (Hostname: {payload.Hostname})");
|
||||
|
||||
// Status-Cache für Dashboard schreiben
|
||||
WriteStatusCache(payload, response, true);
|
||||
|
||||
// Auto-Update prüfen
|
||||
if (!string.IsNullOrEmpty(response.AgentVersion) &&
|
||||
System.Version.TryParse(response.AgentVersion, out var serverVer) &&
|
||||
System.Version.TryParse(Version, out var localVer) &&
|
||||
serverVer > localVer)
|
||||
{
|
||||
Log($"UPDATE: Neue Agent-Version verfügbar: {response.AgentVersion} (aktuell: {Version})");
|
||||
await new CommandExecutor(_api, payload.Hostname, DataDir, _exePath)
|
||||
.ExecuteAsync(new PatchCommand { Id = 0, Command = "update_agent" });
|
||||
return;
|
||||
}
|
||||
|
||||
// Patch-Commands ausführen
|
||||
var executor = new CommandExecutor(_api, payload.Hostname, DataDir, _exePath);
|
||||
foreach (var cmd in response.Commands)
|
||||
{
|
||||
Log($"PATCH: Command empfangen: {cmd.Command}");
|
||||
await executor.ExecuteAsync(cmd);
|
||||
}
|
||||
|
||||
// Ankündigungen anzeigen
|
||||
if (response.Announcements.Count > 0)
|
||||
{
|
||||
_notifier!.ShowAnnouncements(response.Announcements);
|
||||
foreach (var ann in response.Announcements)
|
||||
Log($"ANNOUNCEMENT: Dialog für {SystemInfoService.GetLastUser()} gestartet - ID {ann.Id}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log($"ERROR: {ex.Message}");
|
||||
WriteStatusCache(null, null, false);
|
||||
}
|
||||
}
|
||||
|
||||
private CheckinPayload CollectData()
|
||||
{
|
||||
var (cpuModel, cpuCores) = SystemInfoService.GetCpuInfo();
|
||||
var (ramTotal, ramUsed) = SystemInfoService.GetRamInfo();
|
||||
var (diskTotal, diskFree) = SystemInfoService.GetDiskInfo();
|
||||
var (tpmPresent, tpmVersion, tpmV2) = SystemInfoService.GetTpmInfo();
|
||||
var (defEnabled, defSigAge, _) = SecurityInfoService.GetDefenderStatus();
|
||||
|
||||
return new CheckinPayload
|
||||
{
|
||||
Hostname = SystemInfoService.GetHostname(),
|
||||
AgentVersion = Version,
|
||||
Os = SystemInfoService.GetOs(),
|
||||
OsVersion = SystemInfoService.GetOsVersion(),
|
||||
Domain = SystemInfoService.GetDomain(),
|
||||
IpAddress = SystemInfoService.GetIpAddress(),
|
||||
MacAddress = SystemInfoService.GetMacAddress(),
|
||||
LastUser = SystemInfoService.GetLastUser(),
|
||||
CpuModel = cpuModel,
|
||||
CpuCores = cpuCores,
|
||||
CpuUsage = SystemInfoService.GetCpuUsage(),
|
||||
RamTotal = ramTotal,
|
||||
RamUsed = ramUsed,
|
||||
DiskTotal = diskTotal,
|
||||
DiskFree = diskFree,
|
||||
UptimeHours = SystemInfoService.GetUptimeHours(),
|
||||
PendingUpdates = SystemInfoService.GetPendingUpdates(),
|
||||
TpmPresent = tpmPresent,
|
||||
TpmVersion = tpmVersion,
|
||||
TpmV2 = tpmV2,
|
||||
SecureBoot = SystemInfoService.GetSecureBoot(),
|
||||
Win11Ready = SystemInfoService.GetWin11Readiness(tpmV2, SystemInfoService.GetSecureBoot(), cpuCores, ramTotal),
|
||||
BitlockerStatus = SecurityInfoService.GetBitlockerStatus(),
|
||||
DefenderEnabled = defEnabled,
|
||||
DefenderSignaturesAge = defSigAge >= 0 ? defSigAge : null,
|
||||
HardwareSerial = SystemInfoService.GetHardwareSerial(),
|
||||
InstalledSoftware = SystemInfoService.GetInstalledSoftware(),
|
||||
};
|
||||
}
|
||||
|
||||
private void WriteStatusCache(CheckinPayload? p, CheckinResponse? r, bool online)
|
||||
{
|
||||
try
|
||||
{
|
||||
var status = new StatusCache
|
||||
{
|
||||
Hostname = p?.Hostname ?? SystemInfoService.GetHostname(),
|
||||
LastCheckin = DateTime.Now,
|
||||
AgentVersion = Version,
|
||||
ServerUrl = _config?.ServerUrl ?? "",
|
||||
Online = online,
|
||||
CpuUsage = p?.CpuUsage,
|
||||
RamTotal = p?.RamTotal,
|
||||
RamUsed = p?.RamUsed,
|
||||
DiskTotal = p?.DiskTotal,
|
||||
DiskFree = p?.DiskFree,
|
||||
PendingUpdates = p?.PendingUpdates ?? 0,
|
||||
BitlockerStatus = p?.BitlockerStatus ?? "",
|
||||
DefenderEnabled = p?.DefenderEnabled ?? false,
|
||||
DefenderSignaturesAge = p?.DefenderSignaturesAge,
|
||||
HardwareSerial = p?.HardwareSerial ?? "",
|
||||
Os = p?.Os ?? "",
|
||||
LastUser = p?.LastUser ?? "",
|
||||
InstalledSoftware = p?.InstalledSoftware ?? [],
|
||||
};
|
||||
File.WriteAllText(StatusPath, JsonConvert.SerializeObject(status, Formatting.Indented));
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
private static void SecureConfigFile(string path)
|
||||
{
|
||||
try
|
||||
{
|
||||
var fi = new System.IO.FileInfo(path);
|
||||
var acl = fi.GetAccessControl();
|
||||
acl.SetAccessRuleProtection(true, false); // Vererbung entfernen
|
||||
// Nur SYSTEM und Administratoren
|
||||
acl.AddAccessRule(new System.Security.AccessControl.FileSystemAccessRule(
|
||||
"SYSTEM", System.Security.AccessControl.FileSystemRights.FullControl,
|
||||
System.Security.AccessControl.AccessControlType.Allow));
|
||||
acl.AddAccessRule(new System.Security.AccessControl.FileSystemAccessRule(
|
||||
"Administrators", System.Security.AccessControl.FileSystemRights.FullControl,
|
||||
System.Security.AccessControl.AccessControlType.Allow));
|
||||
fi.SetAccessControl(acl);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
public static void Log(string msg)
|
||||
{
|
||||
try
|
||||
{
|
||||
var line = $"{DateTime.Now:yyyy-MM-dd HH:mm:ss} {msg}";
|
||||
File.AppendAllText(LogPath, line + Environment.NewLine, System.Text.Encoding.UTF8);
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user