3 sys.path.append('./sec')
8 from pl_to_geni import *
10 ROOT_AUTH = 'planetlab' #need to know the higher most node
15 self.login_base = None
18 dic = {'name':self.name, 'login_base':self.login_base, 'node_data':None}
21 if self.node_data.has_key('key_info'):
22 dic['node_data']['key_info'] = self.node_data['key_info'].serial()
23 if self.node_data.has_key('db_info'):
24 dic['node_data']['db_info'] = self.node_data['db_info'].serial()
36 return {'folder': self.folder, 'id_file': self.id_file, 'id_key_file': self.id_key_file, 'acc_file': self.acc_file, 'cred_file': self.cred_file, 'last_update': self.last_update}
40 self.table_name = '' #ex: planetlab.br_sr
41 self.db_name = '' #ex: plDB
47 return {'table_name':self.table_name, 'db_name':self.db_name, 'address':self.address, 'port':self.port, 'user':self.user, 'password':self.password}
55 if len(self.children)>0:
56 for c in self.children:
57 children.append(c.serial())
59 return {'children':children, 'info':self.info.serial()}
61 return {'children':children, 'info':None}
64 def __init__(self, type, filename, auth_addr):
65 #the tree for keeping the site names managed by this interface instance
68 self.filename = filename
69 self.auth_addr = auth_addr
72 #check a hrn if exists in the tree, return the info of it, if not found return None
74 def tree_lookup(self, hrn) :
76 if not tree: #tree empty
79 hrn_arr = geni_to_arr(hrn)
81 if tmp_tree.info.name != hrn_arr[0] :
84 cur_name = hrn_arr[0] + ''
85 for i in range(1, len(hrn_arr)):
86 cur_name = cur_name + '.' + hrn_arr[i]
89 for j in range(len(tmp_tree.children)) :
90 if tmp_tree.children[j].info.name == cur_name :
92 child = tmp_tree.children[j]
94 if child_found == False:
104 def is_leaf(self, hrn):
106 if not tree: #tree empty
109 hrn_arr = geni_to_arr(hrn)
111 if tmp_tree.info.name != hrn_arr[0] :
114 cur_name = hrn_arr[0] + ''
115 for i in range(1, len(hrn_arr)):
116 cur_name = cur_name + '.' + hrn_arr[i]
119 for j in range(len(tmp_tree.children)) :
120 if tmp_tree.children[j].info.name == cur_name :
122 child = tmp_tree.children[j]
124 if child_found == False:
130 return tmp_tree.children == []
134 #add a new branch into the tree, branch is indicated by info
136 def tree_add(self, info):
139 hrn_arr = geni_to_arr(info.name)
143 raise TreeException("Wrong input hrn: "+info.name)
146 if len(hrn_arr) == 1:
152 cur_name = hrn_arr[0] + ''
153 if tmp_tree.info.name == cur_name:
154 for i in range(1, len(hrn_arr)):
155 cur_name = cur_name + '.' + hrn_arr[i]
158 for j in range(len(tmp_tree.children)) :
159 if tmp_tree.children[j].info.name == cur_name :
161 child = tmp_tree.children[j]
163 if child_found == False:
164 if len(hrn_arr) - i == 1:
165 #insert the remaining of hrn
166 new_child = TreeNode()
167 new_child.info = info
168 tmp_tree.children.append(new_child)
173 if inserted == False:
174 print "The hrn '"+info.name+"' should be at leaf position to be inserted.\n"
177 #remove the branch indicated by hrn from the tree
179 def tree_remove(self, hrn):
182 hrn_arr = geni_to_arr(hrn)
184 if tmp_tree.info.name == hrn_arr[0] :
185 cur_name = hrn_arr[0] + ''
186 for i in range(1, len(hrn_arr)):
187 cur_name = cur_name + '.' + hrn_arr[i]
190 for j in range(len(tmp_tree.children)) :
191 if tmp_tree.children[j].info.name == cur_name :
193 child = tmp_tree.children[j]
195 if child_found == False:
198 if i == len(hrn_arr)-1:
199 tmp_tree.children.remove(child)
205 #initialize the tree with the file data
207 filename = self.filename
210 #check if dict file exists
211 if not os.path.exists(filename+'_dict'):
212 if not os.path.exists(filename):
213 print 'Error: File not found.\n'
214 raise NonExistingFile(filename)
216 self.__file_to_treedict(filename)
217 self.my_tree = self.__deserialize_tree(eval(open(filename+'_dict').read()))
219 self.my_tree = self.__deserialize_tree(eval(open(filename+'_dict').read()))
220 #create the tables and key folders if they do not exist already
221 self.__sync_with_db_rec(type, self.my_tree)
223 print 'Error in initialzing the tree.\n'
227 open(self.filename+'_dict', 'w').write(str(self.my_tree.serial()))
229 def __sync_with_db_rec(self, type, treenode):
230 self.__sync_with_db(type, treenode)
231 for child in treenode.children:
232 self.__sync_with_db_rec(type, child)
234 #if do not exist, creates the (key folder, private key and self signed cert) and the db table for the node, fills the table with the children info
235 #type: 'slice' or 'component' indicating the registry type
236 #hierarchy:hrn so far
237 #treenode: node to be synched
238 def __sync_with_db(self, type, treenode):
242 if not treenode.info.node_data:
243 treenode.info.node_data = {}
244 #create key folder, private key and self signed cert
245 hrn = treenode.info.name
246 dirname = type+'/'+(hrn).replace('.','/')
247 hrn_suffix = get_leaf(hrn)
248 if os.path.exists(dirname):
249 os.system('rm -rf '+dirname)
252 create_self_cert(hrn_suffix)
255 k.id_file = hrn_suffix+'.cert'
256 k.id_key_file = hrn_suffix +'.pkey'
257 #for the top authority create the acc and cred files
258 if obtain_authority(hrn) == '':
259 id_cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(k.id_file).read())
260 id_pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, open(k.id_key_file).read())
261 uu_id = str(uuid.uuid4().int)
267 rights = '(0-0)(1-0)(2-0)(3-0)(4-0)(5-0)(6-0)(7-0)(8-0)(9-0)'
268 rights = rights + '#0:reg:'+regtype+':'+hrn
269 k.acc_file = 'acc_file'
270 k.cred_file = 'cred_file'
271 acc = create_acc(id_cert, id_pkey, id_cert.get_pubkey(), hrn, uu_id)
272 cred = create_cred(id_cert, id_pkey, id_cert.get_pubkey(), 'Registry credentials', rights)
273 open(k.acc_file, 'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, acc))
274 open(k.cred_file, 'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, cred))
275 treenode.info.node_data['key_info'] = k
277 #create the table and set in the treenode data structure
283 tablename = hrn.replace('.','$') + suffix
284 cnx = get_plDB_conn()
285 querystr = "CREATE TABLE "+tablename+" ( \
297 cnx.query('DROP TABLE IF EXISTS '+tablename) #drop the table if it exists
300 d.table_name = tablename
302 treenode.info.node_data['db_info'] = d
303 #if the authority resides in PL as site, then fill it with the PL data
304 if treenode.children == []:
305 populate_pl_data(hrn_suffix, tablename, type)
306 treenode.info.login_base = hrn_suffix
307 #insert the record into parent's table
308 if obtain_authority(hrn) != '':
318 if treenode.children != []:
319 uu_id = str(uuid.uuid4().int)
320 rights = '(2-0)(4-0)(6-0)(7-0)(8-0)(9-0)(0-1)(1-1)(2-1)(3-1)(4-1)(5-1)(6-1)(7-1)(8-1)(9-1)'
321 rights = rights + '#0:reg:'+regtype+':'+obtain_authority(hrn)+'#1:reg:'+regtype+':'+hrn
322 id_file = treenode.info.node_data['key_info'].folder+'/'+ treenode.info.node_data['key_info'].id_file
323 pubkey = X509.load_cert(id_file).get_pubkey().as_pem(cipher=None)
326 if treenode.children == []: #get pointer if authority resides in PL as site
327 pointer = cnx.query("SELECT site_id FROM sites WHERE login_base='"+hrn_suffix+"'").dictresult()[0]['site_id']
329 record = {'hrn':get_leaf(hrn), 'type':rectype, 'uuid':uu_id, 'rights':rights, 'pubkey':pubkey, 'wrapperURL':wrapper, 'pointer':pointer, 'disabled':disabled}
330 querystr = generate_querystr('INSERT', obtain_authority(hrn).replace('.','$')+suffix, record)
333 #gets a tree in the form of a dictionary,
334 # ex: {'info':{'name':'planetlab', 'node_data':{'key_info':{...}, 'db_info':{...}}}, 'children':[x1, x2, ..]}
335 #returns the tree in the TreeNode class format
336 def __deserialize_tree(self, treenode_dict):
338 node.info = TreeNodeInfo()
339 node.info.name = treenode_dict['info']['name']
340 node.info.login_base = treenode_dict['info']['login_base']
341 if treenode_dict['info']['node_data']:
342 node.info.node_data = {}
343 if treenode_dict['info']['node_data'].has_key('key_info'):
344 node.info.node_data['key_info'] = KeyInfo()
345 keyinf = treenode_dict['info']['node_data']['key_info']
346 node.info.node_data['key_info'].folder = keyinf['folder']
347 node.info.node_data['key_info'].id_file = keyinf['id_file']
348 node.info.node_data['key_info'].id_key_file = keyinf['id_key_file']
349 node.info.node_data['key_info'].acc_file = keyinf['acc_file']
350 node.info.node_data['key_info'].cred_file = keyinf['cred_file']
351 node.info.node_data['key_info'].last_update = keyinf['last_update']
352 if treenode_dict['info']['node_data'].has_key('db_info'):
353 node.info.node_data['db_info'] = DbInfo()
354 dbinf = treenode_dict['info']['node_data']['db_info']
355 node.info.node_data['db_info'].table_name = dbinf['table_name']
356 node.info.node_data['db_info'].db_name = dbinf['db_name']
357 node.info.node_data['db_info'].address = dbinf['address']
358 node.info.node_data['db_info'].port = dbinf['port']
359 node.info.node_data['db_info'].user = dbinf['user']
360 node.info.node_data['db_info'].password = dbinf['password']
361 for child in treenode_dict['children']:
362 node.children.append(self.__deserialize_tree(child))
365 #gets a file name for tree and constructs an output file which contains the tree in dictionary format
366 #write to file: ex: {'info':{'name':'planetlab', 'node_data':{'key_info':{...}, 'db_info':{...}}}, 'children':[x1, x2, ..]}
367 def __file_to_treedict(self, filename):
368 lines = open(filename).readlines()
370 (node, line) = self.__file_to_treedict_rec(lines, 0, hierarchy, 0)
371 open(filename+'_dict', 'w').write(str(node))
374 #return: (node, line)
375 def __file_to_treedict_rec(self, lines, indent, hierarchy, line):
376 node = {'info':{'name':'', 'login_base':'', 'node_data':None}, 'children':[]}
379 while lines[line][j] == '\t':
382 print 'Error in file to dictionary conversion.\n'
384 name = lines[line].split(' ')[0]
385 name = name[j:len(name)]
387 node['info']['name'] = name
389 node['info']['name'] = hierarchy + '.' + name
390 node['info']['login_base'] = name
393 if line+1 != len(lines):
394 while lines[line+1][j] == '\t':
397 print 'Error in file to dictionary conversion.\n'
401 while indent2 > indent:
402 (child, line) = self.__file_to_treedict_rec(lines, indent2, node['info']['name'], line)
403 node['children'].append(child)
405 if line != len(lines):
406 while lines[line][j] == '\t':
412 #determines the key info of a given hrn within the tree, performs calls back to 'server' to obtain updated certs
413 #if the hrn does not exist in the tree hierarchy None is returned
414 #server: the server instance is passed for calls to getCredential/getAccounting if necessary
415 #type is credential or accounting; one of them at a time is determined by the function
416 #returns an array containing the self-signed certificate, private key, and acc or cred chain in string
417 def determine_keyinfo(self, hrn, server, type):
420 info = tree.tree_lookup(hrn)
424 keyinfo = info.node_data['key_info']
425 folder = keyinfo.folder
426 id_file = folder+'/'+keyinfo.id_file
427 id_key_file = folder+'/'+keyinfo.id_key_file
429 if not os.path.exists(folder) or not os.path.exists(id_file):
430 print 'Id file for '+hrn+' does not exist.\n'
436 renew_res = renew_cert(type, folder, reg_type, hrn, server, tree, tree.auth_addr, server.sec)
437 if renew_res == None:
439 if type == 'accounting':
440 keyinfo.acc_file = 'acc_file'
441 acc_str = open(keyinfo.folder+'/'+keyinfo.acc_file).read()
443 keyinfo.cred_file = 'cred_file'
444 cred_str = open(keyinfo.folder+'/'+keyinfo.cred_file).read()
445 id = crypto.load_certificate(crypto.FILETYPE_PEM, open(id_file).read())
446 id_key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(id_key_file).read())
447 return [id, id_key, acc_str, cred_str]