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 #ifndef REMOTING_PROTOCOL_PAIRING_REGISTRY_H_ | 5 #ifndef REMOTING_PROTOCOL_PAIRING_REGISTRY_H_ |
6 #define REMOTING_PROTOCOL_PAIRING_REGISTRY_H_ | 6 #define REMOTING_PROTOCOL_PAIRING_REGISTRY_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 #include <queue> | 9 #include <queue> |
10 #include <string> | 10 #include <string> |
11 #include <vector> | 11 #include <vector> |
12 | 12 |
13 #include "base/callback.h" | 13 #include "base/callback.h" |
14 #include "base/gtest_prod_util.h" | 14 #include "base/gtest_prod_util.h" |
15 #include "base/memory/ref_counted.h" | 15 #include "base/memory/ref_counted.h" |
16 #include "base/memory/scoped_ptr.h" | 16 #include "base/memory/scoped_ptr.h" |
17 #include "base/threading/non_thread_safe.h" | |
18 #include "base/time/time.h" | 17 #include "base/time/time.h" |
19 | 18 |
20 namespace base { | 19 namespace base { |
21 class ListValue; | 20 class ListValue; |
21 class Value; | |
22 class SingleThreadTaskRunner; | |
22 } // namespace base | 23 } // namespace base |
23 | 24 |
25 namespace tracked_objects { | |
26 class Location; | |
27 } // namespace tracked_objects | |
28 | |
24 namespace remoting { | 29 namespace remoting { |
25 namespace protocol { | 30 namespace protocol { |
26 | 31 |
27 // PairingRegistry holds information about paired clients to support | 32 // PairingRegistry holds information about paired clients to support |
28 // PIN-less authentication. For each paired client, the registry holds | 33 // PIN-less authentication. For each paired client, the registry holds |
29 // the following information: | 34 // the following information: |
30 // * The name of the client. This is supplied by the client and is not | 35 // * The name of the client. This is supplied by the client and is not |
31 // guaranteed to be unique. | 36 // guaranteed to be unique. |
32 // * The unique id of the client. This is generated on-demand by this | 37 // * The unique id of the client. This is generated on-demand by this |
33 // class and sent in plain-text by the client during authentication. | 38 // class and sent in plain-text by the client during authentication. |
34 // * The shared secret for the client. This is generated on-demand by this | 39 // * The shared secret for the client. This is generated on-demand by this |
35 // class and used in the SPAKE2 exchange to mutually verify identity. | 40 // class and used in the SPAKE2 exchange to mutually verify identity. |
36 class PairingRegistry : public base::RefCountedThreadSafe<PairingRegistry>, | 41 class PairingRegistry : public base::RefCountedThreadSafe<PairingRegistry> { |
37 public base::NonThreadSafe { | |
38 public: | 42 public: |
39 struct Pairing { | 43 struct Pairing { |
40 Pairing(); | 44 Pairing(); |
41 Pairing(const base::Time& created_time, | 45 Pairing(const base::Time& created_time, |
42 const std::string& client_name, | 46 const std::string& client_name, |
43 const std::string& client_id, | 47 const std::string& client_id, |
44 const std::string& shared_secret); | 48 const std::string& shared_secret); |
45 ~Pairing(); | 49 ~Pairing(); |
46 | 50 |
47 static Pairing Create(const std::string& client_name); | 51 static Pairing Create(const std::string& client_name); |
52 static Pairing CreateFromValue(const base::Value& pairing_json); | |
53 | |
54 scoped_ptr<base::Value> ToValue() const; | |
48 | 55 |
49 bool operator==(const Pairing& other) const; | 56 bool operator==(const Pairing& other) const; |
50 | 57 |
51 bool is_valid() const; | 58 bool is_valid() const; |
52 | 59 |
53 base::Time created_time() const { return created_time_; } | 60 base::Time created_time() const { return created_time_; } |
54 std::string client_id() const { return client_id_; } | 61 std::string client_id() const { return client_id_; } |
55 std::string client_name() const { return client_name_; } | 62 std::string client_name() const { return client_name_; } |
56 std::string shared_secret() const { return shared_secret_; } | 63 std::string shared_secret() const { return shared_secret_; } |
57 | 64 |
58 private: | 65 private: |
59 base::Time created_time_; | 66 base::Time created_time_; |
60 std::string client_name_; | 67 std::string client_name_; |
61 std::string client_id_; | 68 std::string client_id_; |
62 std::string shared_secret_; | 69 std::string shared_secret_; |
63 }; | 70 }; |
64 | 71 |
65 // Mapping from client id to pairing information. | 72 // Mapping from client id to pairing information. |
66 typedef std::map<std::string, Pairing> PairedClients; | 73 typedef std::map<std::string, Pairing> PairedClients; |
67 | 74 |
68 // Delegate callbacks. | 75 // Delegate callbacks. |
69 typedef base::Callback<void(const std::string& pairings_json)> LoadCallback; | 76 typedef base::Callback<void(bool success)> DoneCallback; |
70 typedef base::Callback<void(bool success)> SaveCallback; | |
71 typedef base::Callback<void(Pairing pairing)> GetPairingCallback; | |
72 typedef base::Callback<void(scoped_ptr<base::ListValue> pairings)> | 77 typedef base::Callback<void(scoped_ptr<base::ListValue> pairings)> |
73 GetAllPairingsCallback; | 78 GetAllPairingsCallback; |
79 typedef base::Callback<void(Pairing pairing)> GetPairingCallback; | |
74 | 80 |
75 static const char kCreatedTimeKey[]; | 81 static const char kCreatedTimeKey[]; |
76 static const char kClientIdKey[]; | 82 static const char kClientIdKey[]; |
77 static const char kClientNameKey[]; | 83 static const char kClientNameKey[]; |
78 static const char kSharedSecretKey[]; | 84 static const char kSharedSecretKey[]; |
79 | 85 |
80 // Interface representing the persistent storage back-end. | 86 // Interface representing the persistent storage back-end. |
81 class Delegate { | 87 class Delegate { |
82 public: | 88 public: |
83 virtual ~Delegate() {} | 89 virtual ~Delegate() {} |
84 | 90 |
85 // Save JSON-encoded pairing information to persistent storage. If | 91 // Retrieves all JSON-encoded pairings from persistent storage. |
86 // a non-NULL callback is provided, invoke it on completion to | 92 virtual scoped_ptr<base::ListValue> LoadAll() = 0; |
87 // indicate success or failure. Must not block. | |
88 virtual void Save(const std::string& pairings_json, | |
89 const SaveCallback& callback) = 0; | |
90 | 93 |
91 // Retrieve the JSON-encoded pairing information from persistent | 94 // Deletes all pairings in persistent storage. Must not block. |
Jamie
2013/08/01 22:44:04
I think these are all allowed to block now, correc
alexeypa (please no reviews)
2013/08/01 23:07:42
Done.
| |
92 // storage. Must not block. | 95 virtual bool DeleteAll() = 0; |
93 virtual void Load(const LoadCallback& callback) = 0; | 96 |
97 // Retrieves the pairing identified by |client_id|. | |
98 virtual Pairing Load(const std::string& client_id) = 0; | |
99 | |
100 // Saves |pairing| to persistent storage. | |
101 virtual bool Save(const Pairing& pairing) = 0; | |
102 | |
103 // Deletes the pairing identified by |client_id|. | |
104 virtual bool Delete(const std::string& client_id) = 0; | |
94 }; | 105 }; |
95 | 106 |
96 explicit PairingRegistry(scoped_ptr<Delegate> delegate); | 107 PairingRegistry( |
108 scoped_refptr<base::SingleThreadTaskRunner> delegate_task_runner, | |
109 scoped_ptr<Delegate> delegate); | |
97 | 110 |
98 // Creates a pairing for a new client and saves it to disk. | 111 // Creates a pairing for a new client and saves it to disk. |
99 // | 112 // |
100 // TODO(jamiewalch): Plumb the Save callback into the RequestPairing flow | 113 // TODO(jamiewalch): Plumb the Save callback into the RequestPairing flow |
101 // so that the client isn't sent the pairing information until it has been | 114 // so that the client isn't sent the pairing information until it has been |
102 // saved. | 115 // saved. |
103 Pairing CreatePairing(const std::string& client_name); | 116 Pairing CreatePairing(const std::string& client_name); |
104 | 117 |
105 // Gets the pairing for the specified client id. See the corresponding | 118 // Gets the pairing for the specified client id. See the corresponding |
106 // Delegate method for details. If none is found, the callback is invoked | 119 // Delegate method for details. If none is found, the callback is invoked |
107 // with an invalid Pairing. | 120 // with an invalid Pairing. |
108 void GetPairing(const std::string& client_id, | 121 void GetPairing(const std::string& client_id, |
109 const GetPairingCallback& callback); | 122 const GetPairingCallback& callback); |
110 | 123 |
111 // Gets all pairings with the shared secrets removed as a base::ListValue. | 124 // Gets all pairings with the shared secrets removed as a base::ListValue. |
112 void GetAllPairings(const GetAllPairingsCallback& callback); | 125 void GetAllPairings(const GetAllPairingsCallback& callback); |
113 | 126 |
114 // Delete a pairing, identified by its client ID. |callback| is called with | 127 // Delete a pairing, identified by its client ID. |callback| is called with |
115 // the result of saving the new config, which occurs even if the client ID | 128 // the result of saving the new config, which occurs even if the client ID |
116 // did not match any pairing. | 129 // did not match any pairing. |
117 void DeletePairing(const std::string& client_id, | 130 void DeletePairing(const std::string& client_id, |
118 const SaveCallback& callback); | 131 const DoneCallback& callback); |
119 | 132 |
120 // Clear all pairings from the registry. | 133 // Clear all pairings from the registry. |
121 void ClearAllPairings(const SaveCallback& callback); | 134 void ClearAllPairings(const DoneCallback& callback); |
135 | |
136 protected: | |
137 friend class base::RefCountedThreadSafe<PairingRegistry>; | |
138 virtual ~PairingRegistry(); | |
139 | |
140 // Lets the tests to override task posting to make all callbacks synchronous. | |
Jamie
2013/08/01 22:44:04
Nit: Either "Allows the tests to override..." or "
alexeypa (please no reviews)
2013/08/01 23:07:42
Done.
| |
141 virtual void PostTask( | |
142 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, | |
143 const tracked_objects::Location& from_here, | |
144 const base::Closure& task); | |
122 | 145 |
123 private: | 146 private: |
124 FRIEND_TEST_ALL_PREFIXES(PairingRegistryTest, AddPairing); | 147 FRIEND_TEST_ALL_PREFIXES(PairingRegistryTest, AddPairing); |
125 FRIEND_TEST_ALL_PREFIXES(PairingRegistryTest, GetAllPairingsJSON); | |
126 friend class NegotiatingAuthenticatorTest; | 148 friend class NegotiatingAuthenticatorTest; |
127 friend class base::RefCountedThreadSafe<PairingRegistry>; | |
128 | |
129 virtual ~PairingRegistry(); | |
130 | 149 |
131 // Helper method for unit tests. | 150 // Helper method for unit tests. |
132 void AddPairing(const Pairing& pairing); | 151 void AddPairing(const Pairing& pairing); |
133 | 152 |
134 // Worker functions for each of the public methods, passed as a callback to | 153 // Blocking helper methods used to call the delegate. |
135 // the delegate. | 154 void DoLoadAll( |
136 void MergePairingAndSave(const Pairing& pairing, | 155 const protocol::PairingRegistry::GetAllPairingsCallback& callback); |
137 const SaveCallback& callback, | 156 void DoDeleteAll( |
138 const std::string& pairings_json); | 157 const protocol::PairingRegistry::DoneCallback& callback); |
139 void DoGetPairing(const std::string& client_id, | 158 void DoLoad( |
140 const GetPairingCallback& callback, | 159 const std::string& client_id, |
141 const std::string& pairings_json); | 160 const protocol::PairingRegistry::GetPairingCallback& callback); |
142 void SanitizePairings(const GetAllPairingsCallback& callback, | 161 void DoSave( |
143 const std::string& pairings_json); | 162 const protocol::PairingRegistry::Pairing& pairing, |
144 void DoDeletePairing(const std::string& client_id, | 163 const protocol::PairingRegistry::DoneCallback& callback); |
145 const SaveCallback& callback, | 164 void DoDelete( |
146 const std::string& pairings_json); | 165 const std::string& client_id, |
166 const protocol::PairingRegistry::DoneCallback& callback); | |
147 | 167 |
148 // "Trampoline" callbacks that schedule the next pending request and then | 168 // "Trampoline" callbacks that schedule the next pending request and then |
149 // invoke the original caller-supplied callback. | 169 // invoke the original caller-supplied callback. |
150 void InvokeLoadCallbackAndScheduleNext( | 170 void InvokeDoneCallbackAndScheduleNext( |
151 const LoadCallback& callback, const std::string& pairings_json); | 171 const DoneCallback& callback, bool success); |
152 void InvokeSaveCallbackAndScheduleNext( | |
153 const SaveCallback& callback, bool success); | |
154 void InvokeGetPairingCallbackAndScheduleNext( | 172 void InvokeGetPairingCallbackAndScheduleNext( |
155 const GetPairingCallback& callback, Pairing pairing); | 173 const GetPairingCallback& callback, Pairing pairing); |
156 void InvokeGetAllPairingsCallbackAndScheduleNext( | 174 void InvokeGetAllPairingsCallbackAndScheduleNext( |
157 const GetAllPairingsCallback& callback, | 175 const GetAllPairingsCallback& callback, |
158 scoped_ptr<base::ListValue> pairings); | 176 scoped_ptr<base::ListValue> pairings); |
159 | 177 |
178 // Sanitize |pairings| by parsing each entry and removing the secret from it. | |
179 void SanitizePairings(const GetAllPairingsCallback& callback, | |
180 scoped_ptr<base::ListValue> pairings); | |
181 | |
160 // Queue management methods. | 182 // Queue management methods. |
161 void ServiceOrQueueRequest(const base::Closure& request); | 183 void ServiceOrQueueRequest(const base::Closure& request); |
162 void ServiceNextRequest(); | 184 void ServiceNextRequest(); |
163 | 185 |
164 // Translate between the structured and serialized forms of the pairing data. | 186 // Task runner on which all public methods of this class should be called. |
165 static PairedClients DecodeJson(const std::string& pairings_json); | 187 scoped_refptr<base::SingleThreadTaskRunner> caller_task_runner_; |
166 static std::string EncodeJson(const PairedClients& clients); | 188 |
167 static scoped_ptr<base::ListValue> ConvertToListValue( | 189 // Task runner used to run blocking calls to the delegate. A single thread |
168 const PairedClients& clients, | 190 // task runner is used to guarantee that one one method of the delegate is |
169 bool include_shared_secrets); | 191 // called at a time. |
192 scoped_refptr<base::SingleThreadTaskRunner> delegate_task_runner_; | |
170 | 193 |
171 scoped_ptr<Delegate> delegate_; | 194 scoped_ptr<Delegate> delegate_; |
172 | 195 |
173 std::queue<base::Closure> pending_requests_; | 196 std::queue<base::Closure> pending_requests_; |
174 | 197 |
175 DISALLOW_COPY_AND_ASSIGN(PairingRegistry); | 198 DISALLOW_COPY_AND_ASSIGN(PairingRegistry); |
176 }; | 199 }; |
177 | 200 |
178 } // namespace protocol | 201 } // namespace protocol |
179 } // namespace remoting | 202 } // namespace remoting |
180 | 203 |
181 #endif // REMOTING_PROTOCOL_PAIRING_REGISTRY_H_ | 204 #endif // REMOTING_PROTOCOL_PAIRING_REGISTRY_H_ |
OLD | NEW |