]> Cypherpunks.ru repositories - govpn.git/commitdiff
Use ssh/terminal package for reading passwords directly from terminal
authorSergey Matveev <stargrave@stargrave.org>
Wed, 13 Jan 2016 19:33:57 +0000 (22:33 +0300)
committerSergey Matveev <stargrave@stargrave.org>
Wed, 13 Jan 2016 19:35:42 +0000 (22:35 +0300)
Signed-off-by: Sergey Matveev <stargrave@stargrave.org>
12 files changed:
VERSION
common.mk
doc/client.texi
doc/example.texi
doc/news.texi
doc/verifier.texi
src/govpn/cmd/govpn-client/main.go
src/govpn/cmd/govpn-verifier/main.go
src/govpn/verifier.go
utils/makedist.sh
utils/newclient.sh
utils/storekey.sh [deleted file]

diff --git a/VERSION b/VERSION
index a75b92f1ed766132f8e6b71376143c6a7111021a..ef425ca98208c00037caa6df391724cc8762d239 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-5.1
+5.2
index 30ac491b052e0d23d9ca91f384575b8da0e45c27..95349c4699392e8227b3f2be75dd2b2cfe697651 100644 (file)
--- a/common.mk
+++ b/common.mk
@@ -35,8 +35,8 @@ install: all doc
        cp -f doc/govpn.info $(INFODIR)
        chmod 644 $(INFODIR)/govpn.info
        mkdir -p $(SHAREDIR)
