Search code examples
gocommand-lineveracrypt

Create veracrypt volumes using golang


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.


Solution

  • 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())
    }