diff --git a/apprelays.js b/apprelays.js
index b274abfa..30466f73 100644
--- a/apprelays.js
+++ b/apprelays.js
@@ -338,7 +338,18 @@ module.exports.CreateSshRelay = function (parent, db, ws, req, args, domain) {
var connectionOptions = { sock: obj.ser }
if (typeof obj.username == 'string') { connectionOptions.username = obj.username; delete obj.username; }
if (typeof obj.password == 'string') { connectionOptions.password = obj.password; delete obj.password; }
- obj.sshClient.connect(connectionOptions);
+ if (typeof obj.privateKey == 'string') { connectionOptions.privateKey = obj.privateKey; delete obj.privateKey; }
+ if (typeof obj.privateKeyPass == 'string') { connectionOptions.passphrase = obj.privateKeyPass; delete obj.privateKeyPass; }
+ try {
+ obj.sshClient.connect(connectionOptions);
+ } catch (ex) {
+ // Exception, this is generally because we did not provide proper credentials. Ask again.
+ obj.relayActive = false;
+ delete obj.sshClient;
+ delete obj.ser.forwardwrite;
+ obj.close();
+ return;
+ }
// We are all set, start receiving data
ws._socket.resume();
@@ -372,6 +383,8 @@ module.exports.CreateSshRelay = function (parent, db, ws, req, args, domain) {
obj.termSize = msg;
obj.username = msg.username;
obj.password = msg.password;
+ obj.privateKey = msg.key;
+ obj.privateKeyPass = msg.keypass;
startRelayConnection();
break;
}
@@ -472,10 +485,14 @@ module.exports.CreateSshTerminalRelay = function (parent, db, ws, req, domain, u
const changed = (node.ssh == null);
// Check if credentials are the same
- if ((typeof node.ssh == 'object') && (node.ssh.u == obj.username) && (node.ssh.p == obj.password)) return;
+ //if ((typeof node.ssh == 'object') && (node.ssh.u == obj.username) && (node.ssh.p == obj.password)) return; // TODO
// Save the credentials
- node.ssh = { u: obj.username, p: obj.password };
+ if (obj.password != null) {
+ node.ssh = { u: obj.username, p: obj.password };
+ } else if (obj.privateKey != null) {
+ node.ssh = { u: obj.username, k: obj.privateKey, kp: obj.privateKeyPass };
+ }
parent.parent.db.Set(node);
// Event node change if needed
@@ -538,7 +555,17 @@ module.exports.CreateSshTerminalRelay = function (parent, db, ws, req, domain, u
var connectionOptions = { sock: obj.ser }
if (typeof obj.username == 'string') { connectionOptions.username = obj.username; }
if (typeof obj.password == 'string') { connectionOptions.password = obj.password; }
- obj.sshClient.connect(connectionOptions);
+ if (typeof obj.privateKey == 'string') { connectionOptions.privateKey = obj.privateKey; }
+ if (typeof obj.privateKeyPass == 'string') { connectionOptions.passphrase = obj.privateKeyPass; }
+ try {
+ obj.sshClient.connect(connectionOptions);
+ } catch (ex) {
+ // Exception, this is generally because we did not provide proper credentials. Ask again.
+ obj.relayActive = false;
+ delete obj.sshClient;
+ delete obj.ser.forwardwrite;
+ try { ws.send(JSON.stringify({ action: 'sshauth' })) } catch (ex) { }
+ }
// We are all set, start receiving data
ws._socket.resume();
@@ -569,13 +596,15 @@ module.exports.CreateSshTerminalRelay = function (parent, db, ws, req, domain, u
switch (msg.action) {
case 'sshauth': {
// Verify inputs
- if ((typeof msg.username != 'string') || (typeof msg.password != 'string')) break;
+ if ((typeof msg.username != 'string') || ((typeof msg.password != 'string') && (typeof msg.key != 'string'))) break;
if ((typeof msg.rows != 'number') || (typeof msg.cols != 'number') || (typeof msg.height != 'number') || (typeof msg.width != 'number')) break;
obj.keep = msg.keep; // If true, keep store credentials on the server if the SSH tunnel connected succesfully.
obj.termSize = msg;
obj.username = msg.username;
obj.password = msg.password;
+ obj.privateKey = msg.key;
+ obj.privateKeyPass = msg.keypass;
// Create a mesh relay authentication cookie
var cookieContent = { userid: user._id, domainid: user.domain, nodeid: obj.nodeid, tcpport: obj.tcpport };
@@ -588,7 +617,7 @@ module.exports.CreateSshTerminalRelay = function (parent, db, ws, req, domain, u
if ((typeof msg.rows != 'number') || (typeof msg.cols != 'number') || (typeof msg.height != 'number') || (typeof msg.width != 'number')) break;
obj.termSize = msg;
- if ((obj.username == null) || (obj.password == null)) return;
+ if ((obj.username == null) || ((obj.password == null) && (obj.privateKey == null))) return;
// Create a mesh relay authentication cookie
var cookieContent = { userid: user._id, domainid: user.domain, nodeid: obj.nodeid, tcpport: obj.tcpport };
@@ -639,13 +668,18 @@ module.exports.CreateSshTerminalRelay = function (parent, db, ws, req, domain, u
if ((err != null) || (nodes == null) || (nodes.length != 1)) return;
const node = nodes[0];
- if ((node.ssh == null) || (typeof node.ssh != 'object') || (typeof node.ssh.u != 'string') || (typeof node.ssh.p != 'string')) {
+ if ((node.ssh == null) || (typeof node.ssh != 'object') || (typeof node.ssh.u != 'string') || ((typeof node.ssh.p != 'string') && (typeof node.ssh.k != 'string'))) {
// Send a request for SSH authentication
try { ws.send(JSON.stringify({ action: 'sshauth' })) } catch (ex) { }
} else {
// Use our existing credentials
obj.username = node.ssh.u;
- obj.password = node.ssh.p;
+ if (typeof node.ssh.p == 'string') {
+ obj.password = node.ssh.p;
+ } else if (typeof node.ssh.k == 'string') {
+ obj.privateKey = node.ssh.k;
+ obj.privateKeyPass = node.ssh.kp;
+ }
try { ws.send(JSON.stringify({ action: 'sshautoauth' })) } catch (ex) { }
}
});
@@ -722,8 +756,15 @@ module.exports.CreateSshFilesRelay = function (parent, db, ws, req, domain, user
const node = nodes[0];
const changed = (node.ssh == null);
+ // Check if credentials are the same
+ //if ((typeof node.ssh == 'object') && (node.ssh.u == obj.username) && (node.ssh.p == obj.password)) return; // TODO
+
// Save the credentials
- node.ssh = { u: obj.username, p: obj.password };
+ if (obj.password != null) {
+ node.ssh = { u: obj.username, p: obj.password };
+ } else if (obj.privateKey != null) {
+ node.ssh = { u: obj.username, k: obj.privateKey, kp: obj.privateKeyPass };
+ }
parent.parent.db.Set(node);
// Event node change if needed
@@ -781,7 +822,17 @@ module.exports.CreateSshFilesRelay = function (parent, db, ws, req, domain, user
var connectionOptions = { sock: obj.ser }
if (typeof obj.username == 'string') { connectionOptions.username = obj.username; }
if (typeof obj.password == 'string') { connectionOptions.password = obj.password; }
- obj.sshClient.connect(connectionOptions);
+ if (typeof obj.privateKey == 'string') { connectionOptions.privateKey = obj.privateKey; }
+ if (typeof obj.privateKeyPass == 'string') { connectionOptions.passphrase = obj.privateKeyPass; }
+ try {
+ obj.sshClient.connect(connectionOptions);
+ } catch (ex) {
+ // Exception, this is generally because we did not provide proper credentials. Ask again.
+ obj.relayActive = false;
+ delete obj.sshClient;
+ delete obj.ser.forwardwrite;
+ try { ws.send(JSON.stringify({ action: 'sshauth' })) } catch (ex) { }
+ }
// We are all set, start receiving data
ws._socket.resume();
@@ -995,11 +1046,13 @@ module.exports.CreateSshFilesRelay = function (parent, db, ws, req, domain, user
if (obj.sshClient != null) return;
// Verify inputs
- if ((typeof msg.username != 'string') || (typeof msg.password != 'string')) break;
+ if ((typeof msg.username != 'string') || ((typeof msg.password != 'string') && (typeof msg.key != 'string'))) break;
obj.keep = (msg.keep === true); // If true, keep store credentials on the server if the SSH tunnel connected succesfully.
obj.username = msg.username;
obj.password = msg.password;
+ obj.privateKey = msg.key;
+ obj.privateKeyPass = msg.keypass;
// Create a mesh relay authentication cookie
var cookieContent = { userid: user._id, domainid: user.domain, nodeid: obj.nodeid, tcpport: obj.tcpport };
@@ -1068,13 +1121,18 @@ module.exports.CreateSshFilesRelay = function (parent, db, ws, req, domain, user
if ((err != null) || (nodes == null) || (nodes.length != 1)) return;
const node = nodes[0];
- if ((node.ssh == null) || (typeof node.ssh != 'object') || (typeof node.ssh.u != 'string') || (typeof node.ssh.p != 'string')) {
+ if ((node.ssh == null) || (typeof node.ssh != 'object') || (typeof node.ssh.u != 'string') || ((typeof node.ssh.p != 'string') && (typeof node.ssh.k != 'string'))) {
// Send a request for SSH authentication
try { ws.send(JSON.stringify({ action: 'sshauth' })) } catch (ex) { }
} else {
// Use our existing credentials
obj.username = node.ssh.u;
- obj.password = node.ssh.p;
+ if (typeof node.ssh.p == 'string') {
+ obj.password = node.ssh.p;
+ } else if (typeof node.ssh.k == 'string') {
+ obj.privateKey = node.ssh.k;
+ obj.privateKeyPass = node.ssh.kp;
+ }
// Create a mesh relay authentication cookie
var cookieContent = { userid: user._id, domainid: user.domain, nodeid: obj.nodeid, tcpport: obj.tcpport };
diff --git a/meshuser.js b/meshuser.js
index 58d6c016..26221cab 100644
--- a/meshuser.js
+++ b/meshuser.js
@@ -717,7 +717,7 @@ module.exports.CreateMeshUser = function (parent, db, ws, req, args, domain, use
if (docs[i].pmt != null) { docs[i].pmt = 1; }
// Remove SSH credentials if present
- if (docs[i].ssh != null) { docs[i].ssh = 1; }
+ if (docs[i].ssh != null) { docs[i].ssh = (docs[i].ssh.k) ? 2 : 1; }
// Remove RDP credentials if present
if (docs[i].rdp != null) { docs[i].rdp = 1; }
diff --git a/views/default-mobile.handlebars b/views/default-mobile.handlebars
index c1ca62f5..7f429dfa 100644
--- a/views/default-mobile.handlebars
+++ b/views/default-mobile.handlebars
@@ -3439,10 +3439,10 @@
if ((node.ssh != null) || (node.rdp != null)) {
var y = [];
if ((meshrights & 4) != 0) {
- if (node.ssh != null) { y.push('' + "SSH" + ' '); }
+ if (node.ssh != null) { y.push('' + ((node.ssh == 2) ? "SSH-Key" : "SSH") + '
'); }
if (node.rdp != null) { y.push('' + "RDP" + '
'); }
} else {
- if (node.ssh != null) { y.push("SSH"); }
+ if (node.ssh != null) { y.push(((node.ssh == 2) ? "SSH-Key" : "SSH")); }
if (node.rdp != null) { y.push("RDP"); }
}
x += addDeviceAttribute("Credentials", y.join(', '));
diff --git a/views/default.handlebars b/views/default.handlebars
index 4d5d9ad2..e28a7700 100644
--- a/views/default.handlebars
+++ b/views/default.handlebars
@@ -6624,10 +6624,10 @@
if ((node.ssh != null) || (node.rdp != null)) {
var y = [];
if ((meshrights & 4) != 0) {
- if (node.ssh != null) { y.push('' + "SSH" + '
'); }
+ if (node.ssh != null) { y.push('' + ((node.ssh == 2)?"SSH-Key":"SSH") + '
'); }
if (node.rdp != null) { y.push('' + "RDP" + '
'); }
} else {
- if (node.ssh != null) { y.push("SSH"); }
+ if (node.ssh != null) { y.push(((node.ssh == 2)?"SSH-Key":"SSH")); }
if (node.rdp != null) { y.push("RDP"); }
}
x += addDeviceAttribute("Credentials", y.join(', '));
@@ -8957,11 +8957,17 @@
switch (j.action) {
case 'sshauth': {
var x = '';
- x += addHtmlValue("Username", '');
- x += addHtmlValue("Password", '');
+ x += addHtmlValue("Authentication", '')
+ x += addHtmlValue("Username", '');
+ x += '