/[gentoo-src]/portage/pym/portage_gpg.py
Gentoo

Contents of /portage/pym/portage_gpg.py

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.11 - (show annotations) (download) (as text)
Sat Feb 26 06:35:20 2005 UTC (9 years, 10 months ago) by jstubbs
Branch: MAIN
CVS Tags: HEAD
Branch point for: portage_2_1
Changes since 1.10: +2 -1 lines
File MIME type: text/x-python
Brought forward changes from portage_2_0

1 # portage_gpg.py -- core Portage functionality
2 # Copyright 2004 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4 # $Header: /var/cvsroot/gentoo-src/portage/pym/portage_gpg.py,v 1.10 2004/11/15 21:42:50 carpaski Exp $
5 cvs_id_string="$Id: portage_gpg.py,v 1.6.2.1 2005/01/16 02:35:33 carpaski Exp $"[5:-2]
6
7 import os
8 import copy
9 import types
10 import portage_exception
11 import portage_checksum
12 import portage_exec
13
14 GPG_BINARY = "/usr/bin/gpg"
15 GPG_OPTIONS = ["--lock-never","--no-random-seed-file",
16 "--no-greeting", "--no-sig-cache"]
17 GPG_VERIFY_FLAGS = ["--verify"]
18
19 GPG_KEYDIR = "--homedir"
20 GPG_KEYRING = "--keyring"
21
22 UNTRUSTED = 0
23 EXISTS = UNTRUSTED + 1
24 MARGINAL = EXISTS + 1
25 TRUSTED = MARGINAL + 1
26
27 def fileStats(filepath):
28 mya = []
29 for x in os.stat(filepath):
30 mya.append(x)
31 mya.append(portage_checksum.perform_checksum(filepath))
32 return mya
33
34
35 class FileChecker:
36 def __init__(self,keydir=None,keyring=None,requireSignedRing=False,minimumTrust=EXISTS):
37 self.minimumTrust = TRUSTED # Default we require trust. For rings.
38 self.keydir = None
39 self.keyring = None
40 self.keyringPath = None
41 self.keyringStats = None
42 self.keyringIsTrusted = False
43
44 if (keydir != None):
45 # Verify that the keydir is valid.
46 if type(keydir) != types.StringType:
47 raise portage_exception.InvalidDataType, "keydir argument: %s" % keydir
48 if not os.path.isdir(keydir):
49 raise portage_exception.DirectoryNotFound, "keydir: %s" % keydir
50 self.keydir = copy.deepcopy(keydir)
51
52 if (keyring != None):
53 # Verify that the keyring is a valid filename and exists.
54 if type(keyring) != types.StringType:
55 raise portage_exception.InvalidDataType, "keyring argument: %s" % keyring
56 if keyring.find("/") != -1:
57 raise portage_exception.InvalidData, "keyring: %s" % keyring
58 pathname = ""
59 if keydir:
60 pathname = keydir + "/" + keyring
61 if not os.path.isfile(pathname):
62 raise portage_exception.FileNotFound, "keyring missing: %s (dev.gentoo.org/~carpaski/gpg/)" % pathname
63
64 keyringPath = keydir+"/"+keyring
65
66 if not keyring or not keyringPath and requireSignedRing:
67 raise portage_exception.MissingParameter
68
69 self.keyringStats = fileStats(keyringPath)
70 self.minimumTrust = TRUSTED
71 if not self.verify(keyringPath, keyringPath+".asc"):
72 self.keyringIsTrusted = False
73 if requireSignedRing:
74 raise portage_exception.InvalidSignature, "Required keyring verification: "+keyringPath
75 else:
76 self.keyringIsTrusted = True
77
78 self.keyring = copy.deepcopy(keyring)
79 self.keyringPath = self.keydir+"/"+self.keyring
80 self.minimumTrust = minimumTrust
81
82 def _verifyKeyring(self):
83 if self.keyringStats and self.keyringPath:
84 new_stats = fileStats(self.keyringPath)
85 if new_stats != self.keyringStats:
86 raise portage_exception.SecurityViolation, "GPG keyring changed!"
87
88 def verify(self, filename, sigfile=None):
89 """Uses minimumTrust to determine if it is Valid/True or Invalid/False"""
90 self._verifyKeyring()
91
92 if not os.path.isfile(filename):
93 raise portage_exception.FileNotFound, filename
94
95 if sigfile and not os.path.isfile(sigfile):
96 raise portage_exception.FileNotFound, sigfile
97
98 if self.keydir and not os.path.isdir(self.keydir):
99 raise portage_exception.DirectoryNotFound, filename
100
101 if self.keyringPath:
102 if not os.path.isfile(self.keyringPath):
103 raise portage_exception.FileNotFound, self.keyringPath
104
105 if not os.path.isfile(filename):
106 raise portage_exception.CommandNotFound, filename
107
108 command = [GPG_BINARY] + GPG_VERIFY_FLAGS + GPG_OPTIONS
109 if self.keydir:
110 command += [GPG_KEYDIR] + [self.keydir]
111 if self.keyring:
112 command += [GPG_KEYRING] + [self.keyring]
113
114 if sigfile:
115 command += [sigfile]
116 command += [filename]
117
118 result,output = portage_exec.spawn_get_output(command,raw_exit_code=True,collect_fds=[1,2])
119
120 signal = result & 0xff
121 result = (result >> 8)
122
123 if signal:
124 raise SignalCaught, "Signal: %d" % (signal)
125
126 trustLevel = UNTRUSTED
127
128 if len(output) == 0:
129 raise portage_exception.UnknownCondition, "GPG generated no output: exited with %d" % (result)
130
131 if result == 0:
132 trustLevel = TRUSTED
133 #if output.find("WARNING") != -1:
134 # trustLevel = MARGINAL
135 if output.find("BAD") != -1:
136 raise portage_exception.InvalidSignature, filename
137 elif result == 1:
138 trustLevel = EXISTS
139 if output.find("BAD") != -1:
140 raise portage_exception.InvalidSignature, filename
141 elif result == 2:
142 trustLevel = UNTRUSTED
143 if output.find("could not be verified") != -1:
144 raise portage_exception.MissingSignature, filename
145 if output.find("public key not found") != -1:
146 if self.keyringIsTrusted: # We trust the ring, but not the key specifically.
147 trustLevel = MARGINAL
148 else:
149 raise portage_exception.InvalidSignature, filename+" (Unknown Signature)"
150 else:
151 raise portage_exception.UnknownCondition, "GPG returned unknown result: %d" % (result)
152
153 if trustLevel >= self.minimumTrust:
154 return True
155 return False

  ViewVC Help
Powered by ViewVC 1.1.20