@microsoft/dev-tunnels-ssh
Version:
SSH library for Dev Tunnels
201 lines • 10.9 kB
JavaScript
"use strict";
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
Object.defineProperty(exports, "__esModule", { value: true });
exports.SshAuthenticatingEventArgs = exports.SshAuthenticationType = void 0;
const vscode_jsonrpc_1 = require("vscode-jsonrpc");
/**
* Indicates the type of authentication being requested by an SSH client or server when an
* `SshSession.authenticating` event is raised.
*/
var SshAuthenticationType;
(function (SshAuthenticationType) {
/**
* The client is attempting to authenticate without any credentials, or with only a
* username, or is merely checking what authentication methods are supported by the server.
*
* This event is raised by an `SshServerSession` when the client requests authentication
* using the "none" method. With this method, all of the credential properties in the
* `SshAuthenticatingEventArgs` are null.
*
* If the server app wishes to allow the client to authenticate with only a username, it may
* return a principal for the user. Othwerwise, the "none" authentication method fails, and
* the client may make a follow-up attempt to authenticate _with_ credentials.
*/
SshAuthenticationType[SshAuthenticationType["clientNone"] = 0] = "clientNone";
/**
* The client is attempting to authenticate with a client host public key.
*
* This event is raised by an `SshServerSession` when the client requests authentication
* using the "hostbased" method. The authentication handler must verify that the public key
* actually belongs to the client host name, _and_ that the network address the client
* connected from matches that host name, before returning a user principal to indicate
* successful authentication.
*/
SshAuthenticationType[SshAuthenticationType["clientHostBased"] = 1] = "clientHostBased";
/**
* The client is attempting to authenticate with a username and password credential.
*
* This event is raised by an `SshServerSession` when the client requests authentication
* using the "password" method. The authentication handler must verify that the username
* and password match known credentials on the server, before returning a user principal
* to indicate successful authentication.
*/
SshAuthenticationType[SshAuthenticationType["clientPassword"] = 2] = "clientPassword";
/**
* The client is querying whether authentication may be possible for a specified username and
* public key without yet proving they have the private key.
*
* This event is raised by an `SshServerSession` when the client requests authentication
* using the "publickey" method _without_ providing a signature. The authentication handler
* must verify that the username and public key match known credentials on the server. If
* they match, an _unauthenticated_ principal should be returned. That indicates to the
* client that they may proceed to actually authenticate using that username and public key.
*/
SshAuthenticationType[SshAuthenticationType["clientPublicKeyQuery"] = 3] = "clientPublicKeyQuery";
/**
* The client is attempting to authenticate with a username and public key credential.
*
* This event is raised by an `SshServerSession` when the client requests authentication
* using the "publickey" method, including a signature that proves they have the private
* key. The authentication handler must verify that the username and public key match known
* credentials on the server, before returning a user principal to indicate successful
* authentication.
*/
SshAuthenticationType[SshAuthenticationType["clientPublicKey"] = 4] = "clientPublicKey";
/**
* The client is attempting to authenticate with interactive prompts.
*
* This event is raised by an `SshServerSession` when the client requests authentication
* using the "keyboard-interactive" method. The event may be raised multiple times for the
* same client to facilitate multi-step authentication.
*/
SshAuthenticationType[SshAuthenticationType["clientInteractive"] = 5] = "clientInteractive";
/**
* The server is attempting to authenticate with a public key credential.
*
* This event is raised by an `SshClientSession` when the server requests
* authentication by providing a signature that proves it has the private key. The client
* authentication handler must verify that the public key matches known public key(s) for
* that server. Or if not known (often the case for the first time connecting to that server)
* it may prompt the user to consent, and then save the public key for later reference. To
* indicate successful authentication, the client authentication handler returns a principal
* that represents the server.
*/
SshAuthenticationType[SshAuthenticationType["serverPublicKey"] = 10] = "serverPublicKey";
})(SshAuthenticationType = exports.SshAuthenticationType || (exports.SshAuthenticationType = {}));
/**
* Arguments for the `SshSession.Authenticating` event that is raised when a client
* or server is requesting authentication.
*
* See `SshAuthenticationType` for a description of the different authentication methods and
* how they map to properties in this event-args object.
*
* After validating the credentials, the event handler must set the `authenticationPromise`
* property to a task that resolves to a principal object to indicate successful authentication.
* That principal will then be associated with the session as the `SshSession.principal` property.
*/
class SshAuthenticatingEventArgs {
constructor(authenticationType, { username, password, publicKey, clientHostname, clientUsername, infoRequest, infoResponse, }, cancellation) {
this.authenticationType = authenticationType;
/**
* Gets or sets a request for more information for interactive authentication.
*
* The server may set this property when handling an interactive authenticating event to prompt
* for information/credentials. The client may read this property when handling an interactive
* authenticating event to determine what prompts to show and what information is requested.
*/
this.infoRequest = null;
/**
* Gets or sets the client's responses to interactive prompts; valid only for interactive
* authentication when information was previously requested via `InfoRequest`.
*/
this.infoResponse = null;
const validate = ({ usernameRequired, passwordRequired, publicKeyRequired, clientHostnameRequired, clientUsernameRequired, }) => {
// This is intentionally not checking for empty strings. The authentication handler
// should determine whether any non-null string values are valid.
if ((typeof username === 'string') !== !!usernameRequired)
return false;
if ((typeof password === 'string') !== !!passwordRequired)
return false;
if (!!publicKey !== !!publicKeyRequired)
return false;
if ((typeof clientHostname === 'string') !== !!clientHostnameRequired)
return false;
if ((typeof clientUsername === 'string') !== !!clientUsernameRequired)
return false;
return true;
};
let valid;
switch (authenticationType) {
case SshAuthenticationType.clientNone:
valid = validate({ usernameRequired: true });
break;
case SshAuthenticationType.clientHostBased:
valid = validate({
usernameRequired: true,
publicKeyRequired: true,
clientHostnameRequired: true,
clientUsernameRequired: true,
});
break;
case SshAuthenticationType.clientPassword:
valid = validate({ usernameRequired: true, passwordRequired: true });
break;
case SshAuthenticationType.clientPublicKeyQuery:
case SshAuthenticationType.clientPublicKey:
valid = validate({ usernameRequired: true, publicKeyRequired: true });
break;
case SshAuthenticationType.serverPublicKey:
valid = validate({ publicKeyRequired: true });
break;
case SshAuthenticationType.clientInteractive:
valid = true;
break;
default:
throw new Error(`Invalid authentication type: ${authenticationType}`);
}
if (!valid) {
throw new Error(`Invalid arguments for authentication type: ${authenticationType}`);
}
this.username = username !== null && username !== void 0 ? username : null;
this.password = password !== null && password !== void 0 ? password : null;
this.publicKey = publicKey !== null && publicKey !== void 0 ? publicKey : null;
this.clientHostname = clientHostname !== null && clientHostname !== void 0 ? clientHostname : null;
this.clientUsername = clientUsername !== null && clientUsername !== void 0 ? clientUsername : null;
this.infoRequest = infoRequest !== null && infoRequest !== void 0 ? infoRequest : null;
this.infoResponse = infoResponse !== null && infoResponse !== void 0 ? infoResponse : null;
this.cancellationValue = cancellation !== null && cancellation !== void 0 ? cancellation : vscode_jsonrpc_1.CancellationToken.None;
}
/**
* Gets a token that is cancelled if the session ends before the authentication handler
* completes.
*/
get cancellation() {
return this.cancellationValue;
}
/* @internal */
set cancellation(value) {
this.cancellationValue = value;
}
toString() {
if (this.infoRequest) {
return `Info request: ${this.infoRequest.name}`;
}
else if (this.infoResponse) {
return `"${this.username}" info response`;
}
else if (this.password) {
return `${this.username ? '"' + this.username + '" ' : ''}[password]`;
}
else if (this.publicKey) {
return `${this.username ? '"' + this.username + '" ' : ''}[${this.publicKey.keyAlgorithmName}]`;
}
else {
return `"${this.username}"`;
}
}
}
exports.SshAuthenticatingEventArgs = SshAuthenticatingEventArgs;
//# sourceMappingURL=sshAuthenticatingEventArgs.js.map