forked from skeeto/passphrase2pgp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
terminal.go
59 lines (54 loc) · 1.21 KB
/
terminal.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
package main
import (
"bytes"
"errors"
"fmt"
"io"
"os"
"syscall"
"golang.org/x/crypto/ssh/terminal"
)
// Read, confirm, and return a passphrase from the user via terminal.
func terminalPassphrase(hint string, repeat int) ([]byte, error) {
fd := int(syscall.Stdin)
var out io.Writer = os.Stderr
if !terminal.IsTerminal(fd) {
tty, err := os.Create("/dev/tty") // O_RDWR
if err != nil {
fatal("failed to open /dev/tty")
}
defer tty.Close()
fd = int(tty.Fd())
out = tty
}
var prompt, promptRepeat string
if hint == "" {
prompt = "passphrase: "
promptRepeat = "passphrase (repeat): "
} else {
prompt = fmt.Sprintf("passphrase [%s]: ", hint)
promptRepeat = fmt.Sprintf("passphrase [%s] (repeat): ", hint)
}
tail := []byte("\n")
out.Write([]byte(prompt))
passphrase, err := terminal.ReadPassword(fd)
if err != nil {
return nil, err
}
if passphrase == nil {
passphrase = make([]byte, 0)
}
out.Write(tail)
for i := 0; i < repeat; i++ {
out.Write([]byte(promptRepeat))
again, err := terminal.ReadPassword(fd)
if err != nil {
return nil, err
}
out.Write(tail)
if !bytes.Equal(again, passphrase) {
return nil, errors.New("passphrases do not match")
}
}
return passphrase, nil
}