diff --git a/cmd/utils.go b/cmd/utils.go index cf3f3a1..cde100a 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -180,10 +180,41 @@ func executeCommand(cmdline string) (string, error) { if gUseSudo { cmd = append(cmd, "sudo") } - cs := strings.Split(cmdline, " ") - - cmd = append(cmd, cs...) - + + var word string + var in_escaped bool + // Split by words, or " enclosed words + for i, c := range (cmdline) { + if string(c) == "\"" { + if in_escaped { + // This is the closing " + cmd = append(cmd, word) + in_escaped = false + } else { + in_escaped = true + } + continue + } + if string(c) == " " { + if in_escaped { + word = word + string(c) + continue + } else { + cmd = append(cmd, word) + word = "" + continue + } + } + if i == (len(cmdline) - 1) { + word = word + string(c) + cmd = append(cmd, word) + break + } + + // else + word = word + string(c) + } + if len(cmd) > 1 { out, err = exec.Command(cmd[0], cmd[1:]...).CombinedOutput() } else { @@ -209,8 +240,39 @@ func executeCommandInJail(jail *Jail, cmdline string) (string, error) { cmd = append(cmd, "jexec", jail.InternalName) - cs := strings.Split(cmdline, " ") - cmd = append(cmd, cs...) + var word string + var in_escaped bool + // Split by words, or " enclosed words + for i, c := range (cmdline) { + if string(c) == "\"" { + if in_escaped { + // This is the closing " + cmd = append(cmd, word) + in_escaped = false + } else { + in_escaped = true + } + continue + } + if string(c) == " " { + if in_escaped { + word = word + string(c) + continue + } else { + cmd = append(cmd, word) + word = "" + continue + } + } + if i == (len(cmdline) - 1) { + word = word + string(c) + cmd = append(cmd, word) + break + } + + // else + word = word + string(c) + } out, err := exec.Command(cmd[0], cmd[1:]...).CombinedOutput() @@ -423,18 +485,6 @@ func getFstab(path string) ([]Mount, error) { return mounts, nil } -/******************************************************************************** - * Get a specific jail reference, to update properties after a range loop - *******************************************************************************/ -func getJailFromArray(name string, jarray []Jail) (*Jail, error) { - for i, j := range jarray { - if name == j.Name { - return &jarray[i], nil - } - } - return &Jail{}, errors.New("Jail not found") -} - /***************************************************************************** * * devfs rules management @@ -466,6 +516,34 @@ func copyDevfsRuleset(ruleset int, srcrs int) error { return nil } +/******************************************************************************** + * Returns value of parameter as read in /var/run/jail.$InternalName.conf + * Directoves without value will return "true" if found + * Returns an error if parameter not found in file +*******************************************************************************/ +func getValueFromRunningConfig(jname string, param string) (string, error) { + content, err := ioutil.ReadFile(fmt.Sprintf("/var/run/jail.%s.conf", jname)) + if err != nil { + return "", err + } + + for _, line := range strings.Split(string(content), "\n") { + if strings.Contains(line, fmt.Sprintf("%s = ", param)) { + split := strings.Split(line, "=") + switch len(split) { + // directives without value + case 0: + return "true", nil + case 1: + return "", fmt.Errorf("Invalid format: %s", line) + case 2: + return strings.Trim(split[1], " ;\""), nil + } + } + } + + return "", fmt.Errorf("Parameter not found: %s", param) +} /******************************************************************************** * Add a rule to specified ruleset * Ex.: addDevfsRuleToRuleset("path bpf* unhide", 1002) @@ -508,6 +586,18 @@ func isStringInArray(strarr []string, searched string) bool { return false } +/******************************************************************************** + * Get a specific jail reference, to update properties after a range loop + *******************************************************************************/ +func getJailFromArray(name string, jarray []Jail) (*Jail, error) { + for i, j := range jarray { + if name == j.Name { + return &jarray[i], nil + } + } + return &Jail{}, errors.New("Jail not found") +} + func getDatastoreFromArray(name string, dsa []Datastore) (*Datastore, error) { for _, d := range dsa { if name == d.Name {