Index: remoting/host/security_key/security_key_auth_handler_linux.cc |
diff --git a/remoting/host/security_key/security_key_auth_handler_linux.cc b/remoting/host/security_key/security_key_auth_handler_linux.cc |
index 346a2febb396c3ed14d25a80041e02610ca61be1..4375ffd6b2527e2f3126aa1c310e2741de33e621 100644 |
--- a/remoting/host/security_key/security_key_auth_handler_linux.cc |
+++ b/remoting/host/security_key/security_key_auth_handler_linux.cc |
@@ -4,19 +4,26 @@ |
#include "remoting/host/security_key/security_key_auth_handler.h" |
-#include <stdint.h> |
#include <unistd.h> |
+#include <cstdint> |
+#include <map> |
#include <memory> |
+#include <string> |
+#include <utility> |
#include "base/bind.h" |
+#include "base/callback.h" |
+#include "base/files/file_path.h" |
#include "base/files/file_util.h" |
#include "base/lazy_instance.h" |
+#include "base/location.h" |
#include "base/logging.h" |
-#include "base/stl_util.h" |
+#include "base/memory/ptr_util.h" |
+#include "base/memory/ref_counted.h" |
+#include "base/memory/weak_ptr.h" |
+#include "base/single_thread_task_runner.h" |
#include "base/threading/thread_checker.h" |
-#include "base/threading/thread_restrictions.h" |
-#include "base/values.h" |
#include "net/base/completion_callback.h" |
#include "net/base/net_errors.h" |
#include "net/socket/stream_socket.h" |
@@ -32,6 +39,11 @@ const int64_t kDefaultRequestTimeoutSeconds = 60; |
base::LazyInstance<base::FilePath>::Leaky g_security_key_socket_name = |
LAZY_INSTANCE_INITIALIZER; |
+void DeleteExistingSocketFile() { |
+ // If the file already exists, a socket in use error is returned. |
+ base::DeleteFile(g_security_key_socket_name.Get(), false); |
+} |
+ |
// Socket authentication function that only allows connections from callers with |
// the current uid. |
bool MatchUid(const net::UnixDomainServerSocket::Credentials& credentials) { |
@@ -53,11 +65,12 @@ namespace remoting { |
class SecurityKeyAuthHandlerLinux : public SecurityKeyAuthHandler { |
public: |
- SecurityKeyAuthHandlerLinux(); |
+ explicit SecurityKeyAuthHandlerLinux( |
+ scoped_refptr<base::SingleThreadTaskRunner> file_task_runner); |
~SecurityKeyAuthHandlerLinux() override; |
private: |
- typedef std::map<int, SecurityKeySocket*> ActiveSockets; |
+ typedef std::map<int, std::unique_ptr<SecurityKeySocket>> ActiveSockets; |
// SecurityKeyAuthHandler interface. |
void CreateSecurityKeyConnection() override; |
@@ -69,6 +82,9 @@ class SecurityKeyAuthHandlerLinux : public SecurityKeyAuthHandler { |
size_t GetActiveConnectionCountForTest() const override; |
void SetRequestTimeoutForTest(base::TimeDelta timeout) override; |
+ // Sets up the socket used for accepting new connections. |
+ void CreateSocket(); |
+ |
// Starts listening for connection. |
void DoAccept(); |
@@ -101,22 +117,28 @@ class SecurityKeyAuthHandlerLinux : public SecurityKeyAuthHandler { |
SendMessageCallback send_message_callback_; |
// The last assigned security key connection id. |
- int last_connection_id_; |
+ int last_connection_id_ = 0; |
// Sockets by connection id used to process gnubbyd requests. |
ActiveSockets active_sockets_; |
+ // Used to perform File IO via Unix Domain Sockets. |
+ scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_; |
+ |
// Timeout used for a request. |
base::TimeDelta request_timeout_; |
+ base::WeakPtrFactory<SecurityKeyAuthHandlerLinux> weak_factory_; |
+ |
DISALLOW_COPY_AND_ASSIGN(SecurityKeyAuthHandlerLinux); |
}; |
std::unique_ptr<SecurityKeyAuthHandler> SecurityKeyAuthHandler::Create( |
ClientSessionDetails* client_session_details, |
- const SendMessageCallback& send_message_callback) { |
+ const SendMessageCallback& send_message_callback, |
+ scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) { |
std::unique_ptr<SecurityKeyAuthHandler> auth_handler( |
- new SecurityKeyAuthHandlerLinux()); |
+ new SecurityKeyAuthHandlerLinux(file_task_runner)); |
auth_handler->SetSendMessageCallback(send_message_callback); |
return auth_handler; |
} |
@@ -126,31 +148,27 @@ void SecurityKeyAuthHandler::SetSecurityKeySocketName( |
g_security_key_socket_name.Get() = security_key_socket_name; |
} |
-SecurityKeyAuthHandlerLinux::SecurityKeyAuthHandlerLinux() |
- : last_connection_id_(0), |
+SecurityKeyAuthHandlerLinux::SecurityKeyAuthHandlerLinux( |
+ scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) |
+ : file_task_runner_(file_task_runner), |
request_timeout_( |
- base::TimeDelta::FromSeconds(kDefaultRequestTimeoutSeconds)) {} |
+ base::TimeDelta::FromSeconds(kDefaultRequestTimeoutSeconds)), |
+ weak_factory_(this) {} |
-SecurityKeyAuthHandlerLinux::~SecurityKeyAuthHandlerLinux() { |
- STLDeleteValues(&active_sockets_); |
-} |
+SecurityKeyAuthHandlerLinux::~SecurityKeyAuthHandlerLinux() {} |
void SecurityKeyAuthHandlerLinux::CreateSecurityKeyConnection() { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(!g_security_key_socket_name.Get().empty()); |
- { |
- // DeleteFile() is a blocking operation, but so is creation of the unix |
- // socket below. Consider moving this class to a different thread if this |
- // causes any problems. See crbug.com/509807. |
- // TODO(joedow): Since this code now runs as a host extension, we should |
- // perform our IO on a separate thread: crbug.com/591739 |
- base::ThreadRestrictions::ScopedAllowIO allow_io; |
- |
- // If the file already exists, a socket in use error is returned. |
- base::DeleteFile(g_security_key_socket_name.Get(), false); |
- } |
+ file_task_runner_->PostTaskAndReply( |
Sergey Ulanov
2016/07/25 18:29:55
add a comment to explain why this is necessary.
joedow
2016/07/25 22:39:25
Done.
|
+ FROM_HERE, base::Bind(&DeleteExistingSocketFile), |
Sergey Ulanov
2016/07/25 18:29:55
nit: here you can post task for base::DeleteFile()
joedow
2016/07/25 22:39:25
Done.
|
+ base::Bind(&SecurityKeyAuthHandlerLinux::CreateSocket, |
+ weak_factory_.GetWeakPtr())); |
+} |
+void SecurityKeyAuthHandlerLinux::CreateSocket() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
HOST_LOG << "Listening for security key requests on " |
<< g_security_key_socket_name.Get().value(); |
@@ -212,9 +230,10 @@ void SecurityKeyAuthHandlerLinux::SetRequestTimeoutForTest( |
} |
void SecurityKeyAuthHandlerLinux::DoAccept() { |
+ DCHECK(thread_checker_.CalledOnValidThread()); |
int result = auth_socket_->Accept( |
&accept_socket_, base::Bind(&SecurityKeyAuthHandlerLinux::OnAccepted, |
- base::Unretained(this))); |
+ weak_factory_.GetWeakPtr())); |
if (result != net::ERR_IO_PENDING) |
OnAccepted(result); |
} |
@@ -232,11 +251,11 @@ void SecurityKeyAuthHandlerLinux::OnAccepted(int result) { |
SecurityKeySocket* socket = new SecurityKeySocket( |
std::move(accept_socket_), request_timeout_, |
base::Bind(&SecurityKeyAuthHandlerLinux::RequestTimedOut, |
- base::Unretained(this), security_key_connection_id)); |
- active_sockets_[security_key_connection_id] = socket; |
+ weak_factory_.GetWeakPtr(), security_key_connection_id)); |
Sergey Ulanov
2016/07/25 18:29:55
nit: don't really need to use weak-ptrs here becau
joedow
2016/07/25 22:39:25
Done. I was thinking this would be safer in case
|
+ active_sockets_[security_key_connection_id] = base::WrapUnique(socket); |
socket->StartReadingRequest( |
base::Bind(&SecurityKeyAuthHandlerLinux::OnReadComplete, |
- base::Unretained(this), security_key_connection_id)); |
+ weak_factory_.GetWeakPtr(), security_key_connection_id)); |
// Continue accepting new connections. |
DoAccept(); |
@@ -260,7 +279,7 @@ void SecurityKeyAuthHandlerLinux::OnReadComplete( |
iter->second->StartReadingRequest( |
base::Bind(&SecurityKeyAuthHandlerLinux::OnReadComplete, |
- base::Unretained(this), security_key_connection_id)); |
+ weak_factory_.GetWeakPtr(), security_key_connection_id)); |
} |
SecurityKeyAuthHandlerLinux::ActiveSockets::const_iterator |
@@ -272,7 +291,6 @@ SecurityKeyAuthHandlerLinux::GetSocketForConnectionId( |
void SecurityKeyAuthHandlerLinux::SendErrorAndCloseActiveSocket( |
const ActiveSockets::const_iterator& iter) { |
iter->second->SendSshError(); |
- delete iter->second; |
active_sockets_.erase(iter); |
} |