mirror of
https://github.com/yusing/godoxy.git
synced 2026-03-18 07:24:31 +01:00
Add new `/proxmox/tail` API endpoint for streaming file contents from Proxmox nodes and LXC containers via WebSocket. Extend journalctl endpoint to support filtering by multiple services simultaneously. Changes: - Add `GET /proxmox/tail` endpoint supporting node-level and LXC container file tailing - Change `service` parameter from string to array in journalctl endpoints - Add input validation (`checkValidInput`) to prevent command injection - Refactor command formatting with proper shell quoting Security: All command inputs are validated for dangerous characters before
60 lines
1.5 KiB
Go
60 lines
1.5 KiB
Go
package proxmox
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// checkValidInput checks if the input contains invalid characters.
|
|
//
|
|
// The characters are: & | $ ; ' " ` $( ${ < >
|
|
// These characters are used in the command line to escape the input or to expand variables.
|
|
// We need to check if the input contains these characters and return an error if it does.
|
|
// This is to prevent command injection.
|
|
func checkValidInput(input string) error {
|
|
if strings.ContainsAny(input, "&|$;'\"`<>") {
|
|
return fmt.Errorf("input contains invalid characters: %q", input)
|
|
}
|
|
if strings.Contains(input, "$(") {
|
|
return fmt.Errorf("input contains $(: %q", input)
|
|
}
|
|
if strings.Contains(input, "${") {
|
|
return fmt.Errorf("input contains ${: %q", input)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func formatTail(files []string, limit int) (string, error) {
|
|
for _, file := range files {
|
|
if err := checkValidInput(file); err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
var command strings.Builder
|
|
command.WriteString("tail -f -q --retry ")
|
|
for _, file := range files {
|
|
fmt.Fprintf(&command, " %q ", file)
|
|
}
|
|
if limit > 0 {
|
|
fmt.Fprintf(&command, " -n %d", limit)
|
|
}
|
|
return command.String(), nil
|
|
}
|
|
|
|
func formatJournalctl(services []string, limit int) (string, error) {
|
|
for _, service := range services {
|
|
if err := checkValidInput(service); err != nil {
|
|
return "", err
|
|
}
|
|
}
|
|
var command strings.Builder
|
|
command.WriteString("journalctl -f")
|
|
for _, service := range services {
|
|
fmt.Fprintf(&command, " -u %q ", service)
|
|
}
|
|
if limit > 0 {
|
|
fmt.Fprintf(&command, " -n %d", limit)
|
|
}
|
|
return command.String(), nil
|
|
}
|