+++ /dev/null
-import os, sys
-import uuid
-sys.path.append('./sec')
-from util import *
-from excep import *
-from sec import *
-from db import *
-from pl_to_geni import *
-
-ROOT_AUTH = 'planetlab' #need to know the higher most node
-
-class TreeNodeInfo:
- def __init__(self):
- self.name = '' # hrn
- self.login_base = None
- self.node_data = None
- def serial(self):
- dic = {'name':self.name, 'login_base':self.login_base, 'node_data':None}
- if self.node_data:
- dic['node_data'] = {}
- if self.node_data.has_key('key_info'):
- dic['node_data']['key_info'] = self.node_data['key_info'].serial()
- if self.node_data.has_key('db_info'):
- dic['node_data']['db_info'] = self.node_data['db_info'].serial()
- return dic
-
-class KeyInfo:
- def __init__(self):
- self.folder = ''
- self.id_file = ''
- self.id_key_file = ''
- self.acc_file = ''
- self.cred_file = ''
- self.last_update = ''
- def serial(self):
- 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}
-
-class DbInfo:
- def __init__(self):
- self.table_name = '' #ex: planetlab.br_sr
- self.db_name = '' #ex: plDB
- self.address = ''
- self.port = 0
- self.user = ''
- self.password = ''
- def serial(self):
- return {'table_name':self.table_name, 'db_name':self.db_name, 'address':self.address, 'port':self.port, 'user':self.user, 'password':self.password}
-
-class TreeNode:
- def __init__(self):
- self.info = None
- self.children = []
- def serial(self):
- children = []
- if len(self.children)>0:
- for c in self.children:
- children.append(c.serial())
- if self.info:
- return {'children':children, 'info':self.info.serial()}
- else:
- return {'children':children, 'info':None}
-
-class InterfaceTree:
- def __init__(self, type, filename, auth_addr):
- #the tree for keeping the site names managed by this interface instance
- self.my_tree = None
- self.type = type
- self.filename = filename
- self.auth_addr = auth_addr
- self.tree_init()
-
- #check a hrn if exists in the tree, return the info of it, if not found return None
- #hrn:string
- def tree_lookup(self, hrn) :
- tree= self.my_tree
- if not tree: #tree empty
- return None
- found = True
- hrn_arr = geni_to_arr(hrn)
- tmp_tree = tree
- if tmp_tree.info.name != hrn_arr[0] :
- found = False
- else :
- cur_name = hrn_arr[0] + ''
- for i in range(1, len(hrn_arr)):
- cur_name = cur_name + '.' + hrn_arr[i]
- child_found = False
- child = {}
- for j in range(len(tmp_tree.children)) :
- if tmp_tree.children[j].info.name == cur_name :
- child_found = True
- child = tmp_tree.children[j]
- break
- if child_found == False:
- found = False
- break
- else:
- tmp_tree = child
- if found == True:
- return tmp_tree.info
- else:
- return None
-
- def is_leaf(self, hrn):
- tree= self.my_tree
- if not tree: #tree empty
- return None
- found = True
- hrn_arr = geni_to_arr(hrn)
- tmp_tree = tree
- if tmp_tree.info.name != hrn_arr[0] :
- found = False
- else :
- cur_name = hrn_arr[0] + ''
- for i in range(1, len(hrn_arr)):
- cur_name = cur_name + '.' + hrn_arr[i]
- child_found = False
- child = {}
- for j in range(len(tmp_tree.children)) :
- if tmp_tree.children[j].info.name == cur_name :
- child_found = True
- child = tmp_tree.children[j]
- break
- if child_found == False:
- found = False
- break
- else:
- tmp_tree = child
- if found == True:
- return tmp_tree.children == []
- else:
- return None
-
- #add a new branch into the tree, branch is indicated by info
- #info: TreeNodeInfo
- def tree_add(self, info):
- tree= self.my_tree
- inserted = False
- hrn_arr = geni_to_arr(info.name)
- tmp_tree = tree
-
- if hrn_arr == []:
- raise TreeException("Wrong input hrn: "+info.name)
- else:
- if tree == None:
- if len(hrn_arr) == 1:
- #insert the node
- tree = TreeNode()
- tree.info = info
- inserted = True
- else:
- cur_name = hrn_arr[0] + ''
- if tmp_tree.info.name == cur_name:
- for i in range(1, len(hrn_arr)):
- cur_name = cur_name + '.' + hrn_arr[i]
- child_found = False
- child = {}
- for j in range(len(tmp_tree.children)) :
- if tmp_tree.children[j].info.name == cur_name :
- child_found = True
- child = tmp_tree.children[j]
- break
- if child_found == False:
- if len(hrn_arr) - i == 1:
- #insert the remaining of hrn
- new_child = TreeNode()
- new_child.info = info
- tmp_tree.children.append(new_child)
- inserted = True
- break
- else:
- tmp_tree = child
- if inserted == False:
- print "The hrn '"+info.name+"' should be at leaf position to be inserted.\n"
- return inserted
-
- #remove the branch indicated by hrn from the tree
- #hrn: string
- def tree_remove(self, hrn):
- tree= self.my_tree
- removed = False
- hrn_arr = geni_to_arr(hrn)
- tmp_tree = tree
- if tmp_tree.info.name == hrn_arr[0] :
- cur_name = hrn_arr[0] + ''
- for i in range(1, len(hrn_arr)):
- cur_name = cur_name + '.' + hrn_arr[i]
- child_found = False
- child = {}
- for j in range(len(tmp_tree.children)) :
- if tmp_tree.children[j].info.name == cur_name :
- child_found = True
- child = tmp_tree.children[j]
- break
- if child_found == False:
- break
- else:
- if i == len(hrn_arr)-1:
- tmp_tree.children.remove(child)
- removed = True
- else:
- tmp_tree = child
- return removed
-
- #initialize the tree with the file data
- def tree_init(self):
- filename = self.filename
- type = self.type
- try:
- #check if dict file exists
- if not os.path.exists(filename+'_dict'):
- if not os.path.exists(filename):
- print 'Error: File not found.\n'
- raise NonExistingFile(filename)
- else:
- self.__file_to_treedict(filename)
- self.my_tree = self.__deserialize_tree(eval(open(filename+'_dict').read()))
- else:
- self.my_tree = self.__deserialize_tree(eval(open(filename+'_dict').read()))
- #create the tables and key folders if they do not exist already
- self.__sync_with_db_rec(type, self.my_tree)
- except:
- print 'Error in initialzing the tree.\n'
- os._exit(1)
-
- def save_tree(self):
- open(self.filename+'_dict', 'w').write(str(self.my_tree.serial()))
-
- def __sync_with_db_rec(self, type, treenode):
- self.__sync_with_db(type, treenode)
- for child in treenode.children:
- self.__sync_with_db_rec(type, child)
-
- #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
- #type: 'slice' or 'component' indicating the registry type
- #hierarchy:hrn so far
- #treenode: node to be synched
- def __sync_with_db(self, type, treenode):
- curdir = os.getcwd()
- key_req = False
- table_req = False
- if not treenode.info.node_data:
- treenode.info.node_data = {}
- #create key folder, private key and self signed cert
- hrn = treenode.info.name
- dirname = type+'/'+(hrn).replace('.','/')
- hrn_suffix = get_leaf(hrn)
- if os.path.exists(dirname):
- os.system('rm -rf '+dirname)
- os.makedirs(dirname)
- os.chdir(dirname)
- create_self_cert(hrn_suffix)
- k = KeyInfo()
- k.folder = dirname
- k.id_file = hrn_suffix+'.cert'
- k.id_key_file = hrn_suffix +'.pkey'
- #for the top authority create the acc and cred files
- if obtain_authority(hrn) == '':
- id_cert = crypto.load_certificate(crypto.FILETYPE_PEM, open(k.id_file).read())
- id_pkey = crypto.load_privatekey(crypto.FILETYPE_PEM, open(k.id_key_file).read())
- uu_id = str(uuid.uuid4().int)
- regtype = ''
- if type == 'slice':
- regtype = 'slc'
- else:
- regtype = 'comp'
- rights = '(0-0)(1-0)(2-0)(3-0)(4-0)(5-0)(6-0)(7-0)(8-0)(9-0)'
- rights = rights + '#0:reg:'+regtype+':'+hrn
- k.acc_file = 'acc_file'
- k.cred_file = 'cred_file'
- acc = create_acc(id_cert, id_pkey, id_cert.get_pubkey(), hrn, uu_id)
- cred = create_cred(id_cert, id_pkey, id_cert.get_pubkey(), 'Registry credentials', rights)
- open(k.acc_file, 'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, acc))
- open(k.cred_file, 'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, cred))
- treenode.info.node_data['key_info'] = k
- os.chdir(curdir)
- #create the table and set in the treenode data structure
- suffix = ''
- if type == 'slice':
- suffix = SR_SUFFIX
- else:
- suffix = CR_SUFFIX
- tablename = hrn.replace('.','$') + suffix
- cnx = get_plDB_conn()
- querystr = "CREATE TABLE "+tablename+" ( \
- hrn text, \
- type text, \
- uuid text, \
- userlist text, \
- rights text, \
- description text, \
- pubkey text, \
- wrapperURL text, \
- disabled text, \
- pointer integer);"
-
- cnx.query('DROP TABLE IF EXISTS '+tablename) #drop the table if it exists
- cnx.query(querystr)
- d = DbInfo()
- d.table_name = tablename
- get_plDB_info(d)
- treenode.info.node_data['db_info'] = d
- #if the authority resides in PL as site, then fill it with the PL data
- if treenode.children == []:
- populate_pl_data(hrn_suffix, tablename, type)
- treenode.info.login_base = hrn_suffix
- #insert the record into parent's table
- if obtain_authority(hrn) != '':
- rectype = ''
- regtype = ''
- if type == 'slice':
- rectype = 'SA'
- regtype = 'slc'
- else:
- rectype = 'MA'
- regtype = 'comp'
- uu_id = ''
- if treenode.children != []:
- uu_id = str(uuid.uuid4().int)
- 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)'
- rights = rights + '#0:reg:'+regtype+':'+obtain_authority(hrn)+'#1:reg:'+regtype+':'+hrn
- id_file = treenode.info.node_data['key_info'].folder+'/'+ treenode.info.node_data['key_info'].id_file
- pubkey = X509.load_cert(id_file).get_pubkey().as_pem(cipher=None)
- wrapper = 'local'
- pointer = -1
- if treenode.children == []: #get pointer if authority resides in PL as site
- pointer = cnx.query("SELECT site_id FROM sites WHERE login_base='"+hrn_suffix+"'").dictresult()[0]['site_id']
- disabled = 'f'
- record = {'hrn':get_leaf(hrn), 'type':rectype, 'uuid':uu_id, 'rights':rights, 'pubkey':pubkey, 'wrapperURL':wrapper, 'pointer':pointer, 'disabled':disabled}
- querystr = generate_querystr('INSERT', obtain_authority(hrn).replace('.','$')+suffix, record)
- cnx.query(querystr)
-
- #gets a tree in the form of a dictionary,
- # ex: {'info':{'name':'planetlab', 'node_data':{'key_info':{...}, 'db_info':{...}}}, 'children':[x1, x2, ..]}
- #returns the tree in the TreeNode class format
- def __deserialize_tree(self, treenode_dict):
- node = TreeNode()
- node.info = TreeNodeInfo()
- node.info.name = treenode_dict['info']['name']
- node.info.login_base = treenode_dict['info']['login_base']
- if treenode_dict['info']['node_data']:
- node.info.node_data = {}
- if treenode_dict['info']['node_data'].has_key('key_info'):
- node.info.node_data['key_info'] = KeyInfo()
- keyinf = treenode_dict['info']['node_data']['key_info']
- node.info.node_data['key_info'].folder = keyinf['folder']
- node.info.node_data['key_info'].id_file = keyinf['id_file']
- node.info.node_data['key_info'].id_key_file = keyinf['id_key_file']
- node.info.node_data['key_info'].acc_file = keyinf['acc_file']
- node.info.node_data['key_info'].cred_file = keyinf['cred_file']
- node.info.node_data['key_info'].last_update = keyinf['last_update']
- if treenode_dict['info']['node_data'].has_key('db_info'):
- node.info.node_data['db_info'] = DbInfo()
- dbinf = treenode_dict['info']['node_data']['db_info']
- node.info.node_data['db_info'].table_name = dbinf['table_name']
- node.info.node_data['db_info'].db_name = dbinf['db_name']
- node.info.node_data['db_info'].address = dbinf['address']
- node.info.node_data['db_info'].port = dbinf['port']
- node.info.node_data['db_info'].user = dbinf['user']
- node.info.node_data['db_info'].password = dbinf['password']
- for child in treenode_dict['children']:
- node.children.append(self.__deserialize_tree(child))
- return node
-
- #gets a file name for tree and constructs an output file which contains the tree in dictionary format
- #write to file: ex: {'info':{'name':'planetlab', 'node_data':{'key_info':{...}, 'db_info':{...}}}, 'children':[x1, x2, ..]}
- def __file_to_treedict(self, filename):
- lines = open(filename).readlines()
- hierarchy = ''
- (node, line) = self.__file_to_treedict_rec(lines, 0, hierarchy, 0)
- open(filename+'_dict', 'w').write(str(node))
-
- #helper function
- #return: (node, line)
- def __file_to_treedict_rec(self, lines, indent, hierarchy, line):
- node = {'info':{'name':'', 'login_base':'', 'node_data':None}, 'children':[]}
- #count #tabs
- j = 0
- while lines[line][j] == '\t':
- j = j+1
- if indent != j:
- print 'Error in file to dictionary conversion.\n'
- return None
- name = lines[line].split(' ')[0]
- name = name[j:len(name)]
- if hierarchy == '':
- node['info']['name'] = name
- else:
- node['info']['name'] = hierarchy + '.' + name
- node['info']['login_base'] = name
- #next indent count
- j = 0
- if line+1 != len(lines):
- while lines[line+1][j] == '\t':
- j = j+1
- if j > indent+1:
- print 'Error in file to dictionary conversion.\n'
- return None
- indent2 = j
- line = line+1
- while indent2 > indent:
- (child, line) = self.__file_to_treedict_rec(lines, indent2, node['info']['name'], line)
- node['children'].append(child)
- j = 0
- if line != len(lines):
- while lines[line][j] == '\t':
- j = j+1
- indent2 = j
- return (node, line)
-
-
- #determines the key info of a given hrn within the tree, performs calls back to 'server' to obtain updated certs
- #if the hrn does not exist in the tree hierarchy None is returned
- #server: the server instance is passed for calls to getCredential/getAccounting if necessary
- #type is credential or accounting; one of them at a time is determined by the function
- #returns an array containing the self-signed certificate, private key, and acc or cred chain in string
- def determine_keyinfo(self, hrn, server, type):
- tree = self
- reg_type = self.type
- info = tree.tree_lookup(hrn)
- if info == None:
- return None
- else:
- keyinfo = info.node_data['key_info']
- folder = keyinfo.folder
- id_file = folder+'/'+keyinfo.id_file
- id_key_file = folder+'/'+keyinfo.id_key_file
- #check the id file
- if not os.path.exists(folder) or not os.path.exists(id_file):
- print 'Id file for '+hrn+' does not exist.\n'
- return None
- else:
- #check acc or cred
- acc_str = None
- cred_str = None
- renew_res = renew_cert(type, folder, reg_type, hrn, server, tree, tree.auth_addr, server.sec)
- if renew_res == None:
- return None
- if type == 'accounting':
- keyinfo.acc_file = 'acc_file'
- acc_str = open(keyinfo.folder+'/'+keyinfo.acc_file).read()
- else:
- keyinfo.cred_file = 'cred_file'
- cred_str = open(keyinfo.folder+'/'+keyinfo.cred_file).read()
- id = crypto.load_certificate(crypto.FILETYPE_PEM, open(id_file).read())
- id_key = crypto.load_privatekey(crypto.FILETYPE_PEM, open(id_key_file).read())
- return [id, id_key, acc_str, cred_str]