diff --git a/demos/web/create-cert.sh b/demos/web/create-cert.sh new file mode 100644 index 000000000..50c9e00df --- /dev/null +++ b/demos/web/create-cert.sh @@ -0,0 +1,10 @@ +# generate self-signed certs with no password for the web and socket servers +mkdir tls +openssl genrsa -des3 -out tls/server.key 1024 +openssl req -new -key tls/server.key -out tls/server.csr +cp tls/server.key tls/server.key.org +openssl rsa -in tls/server.key.org -out tls/server.key +openssl x509 -req -days 365 -in tls/server.csr -signkey tls/server.key -out tls/server.crt +echo 'converting to pem' +cat tls/server.crt tls/server.key > tls/server.pem +echo 'cert complete' diff --git a/demos/web/index.html b/demos/web/index.html index b49ef4ee0..761d84e71 100644 --- a/demos/web/index.html +++ b/demos/web/index.html @@ -233,7 +233,7 @@

Training $("#viewTSNEBtn").click(viewTSNECallback); redrawPeople(); - // createSocket("ws://facerec.cmusatyalab.org:9000", "CMU"); - createSocket("ws:" + window.location.hostname + ":9000", "Local"); + // createSocket("wss://facerec.cmusatyalab.org:9000", "CMU"); + createSocket("wss://" + window.location.hostname + ":9000", "Local"); diff --git a/demos/web/install-deps.sh b/demos/web/install-deps.sh index bd4812bcc..90238e18e 100755 --- a/demos/web/install-deps.sh +++ b/demos/web/install-deps.sh @@ -10,6 +10,8 @@ sudo apt-get install -y libprotobuf-dev libleveldb-dev libsnappy-dev \ python-pip python-numpy python-imaging python-opencv \ git wget cmake gfortran +source ~/openface/demos/web/create-cert.sh + mkdir -p ~/src cd ~/src git clone https://github.com/bvlc/caffe.git diff --git a/demos/web/js/openface-demo.js b/demos/web/js/openface-demo.js index 1ba9deed6..676607ee7 100644 --- a/demos/web/js/openface-demo.js +++ b/demos/web/js/openface-demo.js @@ -16,7 +16,10 @@ limitations under the License. navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || - navigator.mozGetUserMedia || + (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) ? + function(c, os, oe) { + navigator.mediaDevices.getUserMedia(c).then(os,oe); + } : null || navigator.msGetUserMedia; window.URL = window.URL || @@ -329,22 +332,22 @@ function changeServerCallback() { case "Local": socket.close(); redrawPeople(); - createSocket("ws:" + window.location.hostname + ":9000", "Local"); + createSocket("wss:" + window.location.hostname + ":9000", "Local"); break; case "CMU": socket.close(); redrawPeople(); - createSocket("ws://facerec.cmusatyalab.org:9000", "CMU"); + createSocket("wss://facerec.cmusatyalab.org:9000", "CMU"); break; case "AWS East": socket.close(); redrawPeople(); - createSocket("ws://54.159.128.49:9000", "AWS-East"); + createSocket("wss://54.159.128.49:9000", "AWS-East"); break; case "AWS West": socket.close(); redrawPeople(); - createSocket("ws://54.188.234.61:9000", "AWS-West"); + createSocket("wss://54.188.234.61:9000", "AWS-West"); break; default: alert("Unrecognized server: " + $(this.html())); diff --git a/demos/web/simpleSSLServer.py b/demos/web/simpleSSLServer.py new file mode 100644 index 000000000..71c07de1f --- /dev/null +++ b/demos/web/simpleSSLServer.py @@ -0,0 +1,18 @@ +from __future__ import print_function +import BaseHTTPServer +import SimpleHTTPServer +import ssl +import sys + + +'''Adopted from https://www.piware.de/2011/01/creating-an-https-server-in-python/''' + + +def main(port): + httpd = BaseHTTPServer.HTTPServer(('0.0.0.0', port), SimpleHTTPServer.SimpleHTTPRequestHandler) + httpd.socket = ssl.wrap_socket(httpd.socket, certfile='tls/server.pem', server_side=True) + print('now serving tls http on port:', port) + httpd.serve_forever() + +if __name__ == '__main__': + main(int(sys.argv[1])) diff --git a/demos/web/start-servers.sh b/demos/web/start-servers.sh index f10774fa5..0d5768e44 100755 --- a/demos/web/start-servers.sh +++ b/demos/web/start-servers.sh @@ -22,30 +22,25 @@ trap 'kill $(jobs -p)' EXIT cat <:$HTTP_PORT. +address of the Docker container and use https://:$HTTP_PORT. If you're running on a remote computer, find the IP address -and use http://:$HTTP_PORT. - -WARNING: Chromium refuses to connect to the insecure WebSocket server -if you are running a remote or Docker deployment. -We have posted a workaround to forward traffic through localhost -using ncat at http://cmusatyalab.github.io/openface/demo-1-web/. -Track our progress on fixing this at: -https://github.com/cmusatyalab/openface/issues/75. +and use https://:$HTTP_PORT. +WARNING: Chromium will warn on self-signed certificates. Please accept the certificate +and reload the app. EOF WEBSOCKET_LOG='/tmp/openface.websocket.log' printf "WebSocket Server: Logging to '%s'\n\n" $WEBSOCKET_LOG -python2 -m SimpleHTTPServer $HTTP_PORT &> /dev/null & +python2 simpleSSLServer.py $HTTP_PORT &> /dev/null & cd ../../ # Root OpenFace directory. ./demos/web/websocket-server.py --port $WEBSOCKET_PORT 2>&1 | tee $WEBSOCKET_LOG & diff --git a/demos/web/websocket-server.py b/demos/web/websocket-server.py index 9e0f921f7..4a58a992c 100755 --- a/demos/web/websocket-server.py +++ b/demos/web/websocket-server.py @@ -24,8 +24,10 @@ from autobahn.twisted.websocket import WebSocketServerProtocol, \ WebSocketServerFactory +from twisted.internet import task, defer +from twisted.internet.ssl import DefaultOpenSSLContextFactory + from twisted.python import log -from twisted.internet import reactor import argparse import cv2 @@ -53,6 +55,9 @@ modelDir = os.path.join(fileDir, '..', '..', 'models') dlibModelDir = os.path.join(modelDir, 'dlib') openfaceModelDir = os.path.join(modelDir, 'openface') +# For TLS connections +tls_crt = os.path.join(fileDir, 'tls', 'server.crt') +tls_key = os.path.join(fileDir, 'tls', 'server.key') parser = argparse.ArgumentParser() parser.add_argument('--dlibFacePredictor', type=str, help="Path to dlib's face predictor.", @@ -88,8 +93,8 @@ def __repr__(self): class OpenFaceServerProtocol(WebSocketServerProtocol): - def __init__(self): + super(OpenFaceServerProtocol, self).__init__() self.images = {} self.training = True self.people = [] @@ -353,12 +358,14 @@ def processFrame(self, dataURL, identity): plt.close() self.sendMessage(json.dumps(msg)) -if __name__ == '__main__': - log.startLogging(sys.stdout) - factory = WebSocketServerFactory("ws://localhost:{}".format(args.port), - debug=False) +def main(reactor): + log.startLogging(sys.stdout) + factory = WebSocketServerFactory() factory.protocol = OpenFaceServerProtocol + ctx_factory = DefaultOpenSSLContextFactory(tls_key, tls_crt) + reactor.listenSSL(args.port, factory, ctx_factory) + return defer.Deferred() - reactor.listenTCP(args.port, factory) - reactor.run() +if __name__ == '__main__': + task.react(main)