Create veracrypt volumes using golang

328 Views Asked by At

Trying to pass go command line instructions to start veracrypt but it gets exit status 1 or doesn't show an error and doesn't create the requested volume.

func main() {
    cmd := exec.Command("veracrypt",
        "-c", "/home/user/test/samplevolume.vcrypt",
        "--volume-type", "normal",
        "--filesystem", "FAT",
        "--hash", "SHA256",
        "--encryption", "AES",
        "--size", "10M",
        "--pim", "1234",
        "-k", "",
        "--random-source", "/home/user/test/README.md")

    var out bytes.Buffer
    var stderr bytes.Buffer
    cmd.Stderr = &stderr

    stdin, err := cmd.StdinPipe()
    if err != nil {
        fmt.Println(fmt.Sprint(err))
    }

    go func() {
        defer stdin.Close()
        err = cmd.Run()
        // io.WriteString(stdin, "1234")
        // io.WriteString(stdin, "y")
        // io.WriteString(stdin, "1234")
    }()

    if err != nil {
        fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
        return
    }
    fmt.Println("Result: " + out.String())
    // outin, err := cmd.CombinedOutput()
    // if err != nil {
    //  log.Fatal(err)
    // }

    // fmt.Printf("%s\n", outin)
}

The commented part is the other approach that I used which results in exit status 1.

The reason for passing the 3 strings at the end "1234", y, "1234" is because we want to enter the password interactively.

The code doesn't end up creating the veracrypt files.

here is the commandline instructions for veracrypt that we are trying to invoke using golang.

veracrypt -c ~/test/samplevolume.vcrypt --volume-type normal --filesystem FAT --hash SHA256 --encryption AES --size 10M --pim 1234 -k= --random-source ~/test/README.md

Note: Everything is on linux if that matters.

Edit: Also, I am new to golang, sorry if I have made an obvious mistake.

2

There are 2 best solutions below

0
On BEST ANSWER

So I figured out what I was doing wrong. I should have been using the cmd.Start and cmd.Wait. so here is the corrected version. This version can also take user input correctly.

func main() {
    cmd := exec.Command("veracrypt",
        "-c", "/home/user/test/samplevolume.vcrypt",
        "--volume-type", "normal",
        "--filesystem", "FAT",
        "--hash", "SHA256",
        "--encryption", "AES",
        "--size", "10M",
        "--pim", "1234",
        "-k", "",
        "--random-source", "/home/user/test/README.md")

    var out bytes.Buffer
    var stderr bytes.Buffer
    cmd.Stderr = &stderr

    stdin, err := cmd.StdinPipe()
    if err != nil {
        fmt.Println(fmt.Sprint(err))
    }

    go func() {
        defer stdin.Close()
        err = cmd.Start()
        io.WriteString(stdin, "1234\n")
        io.WriteString(stdin, "y\n")
        io.WriteString(stdin, "1234\n")
    }()

    if err != nil {
        fmt.Println(fmt.Sprint(err) + ": " + stderr.String())
        return
    }

    err = cmd.Wait()
    if err != nil {
        fmt.Printf("Command finished with error: %v", err)
    }

    fmt.Println("Result: " + out.String())
}
3
On

You have used the tilde symbol ~ in your path names, but this is not a valid character at the beginning of a Unix path.

Rather, some shells substitute the tilde with the path of the user's home directory before passing it on to the operating system.

Because you are not using a shell, you must provide the actual directory yourself. You cannot use the tilde in the beginning of the paths.