Add charset support for SSH as well
This commit is contained in:
@@ -289,6 +289,24 @@ const initialFieldDef = {
|
|||||||
return "Look like " + addr.type + " address";
|
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: {
|
Notice: {
|
||||||
name: "Notice",
|
name: "Notice",
|
||||||
description: "",
|
description: "",
|
||||||
@@ -535,6 +553,7 @@ class Wizard {
|
|||||||
let config = {
|
let config = {
|
||||||
user: common.strToUint8Array(configInput.user),
|
user: common.strToUint8Array(configInput.user),
|
||||||
auth: getAuthMethodFromStr(configInput.authentication),
|
auth: getAuthMethodFromStr(configInput.authentication),
|
||||||
|
charset: configInput.charset,
|
||||||
credential: sessionData.credential,
|
credential: sessionData.credential,
|
||||||
host: address.parseHostPort(configInput.host, DEFAULT_PORT),
|
host: address.parseHostPort(configInput.host, DEFAULT_PORT),
|
||||||
fingerprint: configInput.fingerprint
|
fingerprint: configInput.fingerprint
|
||||||
@@ -585,6 +604,7 @@ class Wizard {
|
|||||||
configInput.user + "@" + configInput.host,
|
configInput.user + "@" + configInput.host,
|
||||||
self.info,
|
self.info,
|
||||||
self.controls.get("SSH", {
|
self.controls.get("SSH", {
|
||||||
|
charset: configInput.charset,
|
||||||
send(data) {
|
send(data) {
|
||||||
return commandHandler.sendData(data);
|
return commandHandler.sendData(data);
|
||||||
},
|
},
|
||||||
@@ -659,7 +679,17 @@ class Wizard {
|
|||||||
self.hasStarted = true;
|
self.hasStarted = true;
|
||||||
|
|
||||||
self.streams.request(COMMAND_ID, sd => {
|
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();
|
return self.stepWaitForAcceptWait();
|
||||||
@@ -679,6 +709,7 @@ class Wizard {
|
|||||||
user: r.user,
|
user: r.user,
|
||||||
authentication: r.authentication,
|
authentication: r.authentication,
|
||||||
host: r.host,
|
host: r.host,
|
||||||
|
charset: r.encoding,
|
||||||
fingerprint: ""
|
fingerprint: ""
|
||||||
},
|
},
|
||||||
this.session
|
this.session
|
||||||
@@ -692,6 +723,7 @@ class Wizard {
|
|||||||
{ name: "User" },
|
{ name: "User" },
|
||||||
{ name: "Host" },
|
{ name: "Host" },
|
||||||
{ name: "Authentication" },
|
{ name: "Authentication" },
|
||||||
|
{ name: "Encoding" },
|
||||||
{ name: "Notice" }
|
{ name: "Notice" }
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
@@ -828,20 +860,28 @@ export class Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
launch(info, launcher, streams, subs, controls, history) {
|
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');
|
throw new Exception('Given launcher "' + launcher + '" was malformed');
|
||||||
}
|
}
|
||||||
|
|
||||||
let user = matchResult[1],
|
let user = userHostName[1],
|
||||||
host = matchResult[2],
|
host = userHostName[2],
|
||||||
auth = matchResult[3];
|
auth = d[1],
|
||||||
|
charset = d.length >= 3 && d[2] ? d[2] : "utf-8"; // RM after depreciation
|
||||||
|
|
||||||
try {
|
try {
|
||||||
initialFieldDef["User"].verify(user);
|
initialFieldDef["User"].verify(user);
|
||||||
initialFieldDef["Host"].verify(host);
|
initialFieldDef["Host"].verify(host);
|
||||||
initialFieldDef["Authentication"].verify(auth);
|
initialFieldDef["Authentication"].verify(auth);
|
||||||
|
initialFieldDef["Encoding"].verify(charset);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw new Exception(
|
throw new Exception(
|
||||||
'Given launcher "' + launcher + '" was malformed ' + e
|
'Given launcher "' + launcher + '" was malformed ' + e
|
||||||
@@ -853,7 +893,8 @@ export class Command {
|
|||||||
{
|
{
|
||||||
user: user,
|
user: user,
|
||||||
host: host,
|
host: host,
|
||||||
authentication: auth
|
authentication: auth,
|
||||||
|
charset: charset
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
streams,
|
streams,
|
||||||
@@ -864,6 +905,14 @@ export class Command {
|
|||||||
}
|
}
|
||||||
|
|
||||||
launcher(config) {
|
launcher(config) {
|
||||||
return config.user + "@" + config.host + "|" + config.authentication;
|
return (
|
||||||
|
config.user +
|
||||||
|
"@" +
|
||||||
|
config.host +
|
||||||
|
"|" +
|
||||||
|
config.authentication +
|
||||||
|
"|" +
|
||||||
|
(config.charset ? config.charset : "utf-8")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
// You should have received a copy of the GNU Affero General Public License
|
// 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/>.
|
// 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 subscribe from "../stream/subscribe.js";
|
||||||
import * as reader from "../stream/reader.js";
|
import * as reader from "../stream/reader.js";
|
||||||
import * as color from "../commands/color.js";
|
import * as color from "../commands/color.js";
|
||||||
@@ -24,6 +26,35 @@ class Control {
|
|||||||
this.colorM = color;
|
this.colorM = color;
|
||||||
this.colors = this.colorM.get();
|
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.enable = false;
|
||||||
this.sender = data.send;
|
this.sender = data.send;
|
||||||
this.closer = data.close;
|
this.closer = data.close;
|
||||||
@@ -34,7 +65,7 @@ class Control {
|
|||||||
|
|
||||||
data.events.place("stdout", async rd => {
|
data.events.place("stdout", async rd => {
|
||||||
try {
|
try {
|
||||||
self.subs.resolve(await reader.readCompletely(rd));
|
self.subs.resolve(self.charsetDecoder(await reader.readCompletely(rd)));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
@@ -42,7 +73,7 @@ class Control {
|
|||||||
|
|
||||||
data.events.place("stderr", async rd => {
|
data.events.place("stderr", async rd => {
|
||||||
try {
|
try {
|
||||||
self.subs.resolve(await reader.readCompletely(rd));
|
self.subs.resolve(self.charsetDecoder(await reader.readCompletely(rd)));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
@@ -91,7 +122,7 @@ class Control {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.sender(new TextEncoder().encode(data));
|
return this.sender(this.charsetEncoder(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
color() {
|
color() {
|
||||||
|
|||||||
Reference in New Issue
Block a user