Menu

[r108]: / wsproxy.py  Maximize  Restore  History

Download this file

170 lines (144 with data), 5.6 kB

  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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/usr/bin/python
'''
A WebSocket to TCP socket proxy with support for "wss://" encryption.
Copyright 2010 Joel Martin
Licensed under LGPL version 3 (see docs/LICENSE.LGPL-3)
You can make a cert/key with openssl using:
openssl req -new -x509 -days 365 -nodes -out self.pem -keyout self.pem
as taken from http://docs.python.org/dev/library/ssl.html#certificates
'''
import socket, optparse, time
from select import select
from websocket import *
buffer_size = 65536
rec = None
traffic_legend = """
Traffic Legend:
} - Client receive
}. - Client receive partial
{ - Target receive
> - Target send
>. - Target send partial
< - Client send
<. - Client send partial
"""
halt = False
def do_halt():
halt = True
def do_proxy(client, target):
""" Proxy WebSocket to normal socket. """
global rec
cqueue = []
cpartial = ""
tqueue = []
rlist = [client, target]
tstart = int(time.time()*1000)
while halt == False:
wlist = []
tdelta = int(time.time()*1000) - tstart
if tqueue: wlist.append(target)
if cqueue: wlist.append(client)
ins, outs, excepts = select(rlist, wlist, [], 1)
if excepts: raise Exception("Socket exception")
if target in outs:
dat = tqueue.pop(0)
sent = target.send(dat)
if sent == len(dat):
traffic(">")
else:
tqueue.insert(0, dat[sent:])
traffic(".>")
##if rec: rec.write("Target send: %s\n" % map(ord, dat))
if client in outs:
dat = cqueue.pop(0)
sent = client.send(dat)
if sent == len(dat):
traffic("<")
##if rec: rec.write("Client send: %s ...\n" % repr(dat[0:80]))
if rec: rec.write("%s,\n" % repr("{%s{" % tdelta + dat[1:-1]))
else:
cqueue.insert(0, dat[sent:])
traffic("<.")
##if rec: rec.write("Client send partial: %s\n" % repr(dat[0:send]))
if target in ins:
buf = target.recv(buffer_size)
if len(buf) == 0: raise Exception("Target closed")
cqueue.append(encode(buf))
traffic("{")
##if rec: rec.write("Target recv (%d): %s\n" % (len(buf), map(ord, buf)))
if client in ins:
buf = client.recv(buffer_size)
if len(buf) == 0: raise Exception("Client closed")
if buf == '\xff\x00':
raise Exception("Client sent orderly close frame")
elif buf[-1] == '\xff':
if buf.count('\xff') > 1:
traffic(str(buf.count('\xff')))
traffic("}")
##if rec: rec.write("Client recv (%d): %s\n" % (len(buf), repr(buf)))
if rec: rec.write("%s,\n" % (repr("}%s}" % tdelta + buf[1:-1])))
if cpartial:
tqueue.extend(decode(cpartial + buf))
cpartial = ""
else:
tqueue.extend(decode(buf))
else:
traffic(".}")
##if rec: rec.write("Client recv partial (%d): %s\n" % (len(buf), repr(buf)))
cpartial = cpartial + buf
def proxy_handler(client):
global target_host, target_port, options, rec
if settings['record']:
print "Opening record file: %s" % settings['record']
rec = open(settings['record'], 'w+')
rec.write("var VNC_frame_data = [\n")
print "Connecting to: %s:%s" % (target_host, target_port)
tsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tsock.connect((target_host, target_port))
try:
do_proxy(client, tsock)
except:
if tsock: tsock.close()
if rec:
rec.write("'EOF']\n")
rec.close()
raise
if __name__ == '__main__':
usage = "%prog [--record FILE]"
usage += " [source_addr:]source_port target_addr:target_port"
parser = optparse.OptionParser(usage=usage)
parser.add_option("--record",
help="record session to a file", metavar="FILE")
parser.add_option("--foreground", "-f",
dest="daemon", default=True, action="store_false",
help="stay in foreground, do not daemonize")
parser.add_option("--ssl-only", action="store_true",
help="disallow non-encrypted connections")
parser.add_option("--cert", default="self.pem",
help="SSL certificate")
(options, args) = parser.parse_args()
if len(args) > 2: parser.error("Too many arguments")
if len(args) < 2: parser.error("Too few arguments")
if args[0].count(':') > 0:
host,port = args[0].split(':')
else:
host,port = '',args[0]
if args[1].count(':') > 0:
target_host,target_port = args[1].split(':')
else:
parser.error("Error parsing target")
try: port = int(port)
except: parser.error("Error parsing listen port")
try: target_port = int(target_port)
except: parser.error("Error parsing target port")
if options.ssl_only and not os.path.exists(options.cert):
parser.error("SSL only and %s not found" % options.cert)
settings['listen_host'] = host
settings['listen_port'] = port
settings['handler'] = proxy_handler
settings['cert'] = os.path.abspath(options.cert)
settings['ssl_only'] = options.ssl_only
settings['daemon'] = options.daemon
if options.record:
settings['record'] = os.path.abspath(options.record)
start_server()
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.