[major] various fixups for recent stdin changes

This commit is contained in:
Aaron Meihm 2015-04-20 13:36:03 -05:00 коммит произвёл Julien Vehent
Родитель e75b4425e3
Коммит f26f4b2281
9 изменённых файлов: 74 добавлений и 49 удалений

Просмотреть файл

@ -498,8 +498,8 @@ func runModule(ctx Context, op moduleOp) (err error) {
execTimeOut = op.expireafter.Sub(time.Now())
}
// Command arguments must be in json format
modParams, err := json.Marshal(op.params)
// Build parameters message
modParams, err := json.Marshal(modules.MakeParametersMessage(op.params))
if err != nil {
panic(err)
}

Просмотреть файл

@ -9,6 +9,7 @@ import (
"encoding/json"
"fmt"
"mig"
"mig/modules"
"mig/modules/file"
"time"
)
@ -73,12 +74,17 @@ func commandsToComplianceItems(commands []mig.Command) (items []ComplianceItem,
}
switch cmd.Action.Operations[i].Module {
case "file":
var r file.Results
var el file.SearchResults
var r modules.Result
err = json.Unmarshal(buf, &r)
if err != nil {
return items, err
}
for label, sr := range r.Elements {
err = r.GetElements(&el)
if err != nil {
return items, err
}
for label, sr := range el {
for _, mf := range sr {
bitem.Check.Location = mf.File
bitem.Check.Name = label

Просмотреть файл

@ -18,6 +18,7 @@ import (
"io"
"io/ioutil"
"mig"
"mig/modules"
"mig/pgp"
"mime/multipart"
"net/http"
@ -847,7 +848,7 @@ func PrintCommandResults(cmd mig.Command, onlyFound, showAgent bool) (err error)
}
for i, result := range cmd.Results {
if !onlyFound {
for _, rerr := range cmd.Results.Errors {
for _, rerr := range result.Errors {
fmt.Fprintf(os.Stderr, "%s[error] %s\n", prefix, rerr)
}
}
@ -865,10 +866,10 @@ func PrintCommandResults(cmd mig.Command, onlyFound, showAgent bool) (err error)
}
continue
}
modRunner := mig.AvailableModules[moduleName].Runner()
modRunner := modules.Available[moduleName].Runner()
// look for a result printer in the module
if _, ok := modRunner.(mig.HasResultsPrinter); ok {
outRes, err := modRunner.(mig.HasResultsPrinter).PrintResults(result, onlyFound)
if _, ok := modRunner.(modules.HasResultsPrinter); ok {
outRes, err := modRunner.(modules.HasResultsPrinter).PrintResults(result, onlyFound)
if err != nil {
panic(err)
}

Просмотреть файл

@ -10,6 +10,7 @@ import (
"fmt"
"mig"
"mig/client"
"mig/modules"
"os"
"os/signal"
"time"
@ -50,7 +51,7 @@ Results are sent to stdout, redirect them with "1>/path/to/file".
Each module provides its own set of parameters. Module parameters must be set *after*
global options. Help is available by calling "<module> help". Available modules are:
`, os.Args[0], os.Args[0])
for module, _ := range mig.AvailableModules {
for module, _ := range modules.Available {
fmt.Printf("* %s\n", module)
}
fmt.Printf("To access a module documentation, use: %s <module> help\n", os.Args[0])
@ -125,7 +126,7 @@ func main() {
// * fs.Args() with the module parameters is passed as a string to the module parser
// which will return a module operation to store in the action
op.Module = os.Args[1]
if _, ok := mig.AvailableModules[op.Module]; !ok {
if _, ok := modules.Available[op.Module]; !ok {
panic("Unknown module " + op.Module)
}
@ -154,12 +155,12 @@ func main() {
for _, arg := range fs.Args() {
modargs = append(modargs, arg)
}
modRunner = mig.AvailableModules[op.Module].Runner()
if _, ok := modRunner.(mig.HasParamsParser); !ok {
modRunner = modules.Available[op.Module].Runner()
if _, ok := modRunner.(modules.HasParamsParser); !ok {
fmt.Fprintf(os.Stderr, "[error] module '%s' does not support command line invocation\n", op.Module)
os.Exit(2)
}
op.Parameters, err = modRunner.(mig.HasParamsParser).ParamsParser(modargs)
op.Parameters, err = modRunner.(modules.HasParamsParser).ParamsParser(modargs)
if err != nil || op.Parameters == nil {
panic(err)
}

Просмотреть файл

@ -12,6 +12,7 @@ import (
"io"
"mig"
"mig/client"
"mig/modules"
"strconv"
"strings"
"time"
@ -80,15 +81,15 @@ func actionLauncher(tpl mig.Action, cli client.Client) (err error) {
// ParamsCreator takes care of retrieving using input
var operation mig.Operation
operation.Module = orders[1]
if _, ok := mig.AvailableModules[operation.Module]; ok {
if _, ok := modules.Available[operation.Module]; ok {
// instanciate and call module parameters creation function
modRunner := mig.AvailableModules[operation.Module].Runner()
if _, ok := modRunner.(mig.HasParamsCreator); !ok {
modRunner := modules.Available[operation.Module].Runner()
if _, ok := modRunner.(modules.HasParamsCreator); !ok {
fmt.Println(operation.Module, "module does not provide a parameters creator.")
fmt.Println("You can write your action by hand and import it using 'load <file>'")
break
}
operation.Parameters, err = modRunner.(mig.HasParamsCreator).ParamsCreator()
operation.Parameters, err = modRunner.(modules.HasParamsCreator).ParamsCreator()
if err != nil {
fmt.Printf("Parameters creation failed with error: %v\n", err)
break

Просмотреть файл

@ -22,7 +22,7 @@ import (
"fmt"
"hash"
"io"
"mig"
"mig/modules"
"os"
"path"
"path/filepath"
@ -36,14 +36,14 @@ import (
var debug bool = false
func init() {
mig.RegisterModule("file", func() interface{} {
modules.Register("file", func() interface{} {
return new(Runner)
}, false)
})
}
type Runner struct {
Parameters Parameters
Results Results
Results modules.Result
}
type Parameters struct {
@ -618,7 +618,7 @@ var stats statistics
var walkingErrors []string
func (r Runner) Run(Args []byte) (resStr string) {
func (r Runner) Run() (resStr string) {
var (
roots []string
traversed []string
@ -639,7 +639,7 @@ func (r Runner) Run(Args []byte) (resStr string) {
}
}()
t0 := time.Now()
err := json.Unmarshal(Args, &r.Parameters)
err := modules.ReadInputParameters(&r.Parameters)
if err != nil {
panic(err)
}
@ -720,7 +720,9 @@ func (r Runner) Run(Args []byte) (resStr string) {
if debug {
fmt.Println("---- results ----")
printedResults, err := r.PrintResults([]byte(resStr), false)
var tmpres modules.Result
err = json.Unmarshal([]byte(resStr), &tmpres)
printedResults, err := r.PrintResults(tmpres, false)
if err != nil {
panic(err)
}
@ -1292,15 +1294,7 @@ func getHash(file string, hashType checkType) (hexhash string, err error) {
return
}
type Results struct {
FoundAnything bool `json:"foundanything"`
Success bool `json:"success"`
Elements searchresults `json:"elements"`
Statistics statistics `json:"statistics"`
Errors []string `json:"error"`
}
type searchresults map[string]searchresult
type SearchResults map[string]searchresult
type searchresult []matchedfile
@ -1317,8 +1311,8 @@ type fileinfo struct {
}
// newResults allocates a Results structure
func newResults() *Results {
return &Results{Elements: make(searchresults), FoundAnything: false}
func newResults() *modules.Result {
return &modules.Result{Elements: make(SearchResults), FoundAnything: false}
}
func (r Runner) buildResults(t0 time.Time) (resStr string, err error) {
@ -1328,6 +1322,7 @@ func (r Runner) buildResults(t0 time.Time) (resStr string, err error) {
}
}()
res := newResults()
elements := res.Elements.(SearchResults)
for label, search := range r.Parameters.Searches {
var sr searchresult
// first pass on the results: if matchall is set, verify that all
@ -1462,7 +1457,7 @@ func (r Runner) buildResults(t0 time.Time) (resStr string, err error) {
}
}
nextsearch:
res.Elements[label] = sr
elements[label] = sr
}
// calculate execution time
@ -1501,13 +1496,21 @@ func (r Runner) buildResults(t0 time.Time) (resStr string, err error) {
// only results that have at least one match are returned.
// If foundOnly is not set, all results are returned, along with errors and
// statistics.
func (r Runner) PrintResults(rawResults []byte, foundOnly bool) (prints []string, err error) {
var results Results
err = json.Unmarshal(rawResults, &results)
func (r Runner) PrintResults(result modules.Result, foundOnly bool) (prints []string, err error) {
var (
el SearchResults
stats statistics
)
err = result.GetElements(&el)
if err != nil {
panic(err)
}
for label, sr := range results.Elements {
err = result.GetStatistics(&stats)
if err != nil {
panic(err)
}
for label, sr := range el {
for _, mf := range sr {
var out string
if mf.File == "" {
@ -1571,12 +1574,12 @@ func (r Runner) PrintResults(rawResults []byte, foundOnly bool) (prints []string
}
}
if !foundOnly {
for _, we := range results.Errors {
for _, we := range result.Errors {
prints = append(prints, we)
}
stat := fmt.Sprintf("Statistics: %.0f files checked, %.0f failed to open, %.0f matched, ran in %s.",
results.Statistics.Filescount, results.Statistics.Openfailed,
results.Statistics.Totalhits, results.Statistics.Exectime)
stats.Filescount, stats.Openfailed,
stats.Totalhits, stats.Exectime)
prints = append(prints, stat)
}
return

Просмотреть файл

@ -15,8 +15,8 @@ import (
// Message defines the input messages received by modules.
type Message struct {
Class string // represent the type of message being passed to the module
Parameters interface{} // for `parameters` class, this interface contains the module parameters
Class string `json:"class"` // represent the type of message being passed to the module
Parameters interface{} `json:"parameters"` // for `parameters` class, this interface contains the module parameters
}
const (
@ -74,6 +74,12 @@ type Moduler interface {
ValidateParameters() error
}
func MakeParametersMessage(params interface{}) (ret Message) {
ret.Class = MsgClassParameters
ret.Parameters = params
return
}
// ReadInput reads one line of input from stdin, unmarshal it into a modules.Message
// and returns the message to the caller
func ReadInput() (msg Message, err error) {

Просмотреть файл

@ -11,6 +11,7 @@ import (
"fmt"
"github.com/streadway/amqp"
"mig"
"mig/modules"
"mig/pgp"
"os"
"runtime"
@ -133,7 +134,7 @@ func processNewAction(actionPath string, ctx Context) (err error) {
ctx.Channels.Log <- mig.Log{OpID: ctx.OpID, ActionID: action.ID, Desc: "Action written to database"}.Debug()
// create an array of empty results to serve as default for all commands
emptyResults := make([]mig.ModuleResult, len(action.Operations))
emptyResults := make([]modules.Result, len(action.Operations))
created := 0
for _, agent := range agents {
err := createCommand(ctx, action, agent, emptyResults)
@ -161,7 +162,7 @@ func processNewAction(actionPath string, ctx Context) (err error) {
return
}
func createCommand(ctx Context, action mig.Action, agent mig.Agent, emptyResults []mig.ModuleResult) (err error) {
func createCommand(ctx Context, action mig.Action, agent mig.Agent, emptyResults []modules.Result) (err error) {
cmdid := mig.GenID()
defer func() {
if e := recover(); e != nil {

Просмотреть файл

@ -13,6 +13,7 @@ import (
"github.com/jvehent/gozdef"
"mig"
"mig/event"
"mig/modules"
"mig/modules/file"
"mig/workers"
"os"
@ -141,12 +142,17 @@ func makeComplianceItem(cmd mig.Command, conf Config) (items []gozdef.Compliance
}
switch cmd.Action.Operations[i].Module {
case "file":
var r file.Results
var r modules.Result
var el file.SearchResults
err = json.Unmarshal(buf, &r)
if err != nil {
return items, err
}
for label, sr := range r.Elements {
err = r.GetElements(&el)
if err != nil {
return items, err
}
for label, sr := range el {
for _, mf := range sr {
ci.Check.Location = mf.File
ci.Check.Name = label