diff -Naur smart-0.51/smart/backends/rpm/base.py smart-0.51.tpg/smart/backends/rpm/base.py --- smart-0.51/smart/backends/rpm/base.py 2006-11-07 20:22:46.000000000 +0000 +++ smart-0.51.tpg/smart/backends/rpm/base.py 2007-08-28 08:59:39.000000000 +0000 @@ -53,6 +53,8 @@ getTS.ts = rpm.ts(getTS.root) if not sysconf.get("rpm-check-signatures", False): getTS.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES) + else: + getTS.ts.setVSFlags(0) dbdir = os.path.join(getTS.root, "var/lib/rpm") if not os.path.isdir(dbdir): try: @@ -79,6 +81,8 @@ ts = rpm.ts(getTS.root) if not sysconf.get("rpm-check-signatures", False): ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES) + else: + ts.setVSFlags(0) return ts else: return getTS.ts diff -Naur smart-0.51/smart/backends/rpm/pm.py smart-0.51.tpg/smart/backends/rpm/pm.py --- smart-0.51/smart/backends/rpm/pm.py 2006-08-31 17:59:46.000000000 +0000 +++ smart-0.51.tpg/smart/backends/rpm/pm.py 2007-08-28 08:59:39.000000000 +0000 @@ -40,6 +40,17 @@ except locale.Error: ENCODING = "C" +def get_rpm_public_key(filepath): + f = file(filepath, 'r') + ts = rpm.ts() + ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES) + hdr = ts.hdrFromFdno(f.fileno()) + return hdr.sprintf("%|DSAHEADER?{%{DSAHEADER:pgpsig}}:" + "{%|RSAHEADER?{%{RSAHEADER:pgpsig}}:" + "{%|SIGGPG?{%{SIGGPG:pgpsig}}:" + "{%|SIGPGP?{%{SIGPGP:pgpsig}}:" + "{(none)}|}|}|}|").split()[-1] + class RPMPackageManager(PackageManager): def commit(self, changeset, pkgpaths): @@ -152,12 +163,53 @@ info = loader.getInfo(pkg) mode = pkg in upgrading and "u" or "i" path = pkgpaths[pkg][0] - fd = os.open(path, os.O_RDONLY) - try: - h = ts.hdrFromFdno(fd) - except rpm.error, e: - os.close(fd) - raise Error, "%s: %s" % (os.path.basename(path), e) + for _pass in xrange(2): + fd = os.open(path, os.O_RDONLY) + try: + h = ts.hdrFromFdno(fd) + except rpm.error, e: + os.close(fd) + + # in the slow path we trap the case of a gpg public key not in rpmdb + # and we try to fetch it from the keyserver and we ask the user + # if he wants to trust this key to continue the installation + if not _pass and e.args[0] == 'public key not available': + keyserver = sysconf.get('keyserver') + if not keyserver: + iface.error('To enable the keyserver run: ' + '"smart config --set keyserver=pgp.mit.edu"') + else: + key = get_rpm_public_key(path) + iface.info('Trying to import the key %s from %s...' % (key, keyserver)) + popen = os.popen('LANG=C gpg --keyserver %s --recv-keys %s' % (keyserver, key)) + popen_out = popen.read() + if popen.close() is not None: + iface.error('gpg failed to import keyid %s, ' + 'please make sure that gpg is installed, ' + 'that the keyserver %s is working ' + 'and that the package %s has a valid signature.' % (key, + keyserver, + path)) + else: + popen_out += '\nThe above GPG key has been imported successfully.\n' \ + 'It is required to install this package:\n\n\t' \ + + os.path.basename(path) + \ + '\n\nDo you want to trust this key forever?\n\n' \ + 'You must verify the below fingerprint before answering.\n' \ + + os.popen('LANG=C gpg --fingerprint %s' % key).read() + \ + '\nIf you answer "Yes" all other packages signed with this key ' \ + 'will be installed automatically.' + if iface.askYesNo(popen_out, False): + key_armor = os.popen('LANG=C gpg --export %s' % key, 'r').read() + if ts.pgpImportPubkey(key_armor): + iface.error('rpm failed to import the public key id %s' % key) + else: + # try one more time with the pub key on + continue + + raise Error, "%s: %s" % (os.path.basename(path), e) + else: + break os.close(fd) ts.addInstall(h, (info, path), mode) packages += 1 diff -Naur smart-0.51/smart/interface.py smart-0.51.tpg/smart/interface.py --- smart-0.51/smart/interface.py 2007-03-28 22:31:11.000000000 +0000 +++ smart-0.51.tpg/smart/interface.py 2007-08-28 08:59:39.000000000 +0000 @@ -72,14 +72,14 @@ self._progress = Progress() return self._progress - def askYesNo(self, question, default=False): - return True + def askYesNo(self, question, default=True): + return default - def askContCancel(self, question, default=False): - return True + def askContCancel(self, question, default=True): + return default - def askOkCancel(self, question, default=False): - return True + def askOkCancel(self, question, default=True): + return default def askInput(self, prompt, message=None, widthchars=None, echo=True): return ""