Skip to contentSkip to conversation

gpg_sign.py: get rid of pexpect

PATCH New Robert Yang 1 participant 4 messages Mar 21, 2016

lore
Share & tools
lore
#0 lore raw

cover gpg_sign.py: get rid of pexpect

The following changes since commit d3ab7005f0c899da9f9f132b22861bd5d4f952ba:

tzdata: update to 2016b (2016-03-20 22:58:00 +0000)

are available in the git repository at:

git://git.openembedded.org/openembedded-core-contrib rbt/rpm
http://cgit.openembedded.org/cgit.cgi/openembedded-core-contrib/log/?h=rbt/rpm

Robert Yang (3):
rpm: check _gpg_passphrase before ask for input gpg_sign.py: get rid of pexpect
selftest/signing.py: RPM_GPG_PASSPHRASE_FILE -> RPM_GPG_PASSPHRASE

 meta-selftest/files/signing/secret.txt             |    1 -
 meta/classes/sign_rpm.bbclass                      |   10 +--
 meta/lib/oe/gpg_sign.py                            |   24 ++-----
 meta/lib/oeqa/selftest/signing.py                  |    2 +-
 ...heck-_gpg_passphrase-before-ask-for-input.patch |   70 ++++++++++++++++++++
 meta/recipes-devtools/rpm/rpm_5.4.16.bb            |    1 +
 6 files changed, 84 insertions(+), 24 deletions(-)
 delete mode 100644 meta-selftest/files/signing/secret.txt
 create mode 100644 meta/recipes-devtools/rpm/rpm/rpmqv.c-check-_gpg_passphrase-before-ask-for-input.patch
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH 1/3 rpm: check _gpg_passphrase before ask for input

rpm always asked for pass phrasae when add signature, which made it can't work non-interactively, this patch fix the problem. It will work non-interactively if _gpg_passphrase is defined, and work as before if not.

---
 ...heck-_gpg_passphrase-before-ask-for-input.patch |   70 ++++++++++++++++++++
 meta/recipes-devtools/rpm/rpm_5.4.16.bb            |    1 +
 2 files changed, 71 insertions(+)
 create mode 100644 meta/recipes-devtools/rpm/rpm/rpmqv.c-check-_gpg_passphrase-before-ask-for-input.patch
