8 var hasSshKeygen
= false;
12 return L
.resolveDefault(fs
.list('/root/.ssh/'), []).then(function (entries
) {
14 L
.resolveDefault(fs
.stat('/usr/bin/ssh-keygen'), {}),
17 for (var i
= 0; i
< entries
.length
; i
++) {
18 if (entries
[i
].type
=== 'file' && entries
[i
].name
.match(/\.pub$/)) {
19 tasks
.push(Promise
.resolve(entries
[i
].name
));
20 tasks
.push(fs
.lines('/root/.ssh/' + entries
[i
].name
));
23 return Promise
.all(tasks
);
27 render: function (data
) {
28 hasSshKeygen
= data
[0].type
=== 'file';
29 var sshKeys
= _splitSshKeys(data
.splice(1));
33 m
= new form
.Map('sshtunnel', _('SSH Tunnels'),
34 _('This configures <a %s>SSH Tunnels</a>')
35 .format('href="https://openwrt.org/docs/guide-user/services/ssh/sshtunnel"')
38 s
= m
.section(form
.GridSection
, '_keys');
39 s
.render
= L
.bind(_renderSshKeys
, this, sshKeys
);
45 function _splitSshKeys(sshFiles
) {
47 for (var i
= 0; i
< sshFiles
.length
; i
++) {
48 var sshPubKeyName
= sshFiles
[i
];
49 var sshKeyName
= sshPubKeyName
.substring(0, sshPubKeyName
.length
- 4);
51 var sshPub
= sshFiles
[i
];
52 sshKeys
[sshKeyName
] = '<small><code>' + sshPub
+ '</code></small>';
58 function _renderSshKeys(sshKeys
) {
59 var table
= E('table', {'class': 'table cbi-section-table', 'id': 'keys_table'}, [
60 E('tr', {'class': 'tr table-titles'}, [
61 E('th', {'class': 'th'}, _('Name')),
62 E('th', {'class': 'th'}, _('Public Key')),
66 var rows
= Object
.entries(sshKeys
);
67 cbi_update_table(table
, rows
, null);
69 var keyGenBtn
= E('div', {}, [
71 'submit': _handleKeyGenSubmit
,
73 E('label', {}, _('Generate a new key') + ': '),
74 E('span', {'class': 'control-group'}, [
78 'value': 'id_ed25519',
79 'pattern': '^[a-zA-Z][a-zA-Z0-9_\.]+',
80 'required': 'required',
82 'autocomplete': 'off',
85 'id': 'btnGenerateKey',
87 'class': 'btn cbi-button cbi-button-action',
92 return E('div', {'class': 'cbi-section cbi-tblsection'}, [
93 E('h3', _('SSH Keys')),
94 E('div', {'class': 'cbi-section-descr'},
95 _('Add the pub key to %s or %s.')
96 .format('<code>/root/.ssh/authorized_keys</code>', '<code>/etc/dropbear/authorized_keys</code>') + ' ' +
97 _('In LuCI you can do that with <a %s>System / Administration / SSH-Keys</a>')
98 .format('href="/cgi-bin/luci/admin/system/admin/sshkeys"')
104 function _handleKeyGenSubmit(event
) {
105 event
.preventDefault();
106 var keyName
= document
.querySelector('input[name="keyName"]').value
;
107 if (allSshKeys
[keyName
]) {
108 document
.body
.scrollTop
= document
.documentElement
.scrollTop
= 0;
109 ui
.addNotification(null, E('p', _('A key with that name already exists.'), 'error'));
113 let command
= '/usr/bin/ssh-keygen';
114 let commandArgs
= ['-t', 'ed25519', '-q', '-N', '', '-f', '/root/.ssh/' + keyName
];
116 command
= '/usr/bin/dropbearkey';
117 commandArgs
= ['-t', 'ed25519', '-f', '/root/.ssh/' + keyName
];
119 fs
.exec(command
, commandArgs
).then(function (res
) {
120 if (res
.code
=== 0) {
121 // refresh the page to see the new key
124 throw new Error(res
.stdout
+ ' ' + res
.stderr
);
126 }).catch(function (e
) {
127 document
.body
.scrollTop
= document
.documentElement
.scrollTop
= 0;
128 ui
.addNotification(null, E('p', _('Unable to generate a key: %s').format(e
.message
)), 'error');