Merge 3cdebe788d into 7a4dbad3e8
This commit is contained in:
commit
252d9e70f0
16
README.md
16
README.md
|
|
@ -48,7 +48,7 @@ read binary data off of the receive queue.
|
||||||
The Websock API is documented on the [websock.js API wiki page](https://github.com/kanaka/websockify/wiki/websock.js)
|
The Websock API is documented on the [websock.js API wiki page](https://github.com/kanaka/websockify/wiki/websock.js)
|
||||||
|
|
||||||
See the "Wrap a Program" section below for an example of using Websock
|
See the "Wrap a Program" section below for an example of using Websock
|
||||||
and websockify as a browser telnet client (`wstelnet.html`).
|
and websockify as a browser telnet client (`www/wstelnet.html`).
|
||||||
|
|
||||||
|
|
||||||
### Additional websockify features
|
### Additional websockify features
|
||||||
|
|
@ -107,10 +107,16 @@ port is moved to a new localhost/loopback free high port. websockify
|
||||||
then proxies WebSockets traffic directed to the original port to the
|
then proxies WebSockets traffic directed to the original port to the
|
||||||
new (moved) port of the program.
|
new (moved) port of the program.
|
||||||
|
|
||||||
|
You can build rebind.so like so:
|
||||||
|
|
||||||
|
cd rebind
|
||||||
|
make
|
||||||
|
cd ..
|
||||||
|
|
||||||
The program wrap mode is invoked by replacing the target with `--`
|
The program wrap mode is invoked by replacing the target with `--`
|
||||||
followed by the program command line to wrap.
|
followed by the program command line to wrap.
|
||||||
|
|
||||||
`./websockify 2023 -- PROGRAM ARGS`
|
`bin/websockify 2023 -- PROGRAM ARGS`
|
||||||
|
|
||||||
The `--wrap-mode` option can be used to indicate what action to take
|
The `--wrap-mode` option can be used to indicate what action to take
|
||||||
when the wrapped program exits or daemonizes.
|
when the wrapped program exits or daemonizes.
|
||||||
|
|
@ -119,15 +125,15 @@ Here is an example of using websockify to wrap the vncserver command
|
||||||
(which backgrounds itself) for use with
|
(which backgrounds itself) for use with
|
||||||
[noVNC](https://github.com/kanaka/noVNC):
|
[noVNC](https://github.com/kanaka/noVNC):
|
||||||
|
|
||||||
`./websockify 5901 --wrap-mode=ignore -- vncserver -geometry 1024x768 :1`
|
`bin/websockify 5901 --wrap-mode=ignore -- vncserver -geometry 1024x768 :1`
|
||||||
|
|
||||||
Here is an example of wrapping telnetd (from krb5-telnetd).telnetd
|
Here is an example of wrapping telnetd (from krb5-telnetd).telnetd
|
||||||
exits after the connection closes so the wrap mode is set to respawn
|
exits after the connection closes so the wrap mode is set to respawn
|
||||||
the command:
|
the command:
|
||||||
|
|
||||||
`sudo ./websockify 2023 --wrap-mode=respawn -- telnetd -debug 2023`
|
`sudo bin/websockify 2023 --wrap-mode=respawn -- telnetd -debug 2023`
|
||||||
|
|
||||||
The `wstelnet.html` page demonstrates a simple WebSockets based telnet
|
The `www/wstelnet.html` page demonstrates a simple WebSockets based telnet
|
||||||
client.
|
client.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
'''
|
||||||
|
A WebSocket to TCP socket proxy with support for "wss://" encryption.
|
||||||
|
Copyright 2011 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 optparse, os, sys
|
||||||
|
from websockify.proxy import WebSocketProxy
|
||||||
|
|
||||||
|
|
||||||
|
def websockify_init():
|
||||||
|
usage = "\n %prog [options]"
|
||||||
|
usage += " [source_addr:]source_port target_addr:target_port"
|
||||||
|
usage += "\n %prog [options]"
|
||||||
|
usage += " [source_addr:]source_port -- WRAP_COMMAND_LINE"
|
||||||
|
parser = optparse.OptionParser(usage=usage)
|
||||||
|
parser.add_option("--verbose", "-v", action="store_true",
|
||||||
|
help="verbose messages and per frame traffic")
|
||||||
|
parser.add_option("--record",
|
||||||
|
help="record sessions to FILE.[session_number]", metavar="FILE")
|
||||||
|
parser.add_option("--daemon", "-D",
|
||||||
|
dest="daemon", action="store_true",
|
||||||
|
help="become a daemon (background process)")
|
||||||
|
parser.add_option("--run-once", action="store_true",
|
||||||
|
help="handle a single WebSocket connection and exit")
|
||||||
|
parser.add_option("--timeout", type=int, default=0,
|
||||||
|
help="after TIMEOUT seconds exit when not connected")
|
||||||
|
parser.add_option("--cert", default="self.pem",
|
||||||
|
help="SSL certificate file")
|
||||||
|
parser.add_option("--key", default=None,
|
||||||
|
help="SSL key file (if separate from cert)")
|
||||||
|
parser.add_option("--rebind_path", default="./",
|
||||||
|
help="Directory containing rebind.so")
|
||||||
|
parser.add_option("--ssl-only", action="store_true",
|
||||||
|
help="disallow non-encrypted connections")
|
||||||
|
parser.add_option("--web", default=None, metavar="DIR",
|
||||||
|
help="run webserver on same port. Serve files from DIR.")
|
||||||
|
parser.add_option("--wrap-mode", default="exit", metavar="MODE",
|
||||||
|
choices=["exit", "ignore", "respawn"],
|
||||||
|
help="action to take when the wrapped program exits "
|
||||||
|
"or daemonizes: exit (default), ignore, respawn")
|
||||||
|
(opts, args) = parser.parse_args()
|
||||||
|
|
||||||
|
# Sanity checks
|
||||||
|
if len(args) < 2:
|
||||||
|
parser.error("Too few arguments")
|
||||||
|
if sys.argv.count('--'):
|
||||||
|
opts.wrap_cmd = args[1:]
|
||||||
|
else:
|
||||||
|
opts.wrap_cmd = None
|
||||||
|
if len(args) > 2:
|
||||||
|
parser.error("Too many arguments")
|
||||||
|
|
||||||
|
if opts.ssl_only and not os.path.exists(opts.cert):
|
||||||
|
parser.error("SSL only and %s not found" % opts.cert)
|
||||||
|
|
||||||
|
# Parse host:port and convert ports to numbers
|
||||||
|
if args[0].count(':') > 0:
|
||||||
|
opts.listen_host, opts.listen_port = args[0].rsplit(':', 1)
|
||||||
|
else:
|
||||||
|
opts.listen_host, opts.listen_port = '', args[0]
|
||||||
|
|
||||||
|
try: opts.listen_port = int(opts.listen_port)
|
||||||
|
except: parser.error("Error parsing listen port")
|
||||||
|
|
||||||
|
if opts.wrap_cmd:
|
||||||
|
opts.target_host = None
|
||||||
|
opts.target_port = None
|
||||||
|
else:
|
||||||
|
if args[1].count(':') > 0:
|
||||||
|
opts.target_host, opts.target_port = args[1].rsplit(':', 1)
|
||||||
|
else:
|
||||||
|
parser.error("Error parsing target")
|
||||||
|
try: opts.target_port = int(opts.target_port)
|
||||||
|
except: parser.error("Error parsing target port")
|
||||||
|
|
||||||
|
# Create and start the WebSockets proxy
|
||||||
|
server = WebSocketProxy(**opts.__dict__)
|
||||||
|
server.start_server()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
websockify_init()
|
||||||
6
setup.py
6
setup.py
|
|
@ -22,9 +22,5 @@ setup(name=name,
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
install_requires=['numpy'],
|
install_requires=['numpy'],
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
entry_points={
|
scripts=['bin/websockify'],
|
||||||
'console_scripts': [
|
|
||||||
'websockify = websockify:websockify_init',
|
|
||||||
]
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ as taken from http://docs.python.org/dev/library/ssl.html#certificates
|
||||||
|
|
||||||
import os, sys, select, optparse
|
import os, sys, select, optparse
|
||||||
sys.path.insert(0,os.path.dirname(__file__) + "/../")
|
sys.path.insert(0,os.path.dirname(__file__) + "/../")
|
||||||
from websocket import WebSocketServer
|
from websockify.websocket import WebSocketServer
|
||||||
|
|
||||||
class WebSocketEcho(WebSocketServer):
|
class WebSocketEcho(WebSocketServer):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
../include
|
../www/include
|
||||||
|
|
@ -8,7 +8,7 @@ given a sequence number. Any errors are reported and counted.
|
||||||
|
|
||||||
import sys, os, select, random, time, optparse
|
import sys, os, select, random, time, optparse
|
||||||
sys.path.insert(0,os.path.dirname(__file__) + "/../")
|
sys.path.insert(0,os.path.dirname(__file__) + "/../")
|
||||||
from websocket import WebSocketServer
|
from websockify.websocket import WebSocketServer
|
||||||
|
|
||||||
class WebSocketLoad(WebSocketServer):
|
class WebSocketLoad(WebSocketServer):
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import sys, os, socket, ssl, time, traceback
|
||||||
from select import select
|
from select import select
|
||||||
|
|
||||||
sys.path.insert(0,os.path.dirname(__file__) + "/../")
|
sys.path.insert(0,os.path.dirname(__file__) + "/../")
|
||||||
from websocket import WebSocketServer
|
from websockify.websocket import WebSocketServer
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
print "val: hixie | hybi_base64 | hybi_binary"
|
print "val: hixie | hybi_base64 | hybi_binary"
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
websockify
|
|
||||||
|
|
@ -43,15 +43,20 @@ Traffic Legend:
|
||||||
self.target_port = kwargs.pop('target_port')
|
self.target_port = kwargs.pop('target_port')
|
||||||
self.wrap_cmd = kwargs.pop('wrap_cmd')
|
self.wrap_cmd = kwargs.pop('wrap_cmd')
|
||||||
self.wrap_mode = kwargs.pop('wrap_mode')
|
self.wrap_mode = kwargs.pop('wrap_mode')
|
||||||
|
self.rebind_path = kwargs.pop('rebind_path')
|
||||||
# Last 3 timestamps command was run
|
# Last 3 timestamps command was run
|
||||||
self.wrap_times = [0, 0, 0]
|
self.wrap_times = [0, 0, 0]
|
||||||
|
|
||||||
if self.wrap_cmd:
|
if self.wrap_cmd:
|
||||||
rebinder_path = ['./', os.path.dirname(sys.argv[0])]
|
rebinder_path = [self.rebind_path,
|
||||||
|
self.rebind_path + '/rebind.so',
|
||||||
|
'./rebind.so',
|
||||||
|
os.path.dirname(sys.argv[0]) + 'rebind.so',
|
||||||
|
'rebind/rebind.so',
|
||||||
|
'../rebind/rebind.so']
|
||||||
self.rebinder = None
|
self.rebinder = None
|
||||||
|
|
||||||
for rdir in rebinder_path:
|
for rpath in rebinder_path:
|
||||||
rpath = os.path.join(rdir, "rebind.so")
|
|
||||||
if os.path.exists(rpath):
|
if os.path.exists(rpath):
|
||||||
self.rebinder = rpath
|
self.rebinder = rpath
|
||||||
break
|
break
|
||||||
|
|
@ -212,74 +217,3 @@ Traffic Legend:
|
||||||
if closed:
|
if closed:
|
||||||
# TODO: What about blocking on client socket?
|
# TODO: What about blocking on client socket?
|
||||||
raise self.CClose(closed['code'], closed['reason'])
|
raise self.CClose(closed['code'], closed['reason'])
|
||||||
|
|
||||||
def websockify_init():
|
|
||||||
usage = "\n %prog [options]"
|
|
||||||
usage += " [source_addr:]source_port target_addr:target_port"
|
|
||||||
usage += "\n %prog [options]"
|
|
||||||
usage += " [source_addr:]source_port -- WRAP_COMMAND_LINE"
|
|
||||||
parser = optparse.OptionParser(usage=usage)
|
|
||||||
parser.add_option("--verbose", "-v", action="store_true",
|
|
||||||
help="verbose messages and per frame traffic")
|
|
||||||
parser.add_option("--record",
|
|
||||||
help="record sessions to FILE.[session_number]", metavar="FILE")
|
|
||||||
parser.add_option("--daemon", "-D",
|
|
||||||
dest="daemon", action="store_true",
|
|
||||||
help="become a daemon (background process)")
|
|
||||||
parser.add_option("--run-once", action="store_true",
|
|
||||||
help="handle a single WebSocket connection and exit")
|
|
||||||
parser.add_option("--timeout", type=int, default=0,
|
|
||||||
help="after TIMEOUT seconds exit when not connected")
|
|
||||||
parser.add_option("--cert", default="self.pem",
|
|
||||||
help="SSL certificate file")
|
|
||||||
parser.add_option("--key", default=None,
|
|
||||||
help="SSL key file (if separate from cert)")
|
|
||||||
parser.add_option("--ssl-only", action="store_true",
|
|
||||||
help="disallow non-encrypted connections")
|
|
||||||
parser.add_option("--web", default=None, metavar="DIR",
|
|
||||||
help="run webserver on same port. Serve files from DIR.")
|
|
||||||
parser.add_option("--wrap-mode", default="exit", metavar="MODE",
|
|
||||||
choices=["exit", "ignore", "respawn"],
|
|
||||||
help="action to take when the wrapped program exits "
|
|
||||||
"or daemonizes: exit (default), ignore, respawn")
|
|
||||||
(opts, args) = parser.parse_args()
|
|
||||||
|
|
||||||
# Sanity checks
|
|
||||||
if len(args) < 2:
|
|
||||||
parser.error("Too few arguments")
|
|
||||||
if sys.argv.count('--'):
|
|
||||||
opts.wrap_cmd = args[1:]
|
|
||||||
else:
|
|
||||||
opts.wrap_cmd = None
|
|
||||||
if len(args) > 2:
|
|
||||||
parser.error("Too many arguments")
|
|
||||||
|
|
||||||
if opts.ssl_only and not os.path.exists(opts.cert):
|
|
||||||
parser.error("SSL only and %s not found" % opts.cert)
|
|
||||||
|
|
||||||
# Parse host:port and convert ports to numbers
|
|
||||||
if args[0].count(':') > 0:
|
|
||||||
opts.listen_host, opts.listen_port = args[0].rsplit(':', 1)
|
|
||||||
else:
|
|
||||||
opts.listen_host, opts.listen_port = '', args[0]
|
|
||||||
|
|
||||||
try: opts.listen_port = int(opts.listen_port)
|
|
||||||
except: parser.error("Error parsing listen port")
|
|
||||||
|
|
||||||
if opts.wrap_cmd:
|
|
||||||
opts.target_host = None
|
|
||||||
opts.target_port = None
|
|
||||||
else:
|
|
||||||
if args[1].count(':') > 0:
|
|
||||||
opts.target_host, opts.target_port = args[1].rsplit(':', 1)
|
|
||||||
else:
|
|
||||||
parser.error("Error parsing target")
|
|
||||||
try: opts.target_port = int(opts.target_port)
|
|
||||||
except: parser.error("Error parsing target port")
|
|
||||||
|
|
||||||
# Create and start the WebSockets proxy
|
|
||||||
server = WebSocketProxy(**opts.__dict__)
|
|
||||||
server.start_server()
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
websockify_init()
|
|
||||||
Loading…
Reference in New Issue