/volumes_linux.go
https://gitlab.com/rollbrettler/lachs · Go · 128 lines · 105 code · 19 blank · 4 comment · 26 complexity · a270f18b2dae2b5ae803b823ecc09594 MD5 · raw file
- package lachs
- import (
- "bufio"
- "bytes"
- "log"
- "os/exec"
- "regexp"
- )
- var execCommand = exec.Command
- var execLookPath = exec.LookPath
- var blockDeviceRegex = `(?P<path>.*):(\sSEC_TYPE=\"(.*)\")?(\sLABEL=\"(?P<label>.*)\")?\sUUID=\"(?P<uuid>.*)\"\sTYPE=\"(?P<type>\w*)\"(\sPARTUUID=\"(.*)\")?`
- // Volume represents an encrypted volume
- type Volume struct {
- Path string `json:"path"`
- UUID string `json:"uuid"`
- Type string `json:"type"`
- Unlocked bool `json:"unlocked"`
- }
- // Open opens the encrypted volume
- func (v *Volume) Open(password, mount string) error {
- cryptsetup, err := execLookPath("cryptsetup")
- if err != nil {
- return err
- }
- cmd := execCommand(cryptsetup, "luksOpen", v.Path, mount)
- var stdin bytes.Buffer
- stdin.Write([]byte(password))
- cmd.Stdin = &stdin
- output, err := cmd.Output()
- log.Printf("Luks output: %v\n", string(output))
- if err != nil {
- return err
- }
- return nil
- }
- func (v *Volume) isUnlocked() bool {
- lsblk, err := execLookPath("lsblk")
- if err != nil {
- return false
- }
- cmd := execCommand(lsblk, "-n", "-o", "TYPE", v.Path)
- var stderr bytes.Buffer
- stderr.Write([]byte(""))
- cmd.Stderr = &stderr
- out, err := cmd.Output()
- if err != nil {
- log.Printf("Error from lsblk command: %v | %v | %v\n", err, cmd.Stderr, out)
- return false
- }
- buffer := bytes.NewBuffer(out)
- if len(buffer.Bytes()) == 0 {
- return false
- }
- scanner := bufio.NewScanner(buffer)
- for scanner.Scan() {
- if scanner.Text() == "crypt" {
- return true
- }
- }
- return false
- }
- // Volumes holds all read volumes
- type Volumes struct {
- List []Volume
- }
- // Read reads volumes from the underlying system
- func (vs *Volumes) Read() error {
- blkidPath, err := execLookPath("blkid")
- if err != nil {
- log.Print("blkid cannot be found in $PATH")
- return err
- }
- out, err := execCommand(blkidPath, "-t", "TYPE=crypto_LUKS").Output()
- if err != nil {
- log.Printf("Error from blkid command: %v %v\n", err, out)
- return err
- }
- buffer := bytes.NewBuffer(out)
- if len(buffer.Bytes()) == 0 {
- return nil
- }
- scanner := bufio.NewScanner(buffer)
- for scanner.Scan() {
- blockDeviceRegexp, err := regexp.Compile(blockDeviceRegex)
- if err != nil {
- return err
- }
- match := blockDeviceRegexp.FindStringSubmatch(scanner.Text())
- v := Volume{}
- if match != nil {
- for i, name := range blockDeviceRegexp.SubexpNames() {
- switch name {
- case "uuid":
- v.UUID = match[i]
- case "type":
- v.Type = match[i]
- case "path":
- v.Path = match[i]
- }
- }
- v.Unlocked = v.isUnlocked()
- vs.append(v)
- }
- }
- return nil
- }
- func (vs *Volumes) append(v Volume) {
- vs.List = append(vs.List, v)
- }