Bug 1103120 - Part 6: Server: Move allowConnection to authenticator. r=past

This commit is contained in:
J. Ryan Stinnett 2015-01-26 12:47:13 -06:00
parent 6208e96958
commit f7dece0433
10 changed files with 125 additions and 25 deletions

View File

@ -141,9 +141,12 @@ let USBRemoteDebugger = {
try {
debug("Starting USB debugger on " + portOrPath);
let AuthenticatorType = DebuggerServer.Authenticators.get("PROMPT");
let authenticator = new AuthenticatorType.Server();
authenticator.allowConnection = RemoteDebugger.prompt;
this._listener = DebuggerServer.createListener();
this._listener.portOrPath = portOrPath;
this._listener.allowConnection = RemoteDebugger.prompt;
this._listener.authenticator = authenticator;
this._listener.open();
// Temporary event, until bug 942756 lands and offers a way to know
// when the server is up and running.
@ -179,9 +182,12 @@ let WiFiRemoteDebugger = {
try {
debug("Starting WiFi debugger");
let AuthenticatorType = DebuggerServer.Authenticators.get("PROMPT");
let authenticator = new AuthenticatorType.Server();
authenticator.allowConnection = RemoteDebugger.prompt;
this._listener = DebuggerServer.createListener();
this._listener.portOrPath = -1 /* any available port */;
this._listener.allowConnection = RemoteDebugger.prompt;
this._listener.authenticator = authenticator;
this._listener.discoverable = true;
this._listener.encryption = true;
this._listener.open();

View File

@ -7358,9 +7358,12 @@ var RemoteDebugger = {
let pathOrPort = this._getPath();
if (!pathOrPort)
pathOrPort = this._getPort();
let AuthenticatorType = DebuggerServer.Authenticators.get("PROMPT");
let authenticator = new AuthenticatorType.Server();
authenticator.allowConnection = this._showConnectionPrompt.bind(this);
let listener = DebuggerServer.createListener();
listener.portOrPath = pathOrPort;
listener.allowConnection = this._showConnectionPrompt.bind(this);
listener.authenticator = authenticator;
listener.open();
dump("Remote debugger listening at path " + pathOrPort);
} catch(e) {

View File

@ -437,9 +437,13 @@ function _initDebugging(port) {
do_print("*******************************************************************");
do_print("")
let AuthenticatorType = DebuggerServer.Authenticators.get("PROMPT");
let authenticator = new AuthenticatorType.Server();
authenticator.allowConnection = () => true;
let listener = DebuggerServer.createListener();
listener.portOrPath = port;
listener.allowConnection = () => true;
listener.authenticator = authenticator;
listener.open();
// spin an event loop until the debugger connects.

View File

@ -6,6 +6,10 @@
"use strict";
let Services = require("Services");
loader.lazyRequireGetter(this, "prompt",
"devtools/toolkit/security/prompt");
/**
* An |Authenticator| implements an authentication mechanism via various hooks
* in the client and server debugger socket connection path (see socket.js).
@ -63,6 +67,42 @@ Prompt.Server.prototype = {
advertisement.authentication = Prompt.mode;
},
/**
* Determine whether a connection the server should be allowed or not based on
* this authenticator's policies.
*
* @return true if the connection should be permitted, false otherwise
*/
authenticate() {
return !Services.prefs.getBoolPref("devtools.debugger.prompt-connection") ||
this.allowConnection();
},
/**
* Prompt the user to accept or decline the incoming connection. The default
* implementation is used unless this is overridden on a particular
* authenticator instance.
*
* In PROMPT mode, the |allowConnection| method is provided:
* {
* authentication: "PROMPT",
* client: {
* host,
* port
* },
* server: {
* host,
* port
* }
* }
*
* It is expected that the implementation of |allowConnection| will show a
* prompt to the user so that they can allow or deny the connection.
*
* @return true if the connection should be permitted, false otherwise
*/
allowConnection: prompt.Server.defaultAllowConnection,
};
/**
@ -131,6 +171,47 @@ OOBCert.Server.prototype = {
};
},
/**
* Determine whether a connection the server should be allowed or not based on
* this authenticator's policies.
*
* @return true if the connection should be permitted, false otherwise
*/
authenticate() {
return this.allowConnection();
},
/**
* Prompt the user to accept or decline the incoming connection. The default
* implementation is used unless this is overridden on a particular
* authenticator instance.
*
* In OOB_CERT mode, the |allowConnection| method is provided:
* {
* authentication: "OOB_CERT",
* client: {
* host,
* port,
* cert: {
* sha256
* },
* },
* server: {
* host,
* port,
* cert: {
* sha256
* }
* }
* }
*
* It is expected that the implementation of |allowConnection| will show a
* prompt to the user so that they can allow or deny the connection.
*
* @return true if the connection should be permitted, false otherwise
*/
allowConnection: prompt.Server.defaultAllowConnection,
};
exports.Authenticators = {

View File

@ -21,8 +21,8 @@ let Server = exports.Server = {};
/**
* 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. A separate security handler can be specified for each
* socket via |allowConnection| on a socket listener instance.
* choose to override. This can be overridden via |allowConnection| on the
* socket's authenticator instance.
*
* @return true if the connection should be permitted, false otherwise
*/

View File

@ -25,8 +25,6 @@ loader.lazyRequireGetter(this, "cert",
"devtools/toolkit/security/cert");
loader.lazyRequireGetter(this, "Authenticators",
"devtools/toolkit/security/auth", true);
loader.lazyRequireGetter(this, "prompt",
"devtools/toolkit/security/prompt");
loader.lazyRequireGetter(this, "setTimeout", "Timer", true);
loader.lazyRequireGetter(this, "clearTimeout", "Timer", true);
@ -226,15 +224,6 @@ SocketListener.prototype = {
*/
portOrPath: null,
/**
* Prompt the user to accept or decline the incoming connection. The default
* implementation is used unless this is overridden on a particular socket
* listener instance.
*
* @return true if the connection should be permitted, false otherwise
*/
allowConnection: prompt.Server.defaultAllowConnection,
/**
* Controls whether this listener is announced via the service discovery
* mechanism.
@ -512,8 +501,7 @@ ServerSocketConnection.prototype = {
},
_authenticate() {
if (Services.prefs.getBoolPref("devtools.debugger.prompt-connection") &&
!this._listener.allowConnection()) {
if (!this._listener.authenticator.authenticate()) {
return promise.reject(Cr.NS_ERROR_CONNECTION_REFUSED);
}
return promise.resolve();

View File

@ -28,10 +28,14 @@ add_task(function*() {
add_task(function*() {
equal(DebuggerServer.listeningSockets, 0, "0 listening sockets");
let AuthenticatorType = DebuggerServer.Authenticators.get("PROMPT");
let authenticator = new AuthenticatorType.Server();
authenticator.allowConnection = () => true;
let listener = DebuggerServer.createListener();
ok(listener, "Socket listener created");
listener.portOrPath = -1 /* any available port */;
listener.allowConnection = () => true;
listener.authenticator = authenticator;
listener.encryption = true;
yield listener.open();
equal(DebuggerServer.listeningSockets, 1, "1 listening socket");
@ -69,10 +73,14 @@ add_task(function*() {
add_task(function*() {
equal(DebuggerServer.listeningSockets, 0, "0 listening sockets");
let AuthenticatorType = DebuggerServer.Authenticators.get("PROMPT");
let authenticator = new AuthenticatorType.Server();
authenticator.allowConnection = () => true;
let listener = DebuggerServer.createListener();
ok(listener, "Socket listener created");
listener.portOrPath = -1 /* any available port */;
listener.allowConnection = () => true;
listener.authenticator = authenticator;
listener.encryption = true;
yield listener.open();
equal(DebuggerServer.listeningSockets, 1, "1 listening socket");

View File

@ -261,9 +261,12 @@ function writeTestTempFile(aFileName, aContent) {
let socket_transport = Task.async(function*() {
if (!DebuggerServer.listeningSockets) {
let AuthenticatorType = DebuggerServer.Authenticators.get("PROMPT");
let authenticator = new AuthenticatorType.Server();
authenticator.allowConnection = () => true;
let listener = DebuggerServer.createListener();
listener.portOrPath = -1 /* any available port */;
listener.allowConnection = () => true;
listener.authenticator = authenticator;
yield listener.open();
}
let port = DebuggerServer._listeners[0].port;

View File

@ -22,10 +22,13 @@ function run_test()
function* test_socket_conn()
{
do_check_eq(DebuggerServer.listeningSockets, 0);
let AuthenticatorType = DebuggerServer.Authenticators.get("PROMPT");
let authenticator = new AuthenticatorType.Server();
authenticator.allowConnection = () => true;
let listener = DebuggerServer.createListener();
do_check_true(listener);
listener.portOrPath = -1 /* any available port */;
listener.allowConnection = () => true;
listener.authenticator = authenticator;
listener.open();
do_check_eq(DebuggerServer.listeningSockets, 1);
gPort = DebuggerServer._listeners[0].port;
@ -33,7 +36,7 @@ function* test_socket_conn()
// Open a second, separate listener
gExtraListener = DebuggerServer.createListener();
gExtraListener.portOrPath = -1;
gExtraListener.allowConnection = () => true;
gExtraListener.authenticator = authenticator;
gExtraListener.open();
do_check_eq(DebuggerServer.listeningSockets, 2);

View File

@ -47,9 +47,13 @@ function test_socket_conn_drops_after_too_long_header() {
}
let test_helper = Task.async(function*(payload) {
let AuthenticatorType = DebuggerServer.Authenticators.get("PROMPT");
let authenticator = new AuthenticatorType.Server();
authenticator.allowConnection = () => true;
let listener = DebuggerServer.createListener();
listener.portOrPath = -1;
listener.allowConnection = () => true;
listener.authenticator = authenticator;
listener.open();
let transport = yield DebuggerClient.socketConnect({