--- /dev/null
+#!/usr/bin/python
+
+import os, sys
+from M2Crypto import SSL
+from sec import *
+from cliexcep import *
+import report
+
+# XXX SMBAKER: changed MAX_RESULT from 3000B to 32KB
+MAX_RESULT = 32768
+
+def verify_callback(preverify_ok, ctx):
+ return 1
+
+class GENIClient():
+ def __init__(self, hrn, type, id_file, id_key_file, acc_file, cred_file):
+ self.hrn = hrn
+ self.type = type
+
+ #check if the certificate and the private key exists, terminate if not
+ if not os.path.exists(id_file):
+ report.error("Certificate file " + id_file + " does not exist")
+ raise NonexistingFile(id_file)
+
+ if not os.path.exists(id_key_file):
+ report.error("Key file: " + id_key_file + " does not exist")
+ raise NonexistingFile(key_file)
+
+ report.trace("cert: " + id_file + ", key_file: " + id_key_file)
+
+ #check the acc and cred files
+ if not os.path.exists(acc_file) or not is_valid_chain(acc_file):
+ report.trace("replacing acc_file: " + acc_file + " with anonymous acc")
+ open(acc_file, 'w').write('ANONYM')
+
+ if not os.path.exists(cred_file) or not is_valid_chain(cred_file):
+ report.trace("replacing cred_file: " + cred_file + " with no_cred")
+ open(cred_file, 'w').write('NO_CRED')
+
+ #initialize the security system
+ self.sec = Sec('client', id_file, id_key_file, acc_file, cred_file)
+ #ssl parameters
+ self.ctx = SSL.Context()
+ self.ctx.load_cert(self.sec.id_file, self.sec.id_key_file)
+ self.ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, depth=9, callback=verify_callback)
+
+ def connect(self, host, port):
+ #if the acc and cred needs renewal then do call to authority
+ if self.type == 'user' or self.type == 'slice' or self.type == 'SA':
+ reg_type = 'slice'
+ else:
+ reg_type ='component'
+
+ auth_host = host
+ auth_port = port
+
+ report.trace("renewing accounting")
+ renew_res1 = renew_cert('accounting', '.', reg_type, self.hrn, None, None, (auth_host, auth_port), self.sec)
+ if renew_res1 == None:
+ report.error("There is no certificate in the directory .")
+ raise NoCertInDirectory(".")
+
+ report.trace("renewing credential")
+ renew_res2 = renew_cert('credential', '.', reg_type, self.hrn, None, None, (auth_host, auth_port), self.sec)
+ # XXX check result of renew_res2 ?
+
+ #connect to server
+ server = SSL.Connection(self.ctx)
+
+ report.trace("connecting")
+ server.connect((host,port))
+
+ report.trace("authenticating")
+ peer = self.sec.auth_protocol(server)
+ if peer:
+ report.trace("Authentication successful")
+ return server
+ else:
+ report.error("Authentication failed")
+ raise AuthenticationFailed()
+
+def toFileFormat(res_str):
+ out_str = ""
+ try:
+ res_dict = eval(res_str)
+ if res_dict['geni'].has_key('pubkey'): # in public key, replace '\n' with ' '
+ pubkey = res_dict['geni']['pubkey']
+ pubkey = pubkey.split('-----BEGIN RSA PRIVATE KEY-----')[1].split('-----END RSA PRIVATE KEY-----')[0].replace('\n',' ')
+ pubkey = '-----BEGIN RSA PRIVATE KEY-----'+pubkey+'-----END RSA PRIVATE KEY-----'
+ res_dict['geni']['pubkey'] = pubkey
+
+ if res_dict.has_key('message'):
+ out_str = res_dict['message']+'\n'
+ else:
+ out_str = "{'geni':{\n"
+ for key in res_dict['geni']:
+ val = ''
+ if res_dict['geni'][key] == None:
+ val = ''
+ elif isinstance(res_dict['geni'][key], str):
+ val = res_dict['geni'][key]
+ else:
+ val = str(res_dict['geni'][key])
+ out_str = out_str+"'"+key+"':"+val+"\n"
+ out_str = out_str + "}\n"
+ out_str = out_str + "'pl':{\n"
+ for key in res_dict['pl']:
+ val = ''
+ if res_dict['pl'][key] == None:
+ val = ''
+ if isinstance(res_dict['pl'][key], str):
+ val = res_dict['pl'][key]
+ else:
+ val = str(res_dict['pl'][key])
+ out_str = out_str+"'"+key+"':"+val+"\n"
+ out_str = out_str + "}}"
+ except:
+ out_str = res_str
+ return out_str
+
+def evaluate(call_data):
+ call_data = eval(call_data)
+ #adjust the key format to obey server's storage format
+ if call_data['g_params'].has_key('pubkey'): #replace the ' ' with '\n'
+ pubkey = call_data['g_params']['pubkey']
+ pubkey = pubkey.split('-----BEGIN RSA PRIVATE KEY-----')[1].split('-----END RSA PRIVATE KEY-----')[0].replace(' ','\n')
+ pubkey = '-----BEGIN RSA PRIVATE KEY-----'+pubkey+'-----END RSA PRIVATE KEY-----'
+ call_data['g_params']['pubkey'] = pubkey
+ return call_data
+
+def oldmain():
+ try:
+ #read the input file
+ fp = open('tmp_input.txt', 'r')
+ user_data = fp.readline()
+ call_data = fp.read()
+ print 'Read file.\n'
+
+ #client related info
+ HRN = user_data.split(' ')[0]
+ TYPE = user_data.split(' ')[1].split('\n')[0]
+ name = get_leaf(HRN)
+ ID_FILE = name+'.cert'
+ ID_KEY_FILE = name+'.pkey'
+ ACC_FILE = 'acc_file'
+ CRED_FILE = 'cred_file'
+ my_client = GENIClient(HRN, TYPE, ID_FILE, ID_KEY_FILE, ACC_FILE, CRED_FILE)
+ print 'Constructed client.\n'
+
+ #operation call
+ message = evaluate(call_data)
+ server = my_client.connect(SERVER_HOST, SERVER_PORT)
+ if server:
+ server.write(str(message))
+ result = toFileFormat(server.read(MAX_RESULT))
+ server.close()
+ print 'Performed the call.\n'
+ else:
+ result = "Error in client data structures.\n"
+
+ #write result to output file
+ open('tmp_output.txt','w').write(result)
+ print 'Written to file.\n'
+ except "XXX": # XXX smbaker
+ #write result to output file
+ open('tmp_output.txt','w').write("An error occurred in client stub.\n")
+ print 'Exception occurred.\n'
+
+#if __name__=="__main__":
+# print 'Client started.\n'
+# os.system("echo foo > foo.txt")
+# os.system("mv tmp_input.3 tmp_input.4")
+# os.system("mv tmp_input.2 tmp_input.3")
+# os.system("mv tmp_input.1 tmp_input.2")
+# os.system("cp tmp_input.txt tmp_input.1")
+# main()
--- /dev/null
+# command line interface
+
+import getopt
+import sys
+from clientstub import *
+
+long_opts = ["username=", "usertype=", "help", "outfile=", "credfile="]
+
+# default command line options
+username = "planetlab.scott.pl.smbaker"
+usertype = "user"
+opname = "lookup"
+type = None
+hrn = None
+cred_name = None
+id_file = None
+key_file = None
+acc_file = None
+cred_file = None
+leaf_name = None
+server_host = "127.0.0.1"
+server_port = 8002
+out_file = None
+
+def showhelp():
+ print "syntax: cli <options> command <args>"
+ print "options:"
+ print " --username ... hrn of user performing op"
+ print " --usertype ... kind of user performing op (user, slice, ...)"
+ print " --outfile ... write reply to file"
+ print " --credfile ... credential to pass"
+ print "commands:"
+ print " lookup <type> <hrn>"
+ print " dumpCredential"
+ print " getCredential <cred_name>"
+ print " start <hrn>"
+
+def process_options():
+ global username, usertype, opname
+ global type, hrn, cred_name
+ global leaf_name
+ global id_file, cred_file
+ global acc_file, key_file, out_file
+
+ (options, args) = getopt.getopt(sys.argv[1:], '', long_opts)
+ for opt in options:
+ name = opt[0]
+ val = opt[1]
+
+ if name == "--username":
+ username = val
+ elif name == "--usertype":
+ usertype = val
+ elif name == "--help":
+ showhelp()
+ sys.exit(0)
+ elif name == "--outfile":
+ out_file = val
+ elif name == "--credfile":
+ cred_file = val
+
+ if not args:
+ report.error("no operation specified")
+ sys.exit(-1)
+
+ opname = args[0]
+
+ if opname == "lookup":
+ if len(args) < 3:
+ report.error("syntax: lookup <type> <hrn>")
+ sys.exit(-1)
+ type = args[1]
+ hrn = args[2]
+
+ elif opname == "getCredential":
+ if len(args) < 1:
+ report.error("syntax: getcredential <cred_name>")
+ sys.exit(-1)
+ cred_name = args[1]
+
+ elif opname == "start":
+ if len(args) < 1:
+ report.error("syntax: start <hrn>")
+ sys.exit(-1)
+ hrn = args[1]
+
+ if not leaf_name:
+ leaf_name = get_leaf(username)
+
+ if id_file == None:
+ id_file = leaf_name + ".cert"
+
+ if key_file == None:
+ key_file = leaf_name + ".pkey"
+
+ if acc_file == None:
+ acc_file = "acc_file"
+
+ if cred_file == None:
+ cred_file = "cred_file"
+
+def show_options():
+ print " username:", username
+ print " leaf:", leaf_name
+ print " usertype:", usertype
+ print " id_file:", id_file
+ print " key_file:", key_file
+ print " acc_file:", acc_file
+ print "cred_file:", cred_file
+ print "operation:", opname
+ print " type:", type
+ print " hrn:", hrn
+ print "cred_name:", cred_name
+ print " out_file:", out_file
+
+def get_authority(x):
+ parts = x.split(".")
+ return ".".join(parts[:3])
+
+def compose_message():
+ g_params = {}
+ p_params = {}
+ dict = {"opname": opname}
+
+ if opname == "lookup":
+ g_params["hrn"] = hrn
+ g_params["type"] = type
+
+ elif opname == "getCredential":
+ g_params["cred_name"] = cred_name
+
+ parts = cred_name.split(":")
+ if len(parts) < 2:
+ report.error("bad format for getCredential (slice:hrn.of.slice, ...)")
+
+ # XXX smbaker: this looks redundant
+ if parts[0] == "slice":
+ g_params["hrn"] = get_authority(parts[1])
+ g_params["type"] = "slice"
+
+ elif opname == "start":
+ g_params["hrn"] = hrn
+ g_params["type"] = "slice"
+
+ dict["g_params"] = g_params
+ dict["p_params"] = p_params
+
+ return dict
+
+def do_remote_op():
+ message = compose_message()
+
+ client = GENIClient(username, usertype, id_file, key_file, acc_file, cred_file)
+
+ server = client.connect(server_host, server_port)
+ if not server:
+ report.error("failed to connect to server")
+ sys.exit(-1)
+
+ report.trace("message:" + str(message))
+
+ server.write(str(message))
+
+ reply = server.read(MAX_RESULT)
+ if not reply:
+ report.error("No reply")
+ sys.exit(-1)
+
+ if out_file:
+ open(out_file, "w").write(reply)
+ else:
+ print "////// RESULT: //////"
+ print reply
+
+def dumpCredential():
+ cred_str = open(cred_file).read()
+ c_pem = X509.load_cert_string(cred_str)
+ subjectAltName = c_pem.get_ext("subjectAltName").get_value()
+ info_cert = get_cred_info(subjectAltName)
+
+ print "subject:", c_pem.get_subject().CN
+ print "issuer:", c_pem.get_issuer().CN
+ print "cred_str:"
+ print " ", subjectAltName
+ print "rights:"
+ op_set = info_cert['operation_set']
+ for item in op_set.keys():
+ rights = op_set[item]
+ print " ", item, ", ".join(rights)
+
+ print "interfaces:"
+ interfaces = info_cert['on_interfaces']
+ for item in interfaces:
+ print " ", item['lbl'], item['type'], item['name']
+
+def main():
+ process_options()
+ show_options()
+
+ if opname == "dumpCredential":
+ dumpCredential()
+ sys.exit(0)
+
+ elif opname == "help":
+ showhelp()
+ sys.exit(0)
+
+ elif (opname == "lookup") or \
+ (opname == "getCredential") or \
+ (opname == "start"):
+ do_remote_op()
+
+ else:
+ report.error("unknown operation: " + opname)
+
+if __name__=="__main__":
+ main()
+