Home | History | Annotate | Download | only in host
      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 
     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.
     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 
     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 
    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 
    117 TokenValidatorFactoryImpl::~TokenValidatorFactoryImpl() {
    118 }
    119 
    120 scoped_ptr<protocol::TokenValidator>
    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