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 28namespace { 29 30// Length in bytes of the cryptographic nonce used to salt the token scope. 31const size_t kNonceLength = 16; // 128 bits. 32 33} // namespace 34 35namespace remoting { 36 37 38class 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 60TokenValidatorImpl::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. 75void 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 98std::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 108TokenValidatorFactoryImpl::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 117TokenValidatorFactoryImpl::~TokenValidatorFactoryImpl() { 118} 119 120scoped_ptr<protocol::TokenValidator> 121TokenValidatorFactoryImpl::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