Work on SIO and SSL

This commit is contained in:
calzoneman 2014-01-22 21:12:43 -06:00
parent 4a2366eb06
commit feabf35714
6 changed files with 138 additions and 133 deletions

View File

@ -27,13 +27,10 @@ function handleAuth(data, accept) {
var auth = data.cookie.auth; var auth = data.cookie.auth;
db.users.verifyAuth(auth, function (err, user) { db.users.verifyAuth(auth, function (err, user) {
if (!err) { if (!err) {
console.log('VERIFIED: ' + user.name + ' => ' + user.global_rank);
data.user = { data.user = {
name: user.name, name: user.name,
global_rank: user.global_rank global_rank: user.global_rank
}; };
} else {
console.log('Auth fail: ' + err);
} }
accept(null, true); accept(null, true);
}); });

View File

@ -83,74 +83,6 @@ var Server = function () {
root: path.join(__dirname, "../www") root: path.join(__dirname, "../www")
}); });
}); });
/*
self.express.use(express.urlencoded());
self.express.use(express.json());
self.express.use(express.cookieParser());
// channel route
self.express.get("/r/:channel(*)", function (req, res, next) {
var c = req.params.channel;
if (!$util.isValidChannelName(c)) {
res.redirect("/" + c);
return;
}
self.logHTTP(req);
res.sendfile("channel.html", {
root: path.join(__dirname, "../www")
});
});
// api route
self.api = require("./api")(self);
// index
self.express.get("/", function (req, res, next) {
self.logHTTP(req);
res.sendfile("index.html", {
root: path.join(__dirname, "../www")
});
});
// default route
self.express.get("/:thing(*)", function (req, res, next) {
var opts = {
root: path.join(__dirname, "../www"),
maxAge: self.cfg["asset-cache-ttl"]
};
res.sendfile(req.params.thing, opts, function (e) {
if (e) {
self.logHTTP(req, e.status);
if (req.params.thing.match(/\.\.|(%25)?%2e(%25)?%2e/)) {
res.send("Don't try that again.");
Logger.syslog.log("WARNING: Attempted path traversal "+
"from IP " + self.getHTTPIP(req));
Logger.syslog.log("Path was: " + req.url);
ActionLog.record(self.getHTTPIP(req), "",
"path-traversal",
req.url);
} else if (e.status >= 500) {
Logger.errlog.log(err);
}
res.send(e.status);
} else {
self.logHTTP(req);
}
});
});
// fallback route
self.express.use(function (err, req, res, next) {
self.logHTTP(req, err.status);
if (err.status === 404) {
res.send(404);
} else {
next(err);
}
});
*/
// http/https/sio server init ----------------------------------------- // http/https/sio server init -----------------------------------------
if (Config.get("https.enabled")) { if (Config.get("https.enabled")) {
@ -170,14 +102,7 @@ var Server = function () {
self.http = self.express.listen(Config.get("http.port"), self.http = self.express.listen(Config.get("http.port"),
Config.get("http.host") || undefined); Config.get("http.host") || undefined);
/*
self.ioWeb = express().listen(self.cfg["io-port"], self.cfg["io-host"]);
self.io = require("socket.io").listen(self.ioWeb);
self.io.set("log level", 1);
self.io.sockets.on("connection", function (sock) {
self.handleSocketConnection(sock);
});
*/
require("./io/ioserver").init(self); require("./io/ioserver").init(self);
// background tasks init ---------------------------------------------- // background tasks init ----------------------------------------------

View File

@ -16,6 +16,10 @@ var $util = require('../utilities');
* Handles a GET request for /account/edit * Handles a GET request for /account/edit
*/ */
function handleAccountEditPage(req, res) { function handleAccountEditPage(req, res) {
if (webserver.redirectHttps(req, res)) {
return;
}
logRequest(req); logRequest(req);
var loginName = false; var loginName = false;
if (req.cookies.auth) { if (req.cookies.auth) {
@ -167,6 +171,10 @@ function handleChangeEmail(req, res) {
* Handles a GET request for /account/channels * Handles a GET request for /account/channels
*/ */
function handleAccountChannelPage(req, res) { function handleAccountChannelPage(req, res) {
if (webserver.redirectHttps(req, res)) {
return;
}
logRequest(req); logRequest(req);
var loginName = false; var loginName = false;
if (req.cookies.auth) { if (req.cookies.auth) {
@ -315,6 +323,10 @@ function handleDeleteChannel(req, res) {
* Handles a GET request for /account/profile * Handles a GET request for /account/profile
*/ */
function handleAccountProfilePage(req, res) { function handleAccountProfilePage(req, res) {
if (webserver.redirectHttps(req, res)) {
return;
}
logRequest(req); logRequest(req);
var loginName = false; var loginName = false;

View File

@ -73,6 +73,10 @@ function handleLogin(req, res) {
* Handles a GET request for /login * Handles a GET request for /login
*/ */
function handleLoginPage(req, res) { function handleLoginPage(req, res) {
if (webserver.redirectHttps(req, res)) {
return;
}
if (req.cookies.auth) { if (req.cookies.auth) {
var split = req.cookies.auth.split(":"); var split = req.cookies.auth.split(":");
if (split.length === 2) { if (split.length === 2) {
@ -120,6 +124,10 @@ function handleLogout(req, res) {
* Handles a GET request for /register * Handles a GET request for /register
*/ */
function handleRegisterPage(req, res) { function handleRegisterPage(req, res) {
if (webserver.redirectHttps(req, res)) {
return;
}
if (req.cookies.auth) { if (req.cookies.auth) {
var split = req.cookies.auth.split(":"); var split = req.cookies.auth.split(":");
if (split.length === 2) { if (split.length === 2) {

View File

@ -4,16 +4,17 @@
* @author Calvin Montgomery <cyzon@cyzon.us> * @author Calvin Montgomery <cyzon@cyzon.us>
*/ */
var path = require('path'); var path = require("path");
var net = require('net'); var net = require("net");
var express = require('express'); var express = require("express");
var webroot = path.join(__dirname, '..', 'www'); var webroot = path.join(__dirname, "..", "www");
var sendJade = require('./jade').sendJade; var sendJade = require("./jade").sendJade;
var Server = require('../server'); var Server = require("../server");
var $util = require('../utilities'); var $util = require("../utilities");
var Logger = require('../logger'); var Logger = require("../logger");
var Config = require("../config");
var httplog = new Logger.Logger(path.join(__dirname, '..', '..', 'http.log')); var httplog = new Logger.Logger(path.join(__dirname, "..", "..", "http.log"));
var suspiciousPath = (/admin|adm|\.\.|\/etc\/passwd|\\x5c|%5c|0x5c|setup|install|php|pma|blog|sql|scripts|aspx?|database/ig); var suspiciousPath = (/admin|adm|\.\.|\/etc\/passwd|\\x5c|%5c|0x5c|setup|install|php|pma|blog|sql|scripts|aspx?|database/ig);
/** /**
@ -21,8 +22,8 @@ var suspiciousPath = (/admin|adm|\.\.|\/etc\/passwd|\\x5c|%5c|0x5c|setup|install
*/ */
function isSuspicious(req) { function isSuspicious(req) {
// ZmEu is a penetration script // ZmEu is a penetration script
if (req.header('user-agent') && if (req.header("user-agent") &&
req.header('user-agent').toLowerCase() === 'zmeu') { req.header("user-agent").toLowerCase() === "zmeu") {
return true; return true;
} }
@ -38,9 +39,9 @@ function isSuspicious(req) {
*/ */
function ipForRequest(req) { function ipForRequest(req) {
var ip = req.ip; var ip = req.ip;
if (ip === '127.0.0.1' || ip === '::1') { if (ip === "127.0.0.1" || ip === "::1") {
var xforward = req.header('x-forwarded-for'); var xforward = req.header("x-forwarded-for");
if (typeof xforward !== 'string' || !net.isIP(xforward)) { if (typeof xforward !== "string" || !net.isIP(xforward)) {
return ip; return ip;
} else { } else {
return xforward; return xforward;
@ -61,34 +62,72 @@ function logRequest(req, status) {
ipForRequest(req), ipForRequest(req),
req.route.method.toUpperCase(), req.route.method.toUpperCase(),
req.path, req.path,
status, req.header("user-agent")
req.header('user-agent') ].join(" "));
].join(' ')); }
/**
* Redirects a request to HTTPS if the server supports it
*/
function redirectHttps(req, res) {
if (!req.secure && Config.get("https.enabled")) {
var ssldomain = Config.get("https.domain");
var port = Config.get("https.port");
if (port !== 443) {
ssldomain += ":" + port;
}
res.redirect(ssldomain + req.path);
return true;
}
return false;
}
/**
* Redirects a request to HTTP if the server supports it
*/
function redirectHttp(req, res) {
if (req.secure) {
var domain = Config.get("http.domain");
var port = Config.get("http.port");
if (port !== 80) {
domain += ":" + port;
}
console.log(domain);
res.redirect(domain + req.path);
return true;
}
return false;
} }
/** /**
* Handles a GET request for /r/:channel - serves channel.html * Handles a GET request for /r/:channel - serves channel.html
*/ */
function handleChannel(req, res) { function handleChannel(req, res) {
if (redirectHttp(req, res)) {
return;
}
if (!$util.isValidChannelName(req.params.channel)) { if (!$util.isValidChannelName(req.params.channel)) {
logRequest(req, 404); logRequest(req, 404);
res.status(404); res.status(404);
res.send('Invalid channel name "' + req.params.channel + '"'); res.send("Invalid channel name '" + req.params.channel + "'");
return; return;
} }
logRequest(req); logRequest(req);
var loginName = false; var loginName = false;
if (req.cookies.auth) { if (req.cookies.auth) {
loginName = req.cookies.auth.split(':')[0]; loginName = req.cookies.auth.split(":")[0];
} }
var inst = Server.getServer();
var iourl = ''; var iourl = "";
sendJade(res, 'channel', { sendJade(res, "channel", {
channelName: req.params.channel, channelName: req.params.channel,
layout: 'hd',
loggedIn: loginName !== false, loggedIn: loginName !== false,
loginName: loginName, loginName: loginName,
/*ioUrl: 'http://' + inst.config.sio.domain + ':' + inst.config.sio.port*/ sioSource: Config.get("http.domain") + ":" + Config.get("io.port") +
"/socket.io/socket.io.js"
}); });
} }
@ -97,18 +136,37 @@ function handleChannel(req, res) {
*/ */
function handleIndex(req, res) { function handleIndex(req, res) {
logRequest(req); logRequest(req);
var loginName = false; var loginName = false;
if (req.cookies.auth) { if (req.cookies.auth) {
loginName = req.cookies.auth.split(':')[0]; loginName = req.cookies.auth.split(":")[0];
} }
sendJade(res, 'index', { sendJade(res, "index", {
loggedIn: loginName !== false, loggedIn: loginName !== false,
loginName: loginName, loginName: loginName,
channels: Server.getServer().packChannelList(true) channels: Server.getServer().packChannelList(true)
}); });
} }
/**
* Handles a request for the socket.io information
*/
function handleSocketConfig(req, res) {
logRequest(req);
res.type("application/javascript");
var io_url = Config.get("http.domain") + ":" + Config.get("io.port");
var web_url = Config.get("http.domain") + ":" + Config.get("http.port");
var ssl_url = Config.get("https.domain") + ":" + Config.get("https.port");
res.send("var IO_URL='"+io_url+"',WEB_URL='"+web_url+"',SSL_URL='" + ssl_url +
"',ALLOW_SSL="+Config.get("https.enabled")+";" +
(Config.get("https.enabled") ?
"if(location.protocol=='https:'||USEROPTS.secure_connection){" +
"IO_URL=WEB_URL=SSL_URL;}" : ""));
}
module.exports = { module.exports = {
/** /**
* Initializes webserver callbacks * Initializes webserver callbacks
@ -122,33 +180,38 @@ module.exports = {
/* Order here is important /* Order here is important
* Since I placed /r/:channel above *, the function will * Since I placed /r/:channel above *, the function will
* not apply to the /r/:channel route. This prevents * not apply to the /r/:channel route. This prevents
* duplicate logging, since /r/:channel's callback does * duplicate logging, since /r/:channel"s callback does
* its own logging * its own logging
*/ */
app.get('/r/:channel', handleChannel); app.get("/r/:channel", handleChannel);
app.get('/', handleIndex); app.get("/", handleIndex);
app.all('*', function (req, res, next) { app.get("/sioconfig", handleSocketConfig);
app.all("*", function (req, res, next) {
if (isSuspicious(req)) { if (isSuspicious(req)) {
logRequest(req, 403); logRequest(req, 403);
res.status(403); res.status(403);
if (req.header('user-agent').toLowerCase() === 'zmeu') { if (req.header("user-agent").toLowerCase() === "zmeu") {
res.send('This server disallows requests from ZmEu.'); res.send("This server disallows requests from ZmEu.");
} else { } else {
res.send('The request ' + req.route.method.toUpperCase() + ' ' + res.send("The request " + req.route.method.toUpperCase() + " " +
req.path + ' looks pretty fishy to me. Double check that ' + req.path + " looks pretty fishy to me. Double check that " +
'you typed it correctly.'); "you typed it correctly.");
} }
return; return;
} }
logRequest(req); logRequest(req);
next(); next();
}); });
app.use(express.static('www')); app.use(express.static("www"));
require('./auth').init(app); require("./auth").init(app);
require('./account').init(app); require("./account").init(app);
}, },
logRequest: logRequest, logRequest: logRequest,
ipForRequest: ipForRequest ipForRequest: ipForRequest,
redirectHttps: redirectHttps,
redirectHttp: redirectHttp
}; };

View File

@ -155,18 +155,18 @@ html(lang="en")
ul.nav.nav-tabs ul.nav.nav-tabs
li: a(href="#cs-miscoptions", data-toggle="tab") General Settings li: a(href="#cs-miscoptions", data-toggle="tab") General Settings
li: a(href="#cs-adminoptions", data-toggle="tab") Admin Settings li: a(href="#cs-adminoptions", data-toggle="tab") Admin Settings
li: a(href="#cs-chanlog", data-toggle="tab", onclick="javascript:socket.emit('readChanLog')") Channel Log
li: a(href="#cs-chatfilters", data-toggle="tab", onclick="javascript:socket.emit('requestChatFilters')") Chat Filters
li.dropdown li.dropdown
a#cs-edit-dd-toggle(href="#", data-toggle="dropdown") Edit a#cs-edit-dd-toggle(href="#", data-toggle="dropdown") Edit
span.caret span.caret
ul.dropdown-menu ul.dropdown-menu
li: a(href="#cs-motdeditor", data-toggle="tab", tabindex="-1") Edit MOTD li: a(href="#cs-chatfilters", data-toggle="tab", onclick="javascript:socket.emit('requestChatFilters')") Chat Filters
li: a(href="#cs-csseditor", data-toggle="tab", tabindex="-1") Edit CSS li: a(href="#cs-motdeditor", data-toggle="tab", tabindex="-1") MOTD
li: a(href="#cs-jseditor", data-toggle="tab", tabindex="-1") Edit Javascript li: a(href="#cs-csseditor", data-toggle="tab", tabindex="-1") CSS
li: a(href="#cs-permedit", data-toggle="tab", tabindex="-1") Edit Permissions li: a(href="#cs-jseditor", data-toggle="tab", tabindex="-1") Javascript
li: a(href="#cs-chanranks", data-toggle="tab", tabindex="-1", onclick="javascript:socket.emit('requestChannelRanks')") Edit moderators li: a(href="#cs-permedit", data-toggle="tab", tabindex="-1") Permissions
li: a(href="#cs-chanranks", data-toggle="tab", tabindex="-1", onclick="javascript:socket.emit('requestChannelRanks')") Moderators
li: a(href="#cs-banlist", data-toggle="tab", tabindex="-1", onclick="javascript:socket.emit('requestBanlist')") Ban list li: a(href="#cs-banlist", data-toggle="tab", tabindex="-1", onclick="javascript:socket.emit('requestBanlist')") Ban list
li: a(href="#cs-chanlog", data-toggle="tab", onclick="javascript:socket.emit('readChanLog')") Log
.modal-body .modal-body
.tab-content .tab-content
include channeloptions include channeloptions
@ -185,17 +185,17 @@ html(lang="en")
button.btn.btn-default(type="button", data-dismiss="modal") Close button.btn.btn-default(type="button", data-dismiss="modal") Close
include footer include footer
mixin footer() mixin footer()
script(src="/assets/js/iourl.js") script(src=sioSource)
//script(src="#{ioUrl}/socket.io/socket.io.js") script(src="/sioconfig")
//script(type="text/javascript").
// var IOSERVER = "#{ioUrl}";
// var SOCKET = io.connect(IOSERVER);
// $('#channeloptions').modal();
// $('#channeloptions a[href="#cs-miscoptions"]').tab('show');
script(src="/assets/js/data.js") script(src="/assets/js/data.js")
script(src="/assets/js/util.js") script(src="/assets/js/util.js")
script(src="/assets/js/player.js") script(src="/assets/js/player.js")
script(src="/assets/js/paginator.js") script(src="/assets/js/paginator.js")
script(src="/assets/js/ui.js") script(src="/assets/js/ui.js")
script(src="/assets/js/callbacks.js") script(src="/assets/js/callbacks.js")
script(src="https://www.youtube.com/iframe_api") script(defer, src="https://www.youtube.com/iframe_api")
script(defer, src="//api.dmcdn.net/all.js")
script(defer, src="/assets/js/jwplayer.js")
script(defer, src="/assets/js/sc.js")
script(defer, src="/assets/js/froogaloop.min.js")
script(defer, src="/assets/js/swf.js")