def worker(self, c_conn, c_addr): self.frmwk.print_status("Accept new connect from " + str(c_addr)) ################### CONNET TUNNEL ##################### ### choin and connect to tunnel c_tunnel = self.choin_tunnel() # chon 1 tunnel t_conn = HTTP(c_tunnel[0], timeout=self.connect_timout) ### check tunnel is open if not t_conn: self.frmwk.print_error('Can\'t connect to tunnel') return None ### encrypt/decrypt init # tunnel_ks = self.vc_generatekeyhash(c_tunnel[2]) # tunnel_pe = self.vc_init(c_tunnel[2],tunnel_ks) # tunnel_pd = dict((tunnel_pe[i],i) for i in range(0,len(tunnel_pe))) if self.encrypt: crypt = crypton(c_tunnel[2]) else: crypt = None ################### START READ DATA CLIENT ##################### ### get status and header from sockert c_status, c_headers, c_content_len = self.socket_receiver(c_conn) ### set url, host, port, method s_https = 0 host = c_status[1] if host.startswith(b'http'): parser = parse.urlparse(host) s_host = parser.hostname s_port = parser.port s_path = b'/' + host.split(b'/', 3)[3] if not s_port: if parser.scheme == 'https': s_port = 443 else: s_port = 80 if parser.scheme == 'https': s_https = 1 else: self.frmwk.print_error("Unknown client request connect !") return None ### set status c_send_header = [b' '.join([c_status[0], s_path, c_status[2]])] ### set header for send c_headers.update({b'Connection': b'close'}) # fix host delay for k, v in c_headers.items(): if k.startswith(b'Proxy'): continue c_send_header.append(k + b': ' + v) ## add headers to send all data c_send_header = b"\r\n".join(c_send_header) + b"\r\n\r\n" ### set init param of tunnel c_send_init = self.send_init(s_host, s_port, self.r_buffer, self.s_buffer, s_https, c_tunnel, crypt) ### init and send tunnel parameter t_conn.init( c_tunnel[0], 'POST', { 'Content-Length': len(c_send_init) + len(c_send_header) + c_content_len }) t_conn.send(c_send_init) del c_send_init # clear memory ### get content from client and send to server with r_buffer if c_content_len > 0: c_sent = 0 ####### send header with content for full r_buffer encrypt if self.encrypt: mod_len = len(c_send_header) % len(c_tunnel[2]) data = c_conn.recv(mod_len) data = c_send_header + data data_len = len(data) for i in range(0, data_len, self.r_buffer): t_conn.send( crypt.vc_encrypt( data[i:min(i + self.r_buffer, data_len - i)])) c_sent = mod_len else: t_conn.send(c_send_header) ###### send content if c_sent < c_content_len: while True: data = c_conn.recv( min(self.r_buffer, c_content_len - c_sent)) if self.encrypt: t_conn.send(crypt.vc_encrypt(data)) else: t_conn.send(data) c_sent += len(data) if not data or c_sent == content_lent: break else: if self.encrypt: t_conn.send(crypt.vc_encrypt(c_send_header)) else: t_conn.send(c_send_header) del c_send_header # clear memory ############## END SEND ################ ############# START RECV ############### try: for res_chunk in t_conn.recv(self.s_buffer): if self.encrypt: c_conn.send(crypt.vc_decrypt(res_chunk)) else: c_conn.send(res_chunk) except Exception as e: self.frmwk.print_error(str(e)) finally: t_conn.request.close() c_conn.close() self.frmwk.print_status("Closed connect from " + str(c_addr))
def worker(self, c_conn, c_addr): self.frmwk.print_status("Accept new connect from " + str(c_addr)) ################### CONNET TUNNEL ##################### ### choin and connect to tunnel c_tunnel = self.choin_tunnel() # chon 1 tunnel t_conn = HTTP(c_tunnel[0], timeout=self.connect_timout) ### check tunnel is open if not t_conn: self.frmwk.print_error("Can't connect to tunnel") return None ### encrypt/decrypt init # tunnel_ks = self.vc_generatekeyhash(c_tunnel[2]) # tunnel_pe = self.vc_init(c_tunnel[2],tunnel_ks) # tunnel_pd = dict((tunnel_pe[i],i) for i in range(0,len(tunnel_pe))) if self.encrypt: crypt = crypton(c_tunnel[2]) else: crypt = None ################### START READ DATA CLIENT ##################### ### get status and header from sockert c_status, c_headers, c_content_len = self.socket_receiver(c_conn) ### set url, host, port, method s_https = 0 host = c_status[1] if host.startswith(b"http"): parser = parse.urlparse(host) s_host = parser.hostname s_port = parser.port s_path = b"/" + host.split(b"/", 3)[3] if not s_port: if parser.scheme == "https": s_port = 443 else: s_port = 80 if parser.scheme == "https": s_https = 1 else: self.frmwk.print_error("Unknown client request connect !") return None ### set status c_send_header = [b" ".join([c_status[0], s_path, c_status[2]])] ### set header for send c_headers.update({b"Connection": b"close"}) # fix host delay for k, v in c_headers.items(): if k.startswith(b"Proxy"): continue c_send_header.append(k + b": " + v) ## add headers to send all data c_send_header = b"\r\n".join(c_send_header) + b"\r\n\r\n" ### set init param of tunnel c_send_init = self.send_init(s_host, s_port, self.r_buffer, self.s_buffer, s_https, c_tunnel, crypt) ### init and send tunnel parameter t_conn.init(c_tunnel[0], "POST", {"Content-Length": len(c_send_init) + len(c_send_header) + c_content_len}) t_conn.send(c_send_init) del c_send_init # clear memory ### get content from client and send to server with r_buffer if c_content_len > 0: c_sent = 0 ####### send header with content for full r_buffer encrypt if self.encrypt: mod_len = len(c_send_header) % len(c_tunnel[2]) data = c_conn.recv(mod_len) data = c_send_header + data data_len = len(data) for i in range(0, data_len, self.r_buffer): t_conn.send(crypt.vc_encrypt(data[i : min(i + self.r_buffer, data_len - i)])) c_sent = mod_len else: t_conn.send(c_send_header) ###### send content if c_sent < c_content_len: while True: data = c_conn.recv(min(self.r_buffer, c_content_len - c_sent)) if self.encrypt: t_conn.send(crypt.vc_encrypt(data)) else: t_conn.send(data) c_sent += len(data) if not data or c_sent == content_lent: break else: if self.encrypt: t_conn.send(crypt.vc_encrypt(c_send_header)) else: t_conn.send(c_send_header) del c_send_header # clear memory ############## END SEND ################ ############# START RECV ############### try: for res_chunk in t_conn.recv(self.s_buffer): if self.encrypt: c_conn.send(crypt.vc_decrypt(res_chunk)) else: c_conn.send(res_chunk) except Exception as e: self.frmwk.print_error(str(e)) finally: t_conn.request.close() c_conn.close() self.frmwk.print_status("Closed connect from " + str(c_addr))