meta/recipes-devtools/rpm/rpm/rpmqv.c-check-_gpg_passphrase-before-ask-for-input.patch new file +70 -0
new file mode 100644
index 0000000..c68681c
@@ -0,0 +1,70 @@
+From bb48dbc88a58bc05a43d71a3375fb05358119ec5 Mon Sep 17 00:00:00 2001
+From: Robert Yang <[email protected]>
+Date: Sun, 20 Mar 2016 20:20:16 -0700
+Subject: [PATCH] rpmqv.c: check _gpg_passphrase before ask for input
+
+rpm always asked for pass phrasae when add signature, which made it
+can't work non-interactively, this patch fix the problem. It will work
+non-interactively if _gpg_passphrase is defined, and work as before if
+not.
+
+Upstream-Status: Pending
+
+Signed-off-by: Robert Yang <[email protected]>
+---
+ macros/macros.in |    7 +++++--
+ rpmqv.c          |   17 ++++++++++-------
+ 2 files changed, 15 insertions(+), 9 deletions(-)
+
+diff --git a/macros/macros.in b/macros/macros.in
+index 2e5b07d..01b3aad 100644
+--- a/macros/macros.in
++++ b/macros/macros.in
+@@ -520,15 +520,18 @@ $_arbitrary_tags_tests	Foo:Bar
+ #	Macro(s) to hold the arguments passed to GPG/PGP for package
+ #	signing and verification.
+ #
++
++%_gpg_passphrase_way %{?_gpg_passphrase:--passphrase "%{_gpg_passphrase}"}%{!?_gpg_passphrase:--passphrase-fd 3}
++
+ %__gpg_check_password_cmd	%{__gpg} \
+-	gpg --batch --no-verbose --passphrase-fd 3 -u "%{_gpg_name}" -so -
++	gpg --batch --no-verbose %{_gpg_passphrase_way} -u "%{_gpg_name}" -so -
+ #%__pgp_check_password_cmd	%{__pgp} \
+ #	pgp +batchmode=on +verbose=0 "%{_pgp_name}" -sf
+ #%__pgp5_check_password_cmd	%{__pgp} \
+ #	pgps +batchmode=on +verbose=0 +armor=off "%{_pgp_name}" -f
+ 
+ %__gpg_sign_cmd			%{__gpg} \
+-	gpg --batch --no-verbose --no-armor --passphrase-fd 3 --no-secmem-warning \
++	gpg --batch --no-verbose --no-armor %{_gpg_passphrase_way}  --no-secmem-warning \
+ 	-u "%{_gpg_name}" -sbo %{__signature_filename} %{__plaintext_filename}
+ #%__pgp_sign_cmd			%{__pgp} \
+ #	pgp +batchmode=on +verbose=0 +armor=off \
+diff --git a/rpmqv.c b/rpmqv.c
+index b306486..7604396 100644
+--- a/rpmqv.c
++++ b/rpmqv.c
+@@ -831,13 +831,16 @@ int main(int argc, const char ** argv)
+ #endif
+ 	    )
+ 	    {
+-		passPhrase = Getpass(_("Enter pass phrase: "));
+-		if (rpmCheckPassPhrase(passPhrase)) {
+-		    fprintf(stderr, _("Pass phrase check failed\n"));
+-		    ec = EXIT_FAILURE;
+-		    goto exit;
++		passPhrase = rpmExpand("%{?_gpg_passphrase}", NULL);
++		if (passPhrase == NULL || passPhrase[0] == '\0') {
++			passPhrase = Getpass(_("Enter pass phrase: "));
++			if (rpmCheckPassPhrase(passPhrase)) {
++			    fprintf(stderr, _("Pass phrase check failed\n"));
++			    ec = EXIT_FAILURE;
++			    goto exit;
++			}
++			fprintf(stderr, _("Pass phrase is good.\n"));
+ 		}
+-		fprintf(stderr, _("Pass phrase is good.\n"));
+ 		/* XXX Getpass() should realloc instead. */
+ 		passPhrase = xstrdup(passPhrase);
+ 	    }
meta/recipes-devtools/rpm/rpm_5.4.16.bb +1 -0
index eba043e..7621f8f 100644
@@ -114,6 +114,7 @@ SRC_URI += " \
 	   file://rpm-python-AddErase.patch \
 	   file://rpm-rpmpgp-popt.patch \
 	   file://rpm-fix-lua-tests-compilation-failure.patch \
+	   file://rpmqv.c-check-_gpg_passphrase-before-ask-for-input.patch \
 "
 
 # OE specific changes
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH 2/3 gpg_sign.py: get rid of pexpect

In reply to Robert Yang

The python-expect is not installed on the distro such as Ubuntu by default, and we can get rid of it.

Use RPM_GPG_PASSPHRASE to replace of RPM_GPG_PASSPHRASE_FILE which is more straightforward.

---
 meta/classes/sign_rpm.bbclass |   10 ++++++----
 meta/lib/oe/gpg_sign.py       |   24 ++++++------------------
 2 files changed, 12 insertions(+), 22 deletions(-)
meta/classes/sign_rpm.bbclass +6 -4
index c21e3f0..a8ea75f 100644
@@ -1,8 +1,8 @@
 # Class for generating signed RPM packages.
 #
 # Configuration variables used by this class:
-# RPM_GPG_PASSPHRASE_FILE
-#           Path to a file containing the passphrase of the signing key.
+# RPM_GPG_PASSPHRASE
+#           The passphrase of the signing key.
 # RPM_GPG_NAME
 #           Name of the key to sign with. May be key id or key name.
 # RPM_GPG_BACKEND
@@ -22,8 +22,10 @@ RPM_GPG_BACKEND ?= 'local'
 
 
 python () {
+    if d.getVar('RPM_GPG_PASSPHRASE_FILE', True):
+        raise_sanity_error('RPM_GPG_PASSPHRASE_FILE is replaced by RPM_GPG_PASSPHRASE', d)
     # Check configuration
-    for var in ('RPM_GPG_NAME', 'RPM_GPG_PASSPHRASE_FILE'):
+    for var in ('RPM_GPG_NAME', 'RPM_GPG_PASSPHRASE'):
         if not d.getVar(var, True):
             raise_sanity_error("You need to define %s in the config" % var, d)
 
@@ -44,7 +46,7 @@ python sign_rpm () {
 
     signer.sign_rpms(rpms,
                      d.getVar('RPM_GPG_NAME', True),
-                     d.getVar('RPM_GPG_PASSPHRASE_FILE', True))
+                     d.getVar('RPM_GPG_PASSPHRASE', True))
 }
 
 do_package_index[depends] += "signing-keys:do_deploy"
meta/lib/oe/gpg_sign.py +6 -18
index e738397..b83ee86 100644
@@ -26,32 +26,20 @@ class LocalSigner(object):
             raise bb.build.FuncFailed('Failed to export gpg public key (%s): %s' %
                                       (keyid, output))
 
-    def sign_rpms(self, files, keyid, passphrase_file):
+    def sign_rpms(self, files, keyid, passphrase):
         """Sign RPM files"""
-        import pexpect
 
-        cmd = self.rpm_bin + " --addsign --define '_gpg_name %s' " % keyid
+        cmd = self.rpm_bin + " --addsign --define '_gpg_name %s'  " % keyid
+        cmd += "--define '_gpg_passphrase %s' " % passphrase
         if self.gpg_bin:
             cmd += "--define '%%__gpg %s' " % self.gpg_bin
         if self.gpg_path:
             cmd += "--define '_gpg_path %s' " % self.gpg_path
         cmd += ' '.join(files)
 
-        # Need to use pexpect for feeding the passphrase
-        proc = pexpect.spawn(cmd)
-        try:
-            proc.expect_exact('Enter pass phrase:', timeout=15)
-            with open(passphrase_file) as fobj:
-                proc.sendline(fobj.readline().rstrip('\n'))
-            proc.expect(pexpect.EOF, timeout=900)
-            proc.close()
-        except pexpect.TIMEOUT as err:
-            bb.error('rpmsign timeout: %s' % err)
-            proc.terminate()
-        if os.WEXITSTATUS(proc.status) or not os.WIFEXITED(proc.status):
-            bb.error('rpmsign failed: %s' % proc.before.strip())
-            raise bb.build.FuncFailed("Failed to sign RPM packages")
-
+        status, output = oe.utils.getstatusoutput(cmd)
+        if status:
+            raise bb.build.FuncFailed("Failed to sign RPM packages: %s" % output)
 
     def detach_sign(self, input_file, keyid, passphrase_file, passphrase=None, armor=True):
         """Create a detached signature of a file"""
Signature · 1 line
1.7.9.5
#3 lore raw

PATCH 3/3 selftest/signing.py: RPM_GPG_PASSPHRASE_FILE -> RPM_GPG_PASSPHRASE

In reply to Robert Yang
---
 meta-selftest/files/signing/secret.txt |    1 -
 meta/lib/oeqa/selftest/signing.py      |    2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)
 delete mode 100644 meta-selftest/files/signing/secret.txt
meta-selftest/files/signing/secret.txt deleted +0 -1
deleted file mode 100644
index 5271a52..0000000
@@ -1 +0,0 @@
-test123
meta/lib/oeqa/selftest/signing.py +1 -1
index 1e710e3..312e502 100644
@@ -54,7 +54,7 @@ class Signing(oeSelfTest):
         test_recipe = 'ed'
 
         feature = 'INHERIT += "sign_rpm"\n'
-        feature += 'RPM_GPG_PASSPHRASE_FILE = "%ssecret.txt"\n' % self.gpg_dir
+        feature += 'RPM_GPG_PASSPHRASE = "test123"\n'
         feature += 'RPM_GPG_NAME = "testuser"\n'
         feature += 'RPM_GPG_PUBKEY = "%s%s"\n' % (self.gpg_dir, self.pub_key_name)
         feature += 'GPG_PATH = "%s"\n' % self.gpg_dir
Signature · 1 line
1.7.9.5