From 1546261fcc7ecf83994c2cf8c5d27d3431d9b51a Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 19 Mar 2022 22:00:15 +0100 Subject: [PATCH 1/4] Improve running commands --- utils/osdetail/binmeta_windows.go | 4 +-- utils/osdetail/command.go | 51 ++++++++++++++++++++++++++++ utils/osdetail/powershell_windows.go | 49 -------------------------- utils/osdetail/shell_windows.go | 49 ++++++++++++++++++++++++++ 4 files changed, 102 insertions(+), 51 deletions(-) create mode 100644 utils/osdetail/command.go delete mode 100644 utils/osdetail/powershell_windows.go create mode 100644 utils/osdetail/shell_windows.go diff --git a/utils/osdetail/binmeta_windows.go b/utils/osdetail/binmeta_windows.go index 064d247..056445c 100644 --- a/utils/osdetail/binmeta_windows.go +++ b/utils/osdetail/binmeta_windows.go @@ -16,7 +16,7 @@ func GetBinaryNameFromSystem(path string) (string, error) { } // Clean name. - binName := cleanFileDescription(output) + binName := cleanFileDescription(string(output)) if binName != "" { return binName, nil } @@ -74,5 +74,5 @@ func GetBinaryIconFromSystem(path string) (string, error) { return "", fmt.Errorf("failed to get file properties of %s: %s", path, err) } - return "data:image/png;base64," + output, nil + return "data:image/png;base64," + string(output), nil } diff --git a/utils/osdetail/command.go b/utils/osdetail/command.go new file mode 100644 index 0000000..9285e36 --- /dev/null +++ b/utils/osdetail/command.go @@ -0,0 +1,51 @@ +package osdetail + +import ( + "bytes" + "errors" + "os/exec" + "strings" +) + +// RunCmd runs the given command and run error checks on the output. +func RunCmd(command ...string) (output []byte, err error) { + // Create command to execute. + var cmd *exec.Cmd + switch len(command) { + case 0: + return nil, errors.New("no command supplied") + case 1: + cmd = exec.Command(command[0]) + default: + cmd = exec.Command(command[0], command[1:]...) + } + + // Create and assign output buffers. + var stdoutBuf bytes.Buffer + var stderrBuf bytes.Buffer + cmd.Stdout = &stdoutBuf + cmd.Stderr = &stderrBuf + + // Run command and collect output. + err = cmd.Run() + stdout, stderr := stdoutBuf.Bytes(), stderrBuf.Bytes() + if err != nil { + return nil, err + } + // Command might not return an error, but just write to stdout instead. + if len(stderr) > 0 { + return nil, errors.New(strings.SplitN(string(stderr), "\n", 2)[0]) + } + + // Debugging output: + // fmt.Printf("command stdout: %s\n", stdout) + // fmt.Printf("command stderr: %s\n", stderr) + + // Finalize stdout. + cleanedOutput := bytes.TrimSpace(stdout) + if len(cleanedOutput) == 0 { + return nil, ErrEmptyOutput + } + + return cleanedOutput, nil +} diff --git a/utils/osdetail/powershell_windows.go b/utils/osdetail/powershell_windows.go deleted file mode 100644 index 52ce5c4..0000000 --- a/utils/osdetail/powershell_windows.go +++ /dev/null @@ -1,49 +0,0 @@ -package osdetail - -import ( - "bytes" - "errors" - "os/exec" - "strings" -) - -// RunPowershellCmd runs a powershell command and returns its output. -func RunPowershellCmd(script string) (output string, err error) { - // Create command to execute. - cmd := exec.Command( - "powershell.exe", - "-ExecutionPolicy", "Bypass", - "-NoProfile", - "-NonInteractive", - "[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8\n"+script, - ) - - // Create and assign output buffers. - var stdoutBuf bytes.Buffer - var stderrBuf bytes.Buffer - cmd.Stdout = &stdoutBuf - cmd.Stderr = &stderrBuf - - // Run command and collect output. - err = cmd.Run() - stdout, stderr := stdoutBuf.String(), stderrBuf.String() - if err != nil { - return "", err - } - // Powershell might not return an error, but just write to stdout instead. - if stderr != "" { - return "", errors.New(strings.SplitN(stderr, "\n", 2)[0]) - } - - // Debugging output: - // fmt.Printf("powershell stdout: %s\n", stdout) - // fmt.Printf("powershell stderr: %s\n", stderr) - - // Finalize stdout. - cleanedOutput := strings.TrimSpace(stdout) - if cleanedOutput == "" { - return "", ErrEmptyOutput - } - - return cleanedOutput, nil -} diff --git a/utils/osdetail/shell_windows.go b/utils/osdetail/shell_windows.go new file mode 100644 index 0000000..926b7c8 --- /dev/null +++ b/utils/osdetail/shell_windows.go @@ -0,0 +1,49 @@ +package osdetail + +import ( + "bytes" + "errors" +) + +// RunPowershellCmd runs a powershell command and returns its output. +func RunPowershellCmd(script string) (output []byte, err error) { + // Create command to execute. + return RunCmd( + "powershell.exe", + "-ExecutionPolicy", "Bypass", + "-NoProfile", + "-NonInteractive", + "[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8\n"+script, + ) +} + +const outputSeparator = "pwzzhtuvpwdgozhzbnjj" + +// RunTerminalCmd runs a Windows cmd command and returns its output. +// It sets the output of the cmd to UTF-8 in order to avoid encoding errors. +func RunTerminalCmd(command ...string) (output []byte, err error) { + output, err = RunCmd(append([]string{ + "cmd.exe", + "/c", + "chcp", // Set output encoding... + "65001", // ...to UTF-8. + "&", + "echo", + outputSeparator, + "&", + }, + command..., + )...) + if err != nil { + return nil, err + } + + // Find correct start of output and shift start. + index := bytes.IndexAny(output, outputSeparator+"\r\n") + if index < 0 { + return nil, errors.New("failed to post-process output: could not find output separator") + } + output = output[index+len(outputSeparator)+2:] + + return output, nil +} From deef6cdafc6c3d15a313fa1ca57928dd8c49e013 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 19 Mar 2022 22:00:39 +0100 Subject: [PATCH 2/4] Mark config options as sensitive --- api/config.go | 1 + config/option.go | 3 +++ metrics/config.go | 2 ++ 3 files changed, 6 insertions(+) diff --git a/api/config.go b/api/config.go index 354ea2a..7b037d8 100644 --- a/api/config.go +++ b/api/config.go @@ -65,6 +65,7 @@ func registerConfig() error { Name: "API Keys", Key: CfgAPIKeys, Description: "Define API keys for priviledged access to the API. Every entry is a separate API key with respective permissions. Format is `?read=&write=`. Permissions are `anyone`, `user` and `admin`, and may be omitted.", + Sensitive: true, OptType: config.OptTypeStringArray, ExpertiseLevel: config.ExpertiseLevelDeveloper, ReleaseLevel: config.ReleaseLevelStable, diff --git a/config/option.go b/config/option.go index 9cbfde1..84166f1 100644 --- a/config/option.go +++ b/config/option.go @@ -190,6 +190,9 @@ type Option struct { // Help is considered immutable after the option has // been created. Help string + // Sensitive signifies that the configuration values may contain sensitive + // content, such as authentication keys. + Sensitive bool // OptType defines the type of the option. // OptType is considered immutable after the option has // been created. diff --git a/metrics/config.go b/metrics/config.go index 2b011e6..5815b84 100644 --- a/metrics/config.go +++ b/metrics/config.go @@ -41,6 +41,7 @@ func prepConfig() error { Name: "Metrics Instance Name", Key: CfgOptionInstanceKey, Description: "Define the prometheus instance label for exported metrics. Please note that changing the instance name will reset persisted metrics.", + Sensitive: true, OptType: config.OptTypeString, ExpertiseLevel: config.ExpertiseLevelExpert, ReleaseLevel: config.ReleaseLevelStable, @@ -61,6 +62,7 @@ func prepConfig() error { Name: "Push Prometheus Metrics", Key: CfgOptionPushKey, Description: "Push metrics to this URL in the prometheus format.", + Sensitive: true, OptType: config.OptTypeString, ExpertiseLevel: config.ExpertiseLevelExpert, ReleaseLevel: config.ReleaseLevelStable, From a9b491cac25ee899ea0e343f2b6dee9235241920 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 19 Mar 2022 22:00:57 +0100 Subject: [PATCH 3/4] Add debug info for config options --- config/main.go | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/config/main.go b/config/main.go index 6cd8d7c..d348898 100644 --- a/config/main.go +++ b/config/main.go @@ -4,12 +4,15 @@ import ( "encoding/json" "errors" "flag" + "fmt" "os" "path/filepath" + "sort" "github.com/safing/portbase/dataroot" "github.com/safing/portbase/modules" "github.com/safing/portbase/utils" + "github.com/safing/portbase/utils/debug" ) const ( @@ -80,3 +83,32 @@ func exportConfigCmd() error { _, err = os.Stdout.Write(data) return err } + +// AddToDebugInfo adds all changed global config options to the given debug.Info. +func AddToDebugInfo(di *debug.Info) { + var lines []string + + // Collect all changed settings. + ForEachOption(func(opt *Option) error { + opt.Lock() + defer opt.Unlock() + + if opt.ReleaseLevel <= getReleaseLevel() && opt.activeValue != nil { + if opt.Sensitive { + lines = append(lines, fmt.Sprintf("%s: [redacted]", opt.Key)) + } else { + lines = append(lines, fmt.Sprintf("%s: %v", opt.Key, opt.activeValue.getData(opt))) + } + } + + return nil + }) + sort.Strings(lines) + + // Add data as section. + di.AddSection( + fmt.Sprintf("Config: %d", len(lines)), + debug.UseCodeSection|debug.AddContentLineBreaks, + lines..., + ) +} From 6ef0282dc4801c4939f9cf4019ebaf138216a7c0 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 21 Mar 2022 15:42:41 +0100 Subject: [PATCH 4/4] Fix linter warnings --- config/main.go | 2 +- utils/debug/debug.go | 2 +- utils/osdetail/binmeta.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/main.go b/config/main.go index d348898..1882707 100644 --- a/config/main.go +++ b/config/main.go @@ -89,7 +89,7 @@ func AddToDebugInfo(di *debug.Info) { var lines []string // Collect all changed settings. - ForEachOption(func(opt *Option) error { + _ = ForEachOption(func(opt *Option) error { opt.Lock() defer opt.Unlock() diff --git a/utils/debug/debug.go b/utils/debug/debug.go index bd74e2b..7ff5dec 100644 --- a/utils/debug/debug.go +++ b/utils/debug/debug.go @@ -157,7 +157,7 @@ func (di *Info) AddLastReportedModuleError() { } di.AddSection( - fmt.Sprintf("%s Module Error", strings.Title(me.ModuleName)), + fmt.Sprintf("%s Module Error", strings.Title(me.ModuleName)), //nolint:staticcheck UseCodeSection, me.Format(), ) diff --git a/utils/osdetail/binmeta.go b/utils/osdetail/binmeta.go index 333ba82..76c0e8d 100644 --- a/utils/osdetail/binmeta.go +++ b/utils/osdetail/binmeta.go @@ -76,7 +76,7 @@ func GenerateBinaryNameFromPath(path string) string { // Title-case name-only parts. if nameOnly.MatchString(nameParts[i]) { - nameParts[i] = strings.Title(nameParts[i]) + nameParts[i] = strings.Title(nameParts[i]) //nolint:staticcheck } }