2 # GeniAPI authentication
7 from geni.util.faults import *
8 from geni.util.excep import *
9 from geni.util.credential import Credential
10 from geni.util.trustedroot import TrustedRootList
11 from geni.util.hierarchy import Hierarchy
12 from geni.util.rights import RightList
13 from geni.util.genitable import *
18 Credential based authentication
21 def __init__(self, peer_cert):
22 self.peer_cert = peer_cert
23 self.hierarchy = Hierarchy()
24 self.trusted_cert_list = TrustedRootList().get_list()
28 def check(self, cred, operation):
30 Check the credential against the peer cert (callerGID included
31 in the credential matches the caller that is connected to the
32 HTTPS connection, check if the credential was signed by a
33 trusted cert and check if the credential is allowd to perform
34 the specified operation.
36 self.client_cred = Credential(string = cred)
37 self.client_gid = self.client_cred.get_gid_caller()
38 self.object_gid = self.client_cred.get_gid_object()
40 # make sure the client_gid is not blank
41 if not self.client_gid:
42 raise MissingCallerGID(self.client_cred.get_subject())
44 # make sure the client_gid matches client's certificate
45 peer_cert = self.peer_cert
46 if not peer_cert.is_pubkey(self.client_gid.get_pubkey()):
47 raise ConnectionKeyGIDMismatch(self.client_gid.get_subject())
49 # make sure the client is allowed to perform the operation
51 if not self.client_cred.can_perform(operation):
52 raise InsufficientRights(operation)
54 if self.trusted_cert_list:
55 self.client_cred.verify_chain(self.trusted_cert_list)
57 self.client_gid.verify_chain(self.trusted_cert_list)
59 self.object_gid.verify_chain(self.trusted_cert_list)
64 def get_auth_info(self, auth_hrn):
66 Given an authority name, return the information for that authority.
67 This is basically a stub that calls the hierarchy module.
69 @param auth_hrn human readable name of authority
72 return self.hierarchy.get_auth_info(auth_hrn)
75 def get_auth_table(self, auth_name):
77 Given an authority name, return the database table for that authority.
78 If the databse table does not exist, then one will be automatically
81 @param auth_name human readable name of authority
83 auth_info = self.get_auth_info(auth_name)
84 table = GeniTable(hrn=auth_name,
85 cninfo=auth_info.get_dbinfo())
86 # if the table doesn't exist, then it means we haven't put any records
87 # into this authority yet.
89 if not table.exists():
90 print >> log, "Registry: creating table for authority", auth_name
95 def veriry_auth_belongs_to_me(self, name):
97 Verify that an authority belongs to our hierarchy.
98 This is basically left up to the implementation of the hierarchy
99 module. If the specified name does not belong, ane exception is
100 thrown indicating the caller should contact someone else.
102 @param auth_name human readable name of authority
105 self.get_auth_info(name)
108 def verify_object_belongs_to_me(self, name):
110 Verify that an object belongs to our hierarchy. By extension,
111 this implies that the authority that owns the object belongs
112 to our hierarchy. If it does not an exception is thrown.
114 @param name human readable name of object
116 auth_name = self.get_authority(name)
118 # the root authority belongs to the registry by default?
119 # TODO: is this true?
121 self.verify_auth_belongs_to_me(auth_name)
123 def verify_auth_belongs_to_me(self, name):
124 # get auth info will throw an exception if the authority doesnt exist
125 self.get_auth_info(name)
128 def verify_object_permission(self, name):
130 Verify that the object gid that was specified in the credential
131 allows permission to the object 'name'. This is done by a simple
132 prefix test. For example, an object_gid for plc.arizona would
133 match the objects plc.arizona.slice1 and plc.arizona.
135 @param name human readable name to test
137 object_hrn = self.object_gid.get_hrn()
138 if object_hrn == name:
140 if name.startswith(object_hrn + "."):
142 raise PermissionError(name)
144 def verify_cancreate_credential(self, src_cred, record):
146 Verify that a user can retrive a particular type of credential.
147 For slices, the user must be on the researcher list. For SA and
148 MA the user must be on the pi and operator lists respectively
151 type = record.get_type()
152 cred_object_hrn = src_cred.get_gid_object().get_hrn()
153 if cred_object_hrn in [self.config.GENI_REGISTRY_ROOT_AUTH]:
156 researchers = record.get_geni_info().get("researcher", [])
157 if not (cred_object_hrn in researchers):
158 raise PermissionError(cred_object_hrn + " is not in researcher list for " + record.get_name())
160 pis = record.get_geni_info().get("pi", [])
161 if not (cred_object_hrn in pis):
162 raise PermissionError(cred_object_hrn + " is not in pi list for " + record.get_name())
164 operators = record.get_geni_info().get("operator", [])
165 if not (cred_object_hrn in operators):
166 raise PermissionError(cred_object_hrn + " is not in operator list for " + record.get_name())
168 def get_leaf(self, hrn):
169 parts = hrn.split(".")
170 return ".".join(parts[-1:])
172 def get_authority(self, hrn):
174 parts = hrn.split(".")
175 return ".".join(parts[:-1])
177 def get_auth_type(self, type):
178 if (type=="slice") or (type=="user") or (type=="sa"):
180 elif (type=="component") or (type=="ma"):
183 raise UnknownGeniType(type)
185 def hrn_to_pl_slicename(self, hrn):
186 parts = hrn.split(".")
187 return parts[-2] + "_" + parts[-1]
189 # assuming hrn is the hrn of an authority, return the plc authority name
190 def hrn_to_pl_authname(self, hrn):
191 parts = hrn.split(".")
194 # assuming hrn is the hrn of an authority, return the plc login_base
195 def hrn_to_pl_login_base(self, hrn):
196 return self.hrn_to_pl_authname(hrn)