luci-app-sshtunnel: ssh_keys: list keys without a corresponding .pub
The private keys doesn't have any extension so the only way to clearly say that this file is a key is a presence of the corresponding .pub file. Most of time key files have a prefix id_ e.g. id_rsa etc. The dropbearkey generates a key without a corresponding .pub file e.g. id_dropbearkey. So we need to detect a key files by both .pub file or id_ prefix. Key files without the id_ prefix won't be listed, sorry. Signed-off-by: Sergey Ponomarev <stokito@gmail.com>
This commit is contained in:
parent
3933633dd0
commit
949e7cbcb3
2 changed files with 65 additions and 30 deletions
|
@ -11,14 +11,16 @@ return view.extend({
|
||||||
load: function () {
|
load: function () {
|
||||||
return L.resolveDefault(fs.list('/root/.ssh/'), []).then(function (entries) {
|
return L.resolveDefault(fs.list('/root/.ssh/'), []).then(function (entries) {
|
||||||
var tasks = [
|
var tasks = [
|
||||||
|
// detect if OpenSSH ssh-keygen is installed
|
||||||
L.resolveDefault(fs.stat('/usr/bin/ssh-keygen'), {}),
|
L.resolveDefault(fs.stat('/usr/bin/ssh-keygen'), {}),
|
||||||
];
|
];
|
||||||
|
var sshKeyNames = _findAllPossibleIdKeys(entries);
|
||||||
|
|
||||||
// read pub keys
|
// read pub keys
|
||||||
for (var i = 0; i < entries.length; i++) {
|
for (var sshKeyName of sshKeyNames) {
|
||||||
if (entries[i].type === 'file' && entries[i].name.match(/\.pub$/)) {
|
var sshPubKeyName = sshKeyName + '.pub';
|
||||||
tasks.push(Promise.resolve(entries[i].name));
|
tasks.push(Promise.resolve(sshKeyName));
|
||||||
tasks.push(fs.lines('/root/.ssh/' + entries[i].name));
|
tasks.push(fs.lines('/root/.ssh/' + sshPubKeyName));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Promise.all(tasks);
|
return Promise.all(tasks);
|
||||||
});
|
});
|
||||||
|
@ -42,12 +44,37 @@ return view.extend({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function _findAllPossibleIdKeys(entries) {
|
||||||
|
var sshKeyNames = [];
|
||||||
|
for (var item of entries) {
|
||||||
|
if (item.type !== 'file') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// a key file should have a corresponding .pub file
|
||||||
|
if (item.name.endsWith('.pub')) {
|
||||||
|
var sshPubKeyName = item.name;
|
||||||
|
var sshKeyName = sshPubKeyName.substring(0, sshPubKeyName.length - 4);
|
||||||
|
if (!sshKeyNames.includes(sshKeyName)) {
|
||||||
|
sshKeyNames.push(sshKeyName)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// or at least it should start with id_ e.g. id_dropbear
|
||||||
|
if (item.name.startsWith('id_')) {
|
||||||
|
var sshKeyName = item.name;
|
||||||
|
if (!sshKeyNames.includes(sshKeyName)) {
|
||||||
|
sshKeyNames.push(sshKeyName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sshKeyNames;
|
||||||
|
}
|
||||||
|
|
||||||
function _splitSshKeys(sshFiles) {
|
function _splitSshKeys(sshFiles) {
|
||||||
var sshKeys = {};
|
var sshKeys = {};
|
||||||
for (var i = 0; i < sshFiles.length; i++) {
|
for (var i = 0; i < sshFiles.length; i++) {
|
||||||
var sshPubKeyName = sshFiles[i];
|
var sshKeyName = sshFiles[i];
|
||||||
var sshKeyName = sshPubKeyName.substring(0, sshPubKeyName.length - 4);
|
i++; // next is a .pub content
|
||||||
i++;
|
|
||||||
var sshPub = sshFiles[i];
|
var sshPub = sshFiles[i];
|
||||||
sshKeys[sshKeyName] = '<small><code>' + sshPub + '</code></small>';
|
sshKeys[sshKeyName] = '<small><code>' + sshPub + '</code></small>';
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,24 +5,17 @@
|
||||||
'require ui';
|
'require ui';
|
||||||
'require view';
|
'require view';
|
||||||
|
|
||||||
var allSshKeys = {};
|
|
||||||
|
|
||||||
return view.extend({
|
return view.extend({
|
||||||
load: function () {
|
load: function () {
|
||||||
return L.resolveDefault(fs.list('/root/.ssh/'), []).then(function (entries) {
|
return L.resolveDefault(fs.list('/root/.ssh/'), []).then(function (entries) {
|
||||||
var tasks = [];
|
var sshKeyNames = _findAllPossibleIdKeys(entries);
|
||||||
for (var i = 0; i < entries.length; i++) {
|
return Promise.resolve(sshKeyNames);
|
||||||
if (entries[i].type === 'file' && entries[i].name.match(/\.pub$/)) {
|
|
||||||
tasks.push(Promise.resolve(entries[i].name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Promise.all(tasks);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function (data) {
|
render: function (data) {
|
||||||
var sshKeys = _splitSshKeys(data);
|
var sshKeyNames = data;
|
||||||
if (sshKeys.length === 0) {
|
if (sshKeyNames.length === 0) {
|
||||||
ui.addNotification(null, E('p', _('No SSH keys found, <a %s>generate a new one</a>').format('href="./ssh_keys"')), 'warning');
|
ui.addNotification(null, E('p', _('No SSH keys found, <a %s>generate a new one</a>').format('href="./ssh_keys"')), 'warning');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,9 +51,9 @@ return view.extend({
|
||||||
'See <em>ssh_config IdentityFile</em>')
|
'See <em>ssh_config IdentityFile</em>')
|
||||||
);
|
);
|
||||||
o.value('');
|
o.value('');
|
||||||
Object.keys(sshKeys).forEach(function (keyName) {
|
for (var sshKeyName of sshKeyNames) {
|
||||||
o.value('/root/.ssh/' + keyName, keyName);
|
o.value('/root/.ssh/' + sshKeyName, sshKeyName);
|
||||||
});
|
}
|
||||||
o.optional = true;
|
o.optional = true;
|
||||||
|
|
||||||
|
|
||||||
|
@ -135,13 +128,28 @@ return view.extend({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
function _splitSshKeys(sshFiles) {
|
function _findAllPossibleIdKeys(entries) {
|
||||||
var sshKeys = {};
|
var sshKeyNames = [];
|
||||||
for (var i = 0; i < sshFiles.length; i++) {
|
for (var item of entries) {
|
||||||
var sshPubKeyName = sshFiles[i];
|
if (item.type !== 'file') {
|
||||||
var sshKeyName = sshPubKeyName.substring(0, sshPubKeyName.length - 4);
|
continue
|
||||||
sshKeys[sshKeyName] = '';
|
}
|
||||||
|
// a key file should have a corresponding .pub file
|
||||||
|
if (item.name.endsWith('.pub')) {
|
||||||
|
var sshPubKeyName = item.name;
|
||||||
|
var sshKeyName = sshPubKeyName.substring(0, sshPubKeyName.length - 4);
|
||||||
|
if (!sshKeyNames.includes(sshKeyName)) {
|
||||||
|
sshKeyNames.push(sshKeyName)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// or at least it should start with id_ e.g. id_dropbear
|
||||||
|
if (item.name.startsWith('id_')) {
|
||||||
|
var sshKeyName = item.name;
|
||||||
|
if (!sshKeyNames.includes(sshKeyName)) {
|
||||||
|
sshKeyNames.push(sshKeyName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
allSshKeys = sshKeys;
|
return sshKeyNames;
|
||||||
return sshKeys;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue