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/protocol/third_party_client_authenticator.h" 6 7 #include "base/base64.h" 8 #include "base/bind.h" 9 #include "base/callback.h" 10 #include "base/logging.h" 11 #include "remoting/base/constants.h" 12 #include "remoting/base/rsa_key_pair.h" 13 #include "remoting/protocol/channel_authenticator.h" 14 #include "remoting/protocol/v2_authenticator.h" 15 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" 16 #include "url/gurl.h" 17 18 namespace remoting { 19 namespace protocol { 20 21 ThirdPartyClientAuthenticator::ThirdPartyClientAuthenticator( 22 scoped_ptr<TokenFetcher> token_fetcher) 23 : ThirdPartyAuthenticatorBase(WAITING_MESSAGE), 24 token_fetcher_(token_fetcher.Pass()) { 25 } 26 27 ThirdPartyClientAuthenticator::~ThirdPartyClientAuthenticator() { 28 } 29 30 void ThirdPartyClientAuthenticator::ProcessTokenMessage( 31 const buzz::XmlElement* message, 32 const base::Closure& resume_callback) { 33 std::string token_url = message->TextNamed(kTokenUrlTag); 34 std::string token_scope = message->TextNamed(kTokenScopeTag); 35 36 if (token_url.empty() || token_scope.empty()) { 37 LOG(ERROR) << "Third-party authentication protocol error: " 38 "missing token verification URL or scope."; 39 token_state_ = REJECTED; 40 rejection_reason_ = PROTOCOL_ERROR; 41 resume_callback.Run(); 42 return; 43 } 44 45 token_state_ = PROCESSING_MESSAGE; 46 47 // |token_fetcher_| is owned, so Unretained() is safe here. 48 token_fetcher_->FetchThirdPartyToken( 49 GURL(token_url), token_scope, base::Bind( 50 &ThirdPartyClientAuthenticator::OnThirdPartyTokenFetched, 51 base::Unretained(this), resume_callback)); 52 } 53 54 void ThirdPartyClientAuthenticator::AddTokenElements( 55 buzz::XmlElement* message) { 56 DCHECK_EQ(token_state_, MESSAGE_READY); 57 DCHECK(!token_.empty()); 58 59 buzz::XmlElement* token_tag = new buzz::XmlElement(kTokenTag); 60 token_tag->SetBodyText(token_); 61 message->AddElement(token_tag); 62 token_state_ = ACCEPTED; 63 } 64 65 void ThirdPartyClientAuthenticator::OnThirdPartyTokenFetched( 66 const base::Closure& resume_callback, 67 const std::string& third_party_token, 68 const std::string& shared_secret) { 69 token_ = third_party_token; 70 if (token_.empty() || shared_secret.empty()) { 71 token_state_ = REJECTED; 72 rejection_reason_ = INVALID_CREDENTIALS; 73 } else { 74 token_state_ = MESSAGE_READY; 75 underlying_ = V2Authenticator::CreateForClient( 76 shared_secret, MESSAGE_READY); 77 } 78 resume_callback.Run(); 79 } 80 81 } // namespace protocol 82 } // namespace remoting 83