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=None):
105 gid = GID(string = gidStr)
106 self.validateGid(gid)
107 # request_hash is optional
109 self.verifyGidRequestHash(gid, requestHash, argList)
112 def authenticateCred(self, credStr, argList, requestHash=None):
113 cred = Credential(string = credStr)
114 self.validateCred(cred)
115 # request hash is optional
117 self.verifyCredRequestHash(cred, requestHash, argList)
120 def authenticateCert(self, certStr, requestHash):
121 cert = Certificate(string=certStr)
122 self.validateCert(self, cert)
124 def gidNoop(self, gidStr, value, requestHash):
125 self.authenticateGid(gidStr, [gidStr, value], requestHash)
128 def credNoop(self, credStr, value, requestHash):
129 self.authenticateCred(credStr, [credStr, value], requestHash)
132 def verify_cred_is_me(self, credential):
134 cred = Credential(string=credential)
135 caller_gid = cred.get_gid_caller()
136 caller_hrn = caller_gid.get_hrn()
137 if caller_hrn != self.config.SFA_INTERFACE_HRN:
138 raise GeniPermissionError(self.config.SFA_INTEFACE_HRN)
142 def get_auth_info(self, auth_hrn):
144 Given an authority name, return the information for that authority.
145 This is basically a stub that calls the hierarchy module.
147 @param auth_hrn human readable name of authority
150 return self.hierarchy.get_auth_info(auth_hrn)
153 def veriry_auth_belongs_to_me(self, name):
155 Verify that an authority belongs to our hierarchy.
156 This is basically left up to the implementation of the hierarchy
157 module. If the specified name does not belong, ane exception is
158 thrown indicating the caller should contact someone else.
160 @param auth_name human readable name of authority
163 # get auth info will throw an exception if the authority doesnt exist
164 self.get_auth_info(name)
167 def verify_object_belongs_to_me(self, name):
169 Verify that an object belongs to our hierarchy. By extension,
170 this implies that the authority that owns the object belongs
171 to our hierarchy. If it does not an exception is thrown.
173 @param name human readable name of object
175 auth_name = self.get_authority(name)
178 if name == self.config.SFA_INTERFACE_HRN:
180 self.verify_auth_belongs_to_me(auth_name)
182 def verify_auth_belongs_to_me(self, name):
183 # get auth info will throw an exception if the authority doesnt exist
184 self.get_auth_info(name)
187 def verify_object_permission(self, name):
189 Verify that the object gid that was specified in the credential
190 allows permission to the object 'name'. This is done by a simple
191 prefix test. For example, an object_gid for plc.arizona would
192 match the objects plc.arizona.slice1 and plc.arizona.
194 @param name human readable name to test
196 object_hrn = self.object_gid.get_hrn()
197 if object_hrn == name:
199 if name.startswith(object_hrn + "."):
201 #if name.startswith(get_authority(name)):
204 raise PermissionError(name)
206 def determine_user_rights(self, src_cred, record):
208 Given a user credential and a record, determine what set of rights the
209 user should have to that record.
211 Src_cred can be None when obtaining a user credential, but should be
212 set to a valid user credential when obtaining a slice or authority
215 This is intended to replace determine_rights() and
216 verify_cancreate_credential()
219 type = record['type']
221 cred_object_hrn = src_cred.get_gid_object().get_hrn()
223 # supplying src_cred==None is only valid when obtaining user
225 #assert(type == "user")
227 cred_object_hrn = None
232 researchers = record.get("researcher", [])
233 if (cred_object_hrn in researchers):
240 elif type == "authority":
241 pis = record.get("pi", [])
242 operators = record.get("operator", [])
243 rl.add("authority,sa,ma")
244 if (cred_object_hrn in pis):
246 if (cred_object_hrn in operators):
256 def verify_cancreate_credential(self, src_cred, record):
258 Verify that a user can retrive a particular type of credential.
259 For slices, the user must be on the researcher list. For SA and
260 MA the user must be on the pi and operator lists respectively
263 type = record.get_type()
264 cred_object_hrn = src_cred.get_gid_object().get_hrn()
265 if cred_object_hrn in [self.config.SFA_REGISTRY_ROOT_AUTH]:
268 researchers = record.get("researcher", [])
269 if not (cred_object_hrn in researchers):
270 raise PermissionError(cred_object_hrn + " is not in researcher list for " + record.get_name())
272 pis = record.get("pi", [])
273 if not (cred_object_hrn in pis):
274 raise PermissionError(cred_object_hrn + " is not in pi list for " + record.get_name())
276 operators = record.get("operator", [])
277 if not (cred_object_hrn in operators):
278 raise PermissionError(cred_object_hrn + " is not in operator list for " + record.get_name())
280 def get_authority(self, hrn):
281 return get_authority(hrn)