123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- // Copyright 2013 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 "remoting/host/token_validator_factory_impl.h"
- #include <stddef.h>
- #include <memory>
- #include <utility>
- #include "base/base64.h"
- #include "base/bind.h"
- #include "base/callback.h"
- #include "base/check.h"
- #include "base/json/json_reader.h"
- #include "base/strings/escape.h"
- #include "base/strings/string_util.h"
- #include "base/strings/stringize_macros.h"
- #include "base/task/single_thread_task_runner.h"
- #include "base/values.h"
- #include "build/branding_buildflags.h"
- #include "crypto/random.h"
- #include "net/base/elements_upload_data_stream.h"
- #include "net/base/io_buffer.h"
- #include "net/base/request_priority.h"
- #include "net/base/upload_bytes_element_reader.h"
- #include "net/url_request/url_request.h"
- #include "net/url_request/url_request_context.h"
- #include "remoting/base/rsa_key_pair.h"
- #include "remoting/host/token_validator_base.h"
- #include "url/gurl.h"
- namespace {
- // Length in bytes of the cryptographic nonce used to salt the token scope.
- const size_t kNonceLength = 16; // 128 bits.
- } // namespace
- namespace remoting {
- class TokenValidatorImpl : public TokenValidatorBase {
- public:
- TokenValidatorImpl(
- const ThirdPartyAuthConfig& third_party_auth_config,
- scoped_refptr<RsaKeyPair> key_pair,
- const std::string& local_jid,
- const std::string& remote_jid,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter);
- TokenValidatorImpl(const TokenValidatorImpl&) = delete;
- TokenValidatorImpl& operator=(const TokenValidatorImpl&) = delete;
- protected:
- void StartValidateRequest(const std::string& token) override;
- private:
- static std::string CreateScope(const std::string& local_jid,
- const std::string& remote_jid);
- std::string post_body_;
- scoped_refptr<RsaKeyPair> key_pair_;
- };
- TokenValidatorImpl::TokenValidatorImpl(
- const ThirdPartyAuthConfig& third_party_auth_config,
- scoped_refptr<RsaKeyPair> key_pair,
- const std::string& local_jid,
- const std::string& remote_jid,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter)
- : TokenValidatorBase(third_party_auth_config,
- CreateScope(local_jid, remote_jid),
- request_context_getter),
- key_pair_(key_pair) {
- DCHECK(key_pair_.get());
- }
- // TokenValidator interface.
- void TokenValidatorImpl::StartValidateRequest(const std::string& token) {
- post_body_ = "code=" + base::EscapeUrlEncodedData(token, true) +
- "&client_id=" +
- base::EscapeUrlEncodedData(key_pair_->GetPublicKey(), true) +
- "&client_secret=" +
- base::EscapeUrlEncodedData(key_pair_->SignMessage(token), true) +
- "&grant_type=authorization_code";
- request_ = request_context_getter_->GetURLRequestContext()->CreateRequest(
- third_party_auth_config_.token_validation_url, net::DEFAULT_PRIORITY,
- this, MISSING_TRAFFIC_ANNOTATION);
- #if BUILDFLAG(GOOGLE_CHROME_BRANDING)
- std::string app_name = "Chrome Remote Desktop";
- #else
- std::string app_name = "Chromoting";
- #endif
- #ifndef VERSION
- #error VERSION is not set.
- #endif
- // Set a user-agent for logging/auditing purposes.
- request_->SetExtraRequestHeaderByName(net::HttpRequestHeaders::kUserAgent,
- app_name + " " + STRINGIZE(VERSION),
- true);
- request_->SetExtraRequestHeaderByName(
- net::HttpRequestHeaders::kContentType,
- "application/x-www-form-urlencoded", true);
- request_->set_method("POST");
- std::unique_ptr<net::UploadElementReader> reader(
- new net::UploadBytesElementReader(post_body_.data(), post_body_.size()));
- request_->set_upload(
- net::ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
- request_->Start();
- }
- std::string TokenValidatorImpl::CreateScope(
- const std::string& local_jid,
- const std::string& remote_jid) {
- std::string nonce_bytes;
- crypto::RandBytes(base::WriteInto(&nonce_bytes, kNonceLength + 1),
- kNonceLength);
- std::string nonce;
- base::Base64Encode(nonce_bytes, &nonce);
- // Note that because of how FTL signaling IDs are managed, |local_jid| will
- // not change between connections to a given host instance. We do expect that
- // |remote_jid| will be different for each connection (clients should not
- // reuse the same channel for connections) but the host does not control this.
- // Since at least one of the JIDs will be reused between connections, we rely
- // on the nonce to guarantee that the scope string is unique and cannot be
- // reused for multiple connections.
- return "client:" + remote_jid + " host:" + local_jid + " nonce:" + nonce;
- }
- TokenValidatorFactoryImpl::TokenValidatorFactoryImpl(
- const ThirdPartyAuthConfig& third_party_auth_config,
- scoped_refptr<RsaKeyPair> key_pair,
- scoped_refptr<net::URLRequestContextGetter> request_context_getter)
- : third_party_auth_config_(third_party_auth_config),
- key_pair_(key_pair),
- request_context_getter_(request_context_getter) {
- }
- TokenValidatorFactoryImpl::~TokenValidatorFactoryImpl() = default;
- std::unique_ptr<protocol::TokenValidator>
- TokenValidatorFactoryImpl::CreateTokenValidator(const std::string& local_jid,
- const std::string& remote_jid) {
- return std::make_unique<TokenValidatorImpl>(third_party_auth_config_,
- key_pair_, local_jid, remote_jid,
- request_context_getter_);
- }
- } // namespace remoting
|