blob: 6140ae31d89e6d58dad4753bba4033d38374530a [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 "content/public/browser/browser_context.h"
#include "content/public/common/socket_permission_request.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/api/sockets/sockets_manifest_data.h"
#include "extensions/common/constants.h"
#include "url/gurl.h"
namespace {
bool IsLockedToExtension(const GURL& lock_url) {
return lock_url.SchemeIs(extensions::kExtensionScheme);
}
const extensions::Extension* GetExtensionByLockUrl(
content::BrowserContext* browser_context,
const GURL& lock_url) {
return extensions::ExtensionRegistry::Get(browser_context)
->enabled_extensions()
.GetExtensionOrAppByURL(lock_url);
}
} // namespace
bool ChromeDirectSocketsDelegate::ValidateAddressAndPort(
content::BrowserContext* browser_context,
const GURL& lock_url,
const std::string& address,
uint16_t port,
ProtocolType protocol) const {
if (!IsLockedToExtension(lock_url)) {
return true;
}
// If we're running an extension, follow the chrome.sockets.* permission
// model.
auto* extension = GetExtensionByLockUrl(browser_context, lock_url);
DCHECK(extension);
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});
}
}