fleet/server/datastore/mysql/file_integrity_monitoring.go
John Murphy d5f9fcaeb2 Added FIM support (#1548)
This PR adds support for file integrity monitoring. This is done by providing a simplified API that can be used to PATCH/GET FIM configurations. There is also code to build the FIM configuration to send back to osquery. Each PATCH request, if successful, replaces Fleet's existing FIM configuration. For example:

curl -X "PATCH" "https://localhost:8080/api/v1/kolide/fim" \
     -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzZXNzaW9uX2tleSI6IkVhaFhvZWswMGtWSEdaTTNCWndIMnhpYWxkNWZpcVFDR2hEcW1HK2UySmRNOGVFVE1DeTNTaUlFWmhZNUxhdW1ueFZDV2JiR1Bwdm5TKzdyK3NJUzNnPT0ifQ.SDCHAUA1vTuWGjXtcQds2GZLM27HAAiOUhR4WvgvTNY" \
     -H "Content-Type: application/json; charset=utf-8" \
     -d $'{
  "interval": 500,
  "file_paths": {
    "etc": [
      "/etc/%%"
    ],
    "users": [
      "/Users/%/Library/%%",
      "/Users/%/Documents/%%"
    ],
    "usr": [
      "/usr/bin/%%"
    ]
  }
}'
2017-08-18 10:37:33 -05:00

75 lines
1.9 KiB
Go

package mysql
import (
"database/sql"
"github.com/kolide/fleet/server/kolide"
"github.com/pkg/errors"
)
func (d *Datastore) NewFIMSection(fp *kolide.FIMSection, opts ...kolide.OptionalArg) (result *kolide.FIMSection, err error) {
db := d.getTransaction(opts)
sqlStatement := `
INSERT INTO file_integrity_monitorings (
section_name,
description
) VALUES( ?, ?)
`
var resp sql.Result
resp, err = db.Exec(sqlStatement, fp.SectionName, fp.Description)
if isDuplicate(err) {
return nil, alreadyExists("fim_section", 0)
}
if err != nil {
return nil, errors.Wrap(err, "creating fim section")
}
id, _ := resp.LastInsertId()
fp.ID = uint(id)
sqlStatement = `
INSERT INTO file_integrity_monitoring_files (
file,
file_integrity_monitoring_id
) VALUES( ?, ? )
`
for _, fileName := range fp.Paths {
_, err = db.Exec(sqlStatement, fileName, fp.ID)
if err != nil {
return nil, errors.Wrap(err, "adding path to fim section")
}
}
return fp, nil
}
func (d *Datastore) ClearFIMSections() error {
sqlStatement := "DELETE FROM file_integrity_monitorings"
_, err := d.db.Exec(sqlStatement)
return err
}
func (d *Datastore) FIMSections() (kolide.FIMSections, error) {
sqlStatement := `
SELECT fim.section_name, mf.file FROM
file_integrity_monitorings AS fim
INNER JOIN file_integrity_monitoring_files AS mf
ON (fim.id = mf.file_integrity_monitoring_id)
`
rows, err := d.db.Query(sqlStatement)
if err != nil {
if err == sql.ErrNoRows {
return nil, notFound("FilePath")
}
return nil, errors.Wrap(err, "retrieving fim sections")
}
result := make(kolide.FIMSections)
for rows.Next() {
var sectionName, fileName string
err = rows.Scan(&sectionName, &fileName)
if err != nil {
return nil, errors.Wrap(err, "retrieving path for fim section")
}
result[sectionName] = append(result[sectionName], fileName)
}
return result, nil
}