1b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)// found in the LICENSE file. 4b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 5b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "remoting/protocol/pairing_registry.h" 6b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 7b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/base64.h" 8b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/bind.h" 9b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/guid.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/json/json_string_value_serializer.h" 11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/location.h" 12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/single_thread_task_runner.h" 13eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/strings/string_number_conversions.h" 14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/thread_task_runner_handle.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/values.h" 16b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "crypto/random.h" 17b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 18b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)namespace remoting { 19b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)namespace protocol { 20b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// How many bytes of random data to use for the shared secret. 22b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)const int kKeySize = 16; 23b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 247dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char PairingRegistry::kCreatedTimeKey[] = "createdTime"; 257dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char PairingRegistry::kClientIdKey[] = "clientId"; 267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char PairingRegistry::kClientNameKey[] = "clientName"; 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst char PairingRegistry::kSharedSecretKey[] = "sharedSecret"; 287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PairingRegistry::Pairing::Pairing() { 30b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 31b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PairingRegistry::Pairing::Pairing(const base::Time& created_time, 337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& client_name, 347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& client_id, 357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& shared_secret) 367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) : created_time_(created_time), 377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) client_name_(client_name), 387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) client_id_(client_id), 397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) shared_secret_(shared_secret) { 40b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 41b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)PairingRegistry::Pairing::~Pairing() { 43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 44a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PairingRegistry::Pairing PairingRegistry::Pairing::Create( 46b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) const std::string& client_name) { 477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::Time created_time = base::Time::Now(); 487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string client_id = base::GenerateGUID(); 497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) std::string shared_secret; 50b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) char buffer[kKeySize]; 51b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) crypto::RandBytes(buffer, arraysize(buffer)); 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::Base64Encode(base::StringPiece(buffer, arraysize(buffer)), 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) &shared_secret); 547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return Pairing(created_time, client_name, client_id, shared_secret); 557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 56b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)PairingRegistry::Pairing PairingRegistry::Pairing::CreateFromValue( 58ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const base::DictionaryValue& pairing) { 59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string client_name, client_id; 60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) double created_time_value; 61ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (pairing.GetDouble(kCreatedTimeKey, &created_time_value) && 62ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch pairing.GetString(kClientNameKey, &client_name) && 63ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch pairing.GetString(kClientIdKey, &client_id)) { 64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // The shared secret is optional. 65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::string shared_secret; 66ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch pairing.GetString(kSharedSecretKey, &shared_secret); 67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Time created_time = base::Time::FromJsTime(created_time_value); 68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return Pairing(created_time, client_name, client_id, shared_secret); 69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) LOG(ERROR) << "Failed to load pairing information: unexpected format."; 72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return Pairing(); 73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 75ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochscoped_ptr<base::DictionaryValue> PairingRegistry::Pairing::ToValue() const { 76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<base::DictionaryValue> pairing(new base::DictionaryValue()); 77a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pairing->SetDouble(kCreatedTimeKey, created_time().ToJsTime()); 78a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pairing->SetString(kClientNameKey, client_name()); 79a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pairing->SetString(kClientIdKey, client_id()); 80a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!shared_secret().empty()) 81a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pairing->SetString(kSharedSecretKey, shared_secret()); 82ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch return pairing.Pass(); 837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool PairingRegistry::Pairing::operator==(const Pairing& other) const { 867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return created_time_ == other.created_time_ && 877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) client_id_ == other.client_id_ && 887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) client_name_ == other.client_name_ && 897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) shared_secret_ == other.shared_secret_; 907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 91b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)bool PairingRegistry::Pairing::is_valid() const { 93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // |shared_secret_| is optional. It will be empty on Windows because the 94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // privileged registry key can only be read in the elevated host process. 95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) return !client_id_.empty(); 96b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 97b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)PairingRegistry::PairingRegistry( 99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> delegate_task_runner, 100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<Delegate> delegate) 101a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) : caller_task_runner_(base::ThreadTaskRunnerHandle::Get()), 102a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) delegate_task_runner_(delegate_task_runner), 103a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) delegate_(delegate.Pass()) { 1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(delegate_); 1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PairingRegistry::Pairing PairingRegistry::CreatePairing( 1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const std::string& client_name) { 109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(caller_task_runner_->BelongsToCurrentThread()); 110a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Pairing result = Pairing::Create(client_name); 112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch AddPairing(result); 1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return result; 1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void PairingRegistry::GetPairing(const std::string& client_id, 1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const GetPairingCallback& callback) { 118a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(caller_task_runner_->BelongsToCurrentThread()); 119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 120ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GetPairingCallback wrapped_callback = base::Bind( 121ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch &PairingRegistry::InvokeGetPairingCallbackAndScheduleNext, 122ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch this, callback); 123ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Closure request = base::Bind( 124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &PairingRegistry::DoLoad, this, client_id, wrapped_callback); 125ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ServiceOrQueueRequest(request); 126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 128ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PairingRegistry::GetAllPairings( 129ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const GetAllPairingsCallback& callback) { 130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(caller_task_runner_->BelongsToCurrentThread()); 131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 132ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch GetAllPairingsCallback wrapped_callback = base::Bind( 133ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch &PairingRegistry::InvokeGetAllPairingsCallbackAndScheduleNext, 134ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch this, callback); 135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GetAllPairingsCallback sanitize_callback = base::Bind( 136a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &PairingRegistry::SanitizePairings, 137a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) this, wrapped_callback); 138ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Closure request = base::Bind( 139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &PairingRegistry::DoLoadAll, this, sanitize_callback); 140ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ServiceOrQueueRequest(request); 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 143ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PairingRegistry::DeletePairing( 144a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_id, const DoneCallback& callback) { 145a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(caller_task_runner_->BelongsToCurrentThread()); 146a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 147a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DoneCallback wrapped_callback = base::Bind( 148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &PairingRegistry::InvokeDoneCallbackAndScheduleNext, 149ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch this, callback); 150ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Closure request = base::Bind( 151a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &PairingRegistry::DoDelete, this, client_id, wrapped_callback); 152ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ServiceOrQueueRequest(request); 1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 155ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PairingRegistry::ClearAllPairings( 156a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const DoneCallback& callback) { 157a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(caller_task_runner_->BelongsToCurrentThread()); 158a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 159a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DoneCallback wrapped_callback = base::Bind( 160a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &PairingRegistry::InvokeDoneCallbackAndScheduleNext, 161ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch this, callback); 162ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Closure request = base::Bind( 163a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &PairingRegistry::DoDeleteAll, this, wrapped_callback); 164ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ServiceOrQueueRequest(request); 1657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 1667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 167a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)PairingRegistry::~PairingRegistry() { 168a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 169a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 170a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void PairingRegistry::PostTask( 171a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 172a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const tracked_objects::Location& from_here, 173a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const base::Closure& task) { 174a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) task_runner->PostTask(from_here, task); 175a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid PairingRegistry::AddPairing(const Pairing& pairing) { 178a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DoneCallback wrapped_callback = base::Bind( 179a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &PairingRegistry::InvokeDoneCallbackAndScheduleNext, 180a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) this, DoneCallback()); 181ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Closure request = base::Bind( 182a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) &PairingRegistry::DoSave, this, pairing, wrapped_callback); 183ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ServiceOrQueueRequest(request); 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 186a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void PairingRegistry::DoLoadAll( 187a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const protocol::PairingRegistry::GetAllPairingsCallback& callback) { 188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 189a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 190a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<base::ListValue> pairings = delegate_->LoadAll(); 191a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostTask(caller_task_runner_, FROM_HERE, base::Bind(callback, 192a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) base::Passed(&pairings))); 1937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 194b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 195a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void PairingRegistry::DoDeleteAll( 196a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const protocol::PairingRegistry::DoneCallback& callback) { 197a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 198a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 199a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool success = delegate_->DeleteAll(); 200a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostTask(caller_task_runner_, FROM_HERE, base::Bind(callback, success)); 201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void PairingRegistry::DoLoad( 204a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_id, 205a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const protocol::PairingRegistry::GetPairingCallback& callback) { 206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 207a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Pairing pairing = delegate_->Load(client_id); 209a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostTask(caller_task_runner_, FROM_HERE, base::Bind(callback, pairing)); 2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 212a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void PairingRegistry::DoSave( 213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const protocol::PairingRegistry::Pairing& pairing, 214a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const protocol::PairingRegistry::DoneCallback& callback) { 215a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 216a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 217a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool success = delegate_->Save(pairing); 218a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostTask(caller_task_runner_, FROM_HERE, base::Bind(callback, success)); 2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 2207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 221a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void PairingRegistry::DoDelete( 222a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_id, 223a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const protocol::PairingRegistry::DoneCallback& callback) { 224a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(delegate_task_runner_->BelongsToCurrentThread()); 225a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 226a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) bool success = delegate_->Delete(client_id); 227a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostTask(caller_task_runner_, FROM_HERE, base::Bind(callback, success)); 228ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 229ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 230a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void PairingRegistry::InvokeDoneCallbackAndScheduleNext( 231a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const DoneCallback& callback, bool success) { 232ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // CreatePairing doesn't have a callback, so the callback can be null. 233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!callback.is_null()) 234ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch callback.Run(success); 235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 236ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pending_requests_.pop(); 237ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ServiceNextRequest(); 238ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 239ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 240ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PairingRegistry::InvokeGetPairingCallbackAndScheduleNext( 241ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const GetPairingCallback& callback, Pairing pairing) { 242ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch callback.Run(pairing); 243ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pending_requests_.pop(); 244ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ServiceNextRequest(); 245ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 246ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 247ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PairingRegistry::InvokeGetAllPairingsCallbackAndScheduleNext( 248ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const GetAllPairingsCallback& callback, 249ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch scoped_ptr<base::ListValue> pairings) { 250ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch callback.Run(pairings.Pass()); 251ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pending_requests_.pop(); 252ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ServiceNextRequest(); 253ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 254ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void PairingRegistry::SanitizePairings(const GetAllPairingsCallback& callback, 256a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<base::ListValue> pairings) { 257a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) DCHECK(caller_task_runner_->BelongsToCurrentThread()); 258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scoped_ptr<base::ListValue> sanitized_pairings(new base::ListValue()); 260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (size_t i = 0; i < pairings->GetSize(); ++i) { 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::DictionaryValue* pairing_json; 262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!pairings->GetDictionary(i, &pairing_json)) { 263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) LOG(WARNING) << "A pairing entry is not a dictionary."; 264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) continue; 265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 266eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Parse the pairing data. 268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Pairing pairing = Pairing::CreateFromValue(*pairing_json); 269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (!pairing.is_valid()) { 270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) LOG(WARNING) << "Could not parse a pairing entry."; 271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) continue; 272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 273a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Clear the shared secrect and append the pairing data to the list. 275a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Pairing sanitized_pairing( 276a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pairing.created_time(), 277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pairing.client_name(), 278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pairing.client_id(), 279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ""); 280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) sanitized_pairings->Append(sanitized_pairing.ToValue().release()); 281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 283a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) callback.Run(sanitized_pairings.Pass()); 284b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 285b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) 286ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PairingRegistry::ServiceOrQueueRequest(const base::Closure& request) { 287ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch bool servicing_request = !pending_requests_.empty(); 288ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pending_requests_.push(request); 289ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!servicing_request) { 290ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ServiceNextRequest(); 291ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 292ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch} 293ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 294ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochvoid PairingRegistry::ServiceNextRequest() { 295a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (pending_requests_.empty()) 296ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 297ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) PostTask(delegate_task_runner_, FROM_HERE, pending_requests_.front()); 299868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)} 30090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 301b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} // namespace protocol 302b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} // namespace remoting 303