-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathpinentry.go
130 lines (117 loc) · 3.36 KB
/
pinentry.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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package main
import (
"github.com/apex/log"
"github.com/foxcpp/go-assuan/common"
"github.com/foxcpp/go-assuan/pinentry"
"github.com/keybase/go-keychain"
)
// GetPIN returns a PIN code.
//
// First, it tries to get the PIN from the KeyChain and return it. If not
// found, it request it from the user via the pinentry-mac, store it in
// KeyChain and then return it back, as a result.
//
// Note: it doesn't try to interfere the requests that are not recognised as the
// standard GnuPG tool requests for a PIN code. This is done via RegExp over the
// description that is (not?)provided. Otherwise, pass the execution through,
// down to the the original `pinentry.GetPIN`.
func GetPIN(s pinentry.Settings) (string, *common.Error) {
// Check if this is a standard GnuPG PIN request
m := SCSNRe.FindStringSubmatch(s.Desc)
if m == nil {
client, err := pinentry.LaunchCustom(pmp)
if err != nil {
log.WithError(err).Error("Launch custom pinentry")
return "", &common.Error{
Message: err.Error(),
}
}
fields := (log.Fields)(Apply(&client, s))
ctx := log.WithFields(fields).WithField("gnupg", false)
str, err := client.GetPIN()
if err != nil {
ctx.WithError(err).Error("GetPIN")
return "", &common.Error{
Message: err.Error(),
}
}
ctx.Info("GetPIN")
return str, nil
}
// Try to retrieve the PIN
pin, err := KeychainItemGet(RecordName(m[1]), m[2])
if err != nil && err != keychain.ErrorItemNotFound {
return "", &common.Error{
Message: err.Error(),
}
}
if err == nil && pin != "" {
return pin, nil
}
client, err := pinentry.LaunchCustom(pmp)
if err != nil {
log.WithError(err).Error("Launch custom pinentry")
return "", &common.Error{
Message: err.Error(),
}
}
// Double check the PIN before create the record
(&s).RepeatPrompt = "Repeat PIN"
(&s).Desc = s.Desc + "\n\nNote: the PIN will be saved in the macOs keychain"
fields := (log.Fields)(Apply(&client, s))
ctx := log.WithFields(fields).WithField("gnupg", true)
str, err := client.GetPIN()
if err != nil {
ctx.WithError(err).Error("GetPIN")
return "", &common.Error{
Message: err.Error(),
}
} else {
ctx.Info("GetPIN")
}
err = KeychainItemInsert(str, RecordName(m[1]), m[2])
if err != nil {
return "", &common.Error{
Message: err.Error(),
}
}
return str, nil
}
// Confirm is a passthru function that doesn't do anything
// in addition to the original pinentry executable
func Confirm(s pinentry.Settings) (bool, *common.Error) {
client, err := pinentry.LaunchCustom(pmp)
if err != nil {
log.WithError(err).Error("Launch custom pinentry")
return false, &common.Error{
Message: err.Error(),
}
}
fields := (log.Fields)(Apply(&client, s))
ctx := log.WithFields(fields).WithField("gnupg", false)
err = client.Confirm()
if err != nil {
ctx.WithError(err).Error("Confirm")
return false, &common.Error{
Message: err.Error(),
}
}
ctx.Info("Confirm")
return true, nil
}
// Message is a passthru function that doesn't do anything
// in addition to the original pinentry executable
func Message(s pinentry.Settings) *common.Error {
client, err := pinentry.LaunchCustom(pmp)
if err != nil {
log.WithError(err).Error("Launch custom pinentry")
return &common.Error{
Message: err.Error(),
}
}
fields := (log.Fields)(Apply(&client, s))
ctx := log.WithFields(fields).WithField("gnupg", false)
client.Message()
ctx.Info("Message")
return nil
}