-       cp -f utils/newclient.sh utils/storekey.sh $(SHAREDIR)
-       chmod 755 $(SHAREDIR)/newclient.sh $(SHAREDIR)/storekey.sh
+       cp -f utils/newclient.sh $(SHAREDIR)
+       chmod 755 $(SHAREDIR)/newclient.sh
        mkdir -p $(DOCDIR)
        cp -f -L AUTHORS INSTALL NEWS README README.RU THANKS $(DOCDIR)
        chmod 644 $(DOCDIR)/*
index f1845772cf9e0687743f1c4c02244d66ba347521..ba7503874b41e9e02e3b1334929ddbc4486fc3eb 100644 (file)
@@ -37,8 +37,8 @@ TAP interface name.
 Our client's @ref{Verifier}.
 
 @item -key
-Path to the file with the passphrase. See @ref{Verifier} for
-how to enter passphrase from stdin silently and store it in the file.
+Path to the file with the passphrase. If omitted, then you will be asked
+to enter it in the terminal.
 
 @item -timeout
 @ref{Timeout} setting in seconds.
index 8a52ef7a393a6c8bfaee03b7bf0a9116070db839..fe00545854bd630794b5afedcd5920369aa202ae 100644 (file)
@@ -26,7 +26,7 @@ example:
 
 @verbatim
 client% ./utils/newclient.sh Alice
-Enter passphrase:
+Passphrase:
 Your client verifier is: $argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg
 
 Place the following YAML configuration entry on the server's side:
@@ -35,11 +35,6 @@ Place the following YAML configuration entry on the server's side:
         up: /path/to/up.sh
         iface: or TAP interface name
         verifier: $argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg$KCNIqfS4DGsBTtVytamAzcISgrlEWvNxan1UfBrFu10
-
-Verifier was generated with:
-
-    ./utils/storekey.sh /tmp/passphrase
-    govpn-verifier -key /tmp/passphrase
 @end verbatim
 
 @strong{Prepare the server}. Add this entry to @code{peers.yaml}
@@ -54,7 +49,6 @@ Alice:
 @strong{Prepare network on GNU/Linux IPv4 server}:
 
 @example
-server% umask 077
 server% ip addr add 192.168.0.1/24 dev wlan0
 server% tunctl -t tap10
 server% ip addr add 172.16.0.1/24 dev tap10
@@ -70,8 +64,6 @@ server% govpn-server -bind 192.168.0.1:1194
 @strong{Prepare network on GNU/Linux IPv4 client}:
 
 @example
-client% umask 066
-client% utils/storekey.sh key.txt
 client% ip addr add 192.168.0.2/24 dev wlan0
 client% tunctl -t tap10
 client% ip addr add 172.16.0.2/24 dev tap10
@@ -82,7 +74,6 @@ client% ip route add default via 172.16.0.1
 @strong{Run client daemon itself}:
 @example
 client% govpn-client \
-    -key key.txt \
     -verifier '$argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg' \
     -iface tap10 \
     -remote 192.168.0.1:1194
@@ -101,7 +92,6 @@ client% ifconfig tap10
 client% ifconfig tap10 inet6 fc00::2/96 up
 client% route -6 add default fc00::1
 client% govpn-client \
-    -key key.txt \
     -verifier '$argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg' \
     -iface tap10 \
     -remote "[fe80::1%me0]":1194
index da5e9b28917f88dde29cf550be615e8d4bb2a637..608613a93689fd2ca87430ac8dfe02190c5a8ccc 100644 (file)
@@ -5,6 +5,13 @@
 
 @table @strong
 
+@item Release 5.2
+@cindex Release 5.2
+@itemize
+@item Ability to read passphrases directly from the terminal (user's
+input) without using of keyfiles. @code{storekey.sh} utility removed.
+@end itemize
+
 @item Release 5.1
 @cindex Release 5.1
 @itemize
index 779f247f9e3fd81d725cb0c894db667b7e68a332..861bef0a25ee6cbd76146b8e0211571f908f3f5d 100644 (file)
@@ -1,18 +1,13 @@
 @node Verifier
 @cindex Verifier
-@cindex storekey.sh
 @cindex govpn-verifier
 @subsection Verifier
 
-Verifier is created using @code{govpn-verifier} utility. But currently
-Go does not provide native instruments to read passwords without echoing
-them to stdout. You can use @code{utils/storekey.sh} script to read them
-silently.
+Verifier is created using @code{govpn-verifier} utility.
 
 @example
-% utils/storekey.sh mypass.txt
-Enter passphrase:[hello world]
-% govpn-verifier -key mypass.txt
+% govpn-verifier
+Passphrase:[hello world]
 $argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg$KCNIqfS4DGsBTtVytamAzcISgrlEWvNxan1UfBrFu10
 $argon2d$m=4096,t=128,p=1$bwR5VjeCYIQaa8SeaI3rqg
 @end example
@@ -25,10 +20,11 @@ You can check passphrase against verifier by specifying @code{-verifier}
 option with the path to verifier file:
 
 @example
-% govpn-verifier -key mypass.txt -verifier '$argon2d...'
+% govpn-verifier -verifier '$argon2d...'
+Passphrase:[hello world]
 true
 @end example
 
-Plaintext passphrases @strong{must} be stored on volatile memory, for
-example either in memory disk, or on encrypted filesystem with
-restrictive permissions to the file.
+Optionally you can store plaintext passphrases on volatile memory
+(memory disk, encrypted filesystem with restrictive permissions to the
+file) and provide @code{-key} option.
index c4414050937f20e9740a3233d6e2d0c1fcac193e..e73854cb482e1246fdfa96fdb1188de17e69ecf1 100644 (file)
@@ -74,7 +74,11 @@ func main() {
        if err != nil {
                log.Fatalln(err)
        }
-       priv := verifier.PasswordApply(govpn.StringFromFile(*keyPath))
+       key, err := govpn.KeyRead(*keyPath)
+       if err != nil {
+               log.Fatalln("Unable to read the key", err)
+       }
+       priv := verifier.PasswordApply(key)
        if *encless {
                if *proto != "tcp" {
                        log.Fatalln("Currently encryptionless mode works only with TCP")
index 876d9a53cedb37e36e59f846d1a6a9edc208c650..10bd90b0902e2c934c8c435cc3b5e5e9dbce1a48 100644 (file)
@@ -42,6 +42,10 @@ func main() {
        if *egdPath != "" {
                govpn.EGDInit(*egdPath)
        }
+       key, err := govpn.KeyRead(*keyPath)
+       if err != nil {
+               log.Fatalln("Unable to read the key", err)
+       }
        if *verifier == "" {
                id := new([govpn.IDSize]byte)
                if _, err := govpn.Rand.Read(id[:]); err != nil {
@@ -49,7 +53,7 @@ func main() {
                }
                pid := govpn.PeerId(*id)
                v := govpn.VerifierNew(*mOpt, *tOpt, *pOpt, &pid)
-               v.PasswordApply(govpn.StringFromFile(*keyPath))
+               v.PasswordApply(key)
                fmt.Println(v.LongForm())
                fmt.Println(v.ShortForm())
                return
@@ -62,6 +66,6 @@ func main() {
                log.Fatalln("Verifier does not contain public key")
        }
        pub := *v.Pub
-       v.PasswordApply(govpn.StringFromFile(*keyPath))
+       v.PasswordApply(key)
        fmt.Println(bytes.Equal(v.Pub[:], pub[:]))
 }
index ba51846ce23eb17c42b4a9b9fcc5d0333f848bbc..0dc9388188ad0e1f0c29eec611e7218cae32b687 100644 (file)
@@ -29,6 +29,7 @@ import (
 
        "github.com/agl/ed25519"
        "github.com/magical/argon2"
+       "golang.org/x/crypto/ssh/terminal"
 )
 
 const (
@@ -117,11 +118,26 @@ func (v *Verifier) LongForm() string {
        )
 }
 
-// Read string from the file, trimming newline.
-func StringFromFile(path string) string {
-       s, err := ioutil.ReadFile(path)
+// Read the key either from text file (if path is specified), or
+// from the terminal.
+func KeyRead(path string) (string, error) {
+       var p []byte
+       var err error
+       var pass string
+       if path == "" {
+               fmt.Print("Passphrase:")
+               p, err = terminal.ReadPassword(0)
+               fmt.Print("\n")
+               pass = string(p)
+       } else {
+               p, err = ioutil.ReadFile(path)
+               pass = strings.TrimRight(string(p), "\n")
+       }
        if err != nil {
-               log.Fatalln("Can not read string from", path, err)
+               return "", err
+       }
+       if len(pass) == 0 {
+               return "", errors.New("Empty passphrase submitted")
        }
-       return strings.TrimRight(string(s), "\n")
+       return pass, err
 }
index 18fa7e18c30f72aeadc74b97ecb2245233b0cc95..2a6ee311f36610e0de9c7080fe83defb77b79d0b 100755 (executable)
@@ -32,6 +32,7 @@ golang.org/x/crypto/README
 golang.org/x/crypto/curve25519
 golang.org/x/crypto/poly1305
 golang.org/x/crypto/salsa20
+golang.org/x/crypto/ssh/terminal
 golang.org/x/crypto/xtea
 EOF
 tar cfCI - src $tmp/includes | tar xfC - $tmp
index 44c7ef5e977c044a369a26ad1c1ce185dcaad996..aebc975b52e2f0f37c9810e925963733094e6781 100755 (executable)
@@ -14,11 +14,7 @@ EOF
 }
 
 username=$1
-umask 077
-passphrase=$(mktemp)
-$(dirname $0)/storekey.sh $passphrase
-verifier=$(govpn-verifier -key $passphrase)
-rm -f $passphrase
+verifier=$(govpn-verifier)
 verifierS=$(echo $verifier | sed 's/^\(.*\) .*$/\1/')
 verifierC=$(echo $verifier | sed 's/^.* \(.*\)$/\1/')
 echo
@@ -32,9 +28,4 @@ Place the following YAML configuration entry on the server's side:
         up: /path/to/up.sh
         iface: or TAP interface name
         verifier: $verifierS
-
-Verifier was generated with:
-
-    $(dirname $0)/storekey.sh /tmp/passphrase
-    govpn-verifier -key /tmp/passphrase
 EOF
diff --git a/utils/storekey.sh b/utils/storekey.sh
deleted file mode 100755 (executable)
index 299883d..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/sh -e
-
-[ -n "$1" ] || {
-    cat <<EOF
-Read passphrase from stdin and store it in file.
-
-Usage: $0 <keyfilename>
-EOF
-    exit 1
-}
-
-echo -n Enter passphrase:
-stty -echo
-read passphrase
-stty echo
-umask 077
-cat > $1 <<EOF
-$passphrase
-EOF