123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179 |
- /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
- /* 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";
- var { Ci } = require("chrome");
- var Services = require("Services");
- var DevToolsUtils = require("devtools/shared/DevToolsUtils");
- loader.lazyRequireGetter(this, "DebuggerSocket",
- "devtools/shared/security/socket", true);
- loader.lazyRequireGetter(this, "AuthenticationResult",
- "devtools/shared/security/auth", true);
- const {LocalizationHelper} = require("devtools/shared/l10n");
- const L10N = new LocalizationHelper("devtools/shared/locales/debugger.properties");
- var Client = exports.Client = {};
- var Server = exports.Server = {};
- /**
- * During OOB_CERT authentication, a notification dialog like this is used to
- * to display a token which the user must transfer through some mechanism to the
- * server to authenticate the devices.
- *
- * This implementation presents the token as text for the user to transfer
- * manually. For a mobile device, you should override this implementation with
- * something more convenient, such as displaying a QR code.
- *
- * @param host string
- * The host name or IP address of the debugger server.
- * @param port number
- * The port number of the debugger server.
- * @param cert object (optional)
- * The server's cert details.
- * @param authResult AuthenticationResult
- * Authentication result sent from the server.
- * @param oob object (optional)
- * The token data to be transferred during OOB_CERT step 8:
- * * sha256: hash(ClientCert)
- * * k : K(random 128-bit number)
- * @return object containing:
- * * close: Function to hide the notification
- */
- Client.defaultSendOOB = ({ authResult, oob }) => {
- // Only show in the PENDING state
- if (authResult != AuthenticationResult.PENDING) {
- throw new Error("Expected PENDING result, got " + authResult);
- }
- let title = L10N.getStr("clientSendOOBTitle");
- let header = L10N.getStr("clientSendOOBHeader");
- let hashMsg = L10N.getFormatStr("clientSendOOBHash", oob.sha256);
- let token = oob.sha256.replace(/:/g, "").toLowerCase() + oob.k;
- let tokenMsg = L10N.getFormatStr("clientSendOOBToken", token);
- let msg = `${header}\n\n${hashMsg}\n${tokenMsg}`;
- let prompt = Services.prompt;
- let flags = prompt.BUTTON_POS_0 * prompt.BUTTON_TITLE_CANCEL;
- // Listen for the window our prompt opens, so we can close it programatically
- let promptWindow;
- let windowListener = {
- onOpenWindow(xulWindow) {
- let win = xulWindow.QueryInterface(Ci.nsIInterfaceRequestor)
- .getInterface(Ci.nsIDOMWindow);
- win.addEventListener("load", function listener() {
- win.removeEventListener("load", listener, false);
- if (win.document.documentElement.getAttribute("id") != "commonDialog") {
- return;
- }
- // Found the window
- promptWindow = win;
- Services.wm.removeListener(windowListener);
- }, false);
- },
- onCloseWindow() {},
- onWindowTitleChange() {}
- };
- Services.wm.addListener(windowListener);
- // nsIPrompt is typically a blocking API, so |executeSoon| to get around this
- DevToolsUtils.executeSoon(() => {
- prompt.confirmEx(null, title, msg, flags, null, null, null, null,
- { value: false });
- });
- return {
- close() {
- if (!promptWindow) {
- return;
- }
- promptWindow.document.documentElement.acceptDialog();
- promptWindow = null;
- }
- };
- };
- /**
- * Prompt the user to accept or decline the incoming connection. This is the
- * default implementation that products embedding the debugger server may
- * choose to override. This can be overridden via |allowConnection| on the
- * socket's authenticator instance.
- *
- * @param session object
- * The session object will contain at least the following fields:
- * {
- * authentication,
- * client: {
- * host,
- * port
- * },
- * server: {
- * host,
- * port
- * }
- * }
- * Specific authentication modes may include additional fields. Check
- * the different |allowConnection| methods in ./auth.js.
- * @return An AuthenticationResult value.
- * A promise that will be resolved to the above is also allowed.
- */
- Server.defaultAllowConnection = ({ client, server }) => {
- let title = L10N.getStr("remoteIncomingPromptTitle");
- let header = L10N.getStr("remoteIncomingPromptHeader");
- let clientEndpoint = `${client.host}:${client.port}`;
- let clientMsg = L10N.getFormatStr("remoteIncomingPromptClientEndpoint", clientEndpoint);
- let serverEndpoint = `${server.host}:${server.port}`;
- let serverMsg = L10N.getFormatStr("remoteIncomingPromptServerEndpoint", serverEndpoint);
- let footer = L10N.getStr("remoteIncomingPromptFooter");
- let msg = `${header}\n\n${clientMsg}\n${serverMsg}\n\n${footer}`;
- let disableButton = L10N.getStr("remoteIncomingPromptDisable");
- let prompt = Services.prompt;
- let flags = prompt.BUTTON_POS_0 * prompt.BUTTON_TITLE_OK +
- prompt.BUTTON_POS_1 * prompt.BUTTON_TITLE_CANCEL +
- prompt.BUTTON_POS_2 * prompt.BUTTON_TITLE_IS_STRING +
- prompt.BUTTON_POS_1_DEFAULT;
- let result = prompt.confirmEx(null, title, msg, flags, null, null,
- disableButton, null, { value: false });
- if (result === 0) {
- return AuthenticationResult.ALLOW;
- }
- if (result === 2) {
- return AuthenticationResult.DISABLE_ALL;
- }
- return AuthenticationResult.DENY;
- };
- /**
- * During OOB_CERT authentication, the user must transfer some data through some
- * out of band mechanism from the client to the server to authenticate the
- * devices.
- *
- * This implementation prompts the user for a token as constructed by
- * |Client.defaultSendOOB| that the user needs to transfer manually. For a
- * mobile device, you should override this implementation with something more
- * convenient, such as reading a QR code.
- *
- * @return An object containing:
- * * sha256: hash(ClientCert)
- * * k : K(random 128-bit number)
- * A promise that will be resolved to the above is also allowed.
- */
- Server.defaultReceiveOOB = () => {
- let title = L10N.getStr("serverReceiveOOBTitle");
- let msg = L10N.getStr("serverReceiveOOBBody");
- let input = { value: null };
- let prompt = Services.prompt;
- let result = prompt.prompt(null, title, msg, input, null, { value: false });
- if (!result) {
- return null;
- }
- // Re-create original object from token
- input = input.value.trim();
- let sha256 = input.substring(0, 64);
- sha256 = sha256.replace(/\w{2}/g, "$&:").slice(0, -1).toUpperCase();
- let k = input.substring(64);
- return { sha256, k };
- };
|