From 9b9db35e3ce5af06bc145ea7d891b570ab04c054 Mon Sep 17 00:00:00 2001 From: Pavel Djundik Date: Wed, 19 Feb 2020 12:18:47 +0200 Subject: [PATCH] Implement basic STS reconnection --- src/client.js | 1 + src/plugins/irc-events/cap.js | 65 +++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 src/plugins/irc-events/cap.js diff --git a/src/client.js b/src/client.js index c126aba7..6cb313ff 100644 --- a/src/client.js +++ b/src/client.js @@ -22,6 +22,7 @@ module.exports = Client; const events = [ "away", + "cap", "connection", "unhandled", "ctcp", diff --git a/src/plugins/irc-events/cap.js b/src/plugins/irc-events/cap.js new file mode 100644 index 00000000..b477b1ab --- /dev/null +++ b/src/plugins/irc-events/cap.js @@ -0,0 +1,65 @@ +"use strict"; + +const Msg = require("../../models/msg"); + +module.exports = function(irc, network) { + const client = this; + + irc.on("cap ls", (data) => { + handleSTS(data); + }); + + irc.on("cap new", (data) => { + handleSTS(data); + }); + + function handleSTS(data) { + if (!Object.prototype.hasOwnProperty.call(data.capabilities, "sts")) { + return; + } + + const isSecure = irc.connection.transport.socket.encrypted; + const values = {}; + + data.capabilities.sts.split(",").map((value) => { + value = value.split("=", 2); + values[value[0]] = value[1]; + }); + + if (isSecure) { + // TODO: store and update duration + } else { + const port = parseInt(values.port, 10); + + if (isNaN(port)) { + return; + } + + network.channels[0].pushMessage( + client, + new Msg({ + text: `Server sent a strict transport security policy, reconnecting to port ${port}…`, + }), + true + ); + + // Forcefully end the connection + irc.connection.end(); + + // Update the port + network.port = port; + irc.options.port = port; + + // Enable TLS + network.tls = true; + network.rejectUnauthorized = true; + irc.options.tls = true; + irc.options.rejectUnauthorized = true; + + // Start a new connection + irc.connect(); + + client.save(); + } + } +};