Mark Wilkerson: 1 swap out local keyring for system gpg 7 files changed, 17 insertions(+), 40 deletions(-)
Copy & paste the following snippet into your terminal to import this patchset into git:
curl -s https://lists.sr.ht/~sircmpwn/aerc/patches/27092/mbox | git am -3Learn more about email & git
/x/crypto/openpgp has been deprecated by the golang team. Given the current state of the lib, support for things like smartcards may not be possible. See: https://github.com/golang/go/issues/44226
We should seriously think about dropping this dependency from aerc.
This patch allows for decrypting with existing keyrings and smartcards, but doesn't yet populate the fields for signature verification. I haven't been able to come up with a solution that doesn't involve hacky parsing of the gpg log output (which is also annoyingly sent to stderr). Parsing this output also breaks the idea of having user specified pgp commands in the config. The right way to do this is probably to interface with gpg-agent, but that's a rabbit hole I don't have the bandwidth to sign up for. Open to suggestions!
I was afraid of this. However it does not look like we have a chance since none of the other implementations of pgp do support smart cards. I don't know gpg-agent well enough to evaluate how much work would be required. Would parsing gpg commands be so bad? I know it prevents users from specifying their own commands but only signature verification would be affected as far as I can tell. And maybe, it would be enough if we since gpg exits with a non-zero error code on verification failure: robin@diabtop:~/git/aerc master$ gpg --verify gpg.patch.asc gpg.patch gpg: Signature made Mon 06 Dec 2021 09:31:22 AM CET gpg: using EDDSA key D8B6A9907C3AB720428B606862718E0D666FC335 gpg: checking the trustdb gpg: marginals needed: 3 completes needed: 1 trust model: pgp gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u gpg: Good signature from "Robin Jarry <robin@jarry.cc>" [ultimate] Primary key fingerprint: DC07 18E3 22E2 C760 5EBD C831 4695 7EC0 8FD0 FE90 Subkey fingerprint: D8B6 A990 7C3A B720 428B 6068 6271 8E0D 666F C335 robin@diabtop:~/aerc master$ echo $? 0 robin@diabtop:~/git/aerc master$ echo xxxxxxxxxxxxxxxxxxxxxx>> pouet.patch robin@diabtop:~/git/aerc master$ gpg --verify pouet.patch.asc pouet.patch gpg: Signature made Mon 06 Dec 2021 09:31:22 AM CET gpg: using EDDSA key D8B6A9907C3AB720428B606862718E0D666FC335 gpg: BAD signature from "Robin Jarry <robin@jarry.cc>" [ultimate] robin@diabtop:~/git/aerc master$ echo $? 1 I know this does not provide any info from the signature and it is not really suitable for automation. Did you look at gpgv(1)? For other operations (signature, decryption, encryption), I don't think any output parsing would be required.
--- aerc.go | 4 ---- commands/account/view.go | 2 +- commands/msg/delete.go | 2 +- commands/msgview/next.go | 2 +- lib/messageview.go | 20 +++++++++++++------- widgets/aerc.go | 25 ------------------------- widgets/msglist.go | 2 +- 7 files changed, 17 insertions(+), 40 deletions(-) diff --git a/aerc.go b/aerc.go index b3338ba..dd08619 100644 --- a/aerc.go +++ b/aerc.go @@ -187,10 +187,6 @@ func main() { ui.EnableMouse() } - logger.Println("Initializing PGP keyring") - lib.InitKeyring() - defer lib.UnlockKeyring() -
If you are dropping the keyring, I think more cleanup is needed (see lib/keystore.go). Also, since this is a major (breaking?) change, explicit mention in the docs are mandatory.
logger.Println("Starting Unix server") as, err := lib.StartServer(logger) if err != nil { diff --git a/commands/account/view.go b/commands/account/view.go index 4f59d94..48c7bfc 100644 --- a/commands/account/view.go +++ b/commands/account/view.go @@ -42,7 +42,7 @@ func (ViewMessage) Execute(aerc *widgets.Aerc, args []string) error { aerc.PushError(msg.Error.Error()) return nil } - lib.NewMessageStoreView(msg, store, aerc.DecryptKeys, + lib.NewMessageStoreView(msg, store, func(view lib.MessageView, err error) { if err != nil { aerc.PushError(err.Error()) diff --git a/commands/msg/delete.go b/commands/msg/delete.go index 34eac72..e9dbd93 100644 --- a/commands/msg/delete.go +++ b/commands/msg/delete.go @@ -68,7 +68,7 @@ func (Delete) Execute(aerc *widgets.Aerc, args []string) error { acct.Messages().Invalidate() return nil } - lib.NewMessageStoreView(next, store, aerc.DecryptKeys, + lib.NewMessageStoreView(next, store, func(view lib.MessageView, err error) { if err != nil { aerc.PushError(err.Error()) diff --git a/commands/msgview/next.go b/commands/msgview/next.go index 4291a6a..d61300e 100644 --- a/commands/msgview/next.go +++ b/commands/msgview/next.go @@ -37,7 +37,7 @@ func (NextPrevMsg) Execute(aerc *widgets.Aerc, args []string) error { aerc.RemoveTab(mv) return nil } - lib.NewMessageStoreView(nextMsg, store, aerc.DecryptKeys, + lib.NewMessageStoreView(nextMsg, store, func(view lib.MessageView, err error) { if err != nil { aerc.PushError(err.Error()) diff --git a/lib/messageview.go b/lib/messageview.go index 532d2c8..740ce3a 100644 --- a/lib/messageview.go +++ b/lib/messageview.go @@ -4,10 +4,10 @@ import ( "bytes" "io" "io/ioutil" + "os/exec" "github.com/emersion/go-message" _ "github.com/emersion/go-message/charset" - "github.com/emersion/go-pgpmail" "golang.org/x/crypto/openpgp" "git.sr.ht/~rjarry/aerc/models" @@ -30,6 +30,7 @@ type MessageView interface { // Fetches a specific body part for this message FetchBodyPart(part []int, cb func(io.Reader)) + // TODO figure out what parts we actually need PGPDetails() *openpgp.MessageDetails } @@ -56,13 +57,12 @@ type MessageStoreView struct { messageInfo *models.MessageInfo messageStore *MessageStore message []byte - details *openpgp.MessageDetails + details *openpgp.MessageDetails // TODO bodyStructure *models.BodyStructure } func NewMessageStoreView(messageInfo *models.MessageInfo, - store *MessageStore, decryptKeys openpgp.PromptFunction, - cb func(MessageView, error)) { + store *MessageStore, cb func(MessageView, error)) { msv := &MessageStoreView{messageInfo, store, nil, nil, messageInfo.BodyStructure} @@ -70,12 +70,18 @@ func NewMessageStoreView(messageInfo *models.MessageInfo, if usePGP(messageInfo.BodyStructure) { store.FetchFull([]uint32{messageInfo.Uid}, func(fm *types.FullMessage) { reader := fm.Content.Reader - pgpReader, err := pgpmail.Read(reader, Keyring, decryptKeys, nil) + cmd := exec.Command("gpg", "-d") + cmd.Stdin = reader + out, err := cmd.StdoutPipe() +
For now, no custom commands. Do you plan on adding these in a separate patch?
if err != nil { cb(nil, err) return } - msv.message, err = ioutil.ReadAll(pgpReader.MessageDetails.UnverifiedBody) + // TODO should handle this error + go cmd.Run() + + msv.message, err = ioutil.ReadAll(out) if err != nil { cb(nil, err) return @@ -91,7 +97,7 @@ func NewMessageStoreView(messageInfo *models.MessageInfo, return } msv.bodyStructure = bs - msv.details = pgpReader.MessageDetails + msv.details = &openpgp.MessageDetails{} cb(msv, nil) }) } else {
Exit code should be checked here I guess. Thanks a lot for working on this!
diff --git a/widgets/aerc.go b/widgets/aerc.go index cbde56c..5fcf922 100644 --- a/widgets/aerc.go +++ b/widgets/aerc.go @@ -12,7 +12,6 @@ import ( "github.com/emersion/go-message/mail" "github.com/gdamore/tcell/v2" "github.com/google/shlex" - "golang.org/x/crypto/openpgp" "git.sr.ht/~rjarry/aerc/config" "git.sr.ht/~rjarry/aerc/lib" @@ -613,30 +612,6 @@ func (aerc *Aerc) Initialize(ui *ui.UI) { aerc.ui = ui } -func (aerc *Aerc) DecryptKeys(keys []openpgp.Key, symmetric bool) (b []byte, err error) { - for _, key := range keys { - ident := key.Entity.PrimaryIdentity() - chPass, chErr := aerc.GetPassword("Decrypt PGP private key", - fmt.Sprintf("Enter password for %s (%8X)\nPress <ESC> to cancel", - ident.Name, key.PublicKey.KeyId)) - - for { - select { - case err = <-chErr: - if err != nil { - return nil, err - } - pass := <-chPass - err = key.PrivateKey.Decrypt([]byte(pass)) - return nil, err - default: - aerc.ui.Tick() - } - } - } - return nil, err -} - // errorScreen is a widget that draws an error in the middle of the context func errorScreen(s string, conf config.UIConfig) ui.Drawable { errstyle := conf.GetStyle(config.STYLE_ERROR) diff --git a/widgets/msglist.go b/widgets/msglist.go index 6163d0e..07c0bfa 100644 --- a/widgets/msglist.go +++ b/widgets/msglist.go @@ -296,7 +296,7 @@ func (ml *MessageList) MouseEvent(localX int, localY int, event tcell.Event) { if msg == nil { return } - lib.NewMessageStoreView(msg, store, ml.aerc.DecryptKeys, + lib.NewMessageStoreView(msg, store, func(view lib.MessageView, err error) { if err != nil { ml.aerc.PushError(err.Error()) -- 2.34.0
Hi Mark, The project has been forked a while ago. In the future, could you please send patches to the new mailing list as well? ~rjarry/aerc-devel@lists.sr.ht Mark Wilkerson, Dec 04, 2021 at 04:57: