OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "remoting/protocol/pairing_registry.h" | 5 #include "remoting/protocol/pairing_registry.h" |
6 | 6 |
7 #include "base/base64.h" | 7 #include "base/base64.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/guid.h" | 9 #include "base/guid.h" |
| 10 #include "base/json/json_string_value_serializer.h" |
| 11 #include "base/strings/string_number_conversions.h" |
| 12 #include "base/values.h" |
10 #include "crypto/random.h" | 13 #include "crypto/random.h" |
11 | 14 |
| 15 namespace { |
| 16 const char kCreatedTimeKey[] = "created-time"; |
| 17 const char kClientIdKey[] = "client-id"; |
| 18 const char kClientNameKey[] = "client-name"; |
| 19 const char kSharedSecretKey[] = "shared-secret"; |
| 20 } // namespace |
| 21 |
12 namespace remoting { | 22 namespace remoting { |
13 namespace protocol { | 23 namespace protocol { |
14 | 24 |
15 // How many bytes of random data to use for the shared secret. | 25 // How many bytes of random data to use for the shared secret. |
16 const int kKeySize = 16; | 26 const int kKeySize = 16; |
17 | 27 |
18 PairingRegistry::Pairing::Pairing() { | 28 PairingRegistry::Pairing::Pairing() { |
19 } | 29 } |
20 | 30 |
21 PairingRegistry::Pairing::Pairing(const base::Time& created_time, | 31 PairingRegistry::Pairing::Pairing(const base::Time& created_time, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 DCHECK(delegate_); | 71 DCHECK(delegate_); |
62 } | 72 } |
63 | 73 |
64 PairingRegistry::~PairingRegistry() { | 74 PairingRegistry::~PairingRegistry() { |
65 } | 75 } |
66 | 76 |
67 PairingRegistry::Pairing PairingRegistry::CreatePairing( | 77 PairingRegistry::Pairing PairingRegistry::CreatePairing( |
68 const std::string& client_name) { | 78 const std::string& client_name) { |
69 DCHECK(CalledOnValidThread()); | 79 DCHECK(CalledOnValidThread()); |
70 Pairing result = Pairing::Create(client_name); | 80 Pairing result = Pairing::Create(client_name); |
71 delegate_->AddPairing(result, AddPairingCallback()); | 81 AddPairing(result); |
72 return result; | 82 return result; |
73 } | 83 } |
74 | 84 |
75 void PairingRegistry::GetPairing(const std::string& client_id, | 85 void PairingRegistry::GetPairing(const std::string& client_id, |
76 const GetPairingCallback& callback) { | 86 const GetPairingCallback& callback) { |
77 DCHECK(CalledOnValidThread()); | 87 DCHECK(CalledOnValidThread()); |
78 delegate_->GetPairing(client_id, callback); | 88 delegate_->Load( |
| 89 base::Bind(&PairingRegistry::DoGetPairing, this, client_id, callback)); |
79 } | 90 } |
80 | 91 |
81 void NotImplementedPairingRegistryDelegate::AddPairing( | 92 void PairingRegistry::AddPairing(const Pairing& pairing) { |
82 const PairingRegistry::Pairing& new_paired_client, | 93 delegate_->Load( |
83 const PairingRegistry::AddPairingCallback& callback) { | 94 base::Bind(&PairingRegistry::MergePairingAndSave, this, pairing)); |
84 NOTIMPLEMENTED(); | |
85 if (!callback.is_null()) { | |
86 callback.Run(false); | |
87 } | |
88 } | 95 } |
89 | 96 |
90 void NotImplementedPairingRegistryDelegate::GetPairing( | 97 void PairingRegistry::MergePairingAndSave(const Pairing& pairing, |
91 const std::string& client_id, | 98 const std::string& pairings_json) { |
92 const PairingRegistry::GetPairingCallback& callback) { | 99 DCHECK(CalledOnValidThread()); |
93 NOTIMPLEMENTED(); | 100 PairedClients clients = DecodeJson(pairings_json); |
94 callback.Run(PairingRegistry::Pairing()); | 101 clients[pairing.client_id()] = pairing; |
| 102 std::string new_pairings_json = EncodeJson(clients); |
| 103 delegate_->Save(new_pairings_json, SaveCallback()); |
| 104 } |
| 105 |
| 106 void PairingRegistry::DoGetPairing(const std::string& client_id, |
| 107 const GetPairingCallback& callback, |
| 108 const std::string& pairings_json) { |
| 109 PairedClients clients = DecodeJson(pairings_json); |
| 110 Pairing result = clients[client_id]; |
| 111 callback.Run(result); |
| 112 } |
| 113 |
| 114 PairingRegistry::PairedClients PairingRegistry::DecodeJson( |
| 115 const std::string& pairings_json) { |
| 116 PairedClients result; |
| 117 |
| 118 if (pairings_json.empty()) { |
| 119 return result; |
| 120 } |
| 121 |
| 122 JSONStringValueSerializer registry(pairings_json); |
| 123 int error_code; |
| 124 std::string error_message; |
| 125 scoped_ptr<base::Value> root( |
| 126 registry.Deserialize(&error_code, &error_message)); |
| 127 if (!root) { |
| 128 LOG(ERROR) << "Failed to load paired clients: " << error_message |
| 129 << " (" << error_code << ")."; |
| 130 return result; |
| 131 } |
| 132 |
| 133 base::ListValue* root_list = NULL; |
| 134 if (!root->GetAsList(&root_list)) { |
| 135 LOG(ERROR) << "Failed to load paired clients: root node is not a list."; |
| 136 return result; |
| 137 } |
| 138 |
| 139 for (size_t i = 0; i < root_list->GetSize(); ++i) { |
| 140 base::DictionaryValue* pairing = NULL; |
| 141 std::string client_name, client_id, shared_secret; |
| 142 double created_time_value; |
| 143 if (root_list->GetDictionary(i, &pairing) && |
| 144 pairing->GetDouble(kCreatedTimeKey, &created_time_value) && |
| 145 pairing->GetString(kClientNameKey, &client_name) && |
| 146 pairing->GetString(kClientIdKey, &client_id) && |
| 147 pairing->GetString(kSharedSecretKey, &shared_secret)) { |
| 148 base::Time created_time = base::Time::FromJsTime(created_time_value); |
| 149 result[client_id] = Pairing( |
| 150 created_time, client_name, client_id, shared_secret); |
| 151 } else { |
| 152 LOG(ERROR) << "Paired client " << i << " has unexpected format."; |
| 153 } |
| 154 } |
| 155 |
| 156 return result; |
| 157 } |
| 158 |
| 159 std::string PairingRegistry::EncodeJson(const PairedClients& clients) { |
| 160 base::ListValue root; |
| 161 for (PairedClients::const_iterator i = clients.begin(); |
| 162 i != clients.end(); ++i) { |
| 163 base::DictionaryValue* pairing = new base::DictionaryValue(); |
| 164 pairing->SetDouble(kCreatedTimeKey, i->second.created_time().ToJsTime()); |
| 165 pairing->SetString(kClientNameKey, i->second.client_name()); |
| 166 pairing->SetString(kClientIdKey, i->second.client_id()); |
| 167 pairing->SetString(kSharedSecretKey, i->second.shared_secret()); |
| 168 root.Append(pairing); |
| 169 } |
| 170 |
| 171 std::string result; |
| 172 JSONStringValueSerializer serializer(&result); |
| 173 serializer.Serialize(root); |
| 174 |
| 175 return result; |
95 } | 176 } |
96 | 177 |
97 } // namespace protocol | 178 } // namespace protocol |
98 } // namespace remoting | 179 } // namespace remoting |
OLD | NEW |