From fd483a79ebd83d67bddd5461dbe3da673e4c6dd3 Mon Sep 17 00:00:00 2001 From: Manuel Abascal Date: Tue, 28 Oct 2025 10:31:12 -0500 Subject: [PATCH 01/10] fix(alert): remove debug logs from ngOnInit method in alert entity display Signed-off-by: Manuel Abascal --- .../alert-entity-display/alert-entity-display.component.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/app/data-management/alert-management/shared/components/alert-entity-display/alert-entity-display.component.ts b/frontend/src/app/data-management/alert-management/shared/components/alert-entity-display/alert-entity-display.component.ts index b98e10556..f4a52ee6d 100644 --- a/frontend/src/app/data-management/alert-management/shared/components/alert-entity-display/alert-entity-display.component.ts +++ b/frontend/src/app/data-management/alert-management/shared/components/alert-entity-display/alert-entity-display.component.ts @@ -59,8 +59,6 @@ export class AlertEntityDisplayComponent implements OnInit, OnChanges { } ngOnInit() { - console.log('type', this.type); - console.log('field', this.field); if (this.alert[this.key]) { this.fields = Object.keys(this.alert[this.key]); if (this.alert[this.key].geolocation) { From 5c48cc5c7b02b0f3d483132ada49673e155107f7 Mon Sep 17 00:00:00 2001 From: Manuel Abascal Date: Tue, 28 Oct 2025 14:11:59 -0500 Subject: [PATCH 02/10] feat(agent): add TLS connection option and update command generation for syslog integrations Signed-off-by: Manuel Abascal --- .../guide-syslog/guide-syslog.component.html | 3 +- .../guide-syslog/guide-syslog.component.ts | 4 +- .../agent-action-command.component.ts | 28 +++- .../app/app-module/guides/shared/constant.ts | 154 +++++++++++------- .../util/replace-command-tokens.util.ts | 20 ++- 5 files changed, 131 insertions(+), 78 deletions(-) diff --git a/frontend/src/app/app-module/guides/guide-syslog/guide-syslog.component.html b/frontend/src/app/app-module/guides/guide-syslog/guide-syslog.component.html index 378165bc3..052af7fae 100644 --- a/frontend/src/app/app-module/guides/guide-syslog/guide-syslog.component.html +++ b/frontend/src/app/app-module/guides/guide-syslog/guide-syslog.component.html @@ -32,8 +32,7 @@

+ [platforms]="platforms"> diff --git a/frontend/src/app/app-module/guides/guide-syslog/guide-syslog.component.ts b/frontend/src/app/app-module/guides/guide-syslog/guide-syslog.component.ts index bc0d6dc56..42d382e3c 100644 --- a/frontend/src/app/app-module/guides/guide-syslog/guide-syslog.component.ts +++ b/frontend/src/app/app-module/guides/guide-syslog/guide-syslog.component.ts @@ -85,9 +85,7 @@ export class GuideSyslogComponent implements OnInit { } ngOnInit() {} - getImage(): SyslogModuleImages { - return this.moduleImages.filter(value => value.module === this.moduleEnum)[0]; - } + getPorts(): SyslogModulePorts[] { return this.syslogPorts.filter(value => value.module === this.moduleEnum); } diff --git a/frontend/src/app/app-module/guides/shared/components/agent-action-command.component.ts b/frontend/src/app/app-module/guides/shared/components/agent-action-command.component.ts index 7c6b35aa9..f461dae73 100644 --- a/frontend/src/app/app-module/guides/shared/components/agent-action-command.component.ts +++ b/frontend/src/app/app-module/guides/shared/components/agent-action-command.component.ts @@ -35,7 +35,7 @@ import {UtmModulesEnum} from '../../../shared/enum/utm-module.enum'; {{selectedPlatform.shell}} - + `, styles: [` @@ -59,7 +59,8 @@ export class AgentActionCommandComponent implements OnInit{ @Input() hideProtocols = false; @Input() protocols = [ {id: 1, name: 'TCP'}, - {id: 2, name: 'UDP'} + {id: 2, name: 'TCP/TLS'}, + {id: 3, name: 'UDP'} ]; actions = [ @@ -75,16 +76,25 @@ export class AgentActionCommandComponent implements OnInit{ constructor(private modalService: ModalService) { } - ngOnInit(): void { - console.log(this.selectedPlatform); - } + ngOnInit(): void {} + + get commands() { + + const protocol = this.selectedProtocol && this.selectedProtocol.name === 'TCP/TLS' ? 'tcp' : this.selectedProtocol.name.toLowerCase(); - get command() { - return replaceCommandTokens(this.selectedPlatform.command, { - PORT: this.selectedProtocol && this.selectedProtocol.name.toLowerCase() || '', + const command = replaceCommandTokens(this.selectedPlatform.command, { + PROTOCOL: protocol, AGENT_NAME: this.agent, - ACTION: this.selectedAction && this.selectedAction.action || '' + ACTION: this.selectedAction && this.selectedAction.action || '', + TLS: this.selectedProtocol && this.selectedProtocol.name === 'TCP/TLS' ? ' --tls' : '' }); + + if (this.selectedProtocol && this.selectedProtocol.name === 'TCP/TLS') { + const extras = this.selectedPlatform.extraCommands ? this.selectedPlatform.extraCommands : []; + return [...extras, command]; + } + + return [command]; } get selectedPlatform() { diff --git a/frontend/src/app/app-module/guides/shared/constant.ts b/frontend/src/app/app-module/guides/shared/constant.ts index 5be905914..976dbe6ed 100644 --- a/frontend/src/app/app-module/guides/shared/constant.ts +++ b/frontend/src/app/app-module/guides/shared/constant.ts @@ -1,81 +1,109 @@ +const WINDOWS_SHELL = + 'Run the following PowerShell script as “ADMINISTRATOR” on a server with the UTMStack agent installed.'; + +const LINUX_SHELL = + 'Run the following Bash script as “ADMINISTRATOR” on a server with the UTMStack agent installed.'; + export interface Platform { id: number; name: string; command: string; shell: string; - path: string; - restart: string; + path?: string; + restart?: string; + extraCommands?: string[]; } -export const createPlatforms = (windowsCommandAMD64: string, - windowsCommandARM64: string, - linuxCommand: string, - windowsPath?: string, - windowsRestart?: string, - linuxPath?: string, - linuxRestart?: string) => [ - { - id: 1, - name: 'WINDOWS (AMD64)', - command: windowsCommandAMD64, - shell: 'Run the following powershell script as “ADMINISTRATOR” in a Server with the UTMStack agent Installed.', - path: windowsPath, - restart: windowsRestart - }, - { - id: 2, - name: 'WINDOWS (ARM64)', - command: windowsCommandARM64, - shell: 'Run the following powershell script as “ADMINISTRATOR” in a Server with the UTMStack agent Installed.', - path: windowsPath, - restart: windowsRestart - }, - { - id: 3, - name: 'LINUX', - command: linuxCommand, - shell: 'Run the following bash script as “ADMINISTRATOR” in a Server with the UTMStack agent Installed.', - path: linuxPath, - restart: linuxRestart - } -]; +function createPlatform( + id: number, + name: string, + command: string, + shell: string, + path?: string, + restart?: string, + extraCommands?: string[]): Platform { + return { id, name, command, shell, path, restart, extraCommands }; +} -export const createFileBeatsPlatforms = (windowsCommand: string, - linuxCommand: string, - windowsPath?: string, - windowsRestart?: string, - linuxPath?: string, - linuxRestart?: string) => [ - { - id: 1, - name: 'WINDOWS', - command: windowsCommand, - shell: 'Run the following powershell script as “ADMINISTRATOR” in a Server with the UTMStack agent Installed.', - path: windowsPath, - restart: windowsRestart - }, - { - id: 3, - name: 'LINUX', - command: linuxCommand, - shell: 'Run the following bash script as “ADMINISTRATOR” in a Server with the UTMStack agent Installed.', - path: linuxPath, - restart: linuxRestart - } +export const createPlatforms = ( + windowsCommandAMD64: string, + windowsCommandARM64: string, + linuxCommand: string, + windowsPath?: string, + windowsRestart?: string, + linuxPath?: string, + linuxRestart?: string): Platform[] => [ + createPlatform( + 1, + 'WINDOWS (AMD64)', + windowsCommandAMD64, + WINDOWS_SHELL, + windowsPath, + windowsRestart,[ + `Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_service.exe" \` + -ArgumentList 'load-tls-certs', '[YOUR_CERT_PATH]', '[YOUR_KEY_PATH]' \` + -NoNewWindow -Wait` + ] + ), + createPlatform( + 2, + 'WINDOWS (ARM64)', + windowsCommandARM64, + WINDOWS_SHELL, + windowsPath, + windowsRestart, + [ + `Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_service_arm64.exe" \` + -ArgumentList 'load-tls-certs', '[YOUR_CERT_PATH]', '[YOUR_KEY_PATH]' \` + -NoNewWindow -Wait` + ] + ), + createPlatform( + 3, + 'LINUX', + linuxCommand, + LINUX_SHELL, + linuxPath, + linuxRestart, + [ + `sudo bash -c "/opt/utmstack-linux-agent/utmstack_agent_service load-tls-certs [YOUR_CERT_PATH] [YOUR_KEY_PATH]"` + ] + ) ]; +export const createFileBeatsPlatforms = ( + windowsCommand: string, + linuxCommand: string, + windowsPath?: string, + windowsRestart?: string, + linuxPath?: string, + linuxRestart?: string): Platform[] => [ + createPlatform( + 1, + 'WINDOWS', + windowsCommand, + WINDOWS_SHELL, + windowsPath, + windowsRestart + ), + createPlatform( + 3, + 'LINUX', + linuxCommand, + LINUX_SHELL, + linuxPath, + linuxRestart + ) +]; export const PLATFORMS = createPlatforms( - 'Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_service.exe" -ArgumentList \'ACTION\',' + - ' \'AGENT_NAME\', \'PORT\' -NoNewWindow -Wait\n', - 'Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_service_arm64.exe" -ArgumentList \'ACTION\',' + - ' \'AGENT_NAME\', \'PORT\' -NoNewWindow -Wait\n', - 'sudo bash -c "/opt/utmstack-linux-agent/utmstack_agent_service ACTION AGENT_NAME PORT"' + 'Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_service.exe" -ArgumentList \'ACTION\', \'AGENT_NAME\', \'PROTOCOL\' TLS -NoNewWindow -Wait\n', + 'Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_service_arm64.exe" -ArgumentList \'ACTION\', \'AGENT_NAME\', \'PROTOCOL\' TLS -NoNewWindow -Wait\n', + 'sudo bash -c "/opt/utmstack-linux-agent/utmstack_agent_service ACTION AGENT_NAME PROTOCOL TLS"' ); - export const FILEBEAT_PLATFORMS = createFileBeatsPlatforms( - 'cd "C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\"; Start-Process "filebeat.exe" -ArgumentList "modules", "enable", \"AGENT_NAME\"', + 'cd "C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\"; Start-Process "filebeat.exe" -ArgumentList "modules", "enable", "AGENT_NAME"', 'cd /opt/utmstack-linux-agent/beats/filebeat/ && ./filebeat modules enable AGENT_NAME', 'C:\\Program Files\\UTMStack\\UTMStack Agent\\beats\\filebeat\\modules.d\\', 'Stop-Service -Name UTMStackModulesLogsCollector; Start-Sleep -Seconds 5; Start-Service -Name UTMStackModulesLogsCollector', diff --git a/frontend/src/app/shared/util/replace-command-tokens.util.ts b/frontend/src/app/shared/util/replace-command-tokens.util.ts index 89399eda3..b130861cc 100644 --- a/frontend/src/app/shared/util/replace-command-tokens.util.ts +++ b/frontend/src/app/shared/util/replace-command-tokens.util.ts @@ -1,4 +1,22 @@ -export function replaceCommandTokens(command: string, wordsToReplace: { [key: string]: string }) { +/*export function replaceCommandTokens(command: string, wordsToReplace: { [key: string]: string }) { return Object.keys(wordsToReplace) .reduce((f, s) => f.replace(new RegExp(s, 'ig'), wordsToReplace[s]), command); +}*/ + +export function replaceCommandTokens(command: string, wordsToReplace: { [key: string]: string }) { + let cmd = command; + + Object.entries(wordsToReplace).forEach(([key, value]) => { + if (!value) { + const regex = new RegExp(`\\s*${key}\\b`, 'g'); + cmd = cmd.replace(regex, ''); + } else { + const regex = new RegExp(`${key}\\b`, 'g'); + cmd = cmd.replace(regex, value); + } + }); + + cmd = cmd.replace(/\s+/g, ' ').trim(); + + return cmd; } From 36ad21e8e89c21bec2205983931dd1bf30e7d9fd Mon Sep 17 00:00:00 2001 From: Manuel Abascal Date: Tue, 4 Nov 2025 07:30:12 -0600 Subject: [PATCH 03/10] feat(agent): add TLS support for syslog command generation and update argument handling Signed-off-by: Manuel Abascal --- .../agent-action-command.component.ts | 10 +++-- .../app/app-module/guides/shared/constant.ts | 4 +- .../util/replace-command-tokens.util.ts | 39 ++++++++++++------- 3 files changed, 33 insertions(+), 20 deletions(-) diff --git a/frontend/src/app/app-module/guides/shared/components/agent-action-command.component.ts b/frontend/src/app/app-module/guides/shared/components/agent-action-command.component.ts index f461dae73..8e7ba8679 100644 --- a/frontend/src/app/app-module/guides/shared/components/agent-action-command.component.ts +++ b/frontend/src/app/app-module/guides/shared/components/agent-action-command.component.ts @@ -83,13 +83,15 @@ export class AgentActionCommandComponent implements OnInit{ const protocol = this.selectedProtocol && this.selectedProtocol.name === 'TCP/TLS' ? 'tcp' : this.selectedProtocol.name.toLowerCase(); const command = replaceCommandTokens(this.selectedPlatform.command, { - PROTOCOL: protocol, - AGENT_NAME: this.agent, ACTION: this.selectedAction && this.selectedAction.action || '', - TLS: this.selectedProtocol && this.selectedProtocol.name === 'TCP/TLS' ? ' --tls' : '' + AGENT_NAME: this.agent || '', + PROTOCOL: protocol, + TLS: this.selectedProtocol && this.selectedProtocol.name === 'TCP/TLS' && + this.selectedAction.name === 'ENABLE' ? `--tls` : '' }); - if (this.selectedProtocol && this.selectedProtocol.name === 'TCP/TLS') { + if (this.selectedProtocol && this.selectedProtocol.name === 'TCP/TLS' && + this.selectedAction.name === 'ENABLE') { const extras = this.selectedPlatform.extraCommands ? this.selectedPlatform.extraCommands : []; return [...extras, command]; } diff --git a/frontend/src/app/app-module/guides/shared/constant.ts b/frontend/src/app/app-module/guides/shared/constant.ts index 976dbe6ed..92ea97d80 100644 --- a/frontend/src/app/app-module/guides/shared/constant.ts +++ b/frontend/src/app/app-module/guides/shared/constant.ts @@ -97,8 +97,8 @@ export const createFileBeatsPlatforms = ( ]; export const PLATFORMS = createPlatforms( - 'Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_service.exe" -ArgumentList \'ACTION\', \'AGENT_NAME\', \'PROTOCOL\' TLS -NoNewWindow -Wait\n', - 'Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_service_arm64.exe" -ArgumentList \'ACTION\', \'AGENT_NAME\', \'PROTOCOL\' TLS -NoNewWindow -Wait\n', + 'Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_service.exe" -ArgumentList \'ACTION\', \'AGENT_NAME\', \'PROTOCOL\', \'TLS\' -NoNewWindow -Wait\n', + 'Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_service_arm64.exe" -ArgumentList \'ACTION\', \'AGENT_NAME\', \'PROTOCOL\, \'TLS\' -NoNewWindow -Wait\n', 'sudo bash -c "/opt/utmstack-linux-agent/utmstack_agent_service ACTION AGENT_NAME PROTOCOL TLS"' ); diff --git a/frontend/src/app/shared/util/replace-command-tokens.util.ts b/frontend/src/app/shared/util/replace-command-tokens.util.ts index b130861cc..7dbddc16a 100644 --- a/frontend/src/app/shared/util/replace-command-tokens.util.ts +++ b/frontend/src/app/shared/util/replace-command-tokens.util.ts @@ -1,20 +1,31 @@ -/*export function replaceCommandTokens(command: string, wordsToReplace: { [key: string]: string }) { - return Object.keys(wordsToReplace) - .reduce((f, s) => f.replace(new RegExp(s, 'ig'), wordsToReplace[s]), command); -}*/ - -export function replaceCommandTokens(command: string, wordsToReplace: { [key: string]: string }) { +export function replaceCommandTokens(command: string, wordsToReplace: { [key: string]: string }): string { let cmd = command; - Object.entries(wordsToReplace).forEach(([key, value]) => { - if (!value) { - const regex = new RegExp(`\\s*${key}\\b`, 'g'); - cmd = cmd.replace(regex, ''); - } else { - const regex = new RegExp(`${key}\\b`, 'g'); - cmd = cmd.replace(regex, value); + if (cmd.includes('-ArgumentList')) { + + const args = Object.values(wordsToReplace) + .filter(v => v && v.trim().length > 0) + .map(v => `'${v.trim()}'`) + .join(', '); + + cmd = cmd.replace( + /-ArgumentList\s+(['"].*?['"])(?=\s+-|$)/, + `-ArgumentList ${args}` + ); + } else { + const match = cmd.match(/"(.*)"/); + if (match) { + const original = match[1]; + const parts = original.split(/\s+/); + const fixedCommand = parts[0]; + const args = Object.entries(wordsToReplace) + .filter(([_, v]) => v && v.trim().length > 0) + .map(([_, v]) => v.trim()) + .join(' '); + + cmd = cmd.replace(/"(.*)"/, `"${fixedCommand} ${args}"`); } - }); + } cmd = cmd.replace(/\s+/g, ' ').trim(); From 13659bc2cc4baf8f83447199a98941ddc124e5a1 Mon Sep 17 00:00:00 2001 From: Manuel Abascal Date: Wed, 5 Nov 2025 11:17:37 -0600 Subject: [PATCH 04/10] feat(agent): add TLS support for syslog command generation and update argument handling Signed-off-by: Manuel Abascal --- .../shared/components/agent-action-command.component.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/app-module/guides/shared/components/agent-action-command.component.ts b/frontend/src/app/app-module/guides/shared/components/agent-action-command.component.ts index 8e7ba8679..b10401c4c 100644 --- a/frontend/src/app/app-module/guides/shared/components/agent-action-command.component.ts +++ b/frontend/src/app/app-module/guides/shared/components/agent-action-command.component.ts @@ -33,7 +33,14 @@ import {UtmModulesEnum} from '../../../shared/enum/utm-module.enum'; class="flex-item"> - +
+ After the TLS certificates have been successfully loaded into the system, + it is not necessary to repeat the certificate loading process when enabling + additional integrations that use TLS. The system will automatically apply the + previously configured certificates to ensure secure communication. +
+ {{selectedPlatform.shell}} From 28b91209baf807039e76c90f6cef29578b117942 Mon Sep 17 00:00:00 2001 From: Yadian Llada Lopez Date: Fri, 31 Oct 2025 08:56:06 -0400 Subject: [PATCH 05/10] refactor(agent): remove unused TLS certificate validation and related functions; --- agent/main.go | 36 ------- agent/serv/service.go | 13 --- agent/utils/files.go | 17 ++++ .../utils/{integration_tls.go => int_tls.go} | 97 ------------------- 4 files changed, 17 insertions(+), 146 deletions(-) rename agent/utils/{integration_tls.go => int_tls.go} (67%) diff --git a/agent/main.go b/agent/main.go index 0ea3404c9..60bd7a575 100644 --- a/agent/main.go +++ b/agent/main.go @@ -3,7 +3,6 @@ package main import ( "fmt" "os" - "strings" "time" pb "github.com/utmstack/UTMStack/agent/agent" @@ -170,41 +169,6 @@ func main() { fmt.Println("TLS certificates loaded successfully!") time.Sleep(5 * time.Second) - case "check-tls-certs": - fmt.Println("Checking TLS certificates status ...") - - status := utils.GetTLSStatus( - config.IntegrationCertPath, - config.IntegrationKeyPath, - config.IntegrationCAPath, - ) - - fmt.Printf("Certificate file exists: %v\n", status.CertExists) - fmt.Printf("Private key file exists: %v\n", status.KeyExists) - fmt.Printf("CA certificate file exists: %v\n", status.CAExists) - fmt.Printf("TLS Available: %v\n", status.Available) - fmt.Printf("Certificates Valid: %v\n", status.Valid) - - if status.Error != "" { - fmt.Printf("Error: %s\n", status.Error) - } - - if status.Available { - fmt.Println("\n" + strings.Repeat("=", 50)) - details, err := utils.GetCertificateDetails(config.IntegrationCertPath) - if err == nil { - fmt.Println(details) - } - fmt.Println("TLS is ready for use!") - fmt.Println("Use: ./utmstack_agent enable-tls tcp") - } else { - fmt.Println("\n" + strings.Repeat("=", 50)) - fmt.Println("TLS is NOT available.") - fmt.Println("To enable TLS:") - fmt.Println(" Load your certificates: ./utmstack_agent load-tls-certs [ca]") - } - time.Sleep(5 * time.Second) - case "change-port": fmt.Println("Changing integration port ...") integration := os.Args[2] diff --git a/agent/serv/service.go b/agent/serv/service.go index ea8abdbab..71b021621 100644 --- a/agent/serv/service.go +++ b/agent/serv/service.go @@ -40,19 +40,6 @@ func (p *program) run() { utils.Logger.Fatal("error getting config: %v", err) } - if utils.CheckIfPathExist(config.IntegrationCertPath) && utils.CheckIfPathExist(config.IntegrationKeyPath) { - err = utils.ValidateIntegrationCertificates(config.IntegrationCertPath, config.IntegrationKeyPath) - if err != nil { - utils.Logger.ErrorF("TLS certificates are invalid: %v", err) - utils.Logger.Info("TLS functionality will be disabled. Use 'load-tls-certs' command to fix this.") - } else { - utils.Logger.Info("TLS certificates are valid and ready for use") - } - } else { - utils.Logger.Info("No TLS certificates found. TLS functionality is disabled.") - utils.Logger.Info("Use 'load-tls-certs' command to load your certificates.") - } - db := database.GetDB() err = db.Migrate(models.Log{}) if err != nil { diff --git a/agent/utils/files.go b/agent/utils/files.go index 977b5689c..51da99255 100644 --- a/agent/utils/files.go +++ b/agent/utils/files.go @@ -157,3 +157,20 @@ func IsDirEmpty(path string) (bool, error) { } return false, err } + +func copyFile(src, dst string) error { + sourceFile, err := os.Open(src) + if err != nil { + return err + } + defer sourceFile.Close() + + destFile, err := os.Create(dst) + if err != nil { + return err + } + defer destFile.Close() + + _, err = io.Copy(destFile, sourceFile) + return err +} diff --git a/agent/utils/integration_tls.go b/agent/utils/int_tls.go similarity index 67% rename from agent/utils/integration_tls.go rename to agent/utils/int_tls.go index 741974e9a..5ca5928f3 100644 --- a/agent/utils/integration_tls.go +++ b/agent/utils/int_tls.go @@ -4,12 +4,9 @@ import ( "crypto/rsa" "crypto/tls" "crypto/x509" - "encoding/pem" "fmt" - "io" "os" "path/filepath" - "strings" "time" ) @@ -170,97 +167,3 @@ func LoadUserCertificatesWithStruct(src, dest CertificateFiles) error { return nil } - -func GetTLSStatus(certPath, keyPath, caPath string) TLSStatus { - status := TLSStatus{ - CertExists: CheckIfPathExist(certPath), - KeyExists: CheckIfPathExist(keyPath), - CAExists: CheckIfPathExist(caPath), - } - - if status.CertExists && status.KeyExists { - err := ValidateIntegrationCertificates(certPath, keyPath) - if err == nil { - status.Available = true - status.Valid = true - } else { - status.Error = err.Error() - } - } else { - status.Error = "Certificate or private key files not found" - } - - return status -} - -func GetCertificateDetails(certPath string) (string, error) { - if !CheckIfPathExist(certPath) { - return "", fmt.Errorf("certificate file not found: %s", certPath) - } - - // Parse certificate directly - certData, err := os.ReadFile(certPath) - if err != nil { - return "", fmt.Errorf("error reading certificate: %w", err) - } - - block, _ := pem.Decode(certData) - if block == nil { - return "", fmt.Errorf("failed to decode certificate PEM") - } - - cert, err := x509.ParseCertificate(block.Bytes) - if err != nil { - return "", fmt.Errorf("failed to parse certificate: %w", err) - } - - return formatCertificateDetails(cert), nil -} - -func formatCertificateDetails(cert *x509.Certificate) string { - var builder strings.Builder - - builder.WriteString(fmt.Sprintf("Subject: %s\n", cert.Subject.String())) - builder.WriteString(fmt.Sprintf("Issuer: %s\n", cert.Issuer.String())) - builder.WriteString(fmt.Sprintf("Valid from: %s\n", cert.NotBefore.Format("2006-01-02 15:04:05 UTC"))) - builder.WriteString(fmt.Sprintf("Valid until: %s\n", cert.NotAfter.Format("2006-01-02 15:04:05 UTC"))) - builder.WriteString(fmt.Sprintf("Serial Number: %s\n", cert.SerialNumber.String())) - - if len(cert.DNSNames) > 0 || len(cert.IPAddresses) > 0 { - builder.WriteString("Subject Alternative Names: ") - - for i, dns := range cert.DNSNames { - if i > 0 { - builder.WriteString(", ") - } - builder.WriteString(dns) - } - - for i, ip := range cert.IPAddresses { - if i > 0 || len(cert.DNSNames) > 0 { - builder.WriteString(", ") - } - builder.WriteString(ip.String()) - } - builder.WriteString("\n") - } - - return builder.String() -} - -func copyFile(src, dst string) error { - sourceFile, err := os.Open(src) - if err != nil { - return err - } - defer sourceFile.Close() - - destFile, err := os.Create(dst) - if err != nil { - return err - } - defer destFile.Close() - - _, err = io.Copy(destFile, sourceFile) - return err -} From bcb7d3467b5f11dd3c5327bc4bd811e01c5f85b2 Mon Sep 17 00:00:00 2001 From: AlexSanchez-bit Date: Thu, 16 Oct 2025 10:56:40 -0400 Subject: [PATCH 06/10] fix[frontend](web_console): sanitized password parameter to admit all utf8 characters even url structure ones --- frontend/src/app/core/auth/account.service.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/core/auth/account.service.ts b/frontend/src/app/core/auth/account.service.ts index 1631572ca..02ec14cb5 100644 --- a/frontend/src/app/core/auth/account.service.ts +++ b/frontend/src/app/core/auth/account.service.ts @@ -37,7 +37,8 @@ export class AccountService { } checkPassword(password: string, uuid: string): Observable> { - return this.http.get(SERVER_API_URL + `api/check-credentials?password=${password}&checkUUID=${uuid}`, { + const sanitized_password = encodeURIComponent(password) + return this.http.get(SERVER_API_URL + `api/check-credentials?password=${sanitized_password}&checkUUID=${uuid}`, { observe: 'response', responseType: 'text' }); From 3b4dc160971ca2c175fe07744ef82ac37e2a79c2 Mon Sep 17 00:00:00 2001 From: Manuel Abascal Date: Fri, 31 Oct 2025 09:04:46 -0500 Subject: [PATCH 07/10] Update frontend/src/app/core/auth/account.service.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- frontend/src/app/core/auth/account.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/core/auth/account.service.ts b/frontend/src/app/core/auth/account.service.ts index 02ec14cb5..194090805 100644 --- a/frontend/src/app/core/auth/account.service.ts +++ b/frontend/src/app/core/auth/account.service.ts @@ -37,8 +37,8 @@ export class AccountService { } checkPassword(password: string, uuid: string): Observable> { - const sanitized_password = encodeURIComponent(password) - return this.http.get(SERVER_API_URL + `api/check-credentials?password=${sanitized_password}&checkUUID=${uuid}`, { + const body = { password, checkUUID: uuid }; + return this.http.post(SERVER_API_URL + 'api/check-credentials', body, { observe: 'response', responseType: 'text' }); From ce09bc744994adbdd50477e1e3c4e1f908c5c065 Mon Sep 17 00:00:00 2001 From: AlexSanchez-bit Date: Thu, 16 Oct 2025 09:54:23 -0400 Subject: [PATCH 08/10] fix[frontend](app_settings): added GMT+12 and daylight saving options on date settings --- frontend/src/app/shared/constants/date-timezone-date.const.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/shared/constants/date-timezone-date.const.ts b/frontend/src/app/shared/constants/date-timezone-date.const.ts index ac2068658..ebb65546d 100644 --- a/frontend/src/app/shared/constants/date-timezone-date.const.ts +++ b/frontend/src/app/shared/constants/date-timezone-date.const.ts @@ -25,6 +25,8 @@ export const TIMEZONES: Array<{ label: string; timezone: string, zone: string }> {label: 'Sydney (AEST)', timezone: 'Australia/Sydney', zone: 'Australia'}, {label: 'Melbourne (AEST)', timezone: 'Australia/Melbourne', zone: 'Australia'}, {label: 'Perth (AWST)', timezone: 'Australia/Perth', zone: 'Australia'}, + {label: 'New Zealand (NZST)', timezone: 'Pacific/Auckland', zone: 'Pacific'}, + {label: 'Fiji (FJT)', timezone: 'Pacific/Fiji', zone: 'Pacific'}, {label: 'Beijing (CST)', timezone: 'Asia/Shanghai', zone: 'Asia'}, {label: 'Tokyo (JST)', timezone: 'Asia/Tokyo', zone: 'Asia'}, {label: 'Seoul (KST)', timezone: 'Asia/Seoul', zone: 'Asia'}, @@ -37,7 +39,6 @@ export const TIMEZONES: Array<{ label: string; timezone: string, zone: string }> {label: 'Buenos Aires (ART)', timezone: 'America/Argentina/Buenos_Aires', zone: 'America'}, {label: 'São Paulo (BRT)', timezone: 'America/Sao_Paulo', zone: 'America'}, ]; - export const DATE_FORMATS: Array<{ label: string; format: string; equivalentTo: string }> = [ {label: 'Short', format: 'short', equivalentTo: 'M/d/yy, h:mm a'}, {label: 'Medium', format: 'medium', equivalentTo: 'MMM d, y, h:mm:ss a'}, From 6f17bf2317ecd16bdf654e9400dc0c80c8cba327 Mon Sep 17 00:00:00 2001 From: Yadian Llada Lopez Date: Fri, 31 Oct 2025 13:30:37 -0400 Subject: [PATCH 09/10] feat(agent): validate TLS certificates before enabling TLS for integrations --- agent/modules/configuration.go | 3 +++ agent/modules/syslog.go | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/agent/modules/configuration.go b/agent/modules/configuration.go index 2274c3535..dd5bf90e6 100644 --- a/agent/modules/configuration.go +++ b/agent/modules/configuration.go @@ -69,6 +69,9 @@ func ChangeIntegrationStatus(logTyp string, proto string, isEnabled bool, tlsOpt // Handle TLS configuration if specified if len(tlsOptions) > 0 && isEnabled { if tlsOptions[0] { + if !utils.CheckIfPathExist(config.IntegrationCertPath) || !utils.CheckIfPathExist(config.IntegrationKeyPath) { + return "", fmt.Errorf("TLS certificates not found. Please load certificates first") + } // Enable TLS integration.TCP.TLSEnabled = true mod := GetModule(logTyp) diff --git a/agent/modules/syslog.go b/agent/modules/syslog.go index e2ed0d776..1efdb31aa 100644 --- a/agent/modules/syslog.go +++ b/agent/modules/syslog.go @@ -98,6 +98,12 @@ func (m *SyslogModule) GetPort(proto string) string { func (m *SyslogModule) EnablePort(proto string, enableTLS bool) error { switch proto { case "tcp": + if enableTLS { + if !utils.CheckIfPathExist(config.IntegrationCertPath) || !utils.CheckIfPathExist(config.IntegrationKeyPath) { + return fmt.Errorf("TLS certificates not found. Please load certificates first") + } + } + m.TCPListener.TLSEnabled = enableTLS go m.enableTCP() return nil From 6e47218af53004946469cdffd4cf83909ec334eb Mon Sep 17 00:00:00 2001 From: Manuel Abascal Date: Thu, 6 Nov 2025 10:56:32 -0600 Subject: [PATCH 10/10] feat(agent): update TLS command generation for syslog integrations to use concatenation Signed-off-by: Manuel Abascal --- .../src/app/app-module/guides/shared/constant.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/src/app/app-module/guides/shared/constant.ts b/frontend/src/app/app-module/guides/shared/constant.ts index 92ea97d80..468dd47fc 100644 --- a/frontend/src/app/app-module/guides/shared/constant.ts +++ b/frontend/src/app/app-module/guides/shared/constant.ts @@ -40,9 +40,9 @@ export const createPlatforms = ( WINDOWS_SHELL, windowsPath, windowsRestart,[ - `Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_service.exe" \` - -ArgumentList 'load-tls-certs', '[YOUR_CERT_PATH]', '[YOUR_KEY_PATH]' \` - -NoNewWindow -Wait` + 'Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_service.exe" ' + + '-ArgumentList \'load-tls-certs\', \'[YOUR_CERT_PATH]\', \'[YOUR_KEY_PATH]\' ' + + '-NoNewWindow -Wait' ] ), createPlatform( @@ -53,9 +53,9 @@ export const createPlatforms = ( windowsPath, windowsRestart, [ - `Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_service_arm64.exe" \` - -ArgumentList 'load-tls-certs', '[YOUR_CERT_PATH]', '[YOUR_KEY_PATH]' \` - -NoNewWindow -Wait` + 'Start-Process "C:\\Program Files\\UTMStack\\UTMStack Agent\\utmstack_agent_service_arm64.exe" ' + + '-ArgumentList \'load-tls-certs\', \'[YOUR_CERT_PATH]\', \'[YOUR_KEY_PATH]\' ' + + '-NoNewWindow -Wait' ] ), createPlatform(