4 from M2Crypto import SSL
9 # XXX SMBAKER: changed MAX_RESULT from 3000B to 32KB
12 def verify_callback(preverify_ok, ctx):
16 def __init__(self, hrn, type, id_file, id_key_file, acc_file, cred_file):
20 #check if the certificate and the private key exists, terminate if not
21 if not os.path.exists(id_file):
22 report.error("Certificate file " + id_file + " does not exist")
23 raise NonexistingFile(id_file)
25 if not os.path.exists(id_key_file):
26 report.error("Key file: " + id_key_file + " does not exist")
27 raise NonexistingFile(key_file)
29 report.trace("cert: " + id_file + ", key_file: " + id_key_file)
31 #check the acc and cred files
32 if not os.path.exists(acc_file) or not is_valid_chain(acc_file):
33 report.trace("replacing acc_file: " + acc_file + " with anonymous acc")
34 open(acc_file, 'w').write('ANONYM')
36 if not os.path.exists(cred_file) or not is_valid_chain(cred_file):
37 report.trace("replacing cred_file: " + cred_file + " with no_cred")
38 open(cred_file, 'w').write('NO_CRED')
40 #initialize the security system
41 self.sec = Sec('client', id_file, id_key_file, acc_file, cred_file)
43 self.ctx = SSL.Context()
44 self.ctx.load_cert(self.sec.id_file, self.sec.id_key_file)
45 self.ctx.set_verify(SSL.verify_peer | SSL.verify_fail_if_no_peer_cert, depth=9, callback=verify_callback)
47 def connect(self, host, port):
48 #if the acc and cred needs renewal then do call to authority
49 if self.type == 'user' or self.type == 'slice' or self.type == 'SA':
57 report.trace("renewing accounting")
58 renew_res1 = renew_cert('accounting', '.', reg_type, self.hrn, None, None, (auth_host, auth_port), self.sec)
59 if renew_res1 == None:
60 report.error("There is no certificate in the directory .")
61 raise NoCertInDirectory(".")
63 report.trace("renewing credential")
64 renew_res2 = renew_cert('credential', '.', reg_type, self.hrn, None, None, (auth_host, auth_port), self.sec)
65 # XXX check result of renew_res2 ?
68 server = SSL.Connection(self.ctx)
70 report.trace("connecting")
71 server.connect((host,port))
73 report.trace("authenticating")
74 peer = self.sec.auth_protocol(server)
76 report.trace("Authentication successful")
79 report.error("Authentication failed")
80 raise AuthenticationFailed()
82 def toFileFormat(res_str):
85 res_dict = eval(res_str)
86 if res_dict['geni'].has_key('pubkey'): # in public key, replace '\n' with ' '
87 pubkey = res_dict['geni']['pubkey']
88 pubkey = pubkey.split('-----BEGIN RSA PRIVATE KEY-----')[1].split('-----END RSA PRIVATE KEY-----')[0].replace('\n',' ')
89 pubkey = '-----BEGIN RSA PRIVATE KEY-----'+pubkey+'-----END RSA PRIVATE KEY-----'
90 res_dict['geni']['pubkey'] = pubkey
92 if res_dict.has_key('message'):
93 out_str = res_dict['message']+'\n'
95 out_str = "{'geni':{\n"
96 for key in res_dict['geni']:
98 if res_dict['geni'][key] == None:
100 elif isinstance(res_dict['geni'][key], str):
101 val = res_dict['geni'][key]
103 val = str(res_dict['geni'][key])
104 out_str = out_str+"'"+key+"':"+val+"\n"
105 out_str = out_str + "}\n"
106 out_str = out_str + "'pl':{\n"
107 for key in res_dict['pl']:
109 if res_dict['pl'][key] == None:
111 if isinstance(res_dict['pl'][key], str):
112 val = res_dict['pl'][key]
114 val = str(res_dict['pl'][key])
115 out_str = out_str+"'"+key+"':"+val+"\n"
116 out_str = out_str + "}}"
121 def evaluate(call_data):
122 call_data = eval(call_data)
123 #adjust the key format to obey server's storage format
124 if call_data['g_params'].has_key('pubkey'): #replace the ' ' with '\n'
125 pubkey = call_data['g_params']['pubkey']
126 pubkey = pubkey.split('-----BEGIN RSA PRIVATE KEY-----')[1].split('-----END RSA PRIVATE KEY-----')[0].replace(' ','\n')
127 pubkey = '-----BEGIN RSA PRIVATE KEY-----'+pubkey+'-----END RSA PRIVATE KEY-----'
128 call_data['g_params']['pubkey'] = pubkey
134 fp = open('tmp_input.txt', 'r')
135 user_data = fp.readline()
136 call_data = fp.read()
140 HRN = user_data.split(' ')[0]
141 TYPE = user_data.split(' ')[1].split('\n')[0]
143 ID_FILE = name+'.cert'
144 ID_KEY_FILE = name+'.pkey'
145 ACC_FILE = 'acc_file'
146 CRED_FILE = 'cred_file'
147 my_client = GENIClient(HRN, TYPE, ID_FILE, ID_KEY_FILE, ACC_FILE, CRED_FILE)
148 print 'Constructed client.\n'
151 message = evaluate(call_data)
152 server = my_client.connect(SERVER_HOST, SERVER_PORT)
154 server.write(str(message))
155 result = toFileFormat(server.read(MAX_RESULT))
157 print 'Performed the call.\n'
159 result = "Error in client data structures.\n"
161 #write result to output file
162 open('tmp_output.txt','w').write(result)
163 print 'Written to file.\n'
164 except "XXX": # XXX smbaker
165 #write result to output file
166 open('tmp_output.txt','w').write("An error occurred in client stub.\n")
167 print 'Exception occurred.\n'
169 #if __name__=="__main__":
170 # print 'Client started.\n'
171 # os.system("echo foo > foo.txt")
172 # os.system("mv tmp_input.3 tmp_input.4")
173 # os.system("mv tmp_input.2 tmp_input.3")
174 # os.system("mv tmp_input.1 tmp_input.2")
175 # os.system("cp tmp_input.txt tmp_input.1")