Added support for multiple login 3FA keys.
Ylian Saint-Hilaire committed
Nov 25, 2019 at 14:30 UTC
87411b099ee600e3df8f134a697b3d7265897154
3 files changed
+30
-28
meshcentral.js
+1
@@ -722,6 +722,7 @@ function CreateMeshCentralServer(config, args) {
722
if (obj.config.domains[i].limits == null) { obj.config.domains[i].limits = {}; }
723
if (obj.config.domains[i].dns == null) { obj.config.domains[i].url = (i == '') ? '/' : ('/' + i + '/'); } else { obj.config.domains[i].url = '/'; }
724
obj.config.domains[i].id = i;
725
+ if (typeof obj.config.domains[i].loginkey == 'string') { obj.config.domains[i].loginkey = [obj.config.domains[i].loginkey]; }
726
if (typeof obj.config.domains[i].userallowedip == 'string') { if (obj.config.domains[i].userallowedip == '') { obj.config.domains[i].userallowedip = null; } else { obj.config.domains[i].userallowedip = obj.config.domains[i].userallowedip.split(','); } }
727
if (typeof obj.config.domains[i].userblockedip == 'string') { if (obj.config.domains[i].userblockedip == '') { obj.config.domains[i].userblockedip = null; } else { obj.config.domains[i].userblockedip = obj.config.domains[i].userallowedip.split(','); } }
728
if (typeof obj.config.domains[i].agentallowedip == 'string') { if (obj.config.domains[i].agentallowedip == '') { obj.config.domains[i].agentallowedip = null; } else { obj.config.domains[i].agentallowedip = obj.config.domains[i].agentallowedip.split(','); } }
views/default.handlebars
+12
-11
@@ -114,7 +114,6 @@
114
<td tabindex=0 id=MainMenuMyFiles class="topbar_td style3x" onclick=go(5,event) onkeypress="if (event.key == 'Enter') go(5)">My Files</td>
115
<td tabindex=0 id=MainMenuMyUsers class="topbar_td style3x" onclick=go(4,event) onkeypress="if (event.key == 'Enter') go(4)">My Users</td>
116
<td tabindex=0 id=MainMenuMyServer class="topbar_td style3x" onclick=go(6,event) onkeypress="if (event.key == 'Enter') go(6)">My Server</td>
117
- <!-- <td tabindex=0 id=MainMenuMyPlugins class="topbar_td style3x" onclick=go(7,event) onkeypress="if (event.key == 'Enter') go(7)">My Plugins</td> -->
117
<td class="topbar_td_end style3"> </td>
118
</tr>
119
</table>
@@ -163,15 +162,6 @@
162
</tr>
163
</table>
164
</div>
166
- <!--
167
- <div id=PluginSubMenuSpan>
168
- <table id=PluginSubMenu cellpadding=0 cellspacing=0 class=style1>
169
- <tr>
170
- <td onclick="goPlugin(-1)" onkeypress="if (event.key == 'Enter') goPlugin(-1)" class="topbar_td style3x">Home</td>
171
- </tr>
172
- </table>
173
- </div>
174
- -->
165
<div id=UserDummyMenuSpan>
166
<table id=UserDummyMenu cellpadding=0 cellspacing=0 class=style1>
167
<tr><td class=style3 style=""> </td></tr>
@@ -9422,6 +9412,7 @@
9412
// My Server
9413
if ((x == 6) || (x == 115)) QC('MainMenuMyServer').add(mainMenuActiveClass);
9414
if ((x == 6) || (x == 115) || (x == 40) || (x == 41) || (x == 42)) QC('LeftMenuMyServer').add(leftMenuActiveClass);
9415
+ QV('ServerPlugins', pluginHandler != null);
9416
9417
// column_l max-height
9418
if (webPageStackMenu && (x >= 10)) { QC('column_l').add('room4submenu'); } else { QC('column_l').remove('room4submenu'); }
@@ -9470,8 +9461,12 @@
9461
}
9462
}
9463
9473
- // Plugin
9464
+ //
9465
+ // Plugin Management
9466
+ //
9467
+
9468
function updatePluginList(versInfo) {
9469
+ if (pluginHandler == null) return;
9470
if (Array.isArray(versInfo)) { versInfo.forEach(function(v) { updatePluginList(v); }); }
9471
QV('pluginNoneNotice', installedPluginList.length == 0);
9472
if (installedPluginList.length) {
@@ -9562,15 +9557,18 @@
9557
}
9558
9559
function refreshPluginLatest() {
9560
+ if (pluginHandler == null) return;
9561
meshserver.send({ action: 'pluginLatestCheck' });
9562
}
9563
9564
function distributeCore() {
9565
+ if (pluginHandler == null) return;
9566
meshserver.send({ action: 'distributeCore', nodes: nodes }); // All nodes the user has access to
9567
QV('pluginRestartNotice', false);
9568
}
9569
9570
function pluginActionEx() {
9571
+ if (pluginHandler == null) return;
9572
var act = Q('lastPluginAct').value, id = Q('lastPluginId').value, pVersUrl = Q('lastPluginVersion').value;
9573
9574
switch(act) {
@@ -9595,6 +9593,7 @@
9593
}
9594
9595
function pluginAction(elem, id) {
9596
+ if (pluginHandler == null) return;
9597
if (elem.value == 'downgrade') {
9598
meshserver.send({ 'action': 'getpluginversions', 'id': id });
9599
} else {
@@ -9606,6 +9605,7 @@
9605
}
9606
9607
function goPlugin(pname, title) {
9608
+ if (pluginHandler == null) return;
9609
/*
9610
let holder = Q('PluginSubMenu').querySelectorAll('tr')[0];
9611
let loadedPluginsTDs = holder.querySelectorAll('td');
@@ -9661,6 +9661,7 @@
9661
}
9662
9663
function noGoPlugin(el) {
9664
+ if (pluginHandler == null) return;
9665
/*
9666
QV('PluginSubMenuSpan', false);
9667
let loadedPluginsTDs = Q('PluginSubMenu').querySelectorAll('td');
webserver.js
+17
-17
@@ -497,7 +497,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
497
function handleLogoutRequest(req, res) {
498
const domain = checkUserIpAddress(req, res);
499
if ((domain == null) || (domain.auth == 'sspi')) { parent.debug('web', 'handleLogoutRequest: failed checks.'); res.sendStatus(404); return; }
500
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
500
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
501
502
res.set({ 'Cache-Control': 'no-cache, no-store, must-revalidate', 'Pragma': 'no-cache', 'Expires': '0' });
503
// Destroy the user's session to log them out will be re-created next request
@@ -635,7 +635,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
635
function handleLoginRequest(req, res, direct) {
636
const domain = checkUserIpAddress(req, res);
637
if (domain == null) { parent.debug('web', 'handleLoginRequest: invalid domain'); res.sendStatus(404); return; }
638
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
638
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
639
640
// Check if this is a banned ip address
641
if (obj.checkAllowLogin(req) == false) {
@@ -789,7 +789,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
789
function handleCreateAccountRequest(req, res, direct) {
790
const domain = checkUserIpAddress(req, res);
791
if ((domain == null) || (domain.auth == 'sspi') || (domain.auth == 'ldap')) { parent.debug('web', 'handleCreateAccountRequest: failed checks.'); res.sendStatus(404); return; }
792
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
792
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
793
794
// Always lowercase the email address
795
if (req.body.email) { req.body.email = req.body.email.toLowerCase(); }
@@ -900,7 +900,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
900
// Called to process an account password reset
901
function handleResetPasswordRequest(req, res, direct) {
902
const domain = checkUserIpAddress(req, res);
903
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
903
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
904
905
// Check everything is ok
906
if ((domain == null) || (domain.auth == 'sspi') || (domain.auth == 'ldap') || (typeof req.body.rpassword1 != 'string') || (typeof req.body.rpassword2 != 'string') || (req.body.rpassword1 != req.body.rpassword2) || (typeof req.body.rpasswordhint != 'string') || (req.session == null) || (typeof req.session.resettokenusername != 'string') || (typeof req.session.resettokenpassword != 'string')) {
@@ -984,7 +984,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
984
function handleResetAccountRequest(req, res, direct) {
985
const domain = checkUserIpAddress(req, res);
986
if ((domain == null) || (domain.auth == 'sspi') || (domain.auth == 'ldap') || (obj.args.lanonly == true) || (obj.parent.certificates.CommonName == null) || (obj.parent.certificates.CommonName.indexOf('.') == -1)) { parent.debug('web', 'handleResetAccountRequest: check failed'); res.sendStatus(404); return; }
987
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
987
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
988
989
// Always lowercase the email address
990
if (req.body.email) { req.body.email = req.body.email.toLowerCase(); }
@@ -1077,7 +1077,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1077
function handleCheckMailRequest(req, res) {
1078
const domain = checkUserIpAddress(req, res);
1079
if ((domain == null) || (domain.auth == 'sspi') || (domain.auth == 'ldap')) { parent.debug('web', 'handleCheckMailRequest: failed checks.'); res.sendStatus(404); return; }
1080
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
1080
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
1081
1082
if (req.query.c != null) {
1083
var cookie = obj.parent.decodeCookie(req.query.c, obj.parent.mailserver.mailCookieEncryptionKey, 30);
@@ -1179,7 +1179,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1179
function handleAgentInviteRequest(req, res) {
1180
const domain = getDomain(req);
1181
if ((domain == null) || ((req.query.m == null) && (req.query.c == null))) { parent.debug('web', 'handleAgentInviteRequest: failed checks.'); res.sendStatus(404); return; }
1182
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
1182
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
1183
1184
if (req.query.c != null) {
1185
// A cookie is specified in the query string, use that
@@ -1207,7 +1207,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1207
parent.debug('web', 'handleDeleteAccountRequest()');
1208
const domain = checkUserIpAddress(req, res);
1209
if ((domain == null) || (domain.auth == 'sspi') || (domain.auth == 'ldap')) { parent.debug('web', 'handleDeleteAccountRequest: failed checks.'); res.sendStatus(404); return; }
1210
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
1210
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
1211
1212
var user = null;
1213
if (req.body.authcookie) {
@@ -1294,7 +1294,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1294
function handlePasswordChangeRequest(req, res, direct) {
1295
const domain = checkUserIpAddress(req, res);
1296
if ((domain == null) || (domain.auth == 'sspi') || (domain.auth == 'ldap')) { parent.debug('web', 'handlePasswordChangeRequest: failed checks (1).'); res.sendStatus(404); return; }
1297
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
1297
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
1298
1299
// Check if the user is logged and we have all required parameters
1300
if (!req.session || !req.session.userid || !req.body.apassword0 || !req.body.apassword1 || (req.body.apassword1 != req.body.apassword2) || (req.session.domainid != domain.id)) {
@@ -1335,7 +1335,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1335
function handleRootRequest(req, res, direct) {
1336
const domain = checkUserIpAddress(req, res);
1337
if (domain == null) { parent.debug('web', 'handleRootRequest: invalid domain.'); res.sendStatus(404); return; }
1338
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
1338
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
1339
if (!obj.args) { parent.debug('web', 'handleRootRequest: no obj.args.'); res.sendStatus(500); return; }
1340
1341
if ((domain.sspi != null) && ((req.query.login == null) || (obj.parent.loginCookieEncryptionKey == null))) {
@@ -1607,7 +1607,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1607
function handleRootPostRequest(req, res) {
1608
const domain = checkUserIpAddress(req, res);
1609
if (domain == null) { parent.debug('web', 'handleTermsRequest: Bad domain'); res.sendStatus(404); return; }
1610
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
1610
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
1611
parent.debug('web', 'handleRootPostRequest, action: ' + req.body.action);
1612
1613
switch (req.body.action) {
@@ -1651,7 +1651,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1651
function handleTermsRequest(req, res) {
1652
const domain = checkUserIpAddress(req, res);
1653
if (domain == null) { parent.debug('web', 'handleTermsRequest: Bad domain'); res.sendStatus(404); return; }
1654
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
1654
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
1655
1656
// See if term.txt was loaded from the database
1657
if ((parent.configurationFiles != null) && (parent.configurationFiles['terms.txt'] != null)) {
@@ -1731,7 +1731,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1731
function handleRootCertRequest(req, res) {
1732
const domain = getDomain(req);
1733
if (domain == null) { parent.debug('web', 'handleRootCertRequest: no domain'); res.sendStatus(404); return; }
1734
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
1734
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
1735
if ((obj.userAllowedIp != null) && (checkIpAddressEx(req, res, obj.userAllowedIp, false) === false)) { parent.debug('web', 'handleRootCertRequest: invalid ip'); return; } // Check server-wide IP filter only.
1736
parent.debug('web', 'handleRootCertRequest()');
1737
try {
@@ -1828,7 +1828,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1828
function handleMeScriptRequest(req, res) {
1829
const domain = getDomain(req);
1830
if (domain == null) { parent.debug('web', 'handleMeScriptRequest: no domain'); res.sendStatus(404); return; }
1831
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
1831
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
1832
1833
if ((obj.userAllowedIp != null) && (checkIpAddressEx(req, res, obj.userAllowedIp, false) === false)) { return; } // Check server-wide IP filter only.
1834
if (req.query.type == 1) {
@@ -1857,7 +1857,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1857
function handleDownloadUserFiles(req, res) {
1858
const domain = checkUserIpAddress(req, res);
1859
if (domain == null) { res.sendStatus(404); return; }
1860
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
1860
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
1861
1862
if (obj.common.validateString(req.path, 1, 4096) == false) { res.sendStatus(404); return; }
1863
var domainname = 'domain', spliturl = decodeURIComponent(req.path).split('/'), filename = '';
@@ -2812,7 +2812,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2812
function handleBackupRequest(req, res) {
2813
const domain = checkUserIpAddress(req, res);
2814
if (domain == null) { res.sendStatus(404); return; }
2815
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
2815
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
2816
if ((!req.session) || (req.session == null) || (!req.session.userid) || (obj.parent.args.noserverbackup == 1)) { res.sendStatus(401); return; }
2817
var user = obj.users[req.session.userid];
2818
if ((user == null) || ((user.siteadmin & 1) == 0)) { res.sendStatus(401); return; } // Check if we have server backup rights
@@ -2845,7 +2845,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
2845
function handleRestoreRequest(req, res) {
2846
const domain = checkUserIpAddress(req, res);
2847
if (domain == null) { res.sendStatus(404); return; }
2848
- if ((domain.loginkey != null) && (domain.loginkey != req.query.key)) { res.sendStatus(404); return; } // Check 3FA URL key
2848
+ if ((domain.loginkey != null) && (domain.loginkey.indexOf(req.query.key) == -1)) { res.sendStatus(404); return; } // Check 3FA URL key
2849
if (obj.parent.args.noserverbackup == 1) { res.sendStatus(401); return; }
2850
var authUserid = null;
2851
if ((req.session != null) && (typeof req.session.userid == 'string')) { authUserid = req.session.userid; }