OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/host/security_key/security_key_auth_handler.h" | 5 #include "remoting/host/security_key/security_key_auth_handler.h" |
6 | 6 |
7 #include <stdint.h> | |
8 #include <unistd.h> | 7 #include <unistd.h> |
9 | 8 |
| 9 #include <cstdint> |
10 #include <memory> | 10 #include <memory> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/callback.h" |
13 #include "base/files/file_util.h" | 14 #include "base/files/file_util.h" |
14 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
| 16 #include "base/location.h" |
15 #include "base/logging.h" | 17 #include "base/logging.h" |
16 #include "base/stl_util.h" | 18 #include "base/memory/ptr_util.h" |
| 19 #include "base/memory/ref_counted.h" |
| 20 #include "base/memory/weak_ptr.h" |
| 21 #include "base/single_thread_task_runner.h" |
| 22 #include "base/synchronization/lock.h" |
| 23 // TODO: DEBUG DEBUG DEBUG -> REMOVE LOGGING |
| 24 #include "base/threading/platform_thread.h" |
| 25 #include "base/threading/thread.h" |
| 26 // END DEBUG DEBUG DEBUG |
17 #include "base/threading/thread_checker.h" | 27 #include "base/threading/thread_checker.h" |
18 #include "base/threading/thread_restrictions.h" | 28 #include "base/threading/thread_restrictions.h" |
| 29 #include "base/threading/thread_task_runner_handle.h" |
19 #include "base/values.h" | 30 #include "base/values.h" |
20 #include "net/base/completion_callback.h" | 31 #include "net/base/completion_callback.h" |
21 #include "net/base/net_errors.h" | 32 #include "net/base/net_errors.h" |
22 #include "net/socket/stream_socket.h" | 33 #include "net/socket/stream_socket.h" |
23 #include "net/socket/unix_domain_server_socket_posix.h" | 34 #include "net/socket/unix_domain_server_socket_posix.h" |
24 #include "remoting/base/logging.h" | 35 #include "remoting/base/logging.h" |
25 #include "remoting/host/security_key/security_key_socket.h" | 36 #include "remoting/host/security_key/security_key_socket.h" |
26 | 37 |
27 namespace { | 38 namespace { |
28 | 39 |
(...skipping 17 matching lines...) Expand all Loading... |
46 unsigned int GetCommandCode(const std::string& data) { | 57 unsigned int GetCommandCode(const std::string& data) { |
47 return data.empty() ? -1 : static_cast<unsigned int>(data[0]); | 58 return data.empty() ? -1 : static_cast<unsigned int>(data[0]); |
48 } | 59 } |
49 | 60 |
50 } // namespace | 61 } // namespace |
51 | 62 |
52 namespace remoting { | 63 namespace remoting { |
53 | 64 |
54 class SecurityKeyAuthHandlerLinux : public SecurityKeyAuthHandler { | 65 class SecurityKeyAuthHandlerLinux : public SecurityKeyAuthHandler { |
55 public: | 66 public: |
56 SecurityKeyAuthHandlerLinux(); | 67 explicit SecurityKeyAuthHandlerLinux( |
| 68 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner); |
57 ~SecurityKeyAuthHandlerLinux() override; | 69 ~SecurityKeyAuthHandlerLinux() override; |
58 | 70 |
59 private: | 71 private: |
60 typedef std::map<int, SecurityKeySocket*> ActiveSockets; | 72 // The actual implementation resides in Core class. |
| 73 class Core; |
61 | 74 |
62 // SecurityKeyAuthHandler interface. | 75 // SecurityKeyAuthHandler interface. |
63 void CreateSecurityKeyConnection() override; | 76 void CreateSecurityKeyConnection() override; |
64 bool IsValidConnectionId(int security_key_connection_id) const override; | 77 bool IsValidConnectionId(int security_key_connection_id) const override; |
65 void SendClientResponse(int security_key_connection_id, | 78 void SendClientResponse(int security_key_connection_id, |
66 const std::string& response) override; | 79 const std::string& response) override; |
67 void SendErrorAndCloseConnection(int security_key_connection_id) override; | 80 void SendErrorAndCloseConnection(int security_key_connection_id) override; |
68 void SetSendMessageCallback(const SendMessageCallback& callback) override; | 81 void SetSendMessageCallback(const SendMessageCallback& callback) override; |
69 size_t GetActiveConnectionCountForTest() const override; | 82 size_t GetActiveConnectionCountForTest() const override; |
70 void SetRequestTimeoutForTest(base::TimeDelta timeout) override; | 83 void SetRequestTimeoutForTest(base::TimeDelta timeout) override; |
71 | 84 |
| 85 // Ensures SecurityKeyAuthHandlerLinux methods are called on the same thread. |
| 86 base::ThreadChecker thread_checker_; |
| 87 |
| 88 // Used to pass security key extension messages to the client. |
| 89 SendMessageCallback send_message_callback_; |
| 90 |
| 91 // Timeout used for a request. |
| 92 base::TimeDelta request_timeout_; |
| 93 |
| 94 // Used by |core_| to perform File IO via Unix Domain Sockets. |
| 95 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_; |
| 96 |
| 97 // Responsible for handling security key requests on |file_task_runner_|. |
| 98 std::unique_ptr<Core> core_; |
| 99 |
| 100 DISALLOW_COPY_AND_ASSIGN(SecurityKeyAuthHandlerLinux); |
| 101 }; |
| 102 |
| 103 class SecurityKeyAuthHandlerLinux::Core { |
| 104 public: |
| 105 Core(const SendMessageCallback& send_message_callback, |
| 106 base::TimeDelta timeout); |
| 107 ~Core(); |
| 108 |
| 109 // Creates the accept socket, binds to it, and begins accepting listeners. |
| 110 // Must be called from the file IO task runner. |
| 111 void StartListening(); |
| 112 |
| 113 // Returns whether |security_key_connection_id| corresponds to an active |
| 114 // connection. Can be called from any thread. |
| 115 bool IsValidConnectionId(int security_key_connection_id) const; |
| 116 |
| 117 // Passes |response| to the socket associated with |
| 118 // |security_key_connection_id|. Must be called from the file IO task runner. |
| 119 void SendClientResponse(int security_key_connection_id, |
| 120 const std::string& response); |
| 121 |
| 122 // Sends an SSH error code to the socket assocated with |
| 123 // |security_key_connection_id| and closes it. Must be called from the file |
| 124 // IO task runner. |
| 125 void SendErrorAndCloseConnection(int security_key_connection_id); |
| 126 |
| 127 // Returns the number of active connections. Can be called from any thread. |
| 128 size_t GetActiveConnectionCountForTest() const; |
| 129 |
| 130 private: |
| 131 typedef std::map<int, std::unique_ptr<SecurityKeySocket>> ActiveSockets; |
| 132 |
72 // Starts listening for connection. | 133 // Starts listening for connection. |
73 void DoAccept(); | 134 void DoAccept(); |
74 | 135 |
75 // Called when a connection is accepted. | 136 // Called when a connection is accepted. |
76 void OnAccepted(int result); | 137 void OnAccepted(int result); |
77 | 138 |
78 // Called when a SecurityKeySocket has done reading. | 139 // Called when a SecurityKeySocket has done reading. |
79 void OnReadComplete(int security_key_connection_id); | 140 void OnReadComplete(int security_key_connection_id); |
80 | 141 |
81 // Gets an active socket iterator for |security_key_connection_id|. | 142 // Gets an active socket iterator for |security_key_connection_id|. |
(...skipping 12 matching lines...) Expand all Loading... |
94 // Socket used to listen for authorization requests. | 155 // Socket used to listen for authorization requests. |
95 std::unique_ptr<net::UnixDomainServerSocket> auth_socket_; | 156 std::unique_ptr<net::UnixDomainServerSocket> auth_socket_; |
96 | 157 |
97 // A temporary holder for an accepted connection. | 158 // A temporary holder for an accepted connection. |
98 std::unique_ptr<net::StreamSocket> accept_socket_; | 159 std::unique_ptr<net::StreamSocket> accept_socket_; |
99 | 160 |
100 // Used to pass security key extension messages to the client. | 161 // Used to pass security key extension messages to the client. |
101 SendMessageCallback send_message_callback_; | 162 SendMessageCallback send_message_callback_; |
102 | 163 |
103 // The last assigned security key connection id. | 164 // The last assigned security key connection id. |
104 int last_connection_id_; | 165 int last_connection_id_ = 0; |
105 | 166 |
106 // Sockets by connection id used to process gnubbyd requests. | 167 // Sockets by connection id used to process gnubbyd requests. |
107 ActiveSockets active_sockets_; | 168 ActiveSockets active_sockets_; |
108 | 169 |
| 170 // Protects access to |active_sockets_|. Marked as mutable so this lock can |
| 171 // be acquired inside methods marked 'const'. |
| 172 mutable base::Lock active_sockets_lock_; |
| 173 |
109 // Timeout used for a request. | 174 // Timeout used for a request. |
110 base::TimeDelta request_timeout_; | 175 base::TimeDelta request_timeout_; |
111 | 176 |
112 DISALLOW_COPY_AND_ASSIGN(SecurityKeyAuthHandlerLinux); | 177 // Used to run |send_message_callback_| on the main thread. |
| 178 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner_; |
| 179 |
| 180 base::WeakPtrFactory<Core> weak_factory_; |
| 181 |
| 182 DISALLOW_COPY_AND_ASSIGN(Core); |
113 }; | 183 }; |
114 | 184 |
115 std::unique_ptr<SecurityKeyAuthHandler> SecurityKeyAuthHandler::Create( | 185 std::unique_ptr<SecurityKeyAuthHandler> SecurityKeyAuthHandler::Create( |
116 ClientSessionDetails* client_session_details, | 186 ClientSessionDetails* client_session_details, |
117 const SendMessageCallback& send_message_callback) { | 187 const SendMessageCallback& send_message_callback, |
| 188 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) { |
118 std::unique_ptr<SecurityKeyAuthHandler> auth_handler( | 189 std::unique_ptr<SecurityKeyAuthHandler> auth_handler( |
119 new SecurityKeyAuthHandlerLinux()); | 190 new SecurityKeyAuthHandlerLinux(file_task_runner)); |
120 auth_handler->SetSendMessageCallback(send_message_callback); | 191 auth_handler->SetSendMessageCallback(send_message_callback); |
121 return auth_handler; | 192 return auth_handler; |
122 } | 193 } |
123 | 194 |
124 void SecurityKeyAuthHandler::SetSecurityKeySocketName( | 195 void SecurityKeyAuthHandler::SetSecurityKeySocketName( |
125 const base::FilePath& security_key_socket_name) { | 196 const base::FilePath& security_key_socket_name) { |
126 g_security_key_socket_name.Get() = security_key_socket_name; | 197 g_security_key_socket_name.Get() = security_key_socket_name; |
127 } | 198 } |
128 | 199 |
129 SecurityKeyAuthHandlerLinux::SecurityKeyAuthHandlerLinux() | 200 SecurityKeyAuthHandlerLinux::SecurityKeyAuthHandlerLinux( |
130 : last_connection_id_(0), | 201 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) |
131 request_timeout_( | 202 : request_timeout_( |
132 base::TimeDelta::FromSeconds(kDefaultRequestTimeoutSeconds)) {} | 203 base::TimeDelta::FromSeconds(kDefaultRequestTimeoutSeconds)), |
| 204 file_task_runner_(file_task_runner) { |
| 205 LOG(INFO) << "** SecurityKeyAuthHandlerLinux() called on: " |
| 206 << base::PlatformThread::GetName(); |
| 207 } |
133 | 208 |
134 SecurityKeyAuthHandlerLinux::~SecurityKeyAuthHandlerLinux() { | 209 SecurityKeyAuthHandlerLinux::~SecurityKeyAuthHandlerLinux() { |
135 STLDeleteValues(&active_sockets_); | 210 if (core_) { |
| 211 file_task_runner_->DeleteSoon(FROM_HERE, core_.release()); |
| 212 } |
136 } | 213 } |
137 | 214 |
138 void SecurityKeyAuthHandlerLinux::CreateSecurityKeyConnection() { | 215 void SecurityKeyAuthHandlerLinux::CreateSecurityKeyConnection() { |
139 DCHECK(thread_checker_.CalledOnValidThread()); | 216 DCHECK(thread_checker_.CalledOnValidThread()); |
140 DCHECK(!g_security_key_socket_name.Get().empty()); | 217 DCHECK(!g_security_key_socket_name.Get().empty()); |
| 218 DCHECK(!core_); |
| 219 LOG(INFO) << "** CreateSecurityKeyConnection() called on: " |
| 220 << base::PlatformThread::GetName(); |
141 | 221 |
142 { | 222 core_.reset(new SecurityKeyAuthHandlerLinux::Core(send_message_callback_, |
143 // DeleteFile() is a blocking operation, but so is creation of the unix | 223 request_timeout_)); |
144 // socket below. Consider moving this class to a different thread if this | |
145 // causes any problems. See crbug.com/509807. | |
146 // TODO(joedow): Since this code now runs as a host extension, we should | |
147 // perform our IO on a separate thread: crbug.com/591739 | |
148 base::ThreadRestrictions::ScopedAllowIO allow_io; | |
149 | 224 |
150 // If the file already exists, a socket in use error is returned. | 225 // base::Unretained is safe to use as |core_| is released in the D'tor on |
151 base::DeleteFile(g_security_key_socket_name.Get(), false); | 226 // this thread and destroyed on |file_task_runner_|. |
| 227 file_task_runner_->PostTask( |
| 228 FROM_HERE, base::Bind(&SecurityKeyAuthHandlerLinux::Core::StartListening, |
| 229 base::Unretained(core_.get()))); |
| 230 } |
| 231 |
| 232 bool SecurityKeyAuthHandlerLinux::IsValidConnectionId( |
| 233 int security_key_connection_id) const { |
| 234 DCHECK(thread_checker_.CalledOnValidThread()); |
| 235 return core_ && core_->IsValidConnectionId(security_key_connection_id); |
| 236 } |
| 237 |
| 238 void SecurityKeyAuthHandlerLinux::SendClientResponse( |
| 239 int security_key_connection_id, |
| 240 const std::string& response) { |
| 241 DCHECK(thread_checker_.CalledOnValidThread()); |
| 242 DCHECK(core_); |
| 243 |
| 244 if (!IsValidConnectionId(security_key_connection_id)) { |
| 245 LOG(WARNING) << "Unknown gnubby-auth data connection: '" |
| 246 << security_key_connection_id << "'"; |
| 247 return; |
152 } | 248 } |
153 | 249 |
154 HOST_LOG << "Listening for security key requests on " | 250 // base::Unretained is safe to use as |core_| is released in the D'tor on |
155 << g_security_key_socket_name.Get().value(); | 251 // this thread and destroyed on |file_task_runner_|. |
| 252 file_task_runner_->PostTask( |
| 253 FROM_HERE, |
| 254 base::Bind(&SecurityKeyAuthHandlerLinux::Core::SendClientResponse, |
| 255 base::Unretained(core_.get()), security_key_connection_id, |
| 256 base::ConstRef(response))); |
| 257 } |
| 258 |
| 259 void SecurityKeyAuthHandlerLinux::SendErrorAndCloseConnection( |
| 260 int security_key_connection_id) { |
| 261 DCHECK(thread_checker_.CalledOnValidThread()); |
| 262 DCHECK(core_); |
| 263 |
| 264 if (!IsValidConnectionId(security_key_connection_id)) { |
| 265 LOG(WARNING) << "Unknown gnubby-auth data connection: '" |
| 266 << security_key_connection_id << "'"; |
| 267 return; |
| 268 } |
| 269 |
| 270 // base::Unretained is safe to use as |core_| is released in the D'tor on |
| 271 // this thread and destroyed on |file_task_runner_|. |
| 272 file_task_runner_->PostTask( |
| 273 FROM_HERE, |
| 274 base::Bind( |
| 275 &SecurityKeyAuthHandlerLinux::Core::SendErrorAndCloseConnection, |
| 276 base::Unretained(core_.get()), security_key_connection_id)); |
| 277 } |
| 278 |
| 279 void SecurityKeyAuthHandlerLinux::SetSendMessageCallback( |
| 280 const SendMessageCallback& callback) { |
| 281 DCHECK(thread_checker_.CalledOnValidThread()); |
| 282 DCHECK(!core_) << "Core object already created, callback already set."; |
| 283 send_message_callback_ = callback; |
| 284 } |
| 285 |
| 286 size_t SecurityKeyAuthHandlerLinux::GetActiveConnectionCountForTest() const { |
| 287 DCHECK(thread_checker_.CalledOnValidThread()); |
| 288 return core_ ? core_->GetActiveConnectionCountForTest() : 0; |
| 289 } |
| 290 |
| 291 void SecurityKeyAuthHandlerLinux::SetRequestTimeoutForTest( |
| 292 base::TimeDelta timeout) { |
| 293 DCHECK(thread_checker_.CalledOnValidThread()); |
| 294 DCHECK(!core_) << "Core object already created, timeout already set."; |
| 295 request_timeout_ = timeout; |
| 296 } |
| 297 |
| 298 SecurityKeyAuthHandlerLinux::Core::Core( |
| 299 const SendMessageCallback& send_message_callback, |
| 300 base::TimeDelta timeout) |
| 301 : send_message_callback_(send_message_callback), |
| 302 request_timeout_(timeout), |
| 303 weak_factory_(this) { |
| 304 LOG(INFO) << "** Core() called on: " << base::PlatformThread::GetName(); |
| 305 thread_checker_.DetachFromThread(); |
| 306 main_task_runner_ = base::ThreadTaskRunnerHandle::Get(); |
| 307 } |
| 308 |
| 309 SecurityKeyAuthHandlerLinux::Core::~Core() { |
| 310 LOG(INFO) << "** ~Core() called on: " << base::PlatformThread::GetName(); |
| 311 } |
| 312 |
| 313 void SecurityKeyAuthHandlerLinux::Core::StartListening() { |
| 314 LOG(INFO) << "** Core::StartListening() called on: " |
| 315 << base::PlatformThread::GetName(); |
| 316 DCHECK(thread_checker_.CalledOnValidThread()); |
| 317 DCHECK(!auth_socket_); |
| 318 |
| 319 // If the file already exists, a socket in use error is returned. |
| 320 base::DeleteFile(g_security_key_socket_name.Get(), false); |
156 | 321 |
157 auth_socket_.reset( | 322 auth_socket_.reset( |
158 new net::UnixDomainServerSocket(base::Bind(MatchUid), false)); | 323 new net::UnixDomainServerSocket(base::Bind(MatchUid), false)); |
| 324 |
159 int rv = auth_socket_->BindAndListen(g_security_key_socket_name.Get().value(), | 325 int rv = auth_socket_->BindAndListen(g_security_key_socket_name.Get().value(), |
160 /*backlog=*/1); | 326 /*backlog=*/1); |
161 if (rv != net::OK) { | 327 if (rv != net::OK) { |
162 LOG(ERROR) << "Failed to open socket for auth requests: '" << rv << "'"; | 328 LOG(ERROR) << "Failed to open socket for auth requests: '" << rv << "'"; |
163 return; | 329 return; |
164 } | 330 } |
| 331 |
| 332 HOST_LOG << "Listening for security key requests on " |
| 333 << g_security_key_socket_name.Get().value(); |
| 334 |
165 DoAccept(); | 335 DoAccept(); |
166 } | 336 } |
167 | 337 |
168 bool SecurityKeyAuthHandlerLinux::IsValidConnectionId( | 338 bool SecurityKeyAuthHandlerLinux::Core::IsValidConnectionId( |
169 int security_key_connection_id) const { | 339 int security_key_connection_id) const { |
| 340 LOG(INFO) << "** Core::IsValidConnectionId() called on: " |
| 341 << base::PlatformThread::GetName(); |
| 342 base::AutoLock auto_lock(active_sockets_lock_); |
170 return GetSocketForConnectionId(security_key_connection_id) != | 343 return GetSocketForConnectionId(security_key_connection_id) != |
171 active_sockets_.end(); | 344 active_sockets_.end(); |
172 } | 345 } |
173 | 346 |
174 void SecurityKeyAuthHandlerLinux::SendClientResponse( | 347 void SecurityKeyAuthHandlerLinux::Core::SendClientResponse( |
175 int security_key_connection_id, | 348 int security_key_connection_id, |
176 const std::string& response) { | 349 const std::string& response) { |
| 350 LOG(INFO) << "** Core::SendClientResponse() called on: " |
| 351 << base::PlatformThread::GetName(); |
| 352 DCHECK(thread_checker_.CalledOnValidThread()); |
| 353 |
177 ActiveSockets::const_iterator iter = | 354 ActiveSockets::const_iterator iter = |
178 GetSocketForConnectionId(security_key_connection_id); | 355 GetSocketForConnectionId(security_key_connection_id); |
179 if (iter != active_sockets_.end()) { | 356 if (iter != active_sockets_.end()) { |
180 iter->second->SendResponse(response); | 357 iter->second->SendResponse(response); |
181 } else { | 358 } else { |
182 LOG(WARNING) << "Unknown gnubby-auth data connection: '" | 359 LOG(WARNING) << "Unknown gnubby-auth data connection: '" |
183 << security_key_connection_id << "'"; | 360 << security_key_connection_id << "'"; |
184 } | 361 } |
185 } | 362 } |
186 | 363 |
187 void SecurityKeyAuthHandlerLinux::SendErrorAndCloseConnection( | 364 void SecurityKeyAuthHandlerLinux::Core::SendErrorAndCloseConnection( |
188 int security_key_connection_id) { | 365 int security_key_connection_id) { |
| 366 LOG(INFO) << "** Core::SendErrorAndCloseConnection() called on: " |
| 367 << base::PlatformThread::GetName(); |
| 368 DCHECK(thread_checker_.CalledOnValidThread()); |
| 369 |
189 ActiveSockets::const_iterator iter = | 370 ActiveSockets::const_iterator iter = |
190 GetSocketForConnectionId(security_key_connection_id); | 371 GetSocketForConnectionId(security_key_connection_id); |
191 if (iter != active_sockets_.end()) { | 372 if (iter != active_sockets_.end()) { |
192 HOST_LOG << "Sending security key error"; | 373 HOST_LOG << "Sending security key error"; |
193 SendErrorAndCloseActiveSocket(iter); | 374 SendErrorAndCloseActiveSocket(iter); |
194 } else { | 375 } else { |
195 LOG(WARNING) << "Unknown gnubby-auth data connection: '" | 376 LOG(WARNING) << "Unknown gnubby-auth data connection: '" |
196 << security_key_connection_id << "'"; | 377 << security_key_connection_id << "'"; |
197 } | 378 } |
198 } | 379 } |
199 | 380 |
200 void SecurityKeyAuthHandlerLinux::SetSendMessageCallback( | 381 size_t SecurityKeyAuthHandlerLinux::Core::GetActiveConnectionCountForTest() |
201 const SendMessageCallback& callback) { | 382 const { |
202 send_message_callback_ = callback; | 383 base::AutoLock auto_lock(active_sockets_lock_); |
| 384 return active_sockets_.size(); |
| 385 }; |
| 386 |
| 387 void SecurityKeyAuthHandlerLinux::Core::DoAccept() { |
| 388 LOG(INFO) << "** Core::DoAccept() called on: " |
| 389 << base::PlatformThread::GetName(); |
| 390 DCHECK(thread_checker_.CalledOnValidThread()); |
| 391 |
| 392 int result = auth_socket_->Accept( |
| 393 &accept_socket_, |
| 394 base::Bind(&SecurityKeyAuthHandlerLinux::Core::OnAccepted, |
| 395 weak_factory_.GetWeakPtr())); |
| 396 if (result != net::ERR_IO_PENDING) { |
| 397 OnAccepted(result); |
| 398 } |
203 } | 399 } |
204 | 400 |
205 size_t SecurityKeyAuthHandlerLinux::GetActiveConnectionCountForTest() const { | 401 void SecurityKeyAuthHandlerLinux::Core::OnAccepted(int result) { |
206 return active_sockets_.size(); | 402 LOG(INFO) << "** Core::OnAccepted() called on: " |
207 } | 403 << base::PlatformThread::GetName(); |
208 | |
209 void SecurityKeyAuthHandlerLinux::SetRequestTimeoutForTest( | |
210 base::TimeDelta timeout) { | |
211 request_timeout_ = timeout; | |
212 } | |
213 | |
214 void SecurityKeyAuthHandlerLinux::DoAccept() { | |
215 int result = auth_socket_->Accept( | |
216 &accept_socket_, base::Bind(&SecurityKeyAuthHandlerLinux::OnAccepted, | |
217 base::Unretained(this))); | |
218 if (result != net::ERR_IO_PENDING) | |
219 OnAccepted(result); | |
220 } | |
221 | |
222 void SecurityKeyAuthHandlerLinux::OnAccepted(int result) { | |
223 DCHECK(thread_checker_.CalledOnValidThread()); | 404 DCHECK(thread_checker_.CalledOnValidThread()); |
224 DCHECK_NE(net::ERR_IO_PENDING, result); | 405 DCHECK_NE(net::ERR_IO_PENDING, result); |
225 | 406 |
226 if (result < 0) { | 407 if (result < 0) { |
227 LOG(ERROR) << "Error in accepting a new connection"; | 408 LOG(ERROR) << "Error in accepting a new connection"; |
228 return; | 409 return; |
229 } | 410 } |
230 | 411 |
231 int security_key_connection_id = ++last_connection_id_; | 412 int security_key_connection_id = ++last_connection_id_; |
232 SecurityKeySocket* socket = new SecurityKeySocket( | 413 SecurityKeySocket* socket = new SecurityKeySocket( |
233 std::move(accept_socket_), request_timeout_, | 414 std::move(accept_socket_), request_timeout_, |
234 base::Bind(&SecurityKeyAuthHandlerLinux::RequestTimedOut, | 415 base::Bind(&SecurityKeyAuthHandlerLinux::Core::RequestTimedOut, |
235 base::Unretained(this), security_key_connection_id)); | 416 weak_factory_.GetWeakPtr(), security_key_connection_id)); |
236 active_sockets_[security_key_connection_id] = socket; | 417 { |
| 418 base::AutoLock auto_lock(active_sockets_lock_); |
| 419 active_sockets_[security_key_connection_id] = base::WrapUnique(socket); |
| 420 } |
237 socket->StartReadingRequest( | 421 socket->StartReadingRequest( |
238 base::Bind(&SecurityKeyAuthHandlerLinux::OnReadComplete, | 422 base::Bind(&SecurityKeyAuthHandlerLinux::Core::OnReadComplete, |
239 base::Unretained(this), security_key_connection_id)); | 423 weak_factory_.GetWeakPtr(), security_key_connection_id)); |
240 | 424 |
241 // Continue accepting new connections. | 425 // Continue accepting new connections. |
242 DoAccept(); | 426 DoAccept(); |
243 } | 427 } |
244 | 428 |
245 void SecurityKeyAuthHandlerLinux::OnReadComplete( | 429 void SecurityKeyAuthHandlerLinux::Core::OnReadComplete( |
246 int security_key_connection_id) { | 430 int security_key_connection_id) { |
| 431 LOG(INFO) << "** Core::OnReadComplete() called on: " |
| 432 << base::PlatformThread::GetName(); |
247 DCHECK(thread_checker_.CalledOnValidThread()); | 433 DCHECK(thread_checker_.CalledOnValidThread()); |
248 | 434 |
249 ActiveSockets::const_iterator iter = | 435 ActiveSockets::const_iterator iter = |
250 active_sockets_.find(security_key_connection_id); | 436 active_sockets_.find(security_key_connection_id); |
251 DCHECK(iter != active_sockets_.end()); | 437 DCHECK(iter != active_sockets_.end()); |
252 std::string request_data; | 438 std::string request_data; |
253 if (!iter->second->GetAndClearRequestData(&request_data)) { | 439 if (!iter->second->GetAndClearRequestData(&request_data)) { |
254 SendErrorAndCloseActiveSocket(iter); | 440 SendErrorAndCloseActiveSocket(iter); |
255 return; | 441 return; |
256 } | 442 } |
257 | 443 |
258 HOST_LOG << "Received security key request: " << GetCommandCode(request_data); | 444 HOST_LOG << "Received security key request: " << GetCommandCode(request_data); |
259 send_message_callback_.Run(security_key_connection_id, request_data); | 445 main_task_runner_->PostTask( |
| 446 FROM_HERE, base::Bind(send_message_callback_, security_key_connection_id, |
| 447 request_data)); |
260 | 448 |
261 iter->second->StartReadingRequest( | 449 iter->second->StartReadingRequest( |
262 base::Bind(&SecurityKeyAuthHandlerLinux::OnReadComplete, | 450 base::Bind(&SecurityKeyAuthHandlerLinux::Core::OnReadComplete, |
263 base::Unretained(this), security_key_connection_id)); | 451 weak_factory_.GetWeakPtr(), security_key_connection_id)); |
264 } | 452 } |
265 | 453 |
266 SecurityKeyAuthHandlerLinux::ActiveSockets::const_iterator | 454 SecurityKeyAuthHandlerLinux::Core::ActiveSockets::const_iterator |
267 SecurityKeyAuthHandlerLinux::GetSocketForConnectionId( | 455 SecurityKeyAuthHandlerLinux::Core::GetSocketForConnectionId( |
268 int security_key_connection_id) const { | 456 int security_key_connection_id) const { |
269 return active_sockets_.find(security_key_connection_id); | 457 return active_sockets_.find(security_key_connection_id); |
270 } | 458 } |
271 | 459 |
272 void SecurityKeyAuthHandlerLinux::SendErrorAndCloseActiveSocket( | 460 void SecurityKeyAuthHandlerLinux::Core::SendErrorAndCloseActiveSocket( |
273 const ActiveSockets::const_iterator& iter) { | 461 const ActiveSockets::const_iterator& iter) { |
| 462 LOG(INFO) << "** Core::SendErrorAndCloseActiveSocket() called on: " |
| 463 << base::PlatformThread::GetName(); |
| 464 DCHECK(thread_checker_.CalledOnValidThread()); |
| 465 |
274 iter->second->SendSshError(); | 466 iter->second->SendSshError(); |
275 delete iter->second; | 467 { |
276 active_sockets_.erase(iter); | 468 base::AutoLock auto_lock(active_sockets_lock_); |
| 469 active_sockets_.erase(iter); |
| 470 } |
277 } | 471 } |
278 | 472 |
279 void SecurityKeyAuthHandlerLinux::RequestTimedOut( | 473 void SecurityKeyAuthHandlerLinux::Core::RequestTimedOut( |
280 int security_key_connection_id) { | 474 int security_key_connection_id) { |
| 475 DCHECK(thread_checker_.CalledOnValidThread()); |
281 HOST_LOG << "SecurityKey request timed out"; | 476 HOST_LOG << "SecurityKey request timed out"; |
282 ActiveSockets::const_iterator iter = | 477 ActiveSockets::const_iterator iter = |
283 active_sockets_.find(security_key_connection_id); | 478 GetSocketForConnectionId(security_key_connection_id); |
284 if (iter != active_sockets_.end()) | 479 if (iter != active_sockets_.end()) { |
285 SendErrorAndCloseActiveSocket(iter); | 480 SendErrorAndCloseActiveSocket(iter); |
| 481 } |
286 } | 482 } |
287 | 483 |
288 } // namespace remoting | 484 } // namespace remoting |
OLD | NEW |