diff options
author | pzread <netfirewall@gmail.com> | 2013-05-16 21:33:57 +0800 |
---|---|---|
committer | pzread <netfirewall@gmail.com> | 2013-05-16 21:33:57 +0800 |
commit | 77fd7140f8891079dd7b99f18e2d594c3b0a98ad (patch) | |
tree | 065eb8b18466bfc406d3586e89eb3d6c044fb68a /src/py | |
parent | 172b58b3f60c4b0277ad85fab728a5911bd573ac (diff) | |
download | taiwan-online-judge-77fd7140f8891079dd7b99f18e2d594c3b0a98ad.tar taiwan-online-judge-77fd7140f8891079dd7b99f18e2d594c3b0a98ad.tar.gz taiwan-online-judge-77fd7140f8891079dd7b99f18e2d594c3b0a98ad.tar.bz2 taiwan-online-judge-77fd7140f8891079dd7b99f18e2d594c3b0a98ad.tar.lz taiwan-online-judge-77fd7140f8891079dd7b99f18e2d594c3b0a98ad.tar.xz taiwan-online-judge-77fd7140f8891079dd7b99f18e2d594c3b0a98ad.tar.zst taiwan-online-judge-77fd7140f8891079dd7b99f18e2d594c3b0a98ad.zip |
Done base auth and iden verify
Diffstat (limited to 'src/py')
-rw-r--r-- | src/py/backend_server.py | 58 | ||||
-rw-r--r-- | src/py/center_server.py | 63 | ||||
-rw-r--r-- | src/py/imc/auth.py | 51 | ||||
-rwxr-xr-x | src/py/imc/proxy.py | 52 |
4 files changed, 152 insertions, 72 deletions
diff --git a/src/py/backend_server.py b/src/py/backend_server.py index 0334417..d64d084 100644 --- a/src/py/backend_server.py +++ b/src/py/backend_server.py @@ -15,6 +15,7 @@ import tornado.websocket import netio import imc.nonblock +from imc.auth import Auth from imc.proxy import Proxy,Connection,imc_call,imc_call_async,imc_register_call class BackendWorker(tornado.tcpserver.TCPServer): @@ -23,12 +24,11 @@ class BackendWorker(tornado.tcpserver.TCPServer): self._ioloop = tornado.ioloop.IOLoop.current() self.center_addr = center_addr - self._linkclass = 'backend' - self._linkid = None self.sock_addr = None self.ws_port = ws_port - self._iden = None + self._linkid = None + self._idendesc = None self._pendconn_linkidmap = {} self._client_linkidmap = {} @@ -78,14 +78,14 @@ class BackendWorker(tornado.tcpserver.TCPServer): conn.add_close_callback(lambda conn : self.del_client(conn.linkid)) Proxy.instance.add_conn(conn) - imc_call_async(self._iden,'/center/' + self.center_conn.linkid + '/','add_client',{'backend_linkid':self._linkid,'client_linkid':linkid}) + imc_call_async(self._idendesc,'/center/' + self.center_conn.linkid + '/','add_client',{'backend_linkid':self._linkid,'client_linkid':linkid}) return conn def del_client(self,linkid): del self._client_linkidmap[linkid] - imc_call_async(self._iden,'/center/' + self.center_conn.linkid + '/','del_client',linkid) + imc_call_async(self._idendesc,'/center/' + self.center_conn.linkid + '/','del_client',linkid) def _conn_center(self): def __retry(): @@ -98,28 +98,30 @@ class BackendWorker(tornado.tcpserver.TCPServer): def ___recv_info_cb(data): info = json.loads(data.decode('utf-8')) - self._linkid = info['linkid'] - self._iden = {'linkclass':self._linkid,'linkid':self._linkid} + Auth() + f = open('pubkey.pem','r') + Auth.instance.set_verifykey(f.read()) - self.center_conn = netio.SocketConnection(info['center_linkid'],stream) - Proxy(self._linkid,self._connect_linkid) + self._idendesc = info['idendesc'] + iden = Auth.instance.get_iden(self._idendesc) + self._linkid = iden['linkid'] + Proxy(self._linkid,Auth.instance,self._connect_linkid) + self.center_conn = netio.SocketConnection(info['center_linkid'],stream) self.center_conn.add_close_callback(lambda conn : __retry()) Proxy.instance.add_conn(self.center_conn) - print('/backend/' + self._linkid) - - imc_register_call('','test_dst',self._test_dst) - time.sleep(0.5) + time.sleep(1) - #x = int(self._linkid) - (int(self._linkid) - 2) % 4 + #x = int(self._iden['linkid']) - (int(self._iden['linkid']) - 2) % 4 #self._test_call(None,str(x)) - #self._test_call(None,str(x + 1)) + if int(self._linkid) % 2 == 0: + self._test_call(None,str(int(self._linkid) + 1)) sock_ip,sock_port = self.sock_addr netio.send_pack(stream,bytes(json.dumps({ - 'linkclass':self._linkclass, + 'linkclass':'backend', 'sock_ip':sock_ip, 'sock_port':sock_port, 'ws_ip':'210.70.137.215', @@ -167,7 +169,7 @@ class BackendWorker(tornado.tcpserver.TCPServer): callback(None) return - stat,ret = (yield imc_call(self._iden,'/center/' + self.center_conn.linkid + '/','lookup_linkid',linkid)) + stat,ret = (yield imc_call(self._idendesc,'/center/' + self.center_conn.linkid + '/','lookup_linkid',linkid)) if stat == False or ret == None: callback(None) @@ -191,9 +193,25 @@ class BackendWorker(tornado.tcpserver.TCPServer): @imc.nonblock.func def _test_call(self,iden,param): - #print(time.perf_counter()) - stat,ret = (yield imc_call(self._iden,'/backend/' + param + '/','test_dst','Hello')) - #print(time.perf_counter()) + print(time.perf_counter()) + stat,ret = (yield imc_call(self._idendesc,'/backend/' + param + '/','test_dst','Hello')) + print(time.perf_counter()) + + print(time.perf_counter()) + stat,ret = (yield imc_call(self._idendesc,'/backend/' + param + '/','test_dst','Hello')) + print(time.perf_counter()) + + print(time.perf_counter()) + stat,ret = (yield imc_call(self._idendesc,'/backend/' + self._linkid + '/','test_dst','Hello')) + print(time.perf_counter()) + + + print(time.perf_counter()) + for i in range(5000): + stat,ret = (yield imc_call(self._idendesc,'/backend/' + self._linkid + '/','test_dst','Hello')) + print(time.perf_counter()) + + if stat == True: print(stat,ret) diff --git a/src/py/center_server.py b/src/py/center_server.py index 322f681..b5f05f9 100644 --- a/src/py/center_server.py +++ b/src/py/center_server.py @@ -11,20 +11,19 @@ import tornado.web import netio import imc.nonblock +from imc.auth import Auth from imc.proxy import Proxy,Connection,imc_call,imc_call_async,imc_register_call class Worker: - def __init__(self,stream,linkclass,linkid,worker_info): - global center_serv - + def __init__(self,stream,linkid,idendesc,worker_info,center_linkid): self.stream = stream - self.linkclass = linkclass self.linkid = linkid + self.idendesc = idendesc self.sock_addr = (worker_info['sock_ip'],worker_info['sock_port']) netio.send_pack(self.stream,bytes(json.dumps({ - 'linkid':self.linkid, - 'center_linkid':center_serv.linkid + 'idendesc':self.idendesc, + 'center_linkid':center_linkid }),'utf-8')) conn = netio.SocketConnection(self.linkid,self.stream) @@ -35,10 +34,10 @@ class Worker: pass class BackendWorker(Worker): - def __init__(self,stream,linkid,worker_info): + def __init__(self,stream,linkid,idendesc,worker_info,center_linkid): global center_serv - super().__init__(stream,'backend',linkid,worker_info) + super().__init__(stream,linkid,idendesc,worker_info,center_linkid) self.ws_addr = (worker_info['ws_ip'],worker_info['ws_port']) center_serv.add_backend_worker(self) @@ -58,11 +57,15 @@ class CenterServer(tornado.tcpserver.TCPServer): self._backend_clientmap = {} self._backend_workerlist = [] - self.linkclass = 'center' - self.linkid = self._create_linkid() - Proxy(self.linkid) + Auth() + f = open('privkey.pem','r') + Auth.instance.set_signkey(f.read()) + f = open('pubkey.pem','r') + Auth.instance.set_verifykey(f.read()) - print('/center/' + self.linkid) + self._linkid = self._create_linkid() + self._idendesc = self._create_idendesc('center',self._linkid) + Proxy(self._linkid,Auth.instance) imc_register_call('','lookup_linkid',self._lookup_linkid) imc_register_call('','add_client',self._add_client) @@ -78,18 +81,23 @@ class CenterServer(tornado.tcpserver.TCPServer): linkclass = worker_info['linkclass'] if linkclass == 'backend': linkid = self._create_linkid() - BackendWorker(stream,linkid,worker_info) + idendesc = self._create_idendesc('backend',linkid) + BackendWorker(stream,linkid,idendesc,worker_info,self._linkid) netio.recv_pack(stream,_recv_worker_info) def add_backend_worker(self,backend): - self._worker_linkidmap[backend.linkid] = backend - self._backend_clientmap[backend.linkid] = {} + backend_linkid = backend.linkid + + self._worker_linkidmap[backend_linkid] = backend + self._backend_clientmap[backend_linkid] = {} self._backend_workerlist.append(backend) def del_backend_worker(self,backend): - self._worker_linkidmap.pop(backend.linkid,None) - del self._backend_clientmap[backend.linkid] + backend_linkid = backend.linkid + + del self._worker_linkidmap[backend_linkid] + del self._backend_clientmap[backend_linkid] self._backend_workerlist.remove(backend) def dispatch_client(self): @@ -98,10 +106,11 @@ class CenterServer(tornado.tcpserver.TCPServer): return None linkid = self._create_linkid() + idendesc = self._create_idendesc('client',linkid) backend = self._backend_workerlist[random.randrange(size)] ws_ip,ws_port = backend.ws_addr - return (linkid,backend.linkid,ws_ip,ws_port) + return (idendesc,backend.linkid,ws_ip,ws_port) def _create_linkid(self): linkid = uuid.uuid4() @@ -112,9 +121,12 @@ class CenterServer(tornado.tcpserver.TCPServer): self._linkid_usemap[linkid] = True linkid = str(len(self._linkid_usemap)) - + return linkid + def _create_idendesc(self,linkclass,linkid): + return Auth.instance.sign_iden({'linkclass':linkclass,'linkid':linkid}) + @imc.nonblock.func def _lookup_linkid(self,iden,param): linkid = param @@ -139,7 +151,7 @@ class CenterServer(tornado.tcpserver.TCPServer): print(client_linkid); - imc_call_async({'linkclass':'center','linkid':self.linkid},'/client/' + client_linkid + '/','test_call','Hello Client',lambda result:print(result)) + imc_call_async(self._idendesc,'/client/' + client_linkid + '/','test_call','Hello Client',lambda result:print(result)) @imc.nonblock.func def _del_client(self,iden,param): @@ -154,13 +166,6 @@ class CenterServer(tornado.tcpserver.TCPServer): @imc.nonblock.func def _test_dst(self,iden,param): - #stat,ret = (yield imc_call( - # {'linkclass':'center','linkid':self.linkid}, - # '/center/' + self.linkid + '/', - # 'test_dstb', - # 'Hello X' - #)) - linkidlist = [] clientmaps = self._backend_clientmap.values() for clientmap in clientmaps: @@ -185,9 +190,9 @@ class WebConnHandler(tornado.web.RequestHandler): if data == None: self.write('Eno_backend') else: - client_linkid,backend_linkid,ip,port = data + client_idendesc,backend_linkid,ip,port = data self.write(json.dumps({ - 'client_linkid':client_linkid, + 'client_idendesc':client_idendesc, 'backend_linkid':backend_linkid, 'ip':ip, 'port':port diff --git a/src/py/imc/auth.py b/src/py/imc/auth.py new file mode 100644 index 0000000..206812a --- /dev/null +++ b/src/py/imc/auth.py @@ -0,0 +1,51 @@ +import time +import json +import binascii + +from Crypto.PublicKey import RSA +from Crypto.Hash import SHA,SHA512 +from Crypto.Signature import PKCS1_v1_5 + +class Auth: + def __init__(self): + self._cache_hashmap = {} + + Auth.instance = self + + def set_signkey(self,key): + self._signer = PKCS1_v1_5.new(RSA.importKey(key)) + + def set_verifykey(self,key): + self._verifier = PKCS1_v1_5.new(RSA.importKey(key)) + + def sign_iden(self,iden): + data = json.dumps(iden) + sign = binascii.hexlify(self._sign(bytes(data,'utf-8'))).decode('utf-8') + + return json.dumps([data,sign]) + + def get_iden(self,idendesc): + pair = json.loads(idendesc) + data = pair[0] + sign = pair[1] + + if self._verify(bytes(data,'utf-8'),binascii.unhexlify(sign)): + return json.loads(data) + + else: + return None + + def _sign(self,data): + return self._signer.sign(SHA512.new(data)) + + def _verify(self,data,sig): + h = SHA512.new(data) + if h in self._cache_hashmap: + return True + + if self._verifier.verify(h,sig) == True: + self._cache_hashmap[h] = True + + return True + else: + return False diff --git a/src/py/imc/proxy.py b/src/py/imc/proxy.py index 6e7e845..2e7647a 100755 --- a/src/py/imc/proxy.py +++ b/src/py/imc/proxy.py @@ -5,6 +5,7 @@ import tornado.ioloop import tornado.stack_context from imc import nonblock +from imc import auth class Connection: def __init__(self,linkid): @@ -26,9 +27,10 @@ class Connection: callback(self) class Proxy: - def __init__(self,linkid,connect_linkid = None): + def __init__(self,linkid,auth,connect_linkid = None): self._ioloop = tornado.ioloop.IOLoop.instance() self._linkid = linkid + self._auth = auth self._connect_linkid = connect_linkid self._conn_linkidmap = {} @@ -107,11 +109,11 @@ class Proxy: def register_call(self,path,func_name,func): self._call_pathmap[''.join([path,func_name])] = func - def call(self,caller_genid,timeout,iden,dst,func_name,param): + def call(self,caller_genid,timeout,idendesc,dst,func_name,param): caller_retid = ''.join([self._linkid,'/',caller_genid]) - self._route_call(caller_retid,timeout,iden,dst,func_name,param) + self._route_call(caller_retid,timeout,idendesc,dst,func_name,param) - def _route_call(self,caller_retid,timeout,iden,dst,func_name,param): + def _route_call(self,caller_retid,timeout,idendesc,dst,func_name,param): def __add_wait_caller(conn_linkid,timeout,fail_callback): self._conn_retidmap[conn_linkid][caller_retid] = { 'caller_linkid':caller_linkid, @@ -122,13 +124,13 @@ class Proxy: def __local_send_remote(conn,caller_linkid,caller_retid): if conn != None: __add_wait_caller(conn.linkid,timeout,__fail_cb) - self._send_msg_call(conn,caller_retid,timeout,iden,dst,func_name,param) + self._send_msg_call(conn,caller_retid,timeout,idendesc,dst,func_name,param) else: __fail_cb(caller_linkid,caller_retid,'Enoexist') def __remote_send_remote(conn,caller_linkid,caller_retid): if conn != None: - self._send_msg_call(conn,caller_retid,timeout,iden,dst,func_name,param) + self._send_msg_call(conn,caller_retid,timeout,idendesc,dst,func_name,param) else: __fail_cb(caller_linkid,caller_retid,'Enoexist') @@ -139,6 +141,16 @@ class Proxy: def __fail_cb(caller_linkid,caller_retid,err): self._ret_call(caller_linkid,caller_retid,(False,err)) + def __direct_ret(result): + if caller_linkid == self._linkid: + self._ioloop.add_callback(self._ret_call,caller_linkid,caller_retid,result) + else: + self.request_conn(caller_linkid,__send_ret,caller_linkid,caller_retid,result) + + iden = self._auth.get_iden(idendesc) + if iden == None: + __direct_ret((False,'Eilliden')) + dst_part = dst.split('/',3) dst_linkid = dst_part[2] dst_path = dst_part[3] @@ -151,18 +163,12 @@ class Proxy: stat,data = self._call_pathmap[''.join([dst_path,func_name])](iden,param) except KeyError: - if caller_linkid == self._linkid: - self._ioloop.add_callback(self._ret_call,caller_linkid,caller_retid,(False,'Enoexist')) - else: - self.request_conn(caller_linkid,__send_ret,caller_linkid,caller_retid,(False,'Enoexist')) - + __direct_ret((False,'Enoexist')) + return if stat == True: - if caller_linkid == self._linkid: - self._ioloop.add_callback(self._ret_call,caller_linkid,caller_retid,(True,data)) - else: - self.request_conn(caller_linkid,__send_ret,caller_linkid,caller_retid,(True,data)) + __direct_ret((True,data)) else: self._retcall_retidmap[''.join([self._linkid,'/',data])] = { @@ -234,12 +240,12 @@ class Proxy: for retid in wait_del: del wait_map[retid] - def _send_msg_call(self,conn,caller_retid,timeout,iden,dst,func_name,param): + def _send_msg_call(self,conn,caller_retid,timeout,idendesc,dst,func_name,param): msg = { 'type':self.MSGTYPE_CALL, 'caller_retid':caller_retid, 'timeout':timeout, - 'iden':iden, + 'idendesc':idendesc, 'dst':dst, 'func_name':func_name, 'param':param @@ -249,12 +255,12 @@ class Proxy: def _recv_msg_call(self,conn,msg): caller_retid = msg['caller_retid'] timeout = msg['timeout'] - iden = msg['iden'] + idendesc = msg['idendesc'] dst = msg['dst'] func_name = msg['func_name'] param = msg['param'] - self._route_call(caller_retid,timeout,iden,dst,func_name,param) + self._route_call(caller_retid,timeout,idendesc,dst,func_name,param) def _send_msg_ret(self,conn,caller_linkid,caller_retid,result): stat,data = result @@ -285,13 +291,13 @@ class Proxy: self._ret_call(caller_linkid,caller_retid,result) @nonblock.call -def imc_call(iden,dst,func_name,param,_genid): - Proxy.instance.call(_genid,10000,iden,dst,func_name,param) +def imc_call(idendesc,dst,func_name,param,_genid): + Proxy.instance.call(_genid,10000,idendesc,dst,func_name,param) -def imc_call_async(iden,dst,func_name,param,callback = None): +def imc_call_async(idendesc,dst,func_name,param,callback = None): @nonblock.func def func(): - result = (yield imc_call(iden,dst,func_name,param)) + result = (yield imc_call(idendesc,dst,func_name,param)) if callback != None: callback(result) |