Subject: bug#17625: 24.4.50; All installed packages marked "unsigned", no archive listed

From: Ted Zlatanov <[email-masked]>
Date: Mon, 29 Sep 2014 20:33:38 -0400

On Wed, 24 Sep 2014 11:05:31 -0400 Stefan Monnier <[email-masked]> wrote: 

>> Do you have a plan to start signing GNU ELPA packages so this can get
>> tested in a real network setup?

SM> GNU ELPA is now signed,

Thank you for working on this!

The docs should be updated:

@c Uncomment this if it becomes true.
@ignore
The public key for the GNU package archive is distributed with Emacs,
in the @file{etc/package-keyring.gpg}.  Emacs uses it automatically.
@end ignore

The ELPA maintainer public key .gpg file is needed. Right now I can't
find it so I can't actually verify any packages. Am I missing something?

Are there docs on the signing process? I don't see anything in the ELPA
repository under admin.

>From the code it seems the EPG glue written by Daiki Ueno expects the
keyring to live in `(expand-file-name "gnupg" package-user-dir)` which
implies we have to provide a way, on startup, to populate that keyring
if it's missing. I don't see any docs or functions to do that. It's not
terribly complicated, just `gpg --homedir DIRNAME --import KEY` but it
would be convenient for users if we provide a wrapper.

IMHO any archives that are signed but not the GNU ELPA should be able to
use this wrapper.  I hope you agree, it's just a matter of avoiding
hard-coding too much.

I also think that we should set `package-check-signature` aggressively
if we can verify a basic signature verification.  So maybe that wrapper
above can finish with a test run of GnuPG to ensure it will DTRT, and if
so, offer to customize and save `package-check-signature`.  I can
atttempt all of the above... do you agree with the workflow?

I am attaching a small patch to provide a "Verify" button in the package
description, so the user doesn't have to try install the package to find
out if it's signed.  If you agree, I can commit it.

Thanks
Ted

=== modified file 'lisp/emacs-lisp/package.el'
--- lisp/emacs-lisp/package.el	2014-09-03 04:21:40 +0000
+++ lisp/emacs-lisp/package.el	2014-09-30 00:04:22 +0000
@@ -842,8 +842,9 @@
                          (epg-context-result-for context 'verify)))
         good-signatures))))
 
-(defun package-install-from-archive (pkg-desc)
-  "Download and install a tar package."
+(defun package-install-from-archive (pkg-desc &optional just-verify)
+  "Download and install a tar package.
+When JUST-VERIFY is set, only verify the signature."
   (let* ((location (package-archive-base pkg-desc))
 	 (file (concat (package-desc-full-name pkg-desc)
 		       (package-desc-suffix pkg-desc)))
@@ -858,7 +859,9 @@
 	    (unless (eq package-check-signature 'allow-unsigned)
 	      (error "Unsigned package: `%s'"
 		     (package-desc-name pkg-desc)))))
-      (package-unpack pkg-desc))
+      ;; do the actual install
+      (unless just-verify
+        (package-unpack pkg-desc)))
     ;; Here the package has been installed successfully, mark it as
     ;; signed if appropriate.
     (when good-signatures
@@ -1432,6 +1435,11 @@
            (package-make-button
             "Install"
             'action 'package-install-button-action
+            'package-desc desc)
+	   (insert " ")
+           (package-make-button
+            "Verify signature"
+            'action 'package-verify-button-action
             'package-desc desc))
 	  (t (insert (capitalize status) ".")))
     (insert "\n")
@@ -1546,6 +1554,13 @@
       (revert-buffer nil t)
       (goto-char (point-min)))))
 
+(defun package-verify-button-action (button)
+  (let ((pkg-desc (button-get button 'package-desc)))
+    (with-demoted-errors
+        (package-install-from-archive pkg-desc t) ; just verify
+      ;; note errors will preempt the following
+      (message "Package was verified"))))
+
 (defun package-keyword-button-action (button)
   (let ((pkg-keyword (button-get button 'package-keyword)))
     (package-show-package-list t (list pkg-keyword))))