• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "remoting/host/token_validator_factory_impl.h"
6 
7 #include "base/base64.h"
8 #include "base/bind.h"
9 #include "base/callback.h"
10 #include "base/json/json_reader.h"
11 #include "base/logging.h"
12 #include "base/single_thread_task_runner.h"
13 #include "base/strings/string_util.h"
14 #include "base/values.h"
15 #include "crypto/random.h"
16 #include "net/base/escape.h"
17 #include "net/base/io_buffer.h"
18 #include "net/base/request_priority.h"
19 #include "net/base/upload_bytes_element_reader.h"
20 #include "net/base/upload_data_stream.h"
21 #include "net/url_request/url_request.h"
22 #include "net/url_request/url_request_context.h"
23 #include "net/url_request/url_request_status.h"
24 #include "remoting/base/rsa_key_pair.h"
25 #include "remoting/host/token_validator_base.h"
26 #include "url/gurl.h"
27 
28 namespace {
29 
30 // Length in bytes of the cryptographic nonce used to salt the token scope.
31 const size_t kNonceLength = 16;  // 128 bits.
32 
33 }  // namespace
34 
35 namespace remoting {
36 
37 
38 class TokenValidatorImpl : public TokenValidatorBase {
39  public:
40   TokenValidatorImpl(
41       const ThirdPartyAuthConfig& third_party_auth_config,
42       scoped_refptr<RsaKeyPair> key_pair,
43       const std::string& local_jid,
44       const std::string& remote_jid,
45       scoped_refptr<net::URLRequestContextGetter> request_context_getter);
46 
47  protected:
48   virtual void StartValidateRequest(const std::string& token) OVERRIDE;
49 
50  private:
51   static std::string CreateScope(const std::string& local_jid,
52                                  const std::string& remote_jid);
53 
54   std::string post_body_;
55   scoped_refptr<RsaKeyPair> key_pair_;
56 
57   DISALLOW_COPY_AND_ASSIGN(TokenValidatorImpl);
58 };
59 
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)60 TokenValidatorImpl::TokenValidatorImpl(
61     const ThirdPartyAuthConfig& third_party_auth_config,
62     scoped_refptr<RsaKeyPair> key_pair,
63     const std::string& local_jid,
64     const std::string& remote_jid,
65     scoped_refptr<net::URLRequestContextGetter> request_context_getter)
66     : TokenValidatorBase(third_party_auth_config,
67                          CreateScope(local_jid, remote_jid),
68                          request_context_getter),
69       key_pair_(key_pair) {
70   DCHECK(key_pair_.get());
71   token_scope_ = CreateScope(local_jid, remote_jid);
72 }
73 
74 // TokenValidator interface.
StartValidateRequest(const std::string & token)75 void TokenValidatorImpl::StartValidateRequest(const std::string& token) {
76   post_body_ = "code=" + net::EscapeUrlEncodedData(token, true) +
77       "&client_id=" + net::EscapeUrlEncodedData(
78           key_pair_->GetPublicKey(), true) +
79       "&client_secret=" + net::EscapeUrlEncodedData(
80           key_pair_->SignMessage(token), true) +
81       "&grant_type=authorization_code";
82 
83   request_ = request_context_getter_->GetURLRequestContext()->CreateRequest(
84       third_party_auth_config_.token_validation_url, net::DEFAULT_PRIORITY,
85       this, NULL);
86   request_->SetExtraRequestHeaderByName(
87       net::HttpRequestHeaders::kContentType,
88       "application/x-www-form-urlencoded", true);
89   request_->set_method("POST");
90   scoped_ptr<net::UploadElementReader> reader(
91       new net::UploadBytesElementReader(
92           post_body_.data(), post_body_.size()));
93   request_->set_upload(make_scoped_ptr(
94       net::UploadDataStream::CreateWithReader(reader.Pass(), 0)));
95   request_->Start();
96 }
97 
CreateScope(const std::string & local_jid,const std::string & remote_jid)98 std::string TokenValidatorImpl::CreateScope(
99     const std::string& local_jid,
100     const std::string& remote_jid) {
101   std::string nonce_bytes;
102   crypto::RandBytes(WriteInto(&nonce_bytes, kNonceLength + 1), kNonceLength);
103   std::string nonce;
104   base::Base64Encode(nonce_bytes, &nonce);
105   return "client:" + remote_jid + " host:" + local_jid + " nonce:" + nonce;
106 }
107 
TokenValidatorFactoryImpl(const ThirdPartyAuthConfig & third_party_auth_config,scoped_refptr<RsaKeyPair> key_pair,scoped_refptr<net::URLRequestContextGetter> request_context_getter)108 TokenValidatorFactoryImpl::TokenValidatorFactoryImpl(
109     const ThirdPartyAuthConfig& third_party_auth_config,
110     scoped_refptr<RsaKeyPair> key_pair,
111     scoped_refptr<net::URLRequestContextGetter> request_context_getter)
112     : third_party_auth_config_(third_party_auth_config),
113       key_pair_(key_pair),
114       request_context_getter_(request_context_getter) {
115 }
116 
~TokenValidatorFactoryImpl()117 TokenValidatorFactoryImpl::~TokenValidatorFactoryImpl() {
118 }
119 
120 scoped_ptr<protocol::TokenValidator>
CreateTokenValidator(const std::string & local_jid,const std::string & remote_jid)121 TokenValidatorFactoryImpl::CreateTokenValidator(
122     const std::string& local_jid,
123     const std::string& remote_jid) {
124   return scoped_ptr<protocol::TokenValidator>(
125       new TokenValidatorImpl(third_party_auth_config_,
126                              key_pair_, local_jid, remote_jid,
127                              request_context_getter_));
128 }
129 
130 }  // namespace remoting
131