From 6d349f133ef63c537b5734264e1a9ff15c4195d9 Mon Sep 17 00:00:00 2001 From: NI Date: Thu, 29 Aug 2019 21:27:43 +0800 Subject: [PATCH] SSH: Change the input box type for Private Key field from textarea to file. --- ui/commands/ssh.js | 47 ++++++++++++++++++++++++++--------- ui/common.css | 2 ++ ui/widgets/connector.vue | 53 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 12 deletions(-) diff --git a/ui/commands/ssh.js b/ui/commands/ssh.js index 11c02b9..5185f8f 100644 --- a/ui/commands/ssh.js +++ b/ui/commands/ssh.js @@ -323,13 +323,14 @@ const initialFieldDef = { }, "Private Key": { name: "Private Key", - description: "Like the one inside ~/.ssh/id_rsa, can't be encrypted", - type: "textarea", + description: + "Like the one inside ~/.ssh/id_rsa, can't be encrypted

" + + "To decrypt the Private Key, use command: " + + "openssl rsa -in /path/to/encrypted_private_key -out " + + "/path/to/decrypted_private_key", + type: "textfile", value: "", - example: - "-----BEGIN RSA PRIVATE KEY-----\r\n" + - "..... yBQZobkBQ50QqhDivQz4i1Pb33Z0Znjnzjoid4 ....\r\n" + - "-----END RSA PRIVATE KEY-----", + example: "", verify(d) { if (d.length <= 0) { throw new Error("Private Key must be specified"); @@ -341,7 +342,29 @@ const initialFieldDef = { ); } - return "We'll login with this private key"; + let lines = d.split("\n"); + + for (let i in lines) { + if (lines[i].indexOf("-") === 0) { + continue; + } + + if (lines[i].indexOf("Proc-Type: 4,ENCRYPTED") === 0) { + throw new Error("Cannot use encrypted Private Key file"); + } + + if (lines[i].indexOf(":") > 0) { + continue; + } + + if (lines[i].indexOf("MII") < 0) { + throw new Error("Cannot use encrypted Private Key file"); + } + + break; + } + + return "We'll login with this Private Key"; } }, Authentication: { @@ -691,15 +714,15 @@ class Wizard { async stepCredentialPrompt(rd, sd, config) { let self = this, - fieldName = ""; + fields = []; switch (config.auth) { case AUTHMETHOD_PASSPHRASE: - fieldName = "Passphrase"; + fields = [{ name: "Passphrase" }]; break; case AUTHMETHOD_PRIVATE_KEY: - fieldName = "Private Key"; + fields = [{ name: "Private Key" }]; break; default: @@ -713,7 +736,7 @@ class Wizard { "Please input your credential", "Login", r => { - let vv = r[fieldName.toLowerCase()]; + let vv = r[fields[0].name.toLowerCase()]; sd.send( CLIENT_CONNECT_RESPOND_CREDENTIAL, @@ -732,7 +755,7 @@ class Wizard { ) ); }, - command.fields(initialFieldDef, [{ name: fieldName }]) + command.fields(initialFieldDef, fields) ); } } diff --git a/ui/common.css b/ui/common.css index e945bd5..f483429 100644 --- a/ui/common.css +++ b/ui/common.css @@ -413,6 +413,7 @@ body { } .form1 > fieldset .field > input[type="text"], +.form1 > fieldset .field > input[type="file"], .form1 > fieldset .field > input[type="email"], .form1 > fieldset .field > input[type="number"], .form1 > fieldset .field > input[type="search"], @@ -455,6 +456,7 @@ body { } .form1 > fieldset .field.error > input[type="text"], +.form1 > fieldset .field.error > input[type="file"], .form1 > fieldset .field.error > input[type="email"], .form1 > fieldset .field.error > input[type="number"], .form1 > fieldset .field.error > input[type="search"], diff --git a/ui/widgets/connector.vue b/ui/widgets/connector.vue index bff6d74..b3e74d5 100644 --- a/ui/widgets/connector.vue +++ b/ui/widgets/connector.vue @@ -114,6 +114,29 @@ @change="verify(key, field, true)" > + + +
{{ field.field.value }}
@@ -387,6 +410,36 @@ export default { event.target.style.height = ""; event.target.style.height = event.target.scrollHeight + "px"; }, + importFile(el, field) { + if (el.files.length <= 0) { + return; + } + + el.disabled = "disabled"; + + let r = new FileReader(); + + r.onload = () => { + let s = el.nextSibling; + + for (;;) { + if (s.tagName !== "INPUT") { + s = s.nextSibling; + + continue; + } + + field.field.value = r.result; + s.dispatchEvent(new Event("change")); + + break; + } + + el.disabled = ""; + }; + + r.readAsText(el.files[0], "utf-8"); + }, verify(key, field, force) { try { field.message = "" + field.field.verify(field.field.value);