mirror of https://github.com/sloumdrone/burrow
107 lines
3.0 KiB
Python
107 lines
3.0 KiB
Python
import socket
|
|
import sys
|
|
import re
|
|
|
|
class Tunnel:
|
|
def __init__(self):
|
|
self.raw_request = None
|
|
self.text_output = None
|
|
self.types = {
|
|
'0': '(TXT)',
|
|
'1': '(MENU)',
|
|
'2': None,
|
|
'3': 'Error code',
|
|
'4': None,
|
|
'5': None,
|
|
'6': None,
|
|
'7': '(INTER)',
|
|
'8': '(TLNET)',
|
|
'9': '(BIN)',
|
|
'+': None,
|
|
'g': '(GIF)',
|
|
'I': '(IMG)',
|
|
't': None,
|
|
'h': '(HTML)',
|
|
'i': '(INFO)',
|
|
's': '(SOUND)'
|
|
}
|
|
|
|
|
|
def make_connection(self, resource, host, itemtype, port=70):
|
|
endline = '\r\n'
|
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
s.settimeout(30.0)
|
|
try:
|
|
port = int(port)
|
|
except:
|
|
port = 70
|
|
s.connect((host, port))
|
|
s.sendall((resource + '\r\n').encode('utf-8'))
|
|
r = s.makefile(mode = 'r', errors='ignore')
|
|
try:
|
|
raw_data = r.read()
|
|
except UnicodeDecodeError:
|
|
raw_data = 'iError decoding server response :(\tfalse\tnull.host\t1'
|
|
|
|
try:
|
|
data = raw_data.decode('utf-8','ignore')
|
|
except:
|
|
data = raw_data
|
|
|
|
self.raw_request = data
|
|
|
|
if itemtype[1] == '1':
|
|
#handle menus
|
|
self.text_output = self.gopher_to_text(self.raw_request)
|
|
elif itemtype[1] == '0':
|
|
#handle text files
|
|
self.text_output = [self.raw_request]
|
|
self.text_output.insert(0,itemtype[1])
|
|
s.close()
|
|
return self.text_output
|
|
|
|
|
|
|
|
def gopher_to_text(self, message):
|
|
message = message.split('\n')
|
|
message = [x.split('\t') for x in message]
|
|
message = [{'type': x[0][0], 'description': x[0][1:], 'resource': x[1], 'host': x[2], 'port': x[3]} for x in message if len(x) >= 4]
|
|
return message
|
|
|
|
|
|
def parse_url(self, url, execute=True):
|
|
regex = r'^(?P<protocol>(?:gopher:\/\/)?)?(?P<host>[\w\.\d]+)(?P<port>(?::\d+)?)?(?P<type>(?:\/\d)?)?(?P<resource>(?:\/[\w\/\d\-?.]*)?)?$'
|
|
match = re.match(regex, url)
|
|
protocol = match.group('protocol')
|
|
itemtype = match.group('type')
|
|
host = match.group('host')
|
|
port = match.group('port')
|
|
resource = match.group('resource')
|
|
|
|
if protocol != 'gopher://' and protocol:
|
|
return False
|
|
if itemtype and not self.types[itemtype[1]]:
|
|
return False
|
|
elif not itemtype:
|
|
itemtype = '/1'
|
|
if not host:
|
|
return False
|
|
if not resource:
|
|
resource = '/'
|
|
if port:
|
|
port = port[1:]
|
|
|
|
if execute:
|
|
self.make_connection(resource, host, itemtype, port)
|
|
else:
|
|
return {'host': host, 'resource': resource, 'type': itemtype}
|
|
|
|
|
|
if __name__ == '__main__':
|
|
inp = sys.argv[1:]
|
|
if len(inp) >= 2:
|
|
test = Tunnel()
|
|
test.make_connection(inp[1],inp[0],'70')
|
|
else:
|
|
print('Incorrect request')
|