@microsoft/dev-tunnels-ssh
Version:
SSH library for Dev Tunnels
320 lines • 14.1 kB
JavaScript
"use strict";
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
Object.defineProperty(exports, "__esModule", { value: true });
exports.SessionReconnectFailureMessage = exports.SshReconnectFailureReason = exports.SessionReconnectResponseMessage = exports.SessionReconnectRequestMessage = exports.SessionChannelRequestMessage = exports.ExtensionInfoMessage = exports.SessionRequestFailureMessage = exports.SessionRequestSuccessMessage = exports.SessionRequestMessage = exports.ServiceAcceptMessage = exports.ServiceRequestMessage = exports.DebugMessage = exports.UnimplementedMessage = exports.IgnoreMessage = exports.DisconnectMessage = exports.SshDisconnectReason = void 0;
const sshMessage_1 = require("./sshMessage");
const connectionMessages_1 = require("./connectionMessages");
var SshDisconnectReason;
(function (SshDisconnectReason) {
SshDisconnectReason[SshDisconnectReason["none"] = 0] = "none";
SshDisconnectReason[SshDisconnectReason["hostNotAllowedToConnect"] = 1] = "hostNotAllowedToConnect";
SshDisconnectReason[SshDisconnectReason["protocolError"] = 2] = "protocolError";
SshDisconnectReason[SshDisconnectReason["keyExchangeFailed"] = 3] = "keyExchangeFailed";
SshDisconnectReason[SshDisconnectReason["reserved"] = 4] = "reserved";
SshDisconnectReason[SshDisconnectReason["macError"] = 5] = "macError";
SshDisconnectReason[SshDisconnectReason["compressionError"] = 6] = "compressionError";
SshDisconnectReason[SshDisconnectReason["serviceNotAvailable"] = 7] = "serviceNotAvailable";
SshDisconnectReason[SshDisconnectReason["protocolVersionNotSupported"] = 8] = "protocolVersionNotSupported";
SshDisconnectReason[SshDisconnectReason["hostKeyNotVerifiable"] = 9] = "hostKeyNotVerifiable";
SshDisconnectReason[SshDisconnectReason["connectionLost"] = 10] = "connectionLost";
SshDisconnectReason[SshDisconnectReason["byApplication"] = 11] = "byApplication";
SshDisconnectReason[SshDisconnectReason["tooManyConnections"] = 12] = "tooManyConnections";
SshDisconnectReason[SshDisconnectReason["authCancelledByUser"] = 13] = "authCancelledByUser";
SshDisconnectReason[SshDisconnectReason["noMoreAuthMethodsAvailable"] = 14] = "noMoreAuthMethodsAvailable";
SshDisconnectReason[SshDisconnectReason["illegalUserName"] = 15] = "illegalUserName";
})(SshDisconnectReason = exports.SshDisconnectReason || (exports.SshDisconnectReason = {}));
class DisconnectMessage extends sshMessage_1.SshMessage {
get messageType() {
return 1;
}
onRead(reader) {
this.reasonCode = reader.readUInt32();
this.description = reader.readString('utf8');
if (reader.available >= 4) {
this.language = reader.readString('ascii');
}
else {
this.language = null;
}
}
onWrite(writer) {
writer.writeUInt32(this.validateField(this.reasonCode, 'reason code'));
writer.writeString(this.description || '', 'utf8');
if (this.language) {
writer.writeString(this.language, 'ascii');
}
}
toString() {
return `${super.toString()} (${SshDisconnectReason[this.reasonCode || 0]}: ${this.description})`;
}
}
exports.DisconnectMessage = DisconnectMessage;
class IgnoreMessage extends sshMessage_1.SshMessage {
get messageType() {
return 2;
}
onRead(reader) { }
onWrite(writer) { }
}
exports.IgnoreMessage = IgnoreMessage;
class UnimplementedMessage extends sshMessage_1.SshMessage {
get messageType() {
return 3;
}
onRead(reader) {
this.sequenceNumber = reader.readUInt32();
}
onWrite(writer) {
writer.writeUInt32(this.validateField(this.sequenceNumber, 'sequence number'));
}
toString() {
return this.unimplementedMessageType
? `${super.toString()} (messageType=${this.unimplementedMessageType})`
: `${super.toString()} (sequenceNumber=${this.sequenceNumber})`;
}
}
exports.UnimplementedMessage = UnimplementedMessage;
class DebugMessage extends sshMessage_1.SshMessage {
constructor(message) {
super();
this.alwaysDisplay = false;
this.message = message;
}
get messageType() {
return 4;
}
onRead(reader) {
this.alwaysDisplay = reader.readBoolean();
this.message = reader.readString('utf8');
this.language = reader.readString('ascii');
}
onWrite(writer) {
var _a, _b;
writer.writeBoolean(this.alwaysDisplay);
writer.writeString((_a = this.message) !== null && _a !== void 0 ? _a : '', 'utf8');
writer.writeString((_b = this.language) !== null && _b !== void 0 ? _b : '', 'ascii');
}
toString() {
return `${super.toString()}: ${this.message}`;
}
}
exports.DebugMessage = DebugMessage;
class ServiceRequestMessage extends sshMessage_1.SshMessage {
get messageType() {
return 5;
}
onRead(reader) {
this.serviceName = reader.readString('ascii');
}
onWrite(writer) {
writer.writeString(this.validateField(this.serviceName, 'service name'), 'ascii');
}
}
exports.ServiceRequestMessage = ServiceRequestMessage;
class ServiceAcceptMessage extends sshMessage_1.SshMessage {
get messageType() {
return 6;
}
onRead(reader) {
this.serviceName = reader.readString('ascii');
}
onWrite(writer) {
writer.writeString(this.validateField(this.serviceName, 'service name'), 'ascii');
}
}
exports.ServiceAcceptMessage = ServiceAcceptMessage;
class SessionRequestMessage extends sshMessage_1.SshMessage {
constructor(requestType, wantReply) {
super();
this.requestType = requestType;
this.wantReply = wantReply !== null && wantReply !== void 0 ? wantReply : false;
}
get messageType() {
return 80;
}
onRead(reader) {
this.requestType = reader.readString('ascii');
this.wantReply = reader.readBoolean();
}
onWrite(writer) {
writer.writeString(this.validateField(this.requestType, 'request type'), 'ascii');
writer.writeBoolean(this.wantReply);
}
toString() {
return `${super.toString()} (requestType=${this.requestType})`;
}
}
exports.SessionRequestMessage = SessionRequestMessage;
class SessionRequestSuccessMessage extends sshMessage_1.SshMessage {
get messageType() {
return 81;
}
onRead(reader) { }
onWrite(writer) { }
}
exports.SessionRequestSuccessMessage = SessionRequestSuccessMessage;
class SessionRequestFailureMessage extends sshMessage_1.SshMessage {
get messageType() {
return 82;
}
onRead(reader) { }
onWrite(writer) { }
}
exports.SessionRequestFailureMessage = SessionRequestFailureMessage;
class ExtensionInfoMessage extends sshMessage_1.SshMessage {
constructor() {
// https://tools.ietf.org/html/draft-ietf-curdle-ssh-ext-info-15
super(...arguments);
this.extensionInfo = {};
}
get messageType() {
return 7;
}
onRead(reader) {
const count = reader.readUInt32();
this.extensionInfo = {};
for (let i = 0; i < count; i++) {
const key = reader.readString('ascii');
const value = reader.readString('utf8');
this.extensionInfo[key] = value;
}
}
onWrite(writer) {
const keys = Object.keys(this.extensionInfo);
writer.writeUInt32(keys.length);
for (const key of keys) {
writer.writeString(key, 'ascii');
writer.writeString(this.extensionInfo[key] || '', 'utf8');
}
}
toString() {
let extensionInfoDetails = '';
for (const [key, value] of Object.entries(this.extensionInfo)) {
if (extensionInfoDetails) {
extensionInfoDetails += '; ';
}
extensionInfoDetails += key;
if (value) {
extensionInfoDetails += '=' + value;
}
}
return `${super.toString()} (${extensionInfoDetails})`;
}
}
exports.ExtensionInfoMessage = ExtensionInfoMessage;
ExtensionInfoMessage.serverIndicator = 'ext-info-c';
ExtensionInfoMessage.clientIndicator = 'ext-info-c';
class SessionChannelRequestMessage extends SessionRequestMessage {
onRead(reader) {
super.onRead(reader);
this.senderChannel = reader.readUInt32();
const request = new connectionMessages_1.ChannelRequestMessage();
request.read(reader);
this.request = request;
}
onWrite(writer) {
super.onWrite(writer);
writer.writeUInt32(this.validateField(this.senderChannel, 'sender channel'));
this.validateField(this.request, 'request message').write(writer);
}
}
exports.SessionChannelRequestMessage = SessionChannelRequestMessage;
class SessionReconnectRequestMessage extends SessionRequestMessage {
onRead(reader) {
super.onRead(reader);
this.clientReconnectToken = reader.readBinary();
this.lastReceivedSequenceNumber = reader.readUInt64();
}
onWrite(writer) {
super.onWrite(writer);
writer.writeBinary(this.validateField(this.clientReconnectToken, 'clientReconnectToken'));
writer.writeUInt64(this.validateField(this.lastReceivedSequenceNumber, 'lastReceivedSequenceNumber'));
}
}
exports.SessionReconnectRequestMessage = SessionReconnectRequestMessage;
class SessionReconnectResponseMessage extends SessionRequestSuccessMessage {
onRead(reader) {
super.onRead(reader);
this.serverReconnectToken = reader.readBinary();
this.lastReceivedSequenceNumber = reader.readUInt64();
}
onWrite(writer) {
super.onWrite(writer);
writer.writeBinary(this.validateField(this.serverReconnectToken, 'serverReconnectToken'));
writer.writeUInt64(this.validateField(this.lastReceivedSequenceNumber, 'lastReceivedSequenceNumber'));
}
}
exports.SessionReconnectResponseMessage = SessionReconnectResponseMessage;
var SshReconnectFailureReason;
(function (SshReconnectFailureReason) {
/** No reason was specified. */
SshReconnectFailureReason[SshReconnectFailureReason["none"] = 0] = "none";
/**
* Reconnection failed due to an unknown server-side error.
*/
SshReconnectFailureReason[SshReconnectFailureReason["unknownServerFailure"] = 1] = "unknownServerFailure";
/**
* The session ID requested by the client for reconnection was not found among
* the server's reconnectable sessions.
*/
SshReconnectFailureReason[SshReconnectFailureReason["sessionNotFound"] = 2] = "sessionNotFound";
/**
* The reconnect token supplied by the client was invalid when checked by the server.
* The validation ensures that the client knows a secret key negotiated in the
* previously connected session.
*/
SshReconnectFailureReason[SshReconnectFailureReason["invalidClientReconnectToken"] = 3] = "invalidClientReconnectToken";
/**
* The server was unable to re-send dropped messages that were requested by the client.
*/
SshReconnectFailureReason[SshReconnectFailureReason["serverDroppedMessages"] = 4] = "serverDroppedMessages";
/**
* Reconnection failed due to an unknown client-side error.
*/
SshReconnectFailureReason[SshReconnectFailureReason["unknownClientFailure"] = 101] = "unknownClientFailure";
/**
* The host key supplied by the reconnected server did not match the host key from the
* original session; the client refused to reconnect to a different host.
*/
SshReconnectFailureReason[SshReconnectFailureReason["differentServerHostKey"] = 102] = "differentServerHostKey";
/**
* The reconnect token supplied by the server was invalid when checked by the client.
* The validation ensures that the server knows a secret key negotiated in the
* previously connected session.
*/
SshReconnectFailureReason[SshReconnectFailureReason["invalidServerReconnectToken"] = 103] = "invalidServerReconnectToken";
/**
* The client was unable to re-send dropped messages that were requested by the server.
*/
SshReconnectFailureReason[SshReconnectFailureReason["clientDroppedMessages"] = 104] = "clientDroppedMessages";
})(SshReconnectFailureReason = exports.SshReconnectFailureReason || (exports.SshReconnectFailureReason = {}));
class SessionReconnectFailureMessage extends SessionRequestFailureMessage {
onRead(reader) {
if (reader.available > 0) {
this.reasonCode = reader.readUInt32();
this.description = reader.readString('utf8');
this.language = reader.readString('ascii');
}
}
onWrite(writer) {
writer.writeUInt32(this.validateField(this.reasonCode, 'reason code'));
writer.writeString(this.description || '', 'utf8');
writer.writeString(this.language || 'en', 'ascii');
}
toString() {
return `${super.toString()} (${SshReconnectFailureReason[this.reasonCode || 0]}: ${this.description})`;
}
}
exports.SessionReconnectFailureMessage = SessionReconnectFailureMessage;
sshMessage_1.SshMessage.index.set(1, DisconnectMessage);
sshMessage_1.SshMessage.index.set(2, IgnoreMessage);
sshMessage_1.SshMessage.index.set(3, UnimplementedMessage);
sshMessage_1.SshMessage.index.set(5, ServiceRequestMessage);
sshMessage_1.SshMessage.index.set(6, ServiceAcceptMessage);
sshMessage_1.SshMessage.index.set(7, ExtensionInfoMessage);
sshMessage_1.SshMessage.index.set(80, SessionRequestMessage);
sshMessage_1.SshMessage.index.set(81, SessionRequestSuccessMessage);
sshMessage_1.SshMessage.index.set(82, SessionRequestFailureMessage);
//# sourceMappingURL=transportMessages.js.map