Web-SSH fixes and improvements.
Ylian Saint-Hilaire committed
May 19, 2022 at 14:41 UTC
9c52cc4d8c0eaef25796e1da86cac6fae43fc64c
2 files changed
+27
-18
apprelays.js
+12
-11
@@ -604,24 +604,24 @@ module.exports.CreateSshRelay = function (parent, db, ws, req, args, domain) {
604
parent.parent.db.Get(obj.cookie.nodeid, function (err, nodes) {
605
if ((err != null) || (nodes == null) || (nodes.length != 1)) return;
606
const node = nodes[0];
607
- if ((domain.allowsavingdevicecredentials === false) || (node.ssh == null) || (typeof node.ssh != 'object') || (node.ssh[user._id] == null) || (typeof node.ssh[user._id].u != 'string') || ((typeof node.ssh[user._id].p != 'string') && (typeof node.ssh[user._id].k != 'string'))) {
607
+ if ((domain.allowsavingdevicecredentials === false) || (node.ssh == null) || (typeof node.ssh != 'object') || (node.ssh[obj.userid] == null) || (typeof node.ssh[obj.userid].u != 'string') || ((typeof node.ssh[obj.userid].p != 'string') && (typeof node.ssh[obj.userid].k != 'string'))) {
608
// Send a request for SSH authentication
609
try { ws.send(JSON.stringify({ action: 'sshauth' })) } catch (ex) { }
610
- } else if ((domain.allowsavingdevicecredentials !== false) && (node.ssh != null) && (typeof node.ssh[user._id].k == 'string') && (node.ssh[user._id].kp == null)) {
610
+ } else if ((domain.allowsavingdevicecredentials !== false) && (node.ssh != null) && (typeof node.ssh[obj.userid].k == 'string') && (node.ssh[obj.userid].kp == null)) {
611
// Send a request for SSH authentication with option for only the private key password
612
- obj.username = node.ssh[user._id].u;
613
- obj.privateKey = node.ssh[user._id].k;
612
+ obj.username = node.ssh[obj.userid].u;
613
+ obj.privateKey = node.ssh[obj.userid].k;
614
try { ws.send(JSON.stringify({ action: 'sshauth', askkeypass: true })) } catch (ex) { }
615
} else {
616
// Use our existing credentials
617
obj.termSize = msg;
618
delete obj.keep;
619
- obj.username = node.ssh[user._id].u;
620
- if (typeof node.ssh[user._id].p == 'string') {
621
- obj.password = node.ssh[user._id].p;
622
- } else if (typeof node.ssh[user._id].k == 'string') {
623
- obj.privateKey = node.ssh[user._id].k;
624
- obj.privateKeyPass = node.ssh[user._id].kp;
619
+ obj.username = node.ssh[obj.userid].u;
620
+ if (typeof node.ssh[obj.userid].p == 'string') {
621
+ obj.password = node.ssh[obj.userid].p;
622
+ } else if (typeof node.ssh[obj.userid].k == 'string') {
623
+ obj.privateKey = node.ssh[obj.userid].k;
624
+ obj.privateKeyPass = node.ssh[obj.userid].kp;
625
}
626
startRelayConnection();
627
}
@@ -686,7 +686,8 @@ module.exports.CreateSshRelay = function (parent, db, ws, req, args, domain) {
686
687
// Decode the authentication cookie
688
obj.cookie = parent.parent.decodeCookie(req.query.auth, parent.parent.loginCookieEncryptionKey);
689
- if (obj.cookie == null) { obj.ws.send(JSON.stringify({ action: 'sessionerror' })); obj.close(); return; }
689
+ if ((obj.cookie == null) || (obj.cookie.userid == null) || (parent.users[obj.cookie.userid] == null)) { obj.ws.send(JSON.stringify({ action: 'sessionerror' })); obj.close(); return; }
690
+ obj.userid = obj.cookie.userid;
691
692
// Get the meshid for this device
693
parent.parent.db.Get(obj.cookie.nodeid, function (err, nodes) {
webserver.js
+15
-7
@@ -6842,7 +6842,9 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6842
}
6843
});
6844
return;
6845
- } else if ((req.query.auth != null) && (req.query.auth != '')) {
6845
+ }
6846
+
6847
+ if ((req.query.auth != null) && (req.query.auth != '')) {
6848
// This is a encrypted cookie authentication
6849
var cookie = obj.parent.decodeCookie(req.query.auth, obj.parent.loginCookieEncryptionKey, 60); // Cookie with 1 hour timeout
6850
if ((cookie == null) && (obj.parent.multiServer != null)) { cookie = obj.parent.decodeCookie(req.query.auth, obj.parent.serverKey, 60); } // Try the server key
@@ -6853,20 +6855,26 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6855
if ((cookie != null) && (cookie.userid != null) && (obj.users[cookie.userid]) && (cookie.domainid == domain.id) && (cookie.userid.split('/')[1] == domain.id)) {
6856
// Valid cookie, we are authenticated. Cookie of format { userid: 'user//name', domain: '' }
6857
func(ws, req, domain, obj.users[cookie.userid], cookie);
6858
+ return;
6859
} else if ((cookie != null) && (cookie.a === 3) && (typeof cookie.u == 'string') && (obj.users[cookie.u]) && (cookie.u.split('/')[1] == domain.id)) {
6860
// Valid cookie, we are authenticated. Cookie of format { u: 'user//name', a: 3 }
6861
func(ws, req, domain, obj.users[cookie.u], cookie);
6862
+ return;
6863
} else if ((cookie != null) && (cookie.nouser === 1)) {
6864
// This is a valid cookie, but no user. This is used for agent self-sharing.
6865
func(ws, req, domain, null, cookie);
6862
- } else {
6866
+ return;
6867
+ } /*else {
6868
// This is a bad cookie, keep going anyway, maybe we have a active session that will save us.
6869
if ((cookie != null) && (cookie.domainid != domain.id)) { parent.debug('web', 'ERR: Invalid domain, got \"' + cookie.domainid + '\", expected \"' + domain.id + '\".'); }
6870
parent.debug('web', 'ERR: Websocket bad cookie auth (Cookie:' + (cookie != null) + '): ' + req.query.auth);
6871
try { ws.send(JSON.stringify({ action: 'close', cause: 'noauth', msg: 'noauth-2b' })); ws.close(); } catch (e) { }
6872
+ return;
6873
}
6868
- return;
6869
- } else if (req.headers['x-meshauth'] != null) {
6874
+ */
6875
+ }
6876
+
6877
+ if (req.headers['x-meshauth'] != null) {
6878
// This is authentication using a custom HTTP header
6879
var s = req.headers['x-meshauth'].split(',');
6880
for (var i in s) { s[i] = Buffer.from(s[i], 'base64').toString(); }
@@ -6954,13 +6962,13 @@ module.exports.CreateWebServer = function (parent, db, args, certificates, doneF
6962
return;
6963
}
6964
6957
- //console.log(req.headers['x-meshauth']);
6958
-
6965
if (obj.args.user && obj.users['user/' + domain.id + '/' + obj.args.user.toLowerCase()]) {
6966
// A default user is active
6967
func(ws, req, domain, obj.users['user/' + domain.id + '/' + obj.args.user.toLowerCase()]);
6968
return;
6963
- } else if (req.session && (req.session.userid != null) && (req.session.userid.split('/')[1] == domain.id) && (obj.users[req.session.userid])) {
6969
+ }
6970
+
6971
+ if (req.session && (req.session.userid != null) && (req.session.userid.split('/')[1] == domain.id) && (obj.users[req.session.userid])) {
6972
// This user is logged in using the ExpressJS session
6973
func(ws, req, domain, obj.users[req.session.userid]);
6974
return;