2 # GeniAPI authentication
10 from sfa.trust.credential import Credential
11 from sfa.trust.trustedroot import TrustedRootList
12 from sfa.trust.rights import RightList
13 from sfa.util.faults import *
14 from sfa.trust.hierarchy import Hierarchy
15 from sfa.util.genitable import GeniTable
16 from sfa.util.config import *
17 from sfa.util.misc import *
18 from sfa.trust.gid import GID
22 Credential based authentication
25 def __init__(self, peer_cert = None, config = None ):
26 self.peer_cert = peer_cert
27 self.hierarchy = Hierarchy()
29 self.config = Config()
30 self.trusted_cert_list = TrustedRootList(self.config.get_trustedroots_dir()).get_list()
33 def check(self, cred, operation):
35 Check the credential against the peer cert (callerGID included
36 in the credential matches the caller that is connected to the
37 HTTPS connection, check if the credential was signed by a
38 trusted cert and check if the credential is allowd to perform
39 the specified operation.
41 self.client_cred = Credential(string = cred)
42 self.client_gid = self.client_cred.get_gid_caller()
43 self.object_gid = self.client_cred.get_gid_object()
45 # make sure the client_gid is not blank
46 if not self.client_gid:
47 raise MissingCallerGID(self.client_cred.get_subject())
49 # make sure the client_gid matches client's certificate
50 peer_cert = self.peer_cert
51 if peer_cert and not peer_cert.is_pubkey(self.client_gid.get_pubkey()):
52 raise ConnectionKeyGIDMismatch(self.client_gid.get_subject())
54 # make sure the client is allowed to perform the operation
56 if not self.client_cred.can_perform(operation):
57 raise InsufficientRights(operation)
59 if self.trusted_cert_list:
60 self.client_cred.verify_chain(self.trusted_cert_list)
62 self.client_gid.verify_chain(self.trusted_cert_list)
64 self.object_gid.verify_chain(self.trusted_cert_list)
69 def verifyGidRequestHash(self, gid, hash, arglist):
70 key = gid.get_pubkey()
71 if not key.verify_string(str(arglist), hash):
72 raise BadRequestHash(hash)
74 def verifyCredRequestHash(self, cred, hash, arglist):
75 gid = cred.get_gid_caller()
76 self.verifyGidRequestHash(gid, hash, arglist)
78 def validateGid(self, gid):
79 if self.trusted_cert_list:
80 gid.verify_chain(self.trusted_cert_list)
82 def validateCred(self, cred):
83 if self.trusted_cert_list:
84 cred.verify_chain(self.trusted_cert_list)
85 caller_gid = cred.get_gid_caller()
86 object_gid = cred.get_gid_object()
88 caller_gid.verify_chain(self.trusted_cert_list)
90 object_gid.verify_chain(self.trusted_cert_list)
92 def authenticateGid(self, gidStr, argList, requestHash):
93 gid = GID(string = gidStr)
95 self.verifyGidRequestHash(gid, requestHash, argList)
98 def authenticateCred(self, credStr, argList, requestHash):
99 cred = Credential(string = credStr)
100 self.validateCred(cred)
101 self.verifyCredRequestHash(cred, requestHash, argList)
104 def authenticateCert(self, certStr, requestHash):
105 cert = Certificate(string=certStr)
106 self.validateCert(self, cert)
108 def gidNoop(self, gidStr, value, requestHash):
109 self.authenticateGid(gidStr, [gidStr, value], requestHash)
112 def credNoop(self, credStr, value, requestHash):
113 self.authenticateCred(credStr, [credStr, value], requestHash)
116 def verify_cred_is_me(self, credential):
118 cred = Credential(string=credential)
119 caller_gid = cred.get_gid_caller()
120 caller_hrn = caller_gid.get_hrn()
121 if caller_hrn != self.config.SFA_INTERFACE_HRN:
122 raise GeniPermissionError(self.config.SFA_INTEFACE_HRN)
126 def get_auth_info(self, auth_hrn):
128 Given an authority name, return the information for that authority.
129 This is basically a stub that calls the hierarchy module.
131 @param auth_hrn human readable name of authority
134 return self.hierarchy.get_auth_info(auth_hrn)
137 def veriry_auth_belongs_to_me(self, name):
139 Verify that an authority belongs to our hierarchy.
140 This is basically left up to the implementation of the hierarchy
141 module. If the specified name does not belong, ane exception is
142 thrown indicating the caller should contact someone else.
144 @param auth_name human readable name of authority
147 # get auth info will throw an exception if the authority doesnt exist
148 self.get_auth_info(name)
151 def verify_object_belongs_to_me(self, name):
153 Verify that an object belongs to our hierarchy. By extension,
154 this implies that the authority that owns the object belongs
155 to our hierarchy. If it does not an exception is thrown.
157 @param name human readable name of object
159 auth_name = self.get_authority(name)
162 if name == self.config.SFA_INTERFACE_HRN:
164 self.verify_auth_belongs_to_me(auth_name)
166 def verify_auth_belongs_to_me(self, name):
167 # get auth info will throw an exception if the authority doesnt exist
168 self.get_auth_info(name)
171 def verify_object_permission(self, name):
173 Verify that the object gid that was specified in the credential
174 allows permission to the object 'name'. This is done by a simple
175 prefix test. For example, an object_gid for plc.arizona would
176 match the objects plc.arizona.slice1 and plc.arizona.
178 @param name human readable name to test
180 object_hrn = self.object_gid.get_hrn()
181 if object_hrn == name:
183 if name.startswith(object_hrn + "."):
185 #if name.startswith(get_authority(name)):
188 raise PermissionError(name)
190 def determine_user_rights(self, src_cred, record):
192 Given a user credential and a record, determine what set of rights the
193 user should have to that record.
195 Src_cred can be None when obtaining a user credential, but should be
196 set to a valid user credential when obtaining a slice or authority
199 This is intended to replace determine_rights() and
200 verify_cancreate_credential()
203 type = record['type']
205 cred_object_hrn = src_cred.get_gid_object().get_hrn()
207 # supplying src_cred==None is only valid when obtaining user
209 #assert(type == "user")
211 cred_object_hrn = None
216 researchers = record.get("researcher", [])
217 if (cred_object_hrn in researchers):
224 elif type == "authority":
225 pis = record.get("pi", [])
226 operators = record.get("operator", [])
227 rl.add("authority,sa,ma")
228 if (cred_object_hrn in pis):
230 if (cred_object_hrn in operators):
240 def verify_cancreate_credential(self, src_cred, record):
242 Verify that a user can retrive a particular type of credential.
243 For slices, the user must be on the researcher list. For SA and
244 MA the user must be on the pi and operator lists respectively
247 type = record.get_type()
248 cred_object_hrn = src_cred.get_gid_object().get_hrn()
249 if cred_object_hrn in [self.config.SFA_REGISTRY_ROOT_AUTH]:
252 researchers = record.get("researcher", [])
253 if not (cred_object_hrn in researchers):
254 raise PermissionError(cred_object_hrn + " is not in researcher list for " + record.get_name())
256 pis = record.get("pi", [])
257 if not (cred_object_hrn in pis):
258 raise PermissionError(cred_object_hrn + " is not in pi list for " + record.get_name())
260 operators = record.get("operator", [])
261 if not (cred_object_hrn in operators):
262 raise PermissionError(cred_object_hrn + " is not in operator list for " + record.get_name())
264 def get_authority(self, hrn):
265 return get_authority(hrn)