summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Stubbs <jstubbs@gentoo.org>2005-08-28 08:37:44 +0000
committerJason Stubbs <jstubbs@gentoo.org>2005-08-28 08:37:44 +0000
commitd9fc4acc572c6647a4f27b838d35d27d805d190e (patch)
tree262a8de35d8c7567312757da5f1f66efdc8cece5 /pym/portage_gpg.py
downloadportage-multirepo-d9fc4acc572c6647a4f27b838d35d27d805d190e.tar.gz
portage-multirepo-d9fc4acc572c6647a4f27b838d35d27d805d190e.tar.bz2
portage-multirepo-d9fc4acc572c6647a4f27b838d35d27d805d190e.zip
Migration (without history) of the current stable line to subversion.
svn path=/main/branches/2.0/; revision=1941
Diffstat (limited to 'pym/portage_gpg.py')
-rw-r--r--pym/portage_gpg.py149
1 files changed, 149 insertions, 0 deletions
diff --git a/pym/portage_gpg.py b/pym/portage_gpg.py
new file mode 100644
index 00000000..deaf36ad
--- /dev/null
+++ b/pym/portage_gpg.py
@@ -0,0 +1,149 @@
+# portage_gpg.py -- core Portage functionality
+# Copyright 2004 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-src/portage/pym/portage_gpg.py,v 1.6.2.1 2005/01/16 02:35:33 carpaski Exp $
+cvs_id_string="$Id: portage_gpg.py,v 1.6.2.1 2005/01/16 02:35:33 carpaski Exp $"[5:-2]
+
+import os
+import copy
+import types
+import commands
+import portage_exception
+import portage_checksum
+
+GPG_BINARY = "/usr/bin/gpg"
+GPG_OPTIONS = " --lock-never --no-random-seed-file --no-greeting --no-sig-cache "
+GPG_VERIFY_FLAGS = " --verify "
+GPG_KEYDIR = " --homedir '%s' "
+GPG_KEYRING = " --keyring '%s' "
+
+UNTRUSTED = 0
+EXISTS = UNTRUSTED + 1
+MARGINAL = EXISTS + 1
+TRUSTED = MARGINAL + 1
+
+def fileStats(filepath):
+ mya = []
+ for x in os.stat(filepath):
+ mya.append(x)
+ mya.append(portage_checksum.perform_checksum(filepath))
+ return mya
+
+
+class FileChecker:
+ def __init__(self,keydir=None,keyring=None,requireSignedRing=False,minimumTrust=EXISTS):
+ self.minimumTrust = TRUSTED # Default we require trust. For rings.
+ self.keydir = None
+ self.keyring = None
+ self.keyringPath = None
+ self.keyringStats = None
+ self.keyringIsTrusted = False
+
+ if (keydir != None):
+ # Verify that the keydir is valid.
+ if type(keydir) != types.StringType:
+ raise portage_exception.InvalidDataType, "keydir argument: %s" % keydir
+ if not os.path.isdir(keydir):
+ raise portage_exception.DirectoryNotFound, "keydir: %s" % keydir
+ self.keydir = copy.deepcopy(keydir)
+
+ if (keyring != None):
+ # Verify that the keyring is a valid filename and exists.
+ if type(keyring) != types.StringType:
+ raise portage_exception.InvalidDataType, "keyring argument: %s" % keyring
+ if keyring.find("/") != -1:
+ raise portage_exception.InvalidData, "keyring: %s" % keyring
+ pathname = ""
+ if keydir:
+ pathname = keydir + "/" + keyring
+ if not os.path.isfile(pathname):
+ raise portage_exception.FileNotFound, "keyring missing: %s (dev.gentoo.org/~carpaski/gpg/)" % pathname
+
+ keyringPath = keydir+"/"+keyring
+
+ if not keyring or not keyringPath and requireSignedRing:
+ raise portage_exception.MissingParameter
+
+ self.keyringStats = fileStats(keyringPath)
+ self.minimumTrust = TRUSTED
+ if not self.verify(keyringPath, keyringPath+".asc"):
+ self.keyringIsTrusted = False
+ if requireSignedRing:
+ raise portage_exception.InvalidSignature, "Required keyring verification: "+keyringPath
+ else:
+ self.keyringIsTrusted = True
+
+ self.keyring = copy.deepcopy(keyring)
+ self.keyringPath = self.keydir+"/"+self.keyring
+ self.minimumTrust = minimumTrust
+
+ def _verifyKeyring(self):
+ if self.keyringStats and self.keyringPath:
+ new_stats = fileStats(self.keyringPath)
+ if new_stats != self.keyringStats:
+ raise portage_exception.SecurityViolation, "GPG keyring changed!"
+
+ def verify(self, filename, sigfile=None):
+ """Uses minimumTrust to determine if it is Valid/True or Invalid/False"""
+ self._verifyKeyring()
+
+ if not os.path.isfile(filename):
+ raise portage_exception.FileNotFound, filename
+
+ if sigfile and not os.path.isfile(sigfile):
+ raise portage_exception.FileNotFound, sigfile
+
+ if self.keydir and not os.path.isdir(self.keydir):
+ raise portage_exception.DirectoryNotFound, filename
+
+ if self.keyringPath:
+ if not os.path.isfile(self.keyringPath):
+ raise portage_exception.FileNotFound, self.keyringPath
+
+ if not os.path.isfile(filename):
+ raise portage_exception.CommandNotFound, filename
+
+ command = GPG_BINARY + GPG_VERIFY_FLAGS + GPG_OPTIONS
+ if self.keydir:
+ command += GPG_KEYDIR % (self.keydir)
+ if self.keyring:
+ command += GPG_KEYRING % (self.keyring)
+
+ if sigfile:
+ command += " '"+sigfile+"'"
+ command += " '"+filename+"'"
+
+ result,output = commands.getstatusoutput(command)
+
+ signal = result & 0xff
+ result = (result >> 8)
+
+ if signal:
+ raise SignalCaught, "Signal: %d" % (signal)
+
+ trustLevel = UNTRUSTED
+ if result == 0:
+ trustLevel = TRUSTED
+ #if output.find("WARNING") != -1:
+ # trustLevel = MARGINAL
+ if output.find("BAD") != -1:
+ raise portage_exception.InvalidSignature, filename
+ elif result == 1:
+ trustLevel = EXISTS
+ if output.find("BAD") != -1:
+ raise portage_exception.InvalidSignature, filename
+ elif result == 2:
+ trustLevel = UNTRUSTED
+ if output.find("could not be verified") != -1:
+ raise portage_exception.MissingSignature, filename
+ if output.find("public key not found") != -1:
+ if self.keyringIsTrusted: # We trust the ring, but not the key specifically.
+ trustLevel = MARGINAL
+ else:
+ raise portage_exception.InvalidSignature, filename+" (Unknown Signature)"
+ else:
+ raise portage_exception.UnknownCondition, "GPG returned unknown result: %d" % (result)
+
+ if trustLevel >= self.minimumTrust:
+ return True
+ return False