[ VM / Service / Observatory ] The VM service now requires an authentication code by default.

Previously, a valid web socket connection would use the following URI:

`ws://127.0.0.1/ws`

Now, by default, the VM service requires a connection to be made with a
URI similar to the following:

`ws://127.0.0.1:8181/Ug_U0QVsqFs=/ws`

where `Ug_U0QVsqFs` is an authentication code generated and shared by the
service.

This behavior can be disabled with the `--disable-service-auth-codes`
flag.

Change-Id: I288aac58e3ba9d35dca8071f3f7e7a073896c271
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/98433
Commit-Queue: Ben Konyi <bkonyi@google.com>
Reviewed-by: Siva Annamalai <asiva@google.com>
This commit is contained in:
Ben Konyi 2019-04-09 22:57:29 +00:00
parent e88363cffd
commit 15b11b0183
18 changed files with 44 additions and 20 deletions

View file

@ -8,6 +8,9 @@
### Dart VM
* The VM service now requires an authentication code by default. This behavior
can be disabled by providing the `--disable-service-auth-codes` flag.
### Tool Changes
#### Linter

View file

@ -80,7 +80,7 @@
'alexmarkov@google.com' ],
'messages_review': [ 'dart-uxr+reviews@google.com' ],
'mirrors' : [ 'rmacnak@google.com' ],
'observatory': [ 'rmacnak@google.com' ],
'observatory': [ 'bkonyi@google.com', 'rmacnak@google.com' ],
'package_vm': [ 'alexmarkov@google.com' ],
'runtime': [ 'vm-dev@dartlang.org' ],
'vm_compiler': [ 'dart-vm-compiler-team+reviews@google.com' ],

View file

