1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
|
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "remoting/base/corp_session_authz_service_client.h"
#include <memory>
#include <utility>
#include "base/functional/bind.h"
#include "base/strings/strcat.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "remoting/base/internal_headers.h"
#include "remoting/base/protobuf_http_request.h"
#include "remoting/base/protobuf_http_request_config.h"
#include "remoting/base/service_urls.h"
#include "remoting/proto/session_authz_service.h"
namespace remoting {
namespace {
template <typename Type>
using ResponseCallback =
base::OnceCallback<void(const HttpStatus&, std::unique_ptr<Type>)>;
template <typename ProtoType, typename StructType>
using ConversionFunction = std::unique_ptr<StructType> (*)(const ProtoType&);
// Creates a callback that takes a response of `ProtoType`, which, upon
// invocation, converts it to a response of `StructType` by calling
// `conversion_function`, then calls `struct_callback`
template <typename ProtoType, typename StructType>
ResponseCallback<ProtoType> ConvertCallback(
ResponseCallback<StructType> struct_callback,
ConversionFunction<ProtoType, StructType> conversion_function) {
return base::BindOnce(
[](ResponseCallback<StructType> struct_callback,
ConversionFunction<ProtoType, StructType> conversion_function,
const HttpStatus& status, std::unique_ptr<ProtoType> proto_type) {
std::move(struct_callback)
.Run(status,
proto_type ? conversion_function(*proto_type) : nullptr);
},
std::move(struct_callback), conversion_function);
}
} // namespace
CorpSessionAuthzServiceClient::CorpSessionAuthzServiceClient(
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
std::unique_ptr<net::ClientCertStore> client_cert_store,
std::unique_ptr<OAuthTokenGetter> oauth_token_getter,
std::string_view support_id)
: oauth_token_getter_(std::move(oauth_token_getter)),
http_client_(ServiceUrls::GetInstance()->remoting_corp_endpoint(),
oauth_token_getter_.get(),
url_loader_factory,
std::move(client_cert_store)),
support_id_(support_id) {
session_authz_path_ = support_id.empty()
? internal::GetRemoteAccessSessionAuthzPath()
: internal::GetRemoteSupportSessionAuthzPath();
}
CorpSessionAuthzServiceClient::~CorpSessionAuthzServiceClient() = default;
void CorpSessionAuthzServiceClient::GenerateHostToken(
GenerateHostTokenCallback callback) {
constexpr net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation(
"remoting_corp_session_authz_generate_host_token",
R"(
semantics {
sender: "Chrome Remote Desktop"
description:
"Generates a host token to be used to authorize a Chrome Remote "
"Desktop connection from a corp user to a corp-managed device "
"(this device)."
trigger:
"Corp user connects to a corp-managed machine. Note that this "
"functionality is not available outside of the corp network so "
"external users will never see this request being made."
user_data {
type: ACCESS_TOKEN
}
data:
"Access token of the Chrome Remote Desktop host's robot account."
destination: GOOGLE_OWNED_SERVICE
internal {
contacts { owners: "//remoting/OWNERS" }
}
last_reviewed: "2024-02-01"
}
policy {
cookies_allowed: NO
setting:
"This request cannot be stopped in settings, but will not be sent "
"if the Chrome Remote Desktop host is not registered on a "
"corp-managed device."
policy_exception_justification:
"Not implemented."
})");
ExecuteRequest(
traffic_annotation, internal::GetGenerateHostTokenRequestVerb(),
internal::GetGenerateHostTokenRequest({.support_id = support_id_}),
ConvertCallback(std::move(callback),
&internal::GetGenerateHostTokenResponseStruct));
}
void CorpSessionAuthzServiceClient::VerifySessionToken(
std::string_view session_token,
VerifySessionTokenCallback callback) {
constexpr net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation(
"remoting_corp_session_authz_verify_session_token",
R"(
semantics {
sender: "Chrome Remote Desktop"
description:
"Verifies a session token returned by the client device and "
"decodes the shared secret from the session token, to be used to "
"authorize a Chrome Remote Desktop connection from a corp user to "
"a corp-managed device (this device)."
trigger:
"Corp user connects to a corp-managed machine. Note that this "
"functionality is not available outside of the corp network so "
"external users will never see this request being made."
user_data {
type: ACCESS_TOKEN
}
data:
"Access token of the Chrome Remote Desktop host's robot account, "
"session token returned by the Chrome Remote Desktop client."
destination: GOOGLE_OWNED_SERVICE
internal {
contacts { owners: "//remoting/OWNERS" }
}
last_reviewed: "2024-02-01"
}
policy {
cookies_allowed: NO
setting:
"This request cannot be stopped in settings, but will not be sent "
"if the Chrome Remote Desktop host is not registered on a "
"corp-managed device."
policy_exception_justification:
"Not implemented."
})");
internal::VerifySessionTokenRequestStruct request;
request.session_token = session_token;
request.support_id = support_id_;
ExecuteRequest(
traffic_annotation, internal::GetVerifySessionTokenRequestVerb(),
internal::GetVerifySessionTokenRequest(request),
ConvertCallback(std::move(callback),
&internal::GetVerifySessionTokenResponseStruct));
}
void CorpSessionAuthzServiceClient::ReauthorizeHost(
std::string_view session_reauth_token,
std::string_view session_id,
base::TimeTicks token_expire_time,
ReauthorizeHostCallback callback) {
constexpr net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation(
"remoting_corp_session_reauthorize_host",
R"(
semantics {
sender: "Chrome Remote Desktop"
description:
"Reauthorizes the current Chrome Remote Desktop connection, "
"initiated by a corp user."
trigger:
"Corp user connects to a corp-managed machine. Note that this "
"functionality is not available outside of the corp network so "
"external users will never see this request being made."
user_data {
type: ACCESS_TOKEN
}
data:
"Access token of the Chrome Remote Desktop host's robot account, "
"session token returned by the Chrome Remote Desktop client."
destination: GOOGLE_OWNED_SERVICE
internal {
contacts { owners: "//remoting/OWNERS" }
}
last_reviewed: "2024-02-01"
}
policy {
cookies_allowed: NO
setting:
"This request cannot be stopped in settings, but will not be sent "
"if the Chrome Remote Desktop host is not registered on a "
"corp-managed device."
policy_exception_justification:
"Not implemented."
})");
internal::ReauthorizeHostRequestStruct request;
request.session_reauth_token = session_reauth_token;
request.session_id = session_id;
request.support_id = support_id_;
ExecuteRequest(traffic_annotation, internal::GetReauthorizeHostRequestVerb(),
internal::GetReauthorizeHostRequest(request),
ConvertCallback(std::move(callback),
&internal::GetReauthorizeHostResponseStruct),
GetReauthRetryPolicy(token_expire_time));
}
template <typename CallbackType>
void CorpSessionAuthzServiceClient::ExecuteRequest(
const net::NetworkTrafficAnnotationTag& traffic_annotation,
std::string_view verb,
std::unique_ptr<google::protobuf::MessageLite> request_message,
CallbackType callback,
scoped_refptr<const ProtobufHttpRequestConfig::RetryPolicy> retry_policy) {
auto request_config =
std::make_unique<ProtobufHttpRequestConfig>(traffic_annotation);
request_config->path = base::StrCat({session_authz_path_, ":", verb});
request_config->api_key = internal::GetRemotingCorpApiKey();
request_config->authenticated = true;
request_config->provide_certificate = true;
request_config->request_message = std::move(request_message);
request_config->retry_policy = std::move(retry_policy);
auto request =
std::make_unique<ProtobufHttpRequest>(std::move(request_config));
request->SetResponseCallback(std::move(callback));
http_client_.ExecuteRequest(std::move(request));
}
} // namespace remoting
|