diff options
author | Marius Mauch <genone@gentoo.org> | 2007-01-25 15:49:26 +0000 |
---|---|---|
committer | Marius Mauch <genone@gentoo.org> | 2007-01-25 15:49:26 +0000 |
commit | 3b08c21101b0801d7c5d6c145a27bef5cd42078c (patch) | |
tree | 2eea73b311d67b567410670630335796bf0a272c /pym/portage/gpg.py | |
parent | b4eed9540e19ee7038ac875f0e084f8256675580 (diff) | |
download | portage-3b08c21101b0801d7c5d6c145a27bef5cd42078c.tar.gz portage-3b08c21101b0801d7c5d6c145a27bef5cd42078c.tar.bz2 portage-3b08c21101b0801d7c5d6c145a27bef5cd42078c.zip |
Namespace sanitizing, step 1
svn path=/main/trunk/; revision=5778
Diffstat (limited to 'pym/portage/gpg.py')
-rw-r--r-- | pym/portage/gpg.py | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/pym/portage/gpg.py b/pym/portage/gpg.py new file mode 100644 index 000000000..04ed60046 --- /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 +# $Id$ + + +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 |