"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=https://main.vscode-cdn.net/sourcemaps/f6cfa2ea2403534de03f069bdf160d06451ed282/node_modules/@microsoft/dev-tunnels-ssh/messages/transportMessages.js.map