mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 08:12:05 +00:00
8219a5c503
Differential Revision: https://phabricator.services.mozilla.com/D177025
221 lines
6.3 KiB
JavaScript
221 lines
6.3 KiB
JavaScript
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
"use strict";
|
|
|
|
loader.lazyRequireGetter(
|
|
this,
|
|
"prompt",
|
|
"resource://devtools/shared/security/prompt.js"
|
|
);
|
|
|
|
/**
|
|
* A simple enum-like object with keys mirrored to values.
|
|
* This makes comparison to a specfic value simpler without having to repeat and
|
|
* mis-type the value.
|
|
*/
|
|
function createEnum(obj) {
|
|
for (const key in obj) {
|
|
obj[key] = key;
|
|
}
|
|
return obj;
|
|
}
|
|
|
|
/**
|
|
* |allowConnection| implementations can return various values as their |result|
|
|
* field to indicate what action to take. By specifying these, we can
|
|
* centralize the common actions available, while still allowing embedders to
|
|
* present their UI in whatever way they choose.
|
|
*/
|
|
var AuthenticationResult = (exports.AuthenticationResult = createEnum({
|
|
/**
|
|
* Close all listening sockets, and disable them from opening again.
|
|
*/
|
|
DISABLE_ALL: null,
|
|
|
|
/**
|
|
* Deny the current connection.
|
|
*/
|
|
DENY: null,
|
|
|
|
/**
|
|
* Additional data needs to be exchanged before a result can be determined.
|
|
*/
|
|
PENDING: null,
|
|
|
|
/**
|
|
* Allow the current connection.
|
|
*/
|
|
ALLOW: null,
|
|
|
|
/**
|
|
* Allow the current connection, and persist this choice for future
|
|
* connections from the same client. This requires a trustable mechanism to
|
|
* identify the client in the future.
|
|
*/
|
|
ALLOW_PERSIST: null,
|
|
}));
|
|
|
|
/**
|
|
* An |Authenticator| implements an authentication mechanism via various hooks
|
|
* in the client and server debugger socket connection path (see socket.js).
|
|
*
|
|
* |Authenticator|s are stateless objects. Each hook method is passed the state
|
|
* it needs by the client / server code in socket.js.
|
|
*
|
|
* Separate instances of the |Authenticator| are created for each use (client
|
|
* connection, server listener) in case some methods are customized by the
|
|
* embedder for a given use case.
|
|
*/
|
|
var Authenticators = {};
|
|
|
|
/**
|
|
* The Prompt authenticator displays a server-side user prompt that includes
|
|
* connection details, and asks the user to verify the connection. There are
|
|
* no cryptographic properties at work here, so it is up to the user to be sure
|
|
* that the client can be trusted.
|
|
*/
|
|
var Prompt = (Authenticators.Prompt = {});
|
|
|
|
Prompt.mode = "PROMPT";
|
|
|
|
Prompt.Client = function () {};
|
|
Prompt.Client.prototype = {
|
|
mode: Prompt.mode,
|
|
|
|
/**
|
|
* When client is about to make a new connection, verify that the connection settings
|
|
* are compatible with this authenticator.
|
|
* @throws if validation requirements are not met
|
|
*/
|
|
validateSettings() {},
|
|
|
|
/**
|
|
* When client has just made a new socket connection, validate the connection
|
|
* to ensure it meets the authenticator's policies.
|
|
*
|
|
* @param host string
|
|
* The host name or IP address of the devtools server.
|
|
* @param port number
|
|
* The port number of the devtools server.
|
|
* @param encryption boolean (optional)
|
|
* Whether the server requires encryption. Defaults to false.
|
|
* @param s nsISocketTransport
|
|
* Underlying socket transport, in case more details are needed.
|
|
* @return boolean
|
|
* Whether the connection is valid.
|
|
*/
|
|
validateConnection() {
|
|
return true;
|
|
},
|
|
|
|
/**
|
|
* Work with the server to complete any additional steps required by this
|
|
* authenticator's policies.
|
|
*
|
|
* Debugging commences after this hook completes successfully.
|
|
*
|
|
* @param host string
|
|
* The host name or IP address of the devtools server.
|
|
* @param port number
|
|
* The port number of the devtools server.
|
|
* @param encryption boolean (optional)
|
|
* Whether the server requires encryption. Defaults to false.
|
|
* @param transport DebuggerTransport
|
|
* A transport that can be used to communicate with the server.
|
|
* @return A promise can be used if there is async behavior.
|
|
*/
|
|
authenticate() {},
|
|
};
|
|
|
|
Prompt.Server = function () {};
|
|
Prompt.Server.prototype = {
|
|
mode: Prompt.mode,
|
|
|
|
/**
|
|
* Augment the service discovery advertisement with any additional data needed
|
|
* to support this authentication mode.
|
|
*
|
|
* @param listener SocketListener
|
|
* The socket listener that was just opened.
|
|
* @param advertisement object
|
|
* The advertisement being built.
|
|
*/
|
|
augmentAdvertisement(listener, advertisement) {
|
|
advertisement.authentication = Prompt.mode;
|
|
},
|
|
|
|
/**
|
|
* Determine whether a connection the server should be allowed or not based on
|
|
* this authenticator's policies.
|
|
*
|
|
* @param session object
|
|
* In PROMPT mode, the |session| includes:
|
|
* {
|
|
* client: {
|
|
* host,
|
|
* port
|
|
* },
|
|
* server: {
|
|
* host,
|
|
* port
|
|
* },
|
|
* transport
|
|
* }
|
|
* @return An AuthenticationResult value.
|
|
* A promise that will be resolved to the above is also allowed.
|
|
*/
|
|
authenticate({ client, server }) {
|
|
if (!Services.prefs.getBoolPref("devtools.debugger.prompt-connection")) {
|
|
return AuthenticationResult.ALLOW;
|
|
}
|
|
return this.allowConnection({
|
|
authentication: this.mode,
|
|
client,
|
|
server,
|
|
});
|
|
},
|
|
|
|
/**
|
|
* Prompt the user to accept or decline the incoming connection. The default
|
|
* implementation is used unless this is overridden on a particular
|
|
* authenticator instance.
|
|
*
|
|
* It is expected that the implementation of |allowConnection| will show a
|
|
* prompt to the user so that they can allow or deny the connection.
|
|
*
|
|
* @param session object
|
|
* In PROMPT mode, the |session| includes:
|
|
* {
|
|
* authentication: "PROMPT",
|
|
* client: {
|
|
* host,
|
|
* port
|
|
* },
|
|
* server: {
|
|
* host,
|
|
* port
|
|
* }
|
|
* }
|
|
* @return An AuthenticationResult value.
|
|
* A promise that will be resolved to the above is also allowed.
|
|
*/
|
|
allowConnection: prompt.Server.defaultAllowConnection,
|
|
};
|
|
|
|
exports.Authenticators = {
|
|
get(mode) {
|
|
if (!mode) {
|
|
mode = Prompt.mode;
|
|
}
|
|
for (const key in Authenticators) {
|
|
const auth = Authenticators[key];
|
|
if (auth.mode === mode) {
|
|
return auth;
|
|
}
|
|
}
|
|
throw new Error("Unknown authenticator mode: " + mode);
|
|
},
|
|
};
|