Add IP cloaking; make tor bans channel specific

This commit is contained in:
calzoneman 2014-08-14 21:42:13 -05:00
parent ecca806a58
commit 8fddbc3e6e
14 changed files with 193 additions and 142 deletions

View file

@ -330,10 +330,24 @@ Channel.prototype.acceptUser = function (user) {
user.autoAFK();
user.socket.on("readChanLog", this.handleReadLog.bind(this, user));
Logger.syslog.log(user.ip + " joined " + this.name);
this.logger.log("[login] Accepted connection from " + user.longip);
Logger.syslog.log(user.realip + " joined " + this.name);
if (user.socket._isUsingTor) {
if (this.modules.options && this.modules.options.get("torbanned")) {
user.kick("This channel has banned connections from Tor.");
user.socket.disconnect(true);
this.logger.log("[login] Blocked connection from Tor exit at " +
user.displayip);
return;
}
this.logger.log("[login] Accepted connection from Tor exit at " +
user.displayip);
} else {
this.logger.log("[login] Accepted connection from " + user.displayip);
}
if (user.is(Flags.U_LOGGED_IN)) {
this.logger.log("[login] " + user.longip + " authenticated as " + user.getName());
this.logger.log("[login] " + user.displayip + " authenticated as " + user.getName());
}
var self = this;
@ -367,7 +381,7 @@ Channel.prototype.partUser = function (user) {
return;
}
this.logger.log("[login] " + user.longip + " (" + user.getName() + ") " +
this.logger.log("[login] " + user.displayip + " (" + user.getName() + ") " +
"disconnected.");
user.channel = null;
/* Should be unnecessary because partUser only occurs if the socket dies */
@ -412,7 +426,7 @@ Channel.prototype.packUserData = function (user) {
muted: user.is(Flags.U_MUTED),
smuted: user.is(Flags.U_SMUTED),
aliases: user.account.aliases,
ip: util.maskIP(user.longip)
ip: user.displayip
}
};
@ -425,7 +439,7 @@ Channel.prototype.packUserData = function (user) {
muted: user.is(Flags.U_MUTED),
smuted: user.is(Flags.U_SMUTED),
aliases: user.account.aliases,
ip: user.ip
ip: user.realip
}
};
@ -534,7 +548,7 @@ Channel.prototype.sendUserJoin = function (users, user) {
user.account.aliases.join(",") + ")", 2);
};
Channel.prototype.readLog = function (shouldMaskIP, cb) {
Channel.prototype.readLog = function (cb) {
var maxLen = 102400;
var file = this.logger.filename;
this.activeLock.lock();
@ -558,16 +572,6 @@ Channel.prototype.readLog = function (shouldMaskIP, cb) {
buffer += data;
});
read.on("end", function () {
if (shouldMaskIP) {
buffer = buffer.replace(
/(?:^|\s)(\d+\.\d+\.\d+)\.\d+/g,
"$1.x"
).replace(
/(?:^|\s)((?:[0-9a-f]+:){3}[0-9a-f]+):(?:[0-9a-f]+:){3}[0-9a-f]+/g,
"$1:x:x:x:x"
);
}
cb(null, buffer);
self.activeLock.release();
});
@ -589,7 +593,7 @@ Channel.prototype.handleReadLog = function (user) {
}
var shouldMaskIP = user.account.globalRank < 255;
this.readLog(shouldMaskIP, function (err, data) {
this.readLog(function (err, data) {
if (err) {
user.socket.emit("readChanLog", {
success: false,

View file

@ -24,36 +24,48 @@ function KickBanModule(channel) {
KickBanModule.prototype = Object.create(ChannelModule.prototype);
function checkIPBan(cname, ip, cb) {
db.channels.isIPBanned(cname, ip, function (err, banned) {
if (err) {
cb(false);
} else {
cb(banned);
}
});
}
function checkNameBan(cname, name, cb) {
db.channels.isNameBanned(cname, name, function (err, banned) {
if (err) {
cb(false);
} else {
cb(banned);
}
});
}
KickBanModule.prototype.onUserPreJoin = function (user, data, cb) {
if (!this.channel.is(Flags.C_REGISTERED)) {
return cb(null, ChannelModule.PASSTHROUGH);
}
var cname = this.channel.name;
db.channels.isIPBanned(cname, user.longip, function (err, banned) {
if (err) {
cb(null, ChannelModule.PASSTHROUGH);
} else if (!banned) {
if (user.is(Flags.U_LOGGED_IN)) {
checkNameBan();
} else {
cb(null, ChannelModule.PASSTHROUGH);
}
} else {
checkIPBan(cname, user.realip, function (banned) {
if (banned) {
cb(null, ChannelModule.DENY);
user.kick("Your IP address is banned from this channel.");
} else {
checkNameBan(cname, user.getName(), function (banned) {
if (banned) {
cb(null, ChannelModule.DENY);
user.kick("Your username is banned from this channel.");
} else {
cb(null, ChannelModule.PASSTHROUGH);
}
});
}
});
function checkNameBan() {
db.channels.isNameBanned(cname, user.getName(), function (err, banned) {
if (err) {
cb(null, ChannelModule.PASSTHROUGH);
} else {
cb(null, banned ? ChannelModule.DENY : ChannelModule.PASSTHROUGH);
}
});
}
};
KickBanModule.prototype.onUserPostJoin = function (user) {
@ -98,7 +110,7 @@ KickBanModule.prototype.sendBanlist = function (users) {
for (var i = 0; i < banlist.length; i++) {
bans.push({
id: banlist[i].id,
ip: banlist[i].ip === "*" ? "*" : util.maskIP(banlist[i].ip),
ip: banlist[i].ip === "*" ? "*" : util.cloakIP(banlist[i].ip),
name: banlist[i].name,
reason: banlist[i].reason,
bannedby: banlist[i].bannedby
@ -381,7 +393,7 @@ KickBanModule.prototype.kickBanTarget = function (name, ip) {
name = name.toLowerCase();
for (var i = 0; i < this.channel.users.length; i++) {
if (this.channel.users[i].getLowerName() === name ||
this.channel.users[i].longip === ip) {
this.channel.users[i].realip === ip) {
this.channel.users[i].kick("You're banned!");
}
}

View file

@ -22,7 +22,8 @@ function OptionsModule(channel) {
show_public: false, // List the channel on the index page
enable_link_regex: true, // Use the built-in link filter
password: false, // Channel password (false -> no password required for entry)
allow_dupes: false // Allow duplicate videos on the playlist
allow_dupes: false, // Allow duplicate videos on the playlist
torbanned: false // Block connections from Tor exit nodes
};
}
@ -245,6 +246,10 @@ OptionsModule.prototype.handleSetOptions = function (user, data) {
this.opts.allow_dupes = Boolean(data.allow_dupes);
}
if ("torbanned" in data && user.account.effectiveRank >= 3) {
this.opts.torbanned = Boolean(data.torbanned);
}
this.channel.logger.log("[mod] " + user.getName() + " updated channel options");
this.sendOpts(this.channel.users);
};

View file

@ -67,7 +67,7 @@ PollModule.prototype.onUserPostJoin = function (user) {
PollModule.prototype.onUserPart = function(user) {
if (this.poll) {
this.poll.unvote(user.ip);
this.poll.unvote(user.realip);
this.sendPollUpdate(this.channel.users);
}
};
@ -142,7 +142,7 @@ PollModule.prototype.handleVote = function (user, data) {
}
if (this.poll) {
this.poll.vote(user.ip, data.option);
this.poll.vote(user.realip, data.option);
this.sendPollUpdate(this.channel.users);
}
};

View file

@ -19,7 +19,7 @@ VoteskipModule.prototype.onUserPart = function(user) {
return;
}
this.unvote(user.ip);
this.unvote(user.realip);
this.update();
};
@ -40,7 +40,7 @@ VoteskipModule.prototype.handleVoteskip = function (user) {
this.poll = new Poll("[server]", "voteskip", ["skip"], false);
}
this.poll.vote(user.ip, 0);
this.poll.vote(user.realip, 0);
var title = "";
if (this.channel.modules.playlist.current) {