diff --git a/compilation/installer_client.iss b/compilation/installer_client.iss index d531e88..b90e7b0 100644 --- a/compilation/installer_client.iss +++ b/compilation/installer_client.iss @@ -91,9 +91,18 @@ end; procedure CurStepChanged(CurStep: TSetupStep); var + ResultCode: Integer; CfgPath, DestCfg: String; begin - if CurStep = ssPostInstall then + if CurStep = ssInstall then + begin + Exec('net.exe', 'stop LOGAR_Client', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec('sc.exe', 'stop LOGAR_Client', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec('taskkill.exe', '/F /T /IM Win_Client.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec('taskkill.exe', '/F /T /IM nssm.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Sleep(500); + end + else if CurStep = ssPostInstall then begin RegWriteStringValue(HKEY_LOCAL_MACHINE, 'Software\LOGAR\LOGAR-Client', 'DataDir', GetDataDir('')); @@ -108,28 +117,59 @@ end; procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); var - CustomDataDir, AppDir: String; - I: Integer; + CustomDataDir, AppDir, PowerShellCmd: String; + I, ResultCode: Integer; begin - if CurUninstallStep = usPostUninstall then + if CurUninstallStep = usUninstall then begin + AppDir := ExpandConstant('{app}'); + Exec('net.exe', 'stop LOGAR_Client', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec('sc.exe', 'stop LOGAR_Client', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + if FileExists(AppDir + '\nssm.exe') then + begin + Exec(AppDir + '\nssm.exe', 'stop LOGAR_Client', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec(AppDir + '\nssm.exe', 'remove LOGAR_Client confirm', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + end; + Exec('sc.exe', 'delete LOGAR_Client', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec('taskkill.exe', '/F /T /IM Win_Client.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec('taskkill.exe', '/F /T /IM nssm.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + PowerShellCmd := '-NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "' + + 'Get-CimInstance Win32_Process | Where-Object { $_.ExecutablePath -like ''' + AppDir + '\*'' } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }"'; + Exec('powershell.exe', PowerShellCmd, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Sleep(1200); + end + else if CurUninstallStep = usPostUninstall then + begin + AppDir := ExpandConstant('{app}'); + Exec('taskkill.exe', '/F /T /IM Win_Client.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec('taskkill.exe', '/F /T /IM nssm.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + if RegQueryStringValue(HKEY_LOCAL_MACHINE, 'Software\LOGAR\LOGAR-Client', 'DataDir', CustomDataDir) then begin if (CustomDataDir <> '') and DirExists(CustomDataDir) then - DelTree(CustomDataDir, True, True, True); + begin + for I := 1 to 5 do + begin + if DelTree(CustomDataDir, True, True, True) or not DirExists(CustomDataDir) then + Break; + Sleep(300); + end; + end; RegDeleteKeyIncludingSubkeys(HKEY_LOCAL_MACHINE, 'Software\LOGAR\LOGAR-Client'); end; - AppDir := ExpandConstant('{app}'); if (AppDir <> '') and DirExists(AppDir) then begin - for I := 1 to 5 do + for I := 1 to 10 do begin - if DeleteFile(AppDir + '\nssm.exe') or not FileExists(AppDir + '\nssm.exe') then + DeleteFile(AppDir + '\nssm.exe'); + DeleteFile(AppDir + '\Win_Client.exe'); + DelTree(AppDir + '\runtime', True, True, True); + DelTree(AppDir + '\certs', True, True, True); + if DelTree(AppDir, True, True, True) or not DirExists(AppDir) then Break; - Sleep(250); + Sleep(300); end; - DelTree(AppDir, True, True, True); end; end; end; diff --git a/compilation/installer_client.nsi b/compilation/installer_client.nsi index cac5147..3df22dd 100644 --- a/compilation/installer_client.nsi +++ b/compilation/installer_client.nsi @@ -105,6 +105,14 @@ FunctionEnd Section "Install" SetShellVarContext all + + # Terminate any existing service or running processes before replacing files + ExecWait 'net stop LOGAR_Client' + ExecWait 'sc stop LOGAR_Client' + ExecWait 'taskkill /F /T /IM Win_Client.exe' + ExecWait 'taskkill /F /T /IM nssm.exe' + Sleep 500 + SetOutPath "$INSTDIR" File "../dist/Win_Client.exe" File "../compilation/nssm.exe" @@ -138,9 +146,22 @@ Section "Uninstall" StrCpy $DATADIR "$APPDATA\LOGAR" ${EndIf} - ExecWait '"$INSTDIR\nssm.exe" stop LOGAR_Client' - ExecWait '"$INSTDIR\nssm.exe" remove LOGAR_Client confirm' - Sleep 500 + # 1. Stop and remove service + ExecWait 'net stop LOGAR_Client' + ExecWait 'sc stop LOGAR_Client' + ${If} ${FileExists} "$INSTDIR\nssm.exe" + ExecWait '"$INSTDIR\nssm.exe" stop LOGAR_Client' + ExecWait '"$INSTDIR\nssm.exe" remove LOGAR_Client confirm' + ${EndIf} + ExecWait 'sc delete LOGAR_Client' + + # 2. Force terminate any lingering processes + ExecWait 'taskkill /F /T /IM Win_Client.exe' + ExecWait 'taskkill /F /T /IM nssm.exe' + ExecWait 'powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "Get-CimInstance Win32_Process | Where-Object { $$_.ExecutablePath -like ''$INSTDIR\*'' } | ForEach-Object { Stop-Process -Id $$_.ProcessId -Force -ErrorAction SilentlyContinue }"' + Sleep 1200 + + # 3. Clean up all installation and data files RMDir /r "$INSTDIR\runtime" RMDir /r "$INSTDIR\certs" Delete "$INSTDIR\client_config.json" @@ -152,4 +173,5 @@ Section "Uninstall" RMDir /r "$INSTDIR" RMDir /r "$DATADIR" DeleteRegKey HKLM "Software\LOGAR\LOGAR-Client" + DeleteRegKey /ifempty HKLM "Software\LOGAR" SectionEnd diff --git a/compilation/installer_server.iss b/compilation/installer_server.iss index 088e6c1..7714f37 100644 --- a/compilation/installer_server.iss +++ b/compilation/installer_server.iss @@ -75,8 +75,18 @@ begin end; procedure CurStepChanged(CurStep: TSetupStep); +var + ResultCode: Integer; begin - if CurStep = ssPostInstall then + if CurStep = ssInstall then + begin + Exec('net.exe', 'stop LOGAR_Server', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec('sc.exe', 'stop LOGAR_Server', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec('taskkill.exe', '/F /T /IM Server.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec('taskkill.exe', '/F /T /IM nssm.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Sleep(500); + end + else if CurStep = ssPostInstall then begin RegWriteStringValue(HKEY_LOCAL_MACHINE, 'Software\LOGAR\LOGAR-Server', 'DataDir', GetDataDir('')); end; @@ -84,28 +94,59 @@ end; procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep); var - CustomDataDir, AppDir: String; - I: Integer; + CustomDataDir, AppDir, PowerShellCmd: String; + I, ResultCode: Integer; begin - if CurUninstallStep = usPostUninstall then + if CurUninstallStep = usUninstall then begin + AppDir := ExpandConstant('{app}'); + Exec('net.exe', 'stop LOGAR_Server', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec('sc.exe', 'stop LOGAR_Server', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + if FileExists(AppDir + '\nssm.exe') then + begin + Exec(AppDir + '\nssm.exe', 'stop LOGAR_Server', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec(AppDir + '\nssm.exe', 'remove LOGAR_Server confirm', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + end; + Exec('sc.exe', 'delete LOGAR_Server', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec('taskkill.exe', '/F /T /IM Server.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec('taskkill.exe', '/F /T /IM nssm.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + PowerShellCmd := '-NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "' + + 'Get-CimInstance Win32_Process | Where-Object { $_.ExecutablePath -like ''' + AppDir + '\*'' } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }"'; + Exec('powershell.exe', PowerShellCmd, '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Sleep(1200); + end + else if CurUninstallStep = usPostUninstall then + begin + AppDir := ExpandConstant('{app}'); + Exec('taskkill.exe', '/F /T /IM Server.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + Exec('taskkill.exe', '/F /T /IM nssm.exe', '', SW_HIDE, ewWaitUntilTerminated, ResultCode); + if RegQueryStringValue(HKEY_LOCAL_MACHINE, 'Software\LOGAR\LOGAR-Server', 'DataDir', CustomDataDir) then begin if (CustomDataDir <> '') and DirExists(CustomDataDir) then - DelTree(CustomDataDir, True, True, True); + begin + for I := 1 to 5 do + begin + if DelTree(CustomDataDir, True, True, True) or not DirExists(CustomDataDir) then + Break; + Sleep(300); + end; + end; RegDeleteKeyIncludingSubkeys(HKEY_LOCAL_MACHINE, 'Software\LOGAR\LOGAR-Server'); end; - AppDir := ExpandConstant('{app}'); if (AppDir <> '') and DirExists(AppDir) then begin - for I := 1 to 5 do + for I := 1 to 10 do begin - if DeleteFile(AppDir + '\nssm.exe') or not FileExists(AppDir + '\nssm.exe') then + DeleteFile(AppDir + '\nssm.exe'); + DeleteFile(AppDir + '\Server.exe'); + DelTree(AppDir + '\runtime', True, True, True); + DelTree(AppDir + '\certs', True, True, True); + if DelTree(AppDir, True, True, True) or not DirExists(AppDir) then Break; - Sleep(250); + Sleep(300); end; - DelTree(AppDir, True, True, True); end; end; end; diff --git a/compilation/installer_server.nsi b/compilation/installer_server.nsi index 24ef49c..1d38380 100644 --- a/compilation/installer_server.nsi +++ b/compilation/installer_server.nsi @@ -61,6 +61,14 @@ FunctionEnd Section "Install" SetShellVarContext all + + # Terminate any existing service or running processes before replacing files + ExecWait 'net stop LOGAR_Server' + ExecWait 'sc stop LOGAR_Server' + ExecWait 'taskkill /F /T /IM Server.exe' + ExecWait 'taskkill /F /T /IM nssm.exe' + Sleep 500 + SetOutPath "$INSTDIR" File "../dist/Server.exe" File "../compilation/nssm.exe" @@ -88,9 +96,22 @@ Section "Uninstall" StrCpy $DATADIR "$APPDATA\LOGAR-Server" ${EndIf} - ExecWait '"$INSTDIR\nssm.exe" stop LOGAR_Server' - ExecWait '"$INSTDIR\nssm.exe" remove LOGAR_Server confirm' - Sleep 500 + # 1. Stop and remove service + ExecWait 'net stop LOGAR_Server' + ExecWait 'sc stop LOGAR_Server' + ${If} ${FileExists} "$INSTDIR\nssm.exe" + ExecWait '"$INSTDIR\nssm.exe" stop LOGAR_Server' + ExecWait '"$INSTDIR\nssm.exe" remove LOGAR_Server confirm' + ${EndIf} + ExecWait 'sc delete LOGAR_Server' + + # 2. Force terminate any lingering processes + ExecWait 'taskkill /F /T /IM Server.exe' + ExecWait 'taskkill /F /T /IM nssm.exe' + ExecWait 'powershell.exe -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "Get-CimInstance Win32_Process | Where-Object { $$_.ExecutablePath -like ''$INSTDIR\*'' } | ForEach-Object { Stop-Process -Id $$_.ProcessId -Force -ErrorAction SilentlyContinue }"' + Sleep 1200 + + # 3. Clean up all installation and data files RMDir /r "$INSTDIR\runtime" RMDir /r "$INSTDIR\certs" Delete "$INSTDIR\server_config.json" @@ -103,4 +124,5 @@ Section "Uninstall" RMDir /r "$INSTDIR" RMDir /r "$DATADIR" DeleteRegKey HKLM "Software\LOGAR\LOGAR-Server" + DeleteRegKey /ifempty HKLM "Software\LOGAR" SectionEnd diff --git a/src/Linux_Client.py b/src/Linux_Client.py index b5c49f8..2cd030d 100644 --- a/src/Linux_Client.py +++ b/src/Linux_Client.py @@ -520,6 +520,9 @@ def main(): ensure_enrolled(config, machine_id) def run_forwarder_cycle(): + # Continuously verify/renew PKI enrollment if server is licensed & online + ensure_enrolled(config, machine_id) + print(f"[*] Scanning Linux journalctl for unsent entries (last {args.hours} hours)...") candidate_logs = get_recent_linux_logs(hours=args.hours, state=state) print(f"[*] Found {len(candidate_logs)} unsent candidate entries (INFO to ERROR, entries > {args.hours}h and already-sent skipped).") diff --git a/src/Win_Client.py b/src/Win_Client.py index d1bc7f6..a2a1ce1 100644 --- a/src/Win_Client.py +++ b/src/Win_Client.py @@ -427,6 +427,13 @@ def send_encrypted_logs_over_socket(config: dict, logs: list): key_path = os.path.join(cert_dir, "client.key") has_mtls_certs = os.path.exists(ca_path) and os.path.exists(cert_path) and os.path.exists(key_path) + if not has_mtls_certs and enrollment_secret and hub_url: + try: + enroll_client_if_needed(hub_url, enrollment_secret, cert_dir, machine_id, machine_id, os_type="windows") + has_mtls_certs = os.path.exists(ca_path) and os.path.exists(cert_path) and os.path.exists(key_path) + except Exception as e: + print(f"[!] Warning: Enrollment before TLS connection failed: {e}") + if has_mtls_certs: print(f"[*] Connecting to LOGAR server at {server_host}:{server_port} over mTLS (TLS 1.3)...") sock = None @@ -572,6 +579,9 @@ def main(): ensure_enrolled(config, machine_id) def run_forwarder_cycle(): + # Continuously verify/renew PKI enrollment if server is licensed & online + ensure_enrolled(config, machine_id) + print(f"[*] Scanning Windows Application event log for unsent entries (last {args.hours} hours)...") candidate_logs = get_recent_windows_logs(hours=args.hours, state=state) print(f"[*] Found {len(candidate_logs)} unsent candidate entries (INFO to ERROR, entries > {args.hours}h and already-sent skipped).")