-
Notifications
You must be signed in to change notification settings - Fork 0
/
demo.py
136 lines (122 loc) · 3.58 KB
/
demo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#!usr/bin/evn python
#! -*- coding:utf8 -*-
import socket
import threading
import struct
import select
from datetime import datetime
import base64
Server_addr = "0.0.0.0"
Server_port = 1080
Server_listen = 5
Auth = False
def make_server():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# server.setblocking(False)
server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
server.bind((Server_addr, Server_port))
server.listen(5)
return server
def base64Encrypt(content):
return base64.encodestring(content)
def base64Decrypt(content):
return base64.decodestring(content)
def recv_argue(conn, size):
remain = size
datas = []
while remain > 0:
data = conn.recv(remain)
if len(data) == 0:
raise Exception("Connection end.")
remain -= len(data)
datas.append(data)
datas = "".join(datas)
if len(datas) != size:
raise Exception("Protocol error")
return datas
def authenticate(conn, auth):
req = recv_argue(conn, 3)
if auth:
#nedd auth
conn.send("\x05\x02")
checkUserPassword(conn)
else:
#don't need auth
conn.send("\x05\x00")
return conn
def checkUserPassword(conn):
pass
def handleRemote(conn):
req = recv_argue(conn, 5)
if len(req) != 5:
raise Exception("1.request error")
if len(req) == 0:
raise Exception("Connection end.")
if ord(req[3]) == 1:
addr_ip = recv_argue(conn, 4)
addr = socket.inet_ntoa(addr_ip)
elif ord(req[3]) == 3:
addr_len = ord(req[4])
addr = recv_argue(conn, int(addr_len))
elif ord(req[3]) == 4:
addr_ip = recv_argue(conn, 16)
addr = socket.inet_ntop(socket.AF_INET6, addr_ip)
else:
raise Exception("addr type not support!")
port = struct.unpack(">H", recv_argue(conn,2))[0]
print datetime.now(), addr, port
remote = socket.create_connection((addr, port))
return remote
def handleRequest(conn, remote):
if remote:
#success
reply = "\x05\x00\x00\x01"
else:
#faile
reply = "\x05\x01\x00\x01"
reply += socket.inet_aton(Server_addr) + struct.pack(">H", Server_port)
conn.send(reply)
return conn
def send_all(sock, data):
bytes_send = 0
while True:
res = sock.send(data[bytes_send:])
if res < 0:
return res
bytes_send += res
if bytes_send == len(data):
return bytes_send
def sofineConnRemote(conn, remote):
try:
sockset = [conn, remote]
while True:
r, w, e = select.select(sockset, [], [])
if conn in r:
data = conn.recv(4096)
if len(data) <= 0:
break
res = send_all(remote, data)
if res < len(data):
raise Exception("faile to send all data to remote")
if remote in r:
data = remote.recv(4096)
if len(data) <= 0:
break
res = send_all(conn, data)
if res < len(data):
raise Exception("failed to send all data to conn")
finally:
conn.close()
remote.close()
def sockets5Server(conn, tth):
conn = authenticate(conn, Auth)
remote = handleRemote(conn)
conn = handleRequest(conn, remote)
sofineConnRemote(conn, remote)
if __name__ == '__main__':
server = make_server()
tth = 0
while True:
conn, addr = server.accept()
tth += 1
threading.Thread(target=sockets5Server, args=(conn, tth)).start()