forked from chromium/chromium
-
-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Direct Sockets: stub implementations for openTCPSocket openUDPSocket
The rename is tentative, blocked on naming decision WICG/direct-sockets#10 Explainer: https://github.com/WICG/raw-sockets/blob/master/docs/explainer.md Intent to Prototype: https://groups.google.com/a/chromium.org/g/blink-dev/c/ARtkaw4e9T4/m/npjeMssPCAAJ Design doc: https://docs.google.com/document/d/1Xa5nFkIWxkL3hZHvDYWPhT8sZvNeFpCUKNuqIwZHxnE/edit?usp=sharing We introduce IDL methods for opening TCP and UDP sockets. We introduce a mojom service that will perform permission checks before forwarding socket opening requests to the Network Service. Not yet implemented: Permissions checks, calls to Network Service Bug: 909927 Change-Id: Ifec9860d4e0b8211af7b142b856efc29cd6f9b35 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2366395 Reviewed-by: Kinuko Yasuda <kinuko@chromium.org> Reviewed-by: Kentaro Hara <haraken@chromium.org> Reviewed-by: Matt Falkenhagen <falken@chromium.org> Reviewed-by: Glen Robertson <glenrob@chromium.org> Commit-Queue: Eric Willigers <ericwilligers@chromium.org> Auto-Submit: Eric Willigers <ericwilligers@chromium.org> Cr-Commit-Position: refs/heads/master@{#802210}
- Loading branch information
1 parent
41fd12b
commit 852cbbc
Showing
39 changed files
with
892 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
file://third_party/blink/renderer/modules/direct_sockets/OWNERS |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
This directory implements permission and user consent checks for the | ||
browser side of socket opening for the [Direct Sockets API]( | ||
https://github.com/WICG/raw-sockets/blob/master/docs/explainer.md). | ||
|
||
Examples of the checks include | ||
- user dialog, allowing user to enter destination address | ||
- permissions policy | ||
- rate limiting | ||
- checking hostnames resolve to public addresses | ||
- content security policy | ||
|
||
When requests to establish TCP or UDP communication have passed the | ||
various checks, they are forwarded to the network service. |
94 changes: 94 additions & 0 deletions
94
content/browser/direct_sockets/direct_sockets_browsertest.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// Copyright 2020 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "base/run_loop.h" | ||
#include "base/strings/stringprintf.h" | ||
#include "base/test/bind_test_util.h" | ||
#include "base/test/scoped_feature_list.h" | ||
#include "content/browser/direct_sockets/direct_sockets_service_impl.h" | ||
#include "content/public/common/content_features.h" | ||
#include "content/public/test/browser_test.h" | ||
#include "content/public/test/browser_test_utils.h" | ||
#include "content/public/test/content_browser_test.h" | ||
#include "content/public/test/content_browser_test_utils.h" | ||
#include "net/base/net_errors.h" | ||
#include "net/test/embedded_test_server/embedded_test_server.h" | ||
#include "url/gurl.h" | ||
|
||
namespace content { | ||
|
||
class DirectSocketsBrowserTest : public ContentBrowserTest { | ||
public: | ||
DirectSocketsBrowserTest() { | ||
feature_list_.InitAndEnableFeature(features::kDirectSockets); | ||
} | ||
~DirectSocketsBrowserTest() override = default; | ||
|
||
GURL GetTestPageURL() { | ||
return embedded_test_server()->GetURL("/direct_sockets/index.html"); | ||
} | ||
|
||
protected: | ||
void SetUp() override { | ||
embedded_test_server()->AddDefaultHandlers(GetTestDataFilePath()); | ||
ASSERT_TRUE(embedded_test_server()->Start()); | ||
|
||
ContentBrowserTest::SetUp(); | ||
} | ||
|
||
private: | ||
base::test::ScopedFeatureList feature_list_; | ||
}; | ||
|
||
IN_PROC_BROWSER_TEST_F(DirectSocketsBrowserTest, OpenTcp_Success) { | ||
EXPECT_TRUE(NavigateToURL(shell(), GetTestPageURL())); | ||
|
||
DirectSocketsServiceImpl::SetPermissionCallbackForTesting( | ||
base::BindLambdaForTesting( | ||
[&](const blink::mojom::DirectSocketOptions&) { return net::OK; })); | ||
|
||
// TODO(crbug.com/905818): Use port from a listening net::TCPServerSocket. | ||
const std::string script = base::StringPrintf( | ||
"openTcp({remoteAddress: '127.0.0.1', remotePort: %d})", 0); | ||
|
||
EXPECT_EQ("openTcp succeeded", EvalJs(shell(), script)); | ||
} | ||
|
||
IN_PROC_BROWSER_TEST_F(DirectSocketsBrowserTest, OpenTcp_NotAllowedError) { | ||
EXPECT_TRUE(NavigateToURL(shell(), GetTestPageURL())); | ||
|
||
// TODO(crbug.com/905818): Use port from a listening net::TCPServerSocket. | ||
const std::string script = base::StringPrintf( | ||
"openTcp({remoteAddress: '127.0.0.1', remotePort: %d})", 0); | ||
|
||
EXPECT_EQ("openTcp failed: NotAllowedError: Permission denied", | ||
EvalJs(shell(), script)); | ||
} | ||
|
||
IN_PROC_BROWSER_TEST_F(DirectSocketsBrowserTest, OpenUdp_Success) { | ||
EXPECT_TRUE(NavigateToURL(shell(), GetTestPageURL())); | ||
|
||
DirectSocketsServiceImpl::SetPermissionCallbackForTesting( | ||
base::BindLambdaForTesting( | ||
[&](const blink::mojom::DirectSocketOptions&) { return net::OK; })); | ||
|
||
// TODO(crbug.com/1119620): Use port from a listening net::UDPServerSocket. | ||
const std::string script = base::StringPrintf( | ||
"openUdp({remoteAddress: '127.0.0.1', remotePort: %d})", 0); | ||
|
||
EXPECT_EQ("openUdp succeeded", EvalJs(shell(), script)); | ||
} | ||
|
||
IN_PROC_BROWSER_TEST_F(DirectSocketsBrowserTest, OpenUdp_NotAllowedError) { | ||
EXPECT_TRUE(NavigateToURL(shell(), GetTestPageURL())); | ||
|
||
// TODO(crbug.com/1119620): Use port from a listening net::UDPServerSocket. | ||
const std::string script = base::StringPrintf( | ||
"openUdp({remoteAddress: '127.0.0.1', remotePort: %d})", 0); | ||
|
||
EXPECT_EQ("openUdp failed: NotAllowedError: Permission denied", | ||
EvalJs(shell(), script)); | ||
} | ||
|
||
} // namespace content |
117 changes: 117 additions & 0 deletions
117
content/browser/direct_sockets/direct_sockets_service_impl.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// Copyright 2020 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "content/browser/direct_sockets/direct_sockets_service_impl.h" | ||
|
||
#include <memory> | ||
|
||
#include "base/bind.h" | ||
#include "base/feature_list.h" | ||
#include "base/optional.h" | ||
#include "content/public/browser/browser_thread.h" | ||
#include "content/public/browser/storage_partition.h" | ||
#include "content/public/common/content_features.h" | ||
#include "mojo/public/cpp/bindings/self_owned_receiver.h" | ||
|
||
namespace content { | ||
|
||
namespace { | ||
|
||
DirectSocketsServiceImpl::PermissionCallback& | ||
GetPermissionCallbackForTesting() { | ||
static base::NoDestructor<DirectSocketsServiceImpl::PermissionCallback> | ||
callback; | ||
return *callback; | ||
} | ||
|
||
} // namespace | ||
|
||
DirectSocketsServiceImpl::DirectSocketsServiceImpl(RenderFrameHost& frame_host) | ||
: frame_host_(&frame_host) {} | ||
|
||
// static | ||
void DirectSocketsServiceImpl::CreateForFrame( | ||
RenderFrameHost* render_frame_host, | ||
mojo::PendingReceiver<blink::mojom::DirectSocketsService> receiver) { | ||
DCHECK_CURRENTLY_ON(BrowserThread::UI); | ||
mojo::MakeSelfOwnedReceiver( | ||
std::make_unique<DirectSocketsServiceImpl>(*render_frame_host), | ||
std::move(receiver)); | ||
} | ||
|
||
void DirectSocketsServiceImpl::OpenTcpSocket( | ||
blink::mojom::DirectSocketOptionsPtr options, | ||
OpenTcpSocketCallback callback) { | ||
if (!options) { | ||
mojo::ReportBadMessage("Invalid request to open socket"); | ||
return; | ||
} | ||
net::Error result = EnsurePermission(*options); | ||
|
||
// TODO(crbug.com/1119681): Collect metrics for usage and permission checks | ||
|
||
if (result == net::OK) { | ||
// TODO(crbug.com/905818): GetNetworkContext()->CreateTCPConnectedSocket | ||
GetNetworkContext(); | ||
NOTIMPLEMENTED(); | ||
} | ||
|
||
std::move(callback).Run(result); | ||
} | ||
|
||
void DirectSocketsServiceImpl::OpenUdpSocket( | ||
blink::mojom::DirectSocketOptionsPtr options, | ||
OpenUdpSocketCallback callback) { | ||
if (!options) { | ||
mojo::ReportBadMessage("Invalid request to open socket"); | ||
return; | ||
} | ||
net::Error result = EnsurePermission(*options); | ||
|
||
// TODO(crbug.com/1119681): Collect metrics for usage and permission checks | ||
|
||
if (result == net::OK) { | ||
// TODO(crbug.com/1119620): GetNetworkContext()->CreateUDPSocket | ||
GetNetworkContext(); | ||
NOTIMPLEMENTED(); | ||
} | ||
|
||
std::move(callback).Run(result); | ||
} | ||
|
||
// static | ||
void DirectSocketsServiceImpl::SetPermissionCallbackForTesting( | ||
PermissionCallback callback) { | ||
GetPermissionCallbackForTesting() = std::move(callback); | ||
} | ||
|
||
net::Error DirectSocketsServiceImpl::EnsurePermission( | ||
const blink::mojom::DirectSocketOptions& options) { | ||
DCHECK(base::FeatureList::IsEnabled(features::kDirectSockets)); | ||
|
||
if (GetPermissionCallbackForTesting()) | ||
return GetPermissionCallbackForTesting().Run(options); | ||
|
||
if (options.send_buffer_size < 0 || options.receive_buffer_size < 0) | ||
return net::ERR_INVALID_ARGUMENT; | ||
|
||
// TODO(crbug.com/1119662): Check for enterprise software policies. | ||
// TODO(crbug.com/1119659): Check permissions policy. | ||
// TODO(crbug.com/1119600): Check for transient activation. | ||
// TODO(crbug.com/1119600): Implement rate limiting. | ||
// TODO(crbug.com/1119601): Check CORS iff requested port is HTTPS. | ||
|
||
// EnsurePermission() will need to become asynchronous: | ||
// TODO(crbug.com/1119597): Show consent dialog | ||
// TODO(crbug.com/1119661): Reject hostnames that resolve to non-public | ||
// addresses. | ||
|
||
return net::ERR_NOT_IMPLEMENTED; | ||
} | ||
|
||
network::mojom::NetworkContext* DirectSocketsServiceImpl::GetNetworkContext() { | ||
return frame_host_->GetStoragePartition()->GetNetworkContext(); | ||
} | ||
|
||
} // namespace content |
60 changes: 60 additions & 0 deletions
60
content/browser/direct_sockets/direct_sockets_service_impl.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// Copyright 2020 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CONTENT_BROWSER_DIRECT_SOCKETS_DIRECT_SOCKETS_SERVICE_IMPL_H_ | ||
#define CONTENT_BROWSER_DIRECT_SOCKETS_DIRECT_SOCKETS_SERVICE_IMPL_H_ | ||
|
||
#include <string> | ||
|
||
#include "base/callback.h" | ||
#include "content/common/content_export.h" | ||
#include "content/public/browser/render_frame_host.h" | ||
#include "mojo/public/cpp/bindings/pending_receiver.h" | ||
#include "net/base/net_errors.h" | ||
#include "third_party/blink/public/mojom/direct_sockets/direct_sockets.mojom.h" | ||
|
||
namespace network { | ||
namespace mojom { | ||
class NetworkContext; | ||
} | ||
} // namespace network | ||
|
||
namespace content { | ||
|
||
// Implementation of the DirectSocketsService Mojo service. | ||
class CONTENT_EXPORT DirectSocketsServiceImpl | ||
: public blink::mojom::DirectSocketsService { | ||
public: | ||
using PermissionCallback = base::RepeatingCallback<net::Error( | ||
const blink::mojom::DirectSocketOptions&)>; | ||
|
||
explicit DirectSocketsServiceImpl(RenderFrameHost& frame_host); | ||
~DirectSocketsServiceImpl() override = default; | ||
|
||
DirectSocketsServiceImpl(const DirectSocketsServiceImpl&) = delete; | ||
DirectSocketsServiceImpl& operator=(const DirectSocketsServiceImpl&) = delete; | ||
|
||
static void CreateForFrame( | ||
RenderFrameHost* render_frame_host, | ||
mojo::PendingReceiver<blink::mojom::DirectSocketsService> receiver); | ||
|
||
// blink::mojom::DirectSocketsService override: | ||
void OpenTcpSocket(blink::mojom::DirectSocketOptionsPtr options, | ||
OpenTcpSocketCallback callback) override; | ||
void OpenUdpSocket(blink::mojom::DirectSocketOptionsPtr options, | ||
OpenUdpSocketCallback callback) override; | ||
|
||
static void SetPermissionCallbackForTesting(PermissionCallback callback); | ||
|
||
private: | ||
net::Error EnsurePermission(const blink::mojom::DirectSocketOptions& options); | ||
|
||
network::mojom::NetworkContext* GetNetworkContext(); | ||
|
||
RenderFrameHost* const frame_host_; | ||
}; | ||
|
||
} // namespace content | ||
|
||
#endif // CONTENT_BROWSER_DIRECT_SOCKETS_DIRECT_SOCKETS_SERVICE_IMPL_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<title>Direct Sockets Test</title> | ||
<script> | ||
'use strict'; | ||
|
||
async function openTcp(options) { | ||
try { | ||
let tcpSocket = await navigator.openTCPSocket(options); | ||
return 'openTcp succeeded'; | ||
} catch(error) { | ||
return ('openTcp failed: ' + error); | ||
} | ||
} | ||
|
||
async function openUdp(options) { | ||
try { | ||
let udpSocket = await navigator.openUDPSocket(options); | ||
return 'openUdp succeeded'; | ||
} catch(error) { | ||
return ('openUdp failed: ' + error); | ||
} | ||
} | ||
|
||
</script> | ||
</head> | ||
<body> | ||
<h1>Direct Sockets Test</h1> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.