forked from keybase/client
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pinentry_nix.go
111 lines (94 loc) · 2.29 KB
/
pinentry_nix.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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.
// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris
package pinentry
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"github.com/keybase/client/go/logger"
)
//
// some borrowed from here:
//
// https://github.com/bradfitz/camlistore/blob/master/pkg/misc/pinentry/pinentry.go
//
// Under the Apache 2.0 license
//
func canExec(s string) error {
fi, err := os.Stat(s)
if err != nil {
return err
}
mode := fi.Mode()
//
// Only consider non-directories that have at least one +x
// bit set.
//
// TODO: Recheck this on Windows!
// See here for lookpath: http://golang.org/src/pkg/os/exec/lp_windows.go
//
// Similar to check from exec.LookPath below
// See here: http://golang.org/src/pkg/os/exec/lp_unix.go
//
switch {
case mode.IsDir():
return fmt.Errorf("Program '%s' is a directory", s)
case int(mode)&0111 == 0:
return fmt.Errorf("Program '%s' isn't executable", s)
default:
return nil
}
}
func FindPinentry(log logger.Logger) (string, error) {
if !HasWindows() {
return "", fmt.Errorf("Can't spawn gui window, not using pinentry")
}
bins := []string{
// If you install MacTools you'll wind up with this pinentry
"/usr/local/MacGPG2/libexec/pinentry-mac.app/Contents/MacOS/pinentry-mac",
}
extraPaths := []string{}
log.Debug("+ FindPinentry()")
cmds := []string{
"pinentry-gtk-2",
"pinentry-qt4",
"pinentry",
}
checkFull := func(s string) bool {
log.Debug("| Check fullpath %s", s)
found := (canExec(s) == nil)
if found {
log.Debug("- Found: %s", s)
}
return found
}
for _, b := range bins {
if checkFull(b) {
return b, nil
}
}
path := os.Getenv("PATH")
for _, c := range cmds {
log.Debug("| Looking for %s in standard PATH %s", c, path)
fullc, err := exec.LookPath(c)
if err == nil {
log.Debug("- Found %s", fullc)
return fullc, nil
}
}
for _, ep := range extraPaths {
for _, c := range cmds {
full := filepath.Join(ep, c)
if checkFull(full) {
return full, nil
}
}
}
log.Debug("- FindPinentry: none found")
return "", fmt.Errorf("No pinentry found, checked a bunch of different places")
}
func (pe *Pinentry) GetTerminalName() {
// Noop on all platforms but Windows
}