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 # validate the client cert if it exists
51 self.verifyPeerCert(self.peer_cert, self.client_gid)
53 # make sure the client is allowed to perform the operation
55 if not self.client_cred.can_perform(operation):
56 raise InsufficientRights(operation)
58 if self.trusted_cert_list:
59 self.client_cred.verify_chain(self.trusted_cert_list)
61 self.client_gid.verify_chain(self.trusted_cert_list)
63 self.object_gid.verify_chain(self.trusted_cert_list)
67 def verifyPeerCert(self, cert, gid):
68 # make sure the client_gid matches client's certificate
70 peer_cert = self.peer_cert
75 peer_gid = self.client_gid
78 if not peer_cert.is_pubkey(peer_gid.get_pubkey()):
79 raise ConnectionKeyGIDMismatch(peer_gid.get_subject())
81 def verifyGidRequestHash(self, gid, hash, arglist):
82 key = gid.get_pubkey()
83 if not key.verify_string(str(arglist), hash):
84 raise BadRequestHash(hash)
86 def verifyCredRequestHash(self, cred, hash, arglist):
87 gid = cred.get_gid_caller()
88 self.verifyGidRequestHash(gid, hash, arglist)
90 def validateGid(self, gid):
91 if self.trusted_cert_list:
92 gid.verify_chain(self.trusted_cert_list)
94 def validateCred(self, cred):
95 if self.trusted_cert_list:
96 cred.verify_chain(self.trusted_cert_list)
97 caller_gid = cred.get_gid_caller()
98 object_gid = cred.get_gid_object()
100 caller_gid.verify_chain(self.trusted_cert_list)
102 object_gid.verify_chain(self.trusted_cert_list)
104 def authenticateGid(self, gidStr, argList, requestHash):
105 gid = GID(string = gidStr)
106 self.validateGid(gid)
107 self.verifyGidRequestHash(gid, requestHash, argList)
110 def authenticateCred(self, credStr, argList, requestHash):
111 cred = Credential(string = credStr)
112 self.validateCred(cred)
113 self.verifyCredRequestHash(cred, requestHash, argList)
116 def authenticateCert(self, certStr, requestHash):
117 cert = Certificate(string=certStr)
118 self.validateCert(self, cert)
120 def gidNoop(self, gidStr, value, requestHash):
121 self.authenticateGid(gidStr, [gidStr, value], requestHash)
124 def credNoop(self, credStr, value, requestHash):
125 self.authenticateCred(credStr, [credStr, value], requestHash)
128 def verify_cred_is_me(self, credential):
130 cred = Credential(string=credential)
131 caller_gid = cred.get_gid_caller()
132 caller_hrn = caller_gid.get_hrn()
133 if caller_hrn != self.config.SFA_INTERFACE_HRN:
134 raise GeniPermissionError(self.config.SFA_INTEFACE_HRN)
138 def get_auth_info(self, auth_hrn):
140 Given an authority name, return the information for that authority.
141 This is basically a stub that calls the hierarchy module.
143 @param auth_hrn human readable name of authority
146 return self.hierarchy.get_auth_info(auth_hrn)
149 def veriry_auth_belongs_to_me(self, name):
151 Verify that an authority belongs to our hierarchy.
152 This is basically left up to the implementation of the hierarchy
153 module. If the specified name does not belong, ane exception is
154 thrown indicating the caller should contact someone else.
156 @param auth_name human readable name of authority
159 # get auth info will throw an exception if the authority doesnt exist
160 self.get_auth_info(name)
163 def verify_object_belongs_to_me(self, name):
165 Verify that an object belongs to our hierarchy. By extension,
166 this implies that the authority that owns the object belongs
167 to our hierarchy. If it does not an exception is thrown.
169 @param name human readable name of object
171 auth_name = self.get_authority(name)
174 if name == self.config.SFA_INTERFACE_HRN:
176 self.verify_auth_belongs_to_me(auth_name)
178 def verify_auth_belongs_to_me(self, name):
179 # get auth info will throw an exception if the authority doesnt exist
180 self.get_auth_info(name)
183 def verify_object_permission(self, name):
185 Verify that the object gid that was specified in the credential
186 allows permission to the object 'name'. This is done by a simple
187 prefix test. For example, an object_gid for plc.arizona would
188 match the objects plc.arizona.slice1 and plc.arizona.
190 @param name human readable name to test
192 object_hrn = self.object_gid.get_hrn()
193 if object_hrn == name:
195 if name.startswith(object_hrn + "."):
197 #if name.startswith(get_authority(name)):
200 raise PermissionError(name)
202 def determine_user_rights(self, src_cred, record):
204 Given a user credential and a record, determine what set of rights the
205 user should have to that record.
207 Src_cred can be None when obtaining a user credential, but should be
208 set to a valid user credential when obtaining a slice or authority
211 This is intended to replace determine_rights() and
212 verify_cancreate_credential()
215 type = record['type']
217 cred_object_hrn = src_cred.get_gid_object().get_hrn()
219 # supplying src_cred==None is only valid when obtaining user
221 #assert(type == "user")
223 cred_object_hrn = None
228 researchers = record.get("researcher", [])
229 if (cred_object_hrn in researchers):
236 elif type == "authority":
237 pis = record.get("pi", [])
238 operators = record.get("operator", [])
239 rl.add("authority,sa,ma")
240 if (cred_object_hrn in pis):
242 if (cred_object_hrn in operators):
252 def verify_cancreate_credential(self, src_cred, record):
254 Verify that a user can retrive a particular type of credential.
255 For slices, the user must be on the researcher list. For SA and
256 MA the user must be on the pi and operator lists respectively
259 type = record.get_type()
260 cred_object_hrn = src_cred.get_gid_object().get_hrn()
261 if cred_object_hrn in [self.config.SFA_REGISTRY_ROOT_AUTH]:
264 researchers = record.get("researcher", [])
265 if not (cred_object_hrn in researchers):
266 raise PermissionError(cred_object_hrn + " is not in researcher list for " + record.get_name())
268 pis = record.get("pi", [])
269 if not (cred_object_hrn in pis):
270 raise PermissionError(cred_object_hrn + " is not in pi list for " + record.get_name())
272 operators = record.get("operator", [])
273 if not (cred_object_hrn in operators):
274 raise PermissionError(cred_object_hrn + " is not in operator list for " + record.get_name())
276 def get_authority(self, hrn):
277 return get_authority(hrn)