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
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):
68 # make sure the client_gid matches client's certificate
69 peer_cert = self.peer_cert
70 if not peer_cert.is_pubkey(self.client_gid.get_pubkey()):
71 raise ConnectionKeyGIDMismatch(self.client_gid.get_subject()
73 def verifyGidRequestHash(self, gid, hash, arglist):
74 key = gid.get_pubkey()
75 if not key.verify_string(str(arglist), hash):
76 raise BadRequestHash(hash)
78 def verifyCredRequestHash(self, cred, hash, arglist):
79 gid = cred.get_gid_caller()
80 self.verifyGidRequestHash(gid, hash, arglist)
82 def validateGid(self, gid):
83 if self.trusted_cert_list:
84 gid.verify_chain(self.trusted_cert_list)
86 def validateCred(self, cred):
87 if self.trusted_cert_list:
88 cred.verify_chain(self.trusted_cert_list)
89 caller_gid = cred.get_gid_caller()
90 object_gid = cred.get_gid_object()
92 caller_gid.verify_chain(self.trusted_cert_list)
94 object_gid.verify_chain(self.trusted_cert_list)
96 def authenticateGid(self, gidStr, argList, requestHash):
97 gid = GID(string = gidStr)
99 self.verifyGidRequestHash(gid, requestHash, argList)
102 def authenticateCred(self, credStr, argList, requestHash):
103 cred = Credential(string = credStr)
104 self.validateCred(cred)
105 self.verifyCredRequestHash(cred, requestHash, argList)
108 def authenticateCert(self, certStr, requestHash):
109 cert = Certificate(string=certStr)
110 self.validateCert(self, cert)
112 def gidNoop(self, gidStr, value, requestHash):
113 self.authenticateGid(gidStr, [gidStr, value], requestHash)
116 def credNoop(self, credStr, value, requestHash):
117 self.authenticateCred(credStr, [credStr, value], requestHash)
120 def verify_cred_is_me(self, credential):
122 cred = Credential(string=credential)
123 caller_gid = cred.get_gid_caller()
124 caller_hrn = caller_gid.get_hrn()
125 if caller_hrn != self.config.SFA_INTERFACE_HRN:
126 raise GeniPermissionError(self.config.SFA_INTEFACE_HRN)
130 def get_auth_info(self, auth_hrn):
132 Given an authority name, return the information for that authority.
133 This is basically a stub that calls the hierarchy module.
135 @param auth_hrn human readable name of authority
138 return self.hierarchy.get_auth_info(auth_hrn)
141 def veriry_auth_belongs_to_me(self, name):
143 Verify that an authority belongs to our hierarchy.
144 This is basically left up to the implementation of the hierarchy
145 module. If the specified name does not belong, ane exception is
146 thrown indicating the caller should contact someone else.
148 @param auth_name human readable name of authority
151 # get auth info will throw an exception if the authority doesnt exist
152 self.get_auth_info(name)
155 def verify_object_belongs_to_me(self, name):
157 Verify that an object belongs to our hierarchy. By extension,
158 this implies that the authority that owns the object belongs
159 to our hierarchy. If it does not an exception is thrown.
161 @param name human readable name of object
163 auth_name = self.get_authority(name)
166 if name == self.config.SFA_INTERFACE_HRN:
168 self.verify_auth_belongs_to_me(auth_name)
170 def verify_auth_belongs_to_me(self, name):
171 # get auth info will throw an exception if the authority doesnt exist
172 self.get_auth_info(name)
175 def verify_object_permission(self, name):
177 Verify that the object gid that was specified in the credential
178 allows permission to the object 'name'. This is done by a simple
179 prefix test. For example, an object_gid for plc.arizona would
180 match the objects plc.arizona.slice1 and plc.arizona.
182 @param name human readable name to test
184 object_hrn = self.object_gid.get_hrn()
185 if object_hrn == name:
187 if name.startswith(object_hrn + "."):
189 #if name.startswith(get_authority(name)):
192 raise PermissionError(name)
194 def determine_user_rights(self, src_cred, record):
196 Given a user credential and a record, determine what set of rights the
197 user should have to that record.
199 Src_cred can be None when obtaining a user credential, but should be
200 set to a valid user credential when obtaining a slice or authority
203 This is intended to replace determine_rights() and
204 verify_cancreate_credential()
207 type = record['type']
209 cred_object_hrn = src_cred.get_gid_object().get_hrn()
211 # supplying src_cred==None is only valid when obtaining user
213 #assert(type == "user")
215 cred_object_hrn = None
220 researchers = record.get("researcher", [])
221 if (cred_object_hrn in researchers):
228 elif type == "authority":
229 pis = record.get("pi", [])
230 operators = record.get("operator", [])
231 rl.add("authority,sa,ma")
232 if (cred_object_hrn in pis):
234 if (cred_object_hrn in operators):
244 def verify_cancreate_credential(self, src_cred, record):
246 Verify that a user can retrive a particular type of credential.
247 For slices, the user must be on the researcher list. For SA and
248 MA the user must be on the pi and operator lists respectively
251 type = record.get_type()
252 cred_object_hrn = src_cred.get_gid_object().get_hrn()
253 if cred_object_hrn in [self.config.SFA_REGISTRY_ROOT_AUTH]:
256 researchers = record.get("researcher", [])
257 if not (cred_object_hrn in researchers):
258 raise PermissionError(cred_object_hrn + " is not in researcher list for " + record.get_name())
260 pis = record.get("pi", [])
261 if not (cred_object_hrn in pis):
262 raise PermissionError(cred_object_hrn + " is not in pi list for " + record.get_name())
264 operators = record.get("operator", [])
265 if not (cred_object_hrn in operators):
266 raise PermissionError(cred_object_hrn + " is not in operator list for " + record.get_name())
268 def get_authority(self, hrn):
269 return get_authority(hrn)