tAllow providing the password on the CLI - cream - Stream encryption utility
 (HTM) git clone git://git.z3bra.org/cream.git
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
       ---
 (DIR) commit fcfffac48aed0854a2aae5858cf57fb6af29d479
 (DIR) parent e490d40348998c25c3823185e2adf15e1ceab87e
 (HTM) Author: Willy Goiffon <contact@z3bra.org>
       Date:   Tue, 31 Jan 2023 10:25:33 +0100
       
       Allow providing the password on the CLI
       
       Diffstat:
         M cream.1                             |      19 ++++++++++++++++---
         M cream.go                            |      25 +++++++++++++++----------
       
       2 files changed, 31 insertions(+), 13 deletions(-)
       ---
 (DIR) diff --git a/cream.1 b/cream.1
       t@@ -11,11 +11,14 @@
        .Op Fl j Ar thread
        .Op Fl t Ar time
        .Op Fl m Ar memory
       +.Op Fl p Ar pass
        .Op Fl s Ar salt
        .Op Fl f Ar file
        .Sh DESCRIPTION
        .Nm
        encrypts and decrypts continuous flows of data, from a password.
       +The password can be provided on the command line, or interactively
       +via the terminal.
        .Pp
        The name is a portemanteau for crypto + stream.
        .Bl -tag -width Ds
       t@@ -48,6 +51,12 @@ Number of parallel threads used. Default: 4.
        Read/write encrypted data from/to
        .Ar file ,
        Depending on the operation mode.
       +.It Fl p Ar pass
       +Derivate the private key from the string
       +.Ar pass .
       +By default, the user will be prompted for the password on the terminal.
       +(See
       +.Sx SECURITY CONSIDERATIONS )
        .It Fl s Ar salt
        Read salt data from
        .Ar salt .
       t@@ -57,6 +66,10 @@ for details about the salt.
        .It Fl h
        Print a quick usage text.
        .El
       +.Sh SECURITY CONSIDERATIONS
       +Providing a password on the command line can be insecure. It could be
       +saved in the shell history, or leaked to processes that can read the
       +process tree.
        .Sh CRYPTOGRAPHIC CONSIDERATIONS
        Cryptographic parameters can be changed from the command line.
        These values will directly affect the time it takes to compute the key,
       t@@ -78,12 +91,12 @@ for each command).
          cream -d < secret.enc > kitten.gif
        .Ed
        .Pp
       -Encrypt multiple files with the same key. This assumes that you input
       -the same password for each call:
       +Encrypt multiple files with the same key. This assumes that 
       +the password is stored in the $PASSWORD environment variable:
        .Bd -literal
          dd if=/dev/urandom of=./salt bs=16 count=1
          for file in *.gif; do
       -    cream -s ./salt < $file > $file.enc
       +    cream -s ./salt -p "$PASSWORD" < $file > $file.enc
          done
        .Ed
        .Sh SEE ALSO
 (DIR) diff --git a/cream.go b/cream.go
       t@@ -40,7 +40,7 @@ type Header struct {
        }
        
        func usage() {
       -        fmt.Printf("usage: %s [-hed] [-b size] [-j thread] [-t time] [-m memory] [-s salt] [-f file]\n", os.Args[0])
       +        fmt.Printf("usage: %s [-hed] [-b size] [-j thread] [-t time] [-m memory] [-p pass] [-s salt] [-f file]\n", os.Args[0])
                os.Exit(2)
        }
        
       t@@ -143,7 +143,7 @@ func decrypt(in *os.File, out *os.File, skip int, key []byte, blen uint32) {
        func main() {
                var err error
                var key, pass []byte
       -        var filename, saltfile string
       +        var password, filename, saltfile string
                var dflag, eflag bool
        
                var time uint64
       t@@ -160,6 +160,7 @@ func main() {
        
                key = make([]byte, chacha20poly1305.KeySize)
        
       +        flag.StringVar(&password, "p", "", "Password")
                flag.StringVar(&filename, "f", "", "Encrypt/decrypt to/from file name")
                flag.StringVar(&saltfile, "s", "", "Read salt from file (encrypt-only)")
                flag.BoolVar(&eflag, "e", false, "encrypt input (default)")
       t@@ -188,15 +189,19 @@ func main() {
                        usage()
                }
        
       -        // Prompt user for password
       -        tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0644)
       -        if err != nil {
       -                log.Fatal(err)
       +        pass = []byte(password)
       +
       +        // Prompt user for password if provided password is empty
       +        if len(pass) == 0 {
       +                tty, err := os.OpenFile("/dev/tty", os.O_RDWR, 0644)
       +                if err != nil {
       +                        log.Fatal(err)
       +                }
       +                defer tty.Close()
       +                fmt.Fprint(tty, "password:")
       +                pass, _ = term.ReadPassword(int(tty.Fd()))
       +                fmt.Fprintln(tty, "")
                }
       -        defer tty.Close()
       -        fmt.Fprint(tty, "password:")
       -        pass, _ = term.ReadPassword(int(tty.Fd()))
       -        fmt.Fprintln(tty, "")
        
                if dflag {
                        if len(filename) > 0 {