Skip to content
Permalink
Browse files

Merge pull request #2 from cruise-automation/collin/fc_script_json_co…

…mbined_output

accept json script output
  • Loading branch information
crmulliner committed Aug 15, 2019
2 parents 79f3acc + 63cb347 commit 5a77f9364e34326690a9b231907188e1d979d477
Showing with 35 additions and 17 deletions.
  1. +2 −2 Readme.md
  2. +26 −10 pkg/analyzer/analyzer.go
  3. +5 −3 pkg/analyzer/filecontent/filecontent.go
  4. +1 −1 scripts/check_file_x8664.sh
  5. +1 −1 test/test.py
@@ -260,11 +260,11 @@ Example Output:
#### Example: Run an external script passing the filename to the script

The file is extracted into a temp directory with a temp name before the script is executed.
The check fails if the script produced output on standard out.
The check produces an offender if the script produced output on stdout or stderr.

- `File` : string, the full path of the file or directory
- `Script` : string, the full path of the script
- `ScriptOptions` : string array, (optional) the first element allows to define a pattern containing wildcards like `?`, `*`, and `**` that is applied to filenames if present it will only check files that match the pattern, this is mostly useful when running the script on a directory. The second element allows passing an argument to the script.
- `ScriptOptions` : string array, (optional) the first element allows to define a pattern containing wildcards like `?`, `*`, and `**` that is applied to filenames if present it will only check files that match the pattern, this is mostly useful when running the script on a directory. The second element allows passing arguments to the script.
- `File` : string, the full path of the file, if the path points to a directory the script is run for every file in the directory and subdirectories

- `Desc` : string, (optional) is a descriptive string that will be attached to failed check
@@ -66,12 +66,12 @@ type globalConfigType struct {
}

type AnalyzerReport struct {
FSType string `json:"fs_type"`
ImageName string `json:"image_name"`
ImageDigest string `json:"image_digest,omitempty"`
Data map[string]interface{} `json:"data,omitempty"`
Offenders map[string][]string `json:"offenders,omitempty"`
Informational map[string][]string `json:"informational,omitempty"`
FSType string `json:"fs_type"`
ImageName string `json:"image_name"`
ImageDigest string `json:"image_digest,omitempty"`
Data map[string]interface{} `json:"data,omitempty"`
Offenders map[string][]interface{} `json:"offenders,omitempty"`
Informational map[string][]interface{} `json:"informational,omitempty"`
}

type Analyzer struct {
@@ -90,8 +90,8 @@ func New(fsp fsparser.FsParser, cfg globalConfigType) *Analyzer {
a.FSType = cfg.FSType
a.ImageName = fsp.ImageName()
a.tmpdir, _ = util.MkTmpDir("analyzer")
a.Offenders = make(map[string][]string)
a.Informational = make(map[string][]string)
a.Offenders = make(map[string][]interface{})
a.Informational = make(map[string][]interface{})
a.Data = make(map[string]interface{})
a.PluginReports = make(map[string]interface{})

@@ -288,11 +288,27 @@ func (a *Analyzer) CheckAllFilesWithPath(cb AllFilesCallback, cbdata AllFilesCal
}

func (a *Analyzer) AddOffender(filepath string, reason string) {
a.Offenders[filepath] = append(a.Offenders[filepath], reason)
var data map[string]interface{}
// this is valid json?
if err := json.Unmarshal([]byte(reason), &data); err == nil {
// yes: store as json
a.Offenders[filepath] = append(a.Offenders[filepath], json.RawMessage(reason))
} else {
// no: store as plain text
a.Offenders[filepath] = append(a.Offenders[filepath], reason)
}
}

func (a *Analyzer) AddInformational(filepath string, reason string) {
a.Informational[filepath] = append(a.Informational[filepath], reason)
var data map[string]interface{}
// this is valid json?
if err := json.Unmarshal([]byte(reason), &data); err == nil {
// yes: store as json
a.Informational[filepath] = append(a.Informational[filepath], json.RawMessage(reason))
} else {
// no: store as plain text
a.Informational[filepath] = append(a.Informational[filepath], reason)
}
}

func (a *Analyzer) HasOffenders() bool {
@@ -266,6 +266,8 @@ type callbackDataType struct {
* be analyzed by the script. This is to speed up execution time since files have to be extracted
* to analyze them with the external script.
*
* The second element in scriptOptions will be passed to the script as cmd line arguments.
*
* The script is run with the following parameters:
* script.sh <filename> <filename in filesystem> <uid> <gid> <mode> <selinux label - can be empty> -- <ScriptOptions[1]>
*/
@@ -296,7 +298,7 @@ func checkFileScript(fi *fsparser.FileInfo, fullpath string, cbData analyzer.All
args = append(args, cbd.scriptOptions[1])
}

out, err := exec.Command(cbd.script, args...).Output()
out, err := exec.Command(cbd.script, args...).CombinedOutput()
if err != nil {
cbd.state.a.AddOffender(path.Join(fullpath, fi.Name), fmt.Sprintf("script(%s) error=%s", cbd.script, err))
}
@@ -308,9 +310,9 @@ func checkFileScript(fi *fsparser.FileInfo, fullpath string, cbData analyzer.All

if len(out) > 0 {
if cbd.informationalOnly {
cbd.state.a.AddInformational(path.Join(fullpath, fi.Name), fmt.Sprintf("script(%s) returned=%s", cbd.script, out))
cbd.state.a.AddInformational(path.Join(fullpath, fi.Name), string(out))
} else {
cbd.state.a.AddOffender(path.Join(fullpath, fi.Name), fmt.Sprintf("script(%s) returned=%s", cbd.script, out))
cbd.state.a.AddOffender(path.Join(fullpath, fi.Name), string(out))
}
}
}
@@ -10,5 +10,5 @@ ORIG_SELINUXLABEL=$6
INFO=$(file ${FILEPATH}|grep "ELF 64-bit LSB executable, x86-64")

if [ -z "$INFO" ]; then
echo -n ${ORIG_FILENAME} "not a x86-64 elf file"
echo -n '{"reason": "not a x86-64 elf file"}'
fi
@@ -78,7 +78,7 @@ def test(cfgfile, e2toolspath=""):
if not "File State Check failed: size: 0 AllowEmpyt=false : this needs to be this way" in data["offenders"]["/file1"]:
SetError("file1 exists but size 0")

if "script(check_file_elf_stripped.sh) returned=elf_x8664 is not stripped" not in data["offenders"]["/bin/elf_x8664"]:
if "elf_x8664 is not stripped" not in data["offenders"]["/bin/elf_x8664"]:
SetError("script failed")

if "informational" not in data:

0 comments on commit 5a77f93

Please sign in to comment.
You can’t perform that action at this time.