More FIDO2 fixes.
Ylian Saint-Hilaire committed
Mar 25, 2019 at 14:43 UTC
b8a0512f839dabd0ae51abf3ec97f72ffa0acc79
4 files changed
+36
-28
package.json
+1
-1
@@ -1,6 +1,6 @@
1
{
2
"name": "meshcentral",
3
- "version": "0.3.0-y",
3
+ "version": "0.3.0-z",
4
"keywords": [
5
"Remote Management",
6
"Intel AMT",
views/login-mobile.handlebars
+1
-1
@@ -260,7 +260,7 @@
260
var passRequirements = "{{{passRequirements}}}";
261
if (passRequirements != "") { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
262
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
263
- var hardwareKeyChallenge = '{{{hkey}}}';
263
+ var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
264
var currentpanel = 0;
265
266
function startup() {
views/login.handlebars
+2
-2
@@ -110,7 +110,7 @@
110
<div id="welcomeText" style="display:none">Connect to your home or office devices from anywhere in the world using <a href="http://www.meshcommander.com/meshcentral2">MeshCentral</a>, the real time, open source remote monitoring and management web site. You will need to download and install a management agent on your computers. Once installed, computers will show up in the "My Devices" section of this web site and you will be able to monitor them and take control of them.</div>
111
<table id="centralTable" style=width:100%>
112
<tr>
113
- <td id="welcomeimage" align="right">
113
+ <td id="welcomeimage" align="right" style="display:none">
114
<picture>
115
<img alt="" width=359 height=310 src=welcome.jpg />
116
</picture>
@@ -332,7 +332,7 @@
332
var newAccountPass = parseInt('{{{newAccountPass}}}');
333
var emailCheck = ('{{{emailcheck}}}' == 'true');
334
var passRequirements = "{{{passRequirements}}}";
335
- var hardwareKeyChallenge = '{{{hkey}}}';
335
+ var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
336
if (passRequirements != "") { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
337
var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
338
var features = parseInt('{{{features}}}');
webserver.js
+32
-24
@@ -396,7 +396,11 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
396
for (var i = 0; i < user.otphkeys.length; i++) { if (user.otphkeys[i].type == 1) { u2fKeys.push(user.otphkeys[i]); } }
397
if (u2fKeys.length > 0) {
398
// Check authentication response
399
- require('authdog').finishAuthentication(req.session.u2fchallenge, authResponse, u2fKeys).then(function (authenticationStatus) { func(true); }, function (error) { func(false); });
399
+ var authdoglib = null;
400
+ try { authdoglib = require('authdog'); } catch (ex) { }
401
+ if (authdoglib == null) { func(false); } else {
402
+ authdoglib.finishAuthentication(req.session.u2fchallenge, authResponse, u2fKeys).then(function (authenticationStatus) { func(true); }, function (error) { console.log(error); func(false); });
403
+ }
404
return;
405
}
406
}
@@ -458,24 +462,28 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
462
}
463
}
464
461
- // Get all U2F keys
462
- var u2fKeys = [];
463
- for (var i = 0; i < user.otphkeys.length; i++) { if (user.otphkeys[i].type == 1) { u2fKeys.push(user.otphkeys[i]); } }
464
-
465
- // Generate a U2F challenge
466
- if (u2fKeys.length > 0) {
467
- require('authdog').startAuthentication('https://' + obj.parent.certificates.CommonName, u2fKeys, { requestId: 0, timeoutSeconds: 60 }).then(function (registrationRequest) {
468
- // Save authentication request to session for later use
469
- req.session.u2fchallenge = registrationRequest;
470
-
471
- // Send authentication request to client
472
- func(JSON.stringify(registrationRequest));
473
- }, function (error) {
474
- // Handle authentication request error
465
+ var authdoglib = null;
466
+ try { authdoglib = require('authdog'); } catch (ex) { }
467
+ if (authdoglib != null) {
468
+ // Get all U2F keys
469
+ var u2fKeys = [];
470
+ for (var i = 0; i < user.otphkeys.length; i++) { if (user.otphkeys[i].type == 1) { u2fKeys.push(user.otphkeys[i]); } }
471
+
472
+ // Generate a U2F challenge
473
+ if (u2fKeys.length > 0) {
474
+ authdoglib.startAuthentication('https://' + obj.parent.certificates.CommonName, u2fKeys, { requestId: 0, timeoutSeconds: 60 }).then(function (registrationRequest) {
475
+ // Save authentication request to session for later use
476
+ req.session.u2fchallenge = registrationRequest;
477
+
478
+ // Send authentication request to client
479
+ func(JSON.stringify(registrationRequest));
480
+ }, function (error) {
481
+ // Handle authentication request error
482
+ func('');
483
+ });
484
+ } else {
485
func('');
476
- });
477
- } else {
478
- func('');
486
+ }
487
}
488
} else {
489
func('');
@@ -1187,9 +1195,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1195
// If this is a 2 factor auth request, look for a hardware key challenge.
1196
// Normal login 2 factor request
1197
if ((req.session.loginmode == '4') && (req.session.tokenusername)) {
1190
- var user = obj.users['user/' + domain.id + '/' + req.session.tokenusername];
1198
+ var user = obj.users['user/' + domain.id + '/' + req.session.tokenusername.toLowerCase()];
1199
if (user != null) {
1192
- getHardwareKeyChallenge(req, domain, user, function (u2fChallenge) { handleRootRequestLogin(req, res, domain, u2fChallenge, passRequirements); });
1200
+ getHardwareKeyChallenge(req, domain, user, function (hwchallenge) { handleRootRequestLogin(req, res, domain, hwchallenge, passRequirements); });
1201
return;
1202
}
1203
}
@@ -1202,7 +1210,7 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1210
} else {
1211
var user = obj.users[docs[0]._id];
1212
if (user != null) {
1205
- getHardwareKeyChallenge(req, domain, user, function (u2fChallenge) { handleRootRequestLogin(req, res, domain, u2fChallenge, passRequirements); });
1213
+ getHardwareKeyChallenge(req, domain, user, function (hwchallenge) { handleRootRequestLogin(req, res, domain, hwchallenge, passRequirements); });
1214
} else {
1215
req.session = null;
1216
res.redirect(domain.url);
@@ -1240,14 +1248,14 @@ module.exports.CreateWebServer = function (parent, db, args, certificates) {
1248
if (obj.args.minify && !req.query.nominify) {
1249
// Try to server the minified version if we can.
1250
try {
1243
- res.render(obj.path.join(obj.parent.webViewsPath, isMobileBrowser(req) ? 'login-mobile-min' : 'login-min'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, footer: (domain.footer == null) ? '' : domain.footer, hkey: hardwareKeyChallenge, message: message, passhint: passhint, welcometext: domain.welcometext?encodeURIComponent(domain.welcometext):null });
1251
+ res.render(obj.path.join(obj.parent.webViewsPath, isMobileBrowser(req) ? 'login-mobile-min' : 'login-min'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, footer: (domain.footer == null) ? '' : domain.footer, hkey: encodeURIComponent(hardwareKeyChallenge), message: message, passhint: passhint, welcometext: domain.welcometext?encodeURIComponent(domain.welcometext):null });
1252
} catch (ex) {
1253
// In case of an exception, serve the non-minified version.
1246
- res.render(obj.path.join(obj.parent.webViewsPath, isMobileBrowser(req) ? 'login-mobile' : 'login'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, footer: (domain.footer == null) ? '' : domain.footer, hkey: hardwareKeyChallenge, message: message, passhint: passhint, welcometext: domain.welcometext ? encodeURIComponent(domain.welcometext) : null });
1254
+ res.render(obj.path.join(obj.parent.webViewsPath, isMobileBrowser(req) ? 'login-mobile' : 'login'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, footer: (domain.footer == null) ? '' : domain.footer, hkey: encodeURIComponent(hardwareKeyChallenge), message: message, passhint: passhint, welcometext: domain.welcometext ? encodeURIComponent(domain.welcometext) : null });
1255
}
1256
} else {
1257
// Serve non-minified version of web pages.
1250
- res.render(obj.path.join(obj.parent.webViewsPath, isMobileBrowser(req) ? 'login-mobile' : 'login'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, footer: (domain.footer == null) ? '' : domain.footer, hkey: hardwareKeyChallenge, message: message, passhint: passhint, welcometext: domain.welcometext ? encodeURIComponent(domain.welcometext) : null });
1258
+ res.render(obj.path.join(obj.parent.webViewsPath, isMobileBrowser(req) ? 'login-mobile' : 'login'), { loginmode: loginmode, rootCertLink: getRootCertLink(), title: domain.title, title2: domain.title2, newAccount: domain.newaccounts, newAccountPass: (((domain.newaccountspass == null) || (domain.newaccountspass == '')) ? 0 : 1), serverDnsName: obj.getWebServerName(domain), serverPublicPort: httpsPort, emailcheck: emailcheck, features: features, sessiontime: args.sessiontime, passRequirements: passRequirements, footer: (domain.footer == null) ? '' : domain.footer, hkey: encodeURIComponent(hardwareKeyChallenge), message: message, passhint: passhint, welcometext: domain.welcometext ? encodeURIComponent(domain.welcometext) : null });
1259
}
1260
1261
/*