This repository has been archived by the owner on Jun 14, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
/
tunnel.py
106 lines (94 loc) · 3.6 KB
/
tunnel.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
'''
FBoT, Foo or Bar over TLS.
Copyright (C) 2017 yvbbrjdr
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''
import socket
import threading
import config
import ssl
from log import log
class Tunnel(object):
hashLength = 32
def __init__(self, clientSocket):
log('connection established', clientSocket)
self.config = config.config['out']
self.clientSocket = clientSocket
def start(self):
self.clientOpen = True
self.serverOpen = False
self.firstPacketSent = False
threading.Thread(target = self.clientSocketThread).start()
def clientSocketThread(self):
while True:
data = self.clientSocket.recv(4096)
if data:
self.clientRecv(data)
else:
self.clientOpen = False
self.clientSocket.close()
if self.serverOpen:
self.serverSocket.shutdown(socket.SHUT_RDWR)
break
def serverSocketThread(self):
while True:
data = self.serverSocket.recv(4096)
if data:
self.clientSocket.send(data)
else:
self.serverOpen = False
self.serverSocket.close()
if self.clientOpen:
self.clientSocket.shutdown(socket.SHUT_RDWR)
break
def clientRecv(self, data):
if self.firstPacketSent:
self.serverSocket.send(data)
else:
self.firstPacketSent = True
if len(data) >= Tunnel.hashLength:
segment = data[:Tunnel.hashLength]
bar = None
for out in self.config:
if out['inpass'] == segment:
bar = out
break
if bar:
self.connectToServer(bar, data[Tunnel.hashLength:])
return
foo = None
for out in self.config:
if out['inpass'] == b'':
foo = out
break
if foo:
self.connectToServer(foo, data)
else:
log('no out found', self.clientSocket)
self.clientSocket.shutdown(socket.SHUT_RDWR)
def connectToServer(self, out, data):
self.serverSocket = socket.socket()
if out['type'] == 'tls':
context = ssl.create_default_context()
if out.get('ca'):
context.load_verify_locations(out['ca'])
self.serverSocket = context.wrap_socket(self.serverSocket, server_hostname = out['addr'])
try:
self.serverSocket.connect((out['addr'], out['port']))
except:
log('%s:%d connect failed' % (out['addr'], out['port']))
self.clientSocket.shutdown(socket.SHUT_RDWR)
return
log('connect to %s:%d' % (out['addr'], out['port']), self.clientSocket)
self.serverOpen = True
self.serverSocket.send(out['outpass'] + data)
threading.Thread(target = self.serverSocketThread).start()