@ -712,6 +712,7 @@ class Server {
if (Platform.packageConfig != null) {
arguments.add('--packages=${Platform.packageConfig}');
}
arguments.add('--disable-service-auth-codes');
//
// Add the server executable.
//

View file

@ -103,6 +103,7 @@ abstract class TestCase {
var vmArgs = [
'--enable-vm-service=0', // Note: use 0 to avoid port collisions.
'--pause_isolates_on_start',
'--disable-service-auth-codes',
outputUri.toFilePath()
];
vmArgs.add('$reloadCount');

View file

@ -408,6 +408,7 @@ main() {
vm = await Process.start(Platform.resolvedExecutable, <String>[
"--pause-isolates-on-exit",
"--enable-vm-service:0",
"--disable-service-auth-codes",
list.path
]);
@ -469,6 +470,7 @@ main() {
'--trace_reload_verbose',
'--enable-vm-service=0', // Note: use 0 to avoid port collisions.
'--pause_isolates_on_start',
'--disable-service-auth-codes',
outputFile.path
];
final vm = await Process.start(Platform.resolvedExecutable, vmArgs);

View file

@ -88,7 +88,8 @@ Dart_Isolate CreateVmServiceIsolate(const IsolateCreationData& data,
Dart_EnterScope();
// Load embedder specific bits and return.
if (!bin::VmService::Setup(config.ip, config.port, config.dev_mode,
/*trace_loading=*/false, config.deterministic)) {
config.disable_auth_codes, /*trace_loading=*/false,
config.deterministic)) {
*error = strdup(bin::VmService::GetErrorMessage());
return nullptr;
}

View file

@ -509,10 +509,10 @@ static Dart_Isolate CreateAndSetupServiceIsolate(const char* script_uri,
CHECK_RESULT(result);
// Load embedder specific bits and return.
if (!VmService::Setup(Options::vm_service_server_ip(),
Options::vm_service_server_port(),
Options::vm_service_dev_mode(),
Options::trace_loading(), Options::deterministic())) {
if (!VmService::Setup(
Options::vm_service_server_ip(), Options::vm_service_server_port(),
Options::vm_service_dev_mode(), Options::vm_service_auth_disabled(),
Options::trace_loading(), Options::deterministic())) {
*error = strdup(VmService::GetErrorMessage());
return NULL;
}

View file

@ -38,6 +38,7 @@ namespace bin {
V(version, version_option) \
V(compile_all, compile_all) \
V(disable_service_origin_check, vm_service_dev_mode) \
V(disable_service_auth_codes, vm_service_auth_disabled) \
V(deterministic, deterministic) \
V(trace_loading, trace_loading) \
V(short_socket_read, short_socket_read) \

View file

@ -147,6 +147,7 @@ class Server {
final String _ip;
final int _port;
final bool _originCheckDisabled;
final bool _authCodesDisabled;
HttpServer _server;
bool get running => _server != null;
@ -157,11 +158,15 @@ class Server {
}
var ip = _server.address.address;
var port = _server.port;
var path = useAuthToken ? "$serviceAuthToken/" : "/";
var path = !_authCodesDisabled ? "$serviceAuthToken/" : "/";
return new Uri(scheme: 'http', host: ip, port: port, path: path);
}
Server(this._service, this._ip, this._port, this._originCheckDisabled);
// On Fuchsia, authentication codes are disabled by default. To enable, the authentication token
// would have to be written into the hub alongside the port number.
Server(this._service, this._ip, this._port, this._originCheckDisabled,
bool authCodesDisabled)
: _authCodesDisabled = (authCodesDisabled || Platform.isFuchsia);
bool _isAllowedOrigin(String origin) {
Uri uri;
@ -214,7 +219,7 @@ class Server {
/// Checks the [requestUri] for the service auth token and returns the path.
/// If the service auth token check fails, returns null.
String _checkAuthTokenAndGetPath(Uri requestUri) {
if (!useAuthToken) {
if (_authCodesDisabled) {
return requestUri.path == '/' ? ROOT_REDIRECT_PATH : requestUri.path;
}
final List<String> requestPathSegments = requestUri.pathSegments;

View file

@ -23,6 +23,9 @@ String _ip;
// Should the HTTP server auto start?
@pragma("vm:entry-point")
bool _autoStart;
// Should the HTTP server require an auth code?
@pragma("vm:entry-point")
bool _authCodesDisabled;
// Should the HTTP server run in devmode?
@pragma("vm:entry-point")
bool _originCheckDisabled;
@ -45,7 +48,8 @@ _lazyServerBoot() {
// Lazily create service.
var service = new VMService();
// Lazily create server.
server = new Server(service, _ip, _port, _originCheckDisabled);
server =
new Server(service, _ip, _port, _originCheckDisabled, _authCodesDisabled);
}
Future cleanupCallback() async {

View file

@ -113,6 +113,7 @@ void VmService::SetNativeResolver() {
bool VmService::Setup(const char* server_ip,
intptr_t server_port,
bool dev_mode_server,
bool auth_codes_disabled,
bool trace_loading,
bool deterministic) {
Dart_Isolate isolate = Dart_CurrentIsolate();
@ -169,6 +170,11 @@ bool VmService::Setup(const char* server_ip,
SHUTDOWN_ON_ERROR(result);
result = Dart_SetField(library, DartUtils::NewString("_originCheckDisabled"),
Dart_NewBoolean(dev_mode_server));
SHUTDOWN_ON_ERROR(result);
result = Dart_SetField(library, DartUtils::NewString("_authCodesDisabled"),
Dart_NewBoolean(auth_codes_disabled));
SHUTDOWN_ON_ERROR(result);
// Are we running on Windows?
#if defined(HOST_OS_WINDOWS)

View file

@ -17,6 +17,7 @@ class VmService {
static bool Setup(const char* server_ip,
intptr_t server_port,
bool dev_mode_server,
bool auth_codes_disabled,
bool trace_loading,
bool deterministic);

View file

@ -60,6 +60,7 @@ struct VmServiceConfiguration {
// TODO(vegorov) document these ones.
bool dev_mode;
bool deterministic;
bool disable_auth_codes;
};
// Create and initialize vm-service isolate. This method should be used

View file

@ -62,8 +62,8 @@ Follow the code review [instructions][code_review] to be able to successfully
submit your code.
The main reviewers for Observatory related CLs are:
- turnidge
- johnmccutchan
- asiva
- bkonyi
- rmacnak
## Write a new service test

View file

@ -52,9 +52,7 @@ class _IOWebSocket implements CommonWebSocket {
}
}
/// The [WebSocketVM] communicates with a Dart VM over WebSocket. The Dart VM
/// can be embedded in Chromium or standalone. In the case of Chromium, we
/// make the service requests via the Chrome Remote Debugging Protocol.
/// The [WebSocketVM] communicates with a Dart VM over WebSocket.
class WebSocketVM extends CommonWebSocketVM {
WebSocketVM(WebSocketVMTarget target) : super(target, new _IOWebSocket());
}

View file

@ -120,7 +120,7 @@ class TargetRepository implements M.TargetRepository {
scheme: 'ws',
host: host ?? serverAddress.host,
port: int.tryParse(port ?? '') ?? serverAddress.port,
path: '/ws',
path: serverAddress.path.isEmpty ? '/ws' : serverAddress.path + 'ws',
);
return wsAddress.toString();
}

View file

@ -132,6 +132,9 @@ class _ServiceTesteeLauncher {
if (pause_on_exit) {
fullArgs.add('--pause-isolates-on-exit');
}
if (!useAuthToken) {
fullArgs.add('--disable-service-auth-codes');
}
if (pause_on_unhandled_exceptions) {
fullArgs.add('--pause-isolates-on-unhandled-exceptions');
}
@ -147,7 +150,7 @@ class _ServiceTesteeLauncher {
fullArgs.addAll(args);
return _spawnCommon(dartExecutable, fullArgs,
<String, String>{'DART_SERVICE_USE_AUTH': '$useAuthToken'});
<String, String>{});
}
Future<Process> _spawnSkyProcess(

View file

@ -41,9 +41,6 @@ String _makeAuthToken() {
// The randomly generated auth token used to access the VM service.
final String serviceAuthToken = _makeAuthToken();
// TODO(johnmccutchan): Enable the auth token and drop the origin check.
final bool useAuthToken = new bool.fromEnvironment('DART_SERVICE_USE_AUTH');
// This is for use by the embedder. It is a map from the isolateId to
// anything implementing IsolateEmbedderData. When an isolate goes away,
// the cleanup method will be invoked after being removed from the map.