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
|
// 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 <utility>
#include "base/base64.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/json/json_reader.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/strings/stringize_macros.h"
#include "base/values.h"
#include "crypto/random.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/escape.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 "net/url_request/url_request_status.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);
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_;
DISALLOW_COPY_AND_ASSIGN(TokenValidatorImpl);
};
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());
token_scope_ = CreateScope(local_jid, remote_jid);
}
// TokenValidator interface.
void TokenValidatorImpl::StartValidateRequest(const std::string& token) {
post_body_ = "code=" + net::EscapeUrlEncodedData(token, true) +
"&client_id=" + net::EscapeUrlEncodedData(
key_pair_->GetPublicKey(), true) +
"&client_secret=" + net::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);
#if defined(GOOGLE_CHROME_BUILD)
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);
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() {
}
std::unique_ptr<protocol::TokenValidator>
TokenValidatorFactoryImpl::CreateTokenValidator(const std::string& local_jid,
const std::string& remote_jid) {
return base::MakeUnique<TokenValidatorImpl>(third_party_auth_config_,
key_pair_, local_jid, remote_jid,
request_context_getter_);
}
} // namespace remoting
|