From 4ec1d0424715096481192ecf4416043770894011 Mon Sep 17 00:00:00 2001 From: calzoneman Date: Mon, 9 Sep 2013 17:16:41 -0500 Subject: [PATCH] Add SSL support --- changelog | 12 +++++ lib/channel.js | 1 + lib/config.js | 4 ++ lib/server.js | 93 ++++++++++++++++++++++++-------------- www/assets/js/callbacks.js | 3 ++ www/assets/js/iourl.js | 5 ++ www/assets/js/ui.js | 9 +--- www/channel.html | 11 +++-- www/index.html | 13 ++---- 9 files changed, 96 insertions(+), 55 deletions(-) diff --git a/changelog b/changelog index 9d2a2100..bceffe18 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,15 @@ +Mon Sep 9 17:11 2013 CDT + * lib/server.js: If SSL is enabled in config, create an additional + server listening with SSL for websockets and HTTPS traffic + * lib/config.js: Add config keys for SSL + * lib/channel.js: Broadcast messages to both regular and SSL sockets + * www/assets/js/iourl.js: Add SSL_URL and automatically set WEB_URL and + IO_URL to SSL_URL when the protocol is HTTPS + * www/assets/js/callbacks.js: Automatically set the secure option on + io.connect() + * www/assets/js/ui.js, www/index.html, www/channel.html: Fix links to + be dependent on the protocol + Sun Sep 8 17:41 2013 CDT * lib/server.js: Change behavior of unloadChannel - deletes all object keys in the channel object and then sets channel.dead = true diff --git a/lib/channel.js b/lib/channel.js index 287ff821..bc3b4406 100644 --- a/lib/channel.js +++ b/lib/channel.js @@ -991,6 +991,7 @@ Channel.prototype.sendAll = function(message, data) { if(this.name == "") return; this.server.io.sockets.in(this.name).emit(message, data); + this.server.sslio.sockets.in(this.name).emit(message, data); } Channel.prototype.sendAllWithPermission = function(perm, msg, data) { diff --git a/lib/config.js b/lib/config.js index a8f15850..82e7d3e0 100644 --- a/lib/config.js +++ b/lib/config.js @@ -20,6 +20,10 @@ var defaults = { "mysql-pw" : "supersecretpass", "express-host" : "0.0.0.0", "io-host" : "0.0.0.0", + "enable-ssl" : false, + "ssl-keyfile" : "", + "ssl-certfile" : "", + "ssl-port" : 443, "asset-cache-ttl" : 0, "web-port" : 8080, "io-port" : 1337, diff --git a/lib/server.js b/lib/server.js index 4fb34907..fcc98721 100644 --- a/lib/server.js +++ b/lib/server.js @@ -1,5 +1,7 @@ var path = require("path"); var fs = require("fs"); +var http = require("http"); +var https = require("https"); var express = require("express"); var Config = require("./config"); var Logger = require("./logger"); @@ -72,6 +74,8 @@ var Server = { app: null, io: null, httpserv: null, + sslserv: null, + sslio: null, ioserv: null, db: null, ips: {}, @@ -92,6 +96,41 @@ var Server = { url = url.substring(0, url.lastIndexOf("?")); this.httpaccess.log([ipstr, req.method, url, status, req.headers["user-agent"]].join(" ")); }, + handleIOConnection: function (socket) { + var self = this; + self.stats.record("socketio", "socket"); + var ip = getSocketIP(socket); + socket._ip = ip; + self.db.isGlobalIPBanned(ip, function (err, bant) { + if(bant) { + Logger.syslog.log("Disconnecting " + ip + " - gbanned"); + socket.emit("kick", { + reason: "You're globally banned." + }); + socket.disconnect(true); + } + }); + + socket.on("disconnect", function () { + self.ips[ip]--; + }.bind(self)); + + if(!(ip in self.ips)) + self.ips[ip] = 0; + self.ips[ip]++; + + if(self.ips[ip] > Server.cfg["ip-connection-limit"]) { + socket.emit("kick", { + reason: "Too many connections from your IP address" + }); + socket.disconnect(true); + return; + } + + // finally a valid user + Logger.syslog.log("Accepted socket from /" + socket._ip); + new User(socket, self); + }, init: function () { var self = this; // init database @@ -171,6 +210,25 @@ var Server = { }); // bind servers + if (self.cfg["enable-ssl"]) { + var key = fs.readFileSync(path.resolve(__dirname, "..", + self.cfg["ssl-keyfile"])); + var cert = fs.readFileSync(path.resolve(__dirname, "..", + self.cfg["ssl-certfile"])); + + var options = { + key: key, + cert: cert + }; + + self.sslserv = https.createServer(options, self.app) + .listen(self.cfg["ssl-port"]); + self.sslio = require("socket.io").listen(self.sslserv); + self.sslio.set("log level", 1); + self.sslio.sockets.on("connection", function (socket) { + self.handleIOConnection(socket); + }); + } self.httpserv = self.app.listen(Server.cfg["web-port"], Server.cfg["express-host"]); self.ioserv = express().listen(Server.cfg["io-port"], @@ -180,39 +238,8 @@ var Server = { self.io = require("socket.io").listen(self.ioserv); self.io.set("log level", 1); self.io.sockets.on("connection", function (socket) { - self.stats.record("socketio", "socket"); - var ip = getSocketIP(socket); - socket._ip = ip; - self.db.isGlobalIPBanned(ip, function (err, bant) { - if(bant) { - Logger.syslog.log("Disconnecting " + ip + " - gbanned"); - socket.emit("kick", { - reason: "You're globally banned." - }); - socket.disconnect(true); - } - }); - - socket.on("disconnect", function () { - self.ips[ip]--; - }.bind(self)); - - if(!(ip in self.ips)) - self.ips[ip] = 0; - self.ips[ip]++; - - if(self.ips[ip] > Server.cfg["ip-connection-limit"]) { - socket.emit("kick", { - reason: "Too many connections from your IP address" - }); - socket.disconnect(true); - return; - } - - // finally a valid user - Logger.syslog.log("Accepted socket from /" + socket._ip); - new User(socket, self); - }.bind(self)); + self.handleIOConnection(socket); + }); // init ACP diff --git a/www/assets/js/callbacks.js b/www/assets/js/callbacks.js index a9b318be..4c3fc071 100644 --- a/www/assets/js/callbacks.js +++ b/www/assets/js/callbacks.js @@ -1148,6 +1148,9 @@ $.getScript(IO_URL+"/socket.io/socket.io.js", function() { if(i >= 0) io.transports.splice(i, 1); } + var opts = {}; + if (location.protocol === "https:") + opts.secure = true; socket = io.connect(IO_URL); setupCallbacks(); } diff --git a/www/assets/js/iourl.js b/www/assets/js/iourl.js index 19f76b90..e92c44c6 100644 --- a/www/assets/js/iourl.js +++ b/www/assets/js/iourl.js @@ -11,3 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI var IO_URL = "http://localhost:1337"; var WEB_URL = "http://localhost:8080"; +var SSL_URL = "https://localhost:443"; + +if (location.protocol === "https:") { + IO_URL = WEB_URL = SSL_URL; +} diff --git a/www/assets/js/ui.js b/www/assets/js/ui.js index ee660870..b6d9ecd7 100644 --- a/www/assets/js/ui.js +++ b/www/assets/js/ui.js @@ -438,14 +438,9 @@ else { var label = $("