Add charset support for SSH as well

This commit is contained in:
NI
2019-10-02 22:30:14 +08:00
parent 81a9424066
commit e77ad353f0
2 changed files with 91 additions and 11 deletions

View File

@@ -289,6 +289,24 @@ const initialFieldDef = {
return "Look like " + addr.type + " address";
}
},
Encoding: {
name: "Encoding",
description: "The character encoding of the server",
type: "select",
value: "utf-8",
example: common.charsetPresets.join(","),
verify(d) {
for (let i in common.charsetPresets) {
if (common.charsetPresets[i] !== d) {
continue;
}
return "";
}
throw new Error('The character encoding "' + d + '" is not supported');
}
},
Notice: {
name: "Notice",
description: "",
@@ -535,6 +553,7 @@ class Wizard {
let config = {
user: common.strToUint8Array(configInput.user),
auth: getAuthMethodFromStr(configInput.authentication),
charset: configInput.charset,
credential: sessionData.credential,
host: address.parseHostPort(configInput.host, DEFAULT_PORT),
fingerprint: configInput.fingerprint
@@ -585,6 +604,7 @@ class Wizard {
configInput.user + "@" + configInput.host,
self.info,
self.controls.get("SSH", {
charset: configInput.charset,
send(data) {
return commandHandler.sendData(data);
},
@@ -659,7 +679,17 @@ class Wizard {
self.hasStarted = true;
self.streams.request(COMMAND_ID, sd => {
return self.buildCommand(sd, this.config, this.session);
return self.buildCommand(
sd,
{
user: this.config.user,
authentication: this.config.authentication,
host: this.config.host,
charset: this.config.charset ? this.config.charset : "utf-8",
fingerprint: this.config.fingerprint
},
this.session
);
});
return self.stepWaitForAcceptWait();
@@ -679,6 +709,7 @@ class Wizard {
user: r.user,
authentication: r.authentication,
host: r.host,
charset: r.encoding,
fingerprint: ""
},
this.session
@@ -692,6 +723,7 @@ class Wizard {
{ name: "User" },
{ name: "Host" },
{ name: "Authentication" },
{ name: "Encoding" },
{ name: "Notice" }
])
);
@@ -828,20 +860,28 @@ export class Command {
}
launch(info, launcher, streams, subs, controls, history) {
let matchResult = launcher.match(new RegExp("^(.*)\\@(.*)\\|(.*)$"));
const d = launcher.split("|", 3);
if (!matchResult || matchResult.length !== 4) {
if (d.length < 2) {
throw new Exception('Given launcher "' + launcher + '" was invalid');
}
const userHostName = d[0].match(new RegExp("^(.*)\\@(.*)$"));
if (!userHostName || userHostName.length !== 3) {
throw new Exception('Given launcher "' + launcher + '" was malformed');
}
let user = matchResult[1],
host = matchResult[2],
auth = matchResult[3];
let user = userHostName[1],
host = userHostName[2],
auth = d[1],
charset = d.length >= 3 && d[2] ? d[2] : "utf-8"; // RM after depreciation
try {
initialFieldDef["User"].verify(user);
initialFieldDef["Host"].verify(host);
initialFieldDef["Authentication"].verify(auth);
initialFieldDef["Encoding"].verify(charset);
} catch (e) {
throw new Exception(
'Given launcher "' + launcher + '" was malformed ' + e
@@ -853,7 +893,8 @@ export class Command {
{
user: user,
host: host,
authentication: auth
authentication: auth,
charset: charset
},
null,
streams,
@@ -864,6 +905,14 @@ export class Command {
}
launcher(config) {
return config.user + "@" + config.host + "|" + config.authentication;
return (
config.user +
"@" +
config.host +
"|" +
config.authentication +
"|" +
(config.charset ? config.charset : "utf-8")
);
}
}

View File

@@ -15,6 +15,8 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import * as iconv from "iconv-lite";
import * as subscribe from "../stream/subscribe.js";
import * as reader from "../stream/reader.js";
import * as color from "../commands/color.js";
@@ -24,6 +26,35 @@ class Control {
this.colorM = color;
this.colors = this.colorM.get();
this.charset = data.charset;
if (this.charset === "utf-8") {
let enc = new TextEncoder();
this.charsetDecoder = d => {
return d;
};
this.charsetEncoder = dStr => {
return enc.encode(dStr);
};
} else {
let dec = new TextDecoder(this.charset),
enc = new TextEncoder();
this.charsetDecoder = d => {
return enc.encode(
dec.decode(d, {
stream: true
})
);
};
this.charsetEncoder = dStr => {
return iconv.encode(dStr, this.charset);
};
}
this.enable = false;
this.sender = data.send;
this.closer = data.close;
@@ -34,7 +65,7 @@ class Control {
data.events.place("stdout", async rd => {
try {
self.subs.resolve(await reader.readCompletely(rd));
self.subs.resolve(self.charsetDecoder(await reader.readCompletely(rd)));
} catch (e) {
// Do nothing
}
@@ -42,7 +73,7 @@ class Control {
data.events.place("stderr", async rd => {
try {
self.subs.resolve(await reader.readCompletely(rd));
self.subs.resolve(self.charsetDecoder(await reader.readCompletely(rd)));
} catch (e) {
// Do nothing
}
@@ -91,7 +122,7 @@ class Control {
return;
}
return this.sender(new TextEncoder().encode(data));
return this.sender(this.charsetEncoder(data));
}
color() {