From: Sergey Matveev Date: Wed, 13 Jan 2016 19:33:57 +0000 (+0300) Subject: Use ssh/terminal package for reading passwords directly from terminal X-Git-Tag: 5.2^2 X-Git-Url: http://www.git.cypherpunks.ru/?p=govpn.git;a=commitdiff_plain;h=ee26626bd18e74679c46caf140772f27e5814cfa Use ssh/terminal package for reading passwords directly from terminal Signed-off-by: Sergey Matveev --- diff --git a/VERSION b/VERSION index a75b92f..ef425ca 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -5.1 +5.2 diff --git a/common.mk b/common.mk index 30ac491..95349c4 100644 --- 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)/* diff --git a/doc/client.texi b/doc/client.texi index f184577..ba75038 100644 --- a/doc/client.texi +++ b/doc/client.texi @@ -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. diff --git a/doc/example.texi b/doc/example.texi index 8a52ef7..fe00545 100644 --- a/doc/example.texi +++ b/doc/example.texi @@ -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 diff --git a/doc/news.texi b/doc/news.texi index da5e9b2..608613a 100644 --- a/doc/news.texi +++ b/doc/news.texi @@ -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 diff --git a/doc/verifier.texi b/doc/verifier.texi index 779f247..861bef0 100644 --- a/doc/verifier.texi +++ b/doc/verifier.texi @@ -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. diff --git a/src/govpn/cmd/govpn-client/main.go b/src/govpn/cmd/govpn-client/main.go index c441405..e73854c 100644 --- a/src/govpn/cmd/govpn-client/main.go +++ b/src/govpn/cmd/govpn-client/main.go @@ -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") diff --git a/src/govpn/cmd/govpn-verifier/main.go b/src/govpn/cmd/govpn-verifier/main.go index 876d9a5..10bd90b 100644 --- a/src/govpn/cmd/govpn-verifier/main.go +++ b/src/govpn/cmd/govpn-verifier/main.go @@ -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[:])) } diff --git a/src/govpn/verifier.go b/src/govpn/verifier.go index ba51846..0dc9388 100644 --- a/src/govpn/verifier.go +++ b/src/govpn/verifier.go @@ -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 } diff --git a/utils/makedist.sh b/utils/makedist.sh index 18fa7e1..2a6ee31 100755 --- a/utils/makedist.sh +++ b/utils/makedist.sh @@ -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 diff --git a/utils/newclient.sh b/utils/newclient.sh index 44c7ef5..aebc975 100755 --- a/utils/newclient.sh +++ b/utils/newclient.sh @@ -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 index 299883d..0000000 --- a/utils/storekey.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -e - -[ -n "$1" ] || { - cat < -EOF - exit 1 -} - -echo -n Enter passphrase: -stty -echo -read passphrase -stty echo -umask 077 -cat > $1 <