blob: be3601f8c64ee67d8ee51a744f27d5a9e215f262 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/direct_sockets/chrome_direct_sockets_delegate.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/socket_permission_request.h"
#include "extensions/browser/process_map.h"
#include "extensions/common/api/sockets/sockets_manifest_data.h"
bool ChromeDirectSocketsDelegate::IsAPIAccessAllowed(
content::RenderFrameHost& rfh) {
const GURL& url = rfh.GetLastCommittedURL();
return HostContentSettingsMapFactory::GetForProfile(rfh.GetBrowserContext())
->GetContentSetting(url, url,
ContentSettingsType::DIRECT_SOCKETS) ==
CONTENT_SETTING_ALLOW;
}
bool ChromeDirectSocketsDelegate::ValidateAddressAndPort(
content::RenderFrameHost& rfh,
const std::string& address,
uint16_t port,
ProtocolType protocol) {
int32_t process_id = rfh.GetProcess()->GetID();
auto* process_map = extensions::ProcessMap::Get(rfh.GetBrowserContext());
if (!process_map->Contains(process_id)) {
// Additional restrictions are imposed only on extension-like contexts.
return true;
}
// If we're running an extension, follow the chrome.sockets.* permission
// model.
const extensions::Extension* extension =
process_map->GetEnabledExtensionByProcessID(process_id);
if (!extension) {
return false;
}
switch (protocol) {
case ProtocolType::kTcp:
return extensions::SocketsManifestData::CheckRequest(
extension,
/*request=*/{content::SocketPermissionRequest::TCP_CONNECT, address,
port});
case ProtocolType::kConnectedUdp:
return extensions::SocketsManifestData::CheckRequest(
extension,
/*request=*/{content::SocketPermissionRequest::UDP_SEND_TO, address,
port});
case ProtocolType::kBoundUdp:
// For kBoundUdp we check both UDP_BIND for the given |address| and
// |port| as well as ensure that UDP_SEND_TO allows routing packets
// anywhere. '*' is the wildcard address, 0 is the wildcard port.
return extensions::SocketsManifestData::CheckRequest(
extension,
/*request=*/{content::SocketPermissionRequest::UDP_BIND,
address, port}) &&
extensions::SocketsManifestData::CheckRequest(
extension,
/*request=*/{content::SocketPermissionRequest::UDP_SEND_TO,
/*host=*/"*", /*port=*/0});
case ProtocolType::kTcpServer:
return extensions::SocketsManifestData::CheckRequest(
extension, /*request=*/{content::SocketPermissionRequest::TCP_LISTEN,
address, port});
}
}