Adding --auth_hook option. This allows

one to filter request on the initial handshake
based on the JS sending an additional string in in the
protocol list:

websocket = new WebSocket(uri, ['base64', user + '-----' + auth])

where two vars are sent separated by '-----'.  This allows one to have
the web server set cookies which in turn can be then sent with the initial
WebSocket connect request and dropped if the user is not authorized.
This commit is contained in:
Cliff Cyphers 2011-10-17 15:41:13 -05:00
parent 40868636da
commit 852de01768
2 changed files with 18 additions and 6 deletions

View File

@ -16,11 +16,11 @@ as taken from http://docs.python.org/dev/library/ssl.html#certificates
''' '''
import os, sys, time, errno, signal, socket, traceback, select import os, sys, time, errno, signal, socket, traceback, select, pdb, re
import array, struct import array, struct
from cgi import parse_qsl from cgi import parse_qsl
from base64 import b64encode, b64decode from base64 import b64encode, b64decode
from subprocess import call
# Imports that vary by python version # Imports that vary by python version
# python 3.0 differences # python 3.0 differences
@ -98,10 +98,11 @@ Sec-WebSocket-Accept: %s\r
def __init__(self, listen_host='', listen_port=None, source_is_ipv6=False, def __init__(self, listen_host='', listen_port=None, source_is_ipv6=False,
verbose=False, cert='', key='', ssl_only=None, verbose=False, cert='', key='', ssl_only=None,
daemon=False, record='', web='', daemon=False, record='', web='',
run_once=False, timeout=0): run_once=False, timeout=0, auth_hook=''):
# settings # settings
self.verbose = verbose self.verbose = verbose
self.auth_hook = auth_hook
self.listen_host = listen_host self.listen_host = listen_host
self.listen_port = listen_port self.listen_port = listen_port
self.ssl_only = ssl_only self.ssl_only = ssl_only
@ -574,11 +575,20 @@ Sec-WebSocket-Accept: %s\r
raise self.EClose("ignoring socket not ready") raise self.EClose("ignoring socket not ready")
# Peek, but do not read the data so that we have a opportunity # Peek, but do not read the data so that we have a opportunity
# to SSL wrap the socket first # to SSL wrap the socket first
handshake = sock.recv(1024, socket.MSG_PEEK) handshake = sock.recv(1024, socket.MSG_PEEK)
#self.msg("Handshake [%s]" % handshake)
tmp = handshake.split("Sec-WebSocket-Protocol:")[1].split(',')[1].split("\r")[0].split('-----')
if self.auth_hook != '':
ret = call([self.auth_hook, tmp[0], tmp[1]])
if ret != 0:
raise self.EClose("auth denied")
if handshake == "": if handshake == "":
raise self.EClose("ignoring empty handshake") raise self.EClose("ignoring empty handshake")
elif handshake.startswith(s2b("<policy-file-request/>")): elif handshake.startswith(s2b("<policy-file-request/>")):
# Answer Flash policy request # Answer Flash policy request

View File

@ -12,6 +12,7 @@ as taken from http://docs.python.org/dev/library/ssl.html#certificates
''' '''
import socket, optparse, time, os, sys, subprocess import socket, optparse, time, os, sys, subprocess
import pdb#;pdb.set_trace();
from select import select from select import select
from websocket import WebSocketServer from websocket import WebSocketServer
@ -149,7 +150,7 @@ Traffic Legend:
# Start proxying # Start proxying
try: try:
self.do_proxy(tsock) self.do_proxy(tsock)
except: except:
if tsock: if tsock:
tsock.shutdown(socket.SHUT_RDWR) tsock.shutdown(socket.SHUT_RDWR)
@ -242,6 +243,7 @@ if __name__ == '__main__':
choices=["exit", "ignore", "respawn"], choices=["exit", "ignore", "respawn"],
help="action to take when the wrapped program exits " help="action to take when the wrapped program exits "
"or daemonizes: exit (default), ignore, respawn") "or daemonizes: exit (default), ignore, respawn")
parser.add_option("--auth_hook", default="")
(opts, args) = parser.parse_args() (opts, args) = parser.parse_args()
# Sanity checks # Sanity checks