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 { } } }