mirror of
https://github.com/fleetdm/fleet
synced 2026-04-25 07:27:33 +00:00
91 lines
2.3 KiB
Go
91 lines
2.3 KiB
Go
// based on github.com/kolide/launcher/pkg/osquery/tables
|
|
package cryptsetup
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// parseStatus parses the output from `cryptsetup status`. This is a
|
|
// pretty simple key, value format, but does have a free form first
|
|
// line. It's not clear if this is going to be stable, or change
|
|
// across versions.
|
|
func parseStatus(rawdata []byte) (map[string]interface{}, error) {
|
|
var data map[string]interface{}
|
|
|
|
if len(rawdata) == 0 {
|
|
return nil, errors.New("No data")
|
|
}
|
|
|
|
scanner := bufio.NewScanner(bytes.NewReader(rawdata))
|
|
firstLine := true
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
if firstLine {
|
|
var err error
|
|
data, err = parseFirstLine(line)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
firstLine = false
|
|
continue
|
|
}
|
|
|
|
kv := strings.SplitN(line, ": ", 2)
|
|
|
|
// blank lines, or other unexpected input can just be skipped.
|
|
if len(kv) < 2 {
|
|
continue
|
|
}
|
|
|
|
data[strings.ReplaceAll(strings.TrimSpace(kv[0]), " ", "_")] = strings.TrimSpace(kv[1])
|
|
}
|
|
|
|
return data, nil
|
|
}
|
|
|
|
// regexp for the first line of the status output.
|
|
var firstLineRegexp = regexp.MustCompile(`^(?:Device (.*) (not found))|(?:(.*?) is ([a-z]+)(?:\.| and is (in use)))`)
|
|
|
|
// parseFirstLine parses the first line of the status output. This
|
|
// appears to be a free form string indicating several pieces of
|
|
// information. It is parsed with a single regexp. (See tests for
|
|
// examples)
|
|
func parseFirstLine(line string) (map[string]interface{}, error) {
|
|
if line == "" {
|
|
return nil, errors.New("Invalid first line")
|
|
}
|
|
|
|
m := firstLineRegexp.FindAllStringSubmatch(line, -1)
|
|
if len(m) != 1 {
|
|
return nil, fmt.Errorf("Failed to match first line: %s", line)
|
|
}
|
|
if len(m[0]) != 6 {
|
|
return nil, fmt.Errorf("Got %d matches. Expected 6. Failed to match first line: %s", len(m[0]), line)
|
|
}
|
|
|
|
data := make(map[string]interface{}, 3)
|
|
|
|
// check for $1 and $2 for the error condition
|
|
if m[0][1] != "" && m[0][2] != "" {
|
|
data["short_name"] = m[0][1]
|
|
data["status"] = strings.ReplaceAll(m[0][2], " ", "_")
|
|
data["mounted"] = strconv.FormatBool(false)
|
|
return data, nil
|
|
}
|
|
|
|
if m[0][3] != "" && m[0][4] != "" {
|
|
data["display_name"] = m[0][3]
|
|
data["status"] = strings.ReplaceAll(m[0][4], " ", "_")
|
|
data["mounted"] = strconv.FormatBool(m[0][5] != "")
|
|
return data, nil
|
|
}
|
|
|
|
return nil, fmt.Errorf("Unknown first line: %s", line)
|
|
}
|