Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: remoting/host/security_key/security_key_auth_handler_win.cc

Issue 2478443002: Use ChannelMojo for remote security key channels. (Closed)
Patch Set: Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <cstdint> 7 #include <cstdint>
8 #include <map> 8 #include <map>
9 #include <memory> 9 #include <memory>
10 #include <string> 10 #include <string>
(...skipping 17 matching lines...) Expand all
28 #include "remoting/host/chromoting_messages.h" 28 #include "remoting/host/chromoting_messages.h"
29 #include "remoting/host/client_session_details.h" 29 #include "remoting/host/client_session_details.h"
30 #include "remoting/host/ipc_util.h" 30 #include "remoting/host/ipc_util.h"
31 #include "remoting/host/security_key/security_key_ipc_constants.h" 31 #include "remoting/host/security_key/security_key_ipc_constants.h"
32 #include "remoting/host/security_key/security_key_ipc_server.h" 32 #include "remoting/host/security_key/security_key_ipc_server.h"
33 33
34 namespace { 34 namespace {
35 35
36 // The timeout used to disconnect a client from the IPC Server channel if it 36 // The timeout used to disconnect a client from the IPC Server channel if it
37 // forgets to do so. This ensures the server channel is not blocked forever. 37 // forgets to do so. This ensures the server channel is not blocked forever.
38 const int kInitialRequestTimeoutSeconds = 5; 38 constexpr base::TimeDelta kInitialRequestTimeout =
39 base::TimeDelta::FromSeconds(5);
39 40
40 // This value represents the amount of time to wait for a security key request 41 // This value represents the amount of time to wait for a security key request
41 // from the client before terminating the connection. 42 // from the client before terminating the connection.
42 const int kSecurityKeyRequestTimeoutSeconds = 60; 43 constexpr base::TimeDelta kSecurityKeyRequestTimeout =
44 base::TimeDelta::FromSeconds(60);
43 45
44 } // namespace 46 } // namespace
45 47
46 namespace remoting { 48 namespace remoting {
47 49
48 // Creates an IPC server channel which services IPC clients that want to start 50 // Creates an IPC server channel which services IPC clients that want to start
49 // a security key forwarding session. Once an IPC Client connects to the 51 // a security key forwarding session. Once an IPC Client connects to the
50 // server, the SecurityKeyAuthHandlerWin class will create a new 52 // server, the SecurityKeyAuthHandlerWin class will create a new
51 // SecurityKeyIpcServer instance that will service that request. The new 53 // SecurityKeyIpcServer instance that will service that request. The new
52 // instance will exist for the lifetime of the security key request and will be 54 // instance will exist for the lifetime of the security key request and will be
53 // assigned a unique IPC channel name and connection id. The channel name is 55 // assigned a unique IPC channel name and connection id. The channel name is
54 // sent to the client which should disconnect the IPC server channel and 56 // sent to the client which should disconnect the IPC server channel and
55 // connect to the security key forwarding session IPC channel to send/receive 57 // connect to the security key forwarding session IPC channel to send/receive
56 // security key messages. The IPC server channel will then be reset so it can 58 // security key messages. The IPC server channel will then be reset so it can
57 // can service the next client/request. This system allows multiple security 59 // can service the next client/request. This system allows multiple security
58 // key forwarding sessions to occur concurrently. 60 // key forwarding sessions to occur concurrently.
59 // TODO(joedow): Update SecurityKeyAuthHandler impls to run on a separate IO 61 // TODO(joedow): Update SecurityKeyAuthHandler impls to run on a separate IO
60 // thread instead of the thread it was created on: crbug.com/591739 62 // thread instead of the thread it was created on: crbug.com/591739
61 class SecurityKeyAuthHandlerWin : public SecurityKeyAuthHandler, 63 class SecurityKeyAuthHandlerWin : public SecurityKeyAuthHandler {
62 public IPC::Listener {
63 public: 64 public:
64 explicit SecurityKeyAuthHandlerWin( 65 explicit SecurityKeyAuthHandlerWin(
65 ClientSessionDetails* client_session_details); 66 ClientSessionDetails* client_session_details);
66 ~SecurityKeyAuthHandlerWin() override; 67 ~SecurityKeyAuthHandlerWin() override;
67 68
68 private: 69 private:
69 typedef std::map<int, std::unique_ptr<SecurityKeyIpcServer>> ActiveChannels; 70 typedef std::map<int, std::unique_ptr<SecurityKeyIpcServer>> ActiveChannels;
70 71
71 // SecurityKeyAuthHandler interface. 72 // SecurityKeyAuthHandler interface.
72 void CreateSecurityKeyConnection() override; 73 void CreateSecurityKeyConnection() override;
73 bool IsValidConnectionId(int security_key_connection_id) const override; 74 bool IsValidConnectionId(int security_key_connection_id) const override;
74 void SendClientResponse(int security_key_connection_id, 75 void SendClientResponse(int security_key_connection_id,
75 const std::string& response) override; 76 const std::string& response) override;
76 void SendErrorAndCloseConnection(int security_key_connection_id) override; 77 void SendErrorAndCloseConnection(int security_key_connection_id) override;
77 void SetSendMessageCallback(const SendMessageCallback& callback) override; 78 void SetSendMessageCallback(const SendMessageCallback& callback) override;
78 size_t GetActiveConnectionCountForTest() const override; 79 size_t GetActiveConnectionCountForTest() const override;
79 void SetRequestTimeoutForTest(base::TimeDelta timeout) override; 80 void SetRequestTimeoutForTest(base::TimeDelta timeout) override;
80 81
81 // IPC::Listener implementation.
82 bool OnMessageReceived(const IPC::Message& message) override;
83 void OnChannelConnected(int32_t peer_pid) override;
84 void OnChannelError() override;
85
86 // Creates the IPC server channel and waits for a connection using 82 // Creates the IPC server channel and waits for a connection using
87 // |ipc_server_channel_name_|. 83 // |ipc_server_channel_name_|.
88 void StartIpcServerChannel(); 84 void StartIpcServerChannel();
89 85
90 // Restarts the IPC server channel to prepare for another connection.
91 void RecreateIpcServerChannel();
92
93 // Closes the IPC channel created for a security key forwarding session. 86 // Closes the IPC channel created for a security key forwarding session.
94 void CloseSecurityKeyRequestIpcChannel(int connection_id); 87 void CloseSecurityKeyRequestIpcChannel(int connection_id);
95 88
96 // Returns the IPC Channel instance created for |connection_id|. 89 // Returns the IPC Channel instance created for |connection_id|.
97 ActiveChannels::const_iterator GetChannelForConnectionId( 90 ActiveChannels::const_iterator GetChannelForConnectionId(
98 int connection_id) const; 91 int connection_id) const;
99 92
100 // Creates a unique name based on the well-known IPC channel name. 93 void OnChannelConnected();
101 std::string GenerateUniqueChannelName();
102 94
103 // Represents the last id assigned to a new security key request IPC channel. 95 // Represents the last id assigned to a new security key request IPC channel.
104 int last_connection_id_ = 0; 96 int last_connection_id_ = 0;
105 97
106 // Sends a security key extension message to the client when called. 98 // Sends a security key extension message to the client when called.
107 SendMessageCallback send_message_callback_; 99 SendMessageCallback send_message_callback_;
108 100
109 // Interface which provides details about the client session. 101 // Interface which provides details about the client session.
110 ClientSessionDetails* client_session_details_ = nullptr; 102 ClientSessionDetails* client_session_details_ = nullptr;
111 103
112 // Tracks the IPC channel created for each security key forwarding session. 104 // Tracks the IPC channel created for each security key forwarding session.
113 ActiveChannels active_channels_; 105 ActiveChannels active_channels_;
114 106
115 // The amount of time to wait for a client to process the connection details 107 // The amount of time to wait for a client to process the connection details
116 // message and disconnect from the IPC server channel before disconnecting it. 108 // message and disconnect from the IPC server channel before disconnecting it.
117 base::TimeDelta disconnect_timeout_; 109 base::TimeDelta disconnect_timeout_;
118 110
119 // Used to recreate the IPC server channel if a client forgets to disconnect.
120 base::OneShotTimer timer_;
121
122 // IPC Clients connect to this channel first to receive their own IPC
123 // channel to start a security key forwarding session on.
124 std::unique_ptr<IPC::Channel> ipc_server_channel_;
125
126 // Ensures SecurityKeyAuthHandlerWin methods are called on the same thread. 111 // Ensures SecurityKeyAuthHandlerWin methods are called on the same thread.
127 base::ThreadChecker thread_checker_; 112 base::ThreadChecker thread_checker_;
128 113
129 base::WeakPtrFactory<SecurityKeyAuthHandlerWin> weak_factory_; 114 base::WeakPtrFactory<SecurityKeyAuthHandlerWin> weak_factory_;
130 115
131 DISALLOW_COPY_AND_ASSIGN(SecurityKeyAuthHandlerWin); 116 DISALLOW_COPY_AND_ASSIGN(SecurityKeyAuthHandlerWin);
132 }; 117 };
133 118
134 std::unique_ptr<SecurityKeyAuthHandler> SecurityKeyAuthHandler::Create( 119 std::unique_ptr<SecurityKeyAuthHandler> SecurityKeyAuthHandler::Create(
135 ClientSessionDetails* client_session_details, 120 ClientSessionDetails* client_session_details,
136 const SendMessageCallback& send_message_callback, 121 const SendMessageCallback& send_message_callback,
137 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) { 122 scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) {
138 std::unique_ptr<SecurityKeyAuthHandler> auth_handler( 123 std::unique_ptr<SecurityKeyAuthHandler> auth_handler(
139 new SecurityKeyAuthHandlerWin(client_session_details)); 124 new SecurityKeyAuthHandlerWin(client_session_details));
140 auth_handler->SetSendMessageCallback(send_message_callback); 125 auth_handler->SetSendMessageCallback(send_message_callback);
141 return auth_handler; 126 return auth_handler;
142 } 127 }
143 128
144 SecurityKeyAuthHandlerWin::SecurityKeyAuthHandlerWin( 129 SecurityKeyAuthHandlerWin::SecurityKeyAuthHandlerWin(
145 ClientSessionDetails* client_session_details) 130 ClientSessionDetails* client_session_details)
146 : client_session_details_(client_session_details), 131 : client_session_details_(client_session_details),
147 disconnect_timeout_( 132 disconnect_timeout_(kInitialRequestTimeout),
148 base::TimeDelta::FromSeconds(kInitialRequestTimeoutSeconds)),
149 weak_factory_(this) { 133 weak_factory_(this) {
150 DCHECK(client_session_details_); 134 DCHECK(client_session_details_);
151 } 135 }
152 136
153 SecurityKeyAuthHandlerWin::~SecurityKeyAuthHandlerWin() {} 137 SecurityKeyAuthHandlerWin::~SecurityKeyAuthHandlerWin() {}
154 138
155 void SecurityKeyAuthHandlerWin::CreateSecurityKeyConnection() { 139 void SecurityKeyAuthHandlerWin::CreateSecurityKeyConnection() {
156 DCHECK(thread_checker_.CalledOnValidThread()); 140 DCHECK(thread_checker_.CalledOnValidThread());
157 StartIpcServerChannel(); 141 StartIpcServerChannel();
158 } 142 }
159 143
160 bool SecurityKeyAuthHandlerWin::IsValidConnectionId(int connection_id) const { 144 bool SecurityKeyAuthHandlerWin::IsValidConnectionId(int connection_id) const {
161 DCHECK(thread_checker_.CalledOnValidThread()); 145 DCHECK(thread_checker_.CalledOnValidThread());
162 return (GetChannelForConnectionId(connection_id) != active_channels_.end()); 146 return connection_id != last_connection_id_ &&
147 (GetChannelForConnectionId(connection_id) != active_channels_.end());
163 } 148 }
164 149
165 void SecurityKeyAuthHandlerWin::SendClientResponse( 150 void SecurityKeyAuthHandlerWin::SendClientResponse(
166 int connection_id, 151 int connection_id,
167 const std::string& response_data) { 152 const std::string& response_data) {
168 DCHECK(thread_checker_.CalledOnValidThread()); 153 DCHECK(thread_checker_.CalledOnValidThread());
169 154
170 ActiveChannels::const_iterator iter = 155 ActiveChannels::const_iterator iter =
171 GetChannelForConnectionId(connection_id); 156 GetChannelForConnectionId(connection_id);
172 if (iter == active_channels_.end()) { 157 if (iter == active_channels_.end()) {
(...skipping 14 matching lines...) Expand all
187 CloseSecurityKeyRequestIpcChannel(connection_id); 172 CloseSecurityKeyRequestIpcChannel(connection_id);
188 } 173 }
189 174
190 void SecurityKeyAuthHandlerWin::SetSendMessageCallback( 175 void SecurityKeyAuthHandlerWin::SetSendMessageCallback(
191 const SendMessageCallback& callback) { 176 const SendMessageCallback& callback) {
192 DCHECK(thread_checker_.CalledOnValidThread()); 177 DCHECK(thread_checker_.CalledOnValidThread());
193 send_message_callback_ = callback; 178 send_message_callback_ = callback;
194 } 179 }
195 180
196 size_t SecurityKeyAuthHandlerWin::GetActiveConnectionCountForTest() const { 181 size_t SecurityKeyAuthHandlerWin::GetActiveConnectionCountForTest() const {
197 return active_channels_.size(); 182 if (active_channels_.empty()) {
183 return 0u;
184 }
185 // One channel is waiting for a connection.
186 return active_channels_.size() - 1;
198 } 187 }
199 188
200 void SecurityKeyAuthHandlerWin::SetRequestTimeoutForTest( 189 void SecurityKeyAuthHandlerWin::SetRequestTimeoutForTest(
201 base::TimeDelta timeout) { 190 base::TimeDelta timeout) {
202 disconnect_timeout_ = timeout; 191 disconnect_timeout_ = timeout;
203 } 192 }
204 193
205 void SecurityKeyAuthHandlerWin::StartIpcServerChannel() { 194 void SecurityKeyAuthHandlerWin::StartIpcServerChannel() {
206 DCHECK(thread_checker_.CalledOnValidThread()); 195 DCHECK(thread_checker_.CalledOnValidThread());
207 196
208 // Create a named pipe owned by the current user (the LocalService account 197 int new_connection_id = ++last_connection_id_;
209 // (SID: S-1-5-19) when running in the network process) which is available to 198 std::unique_ptr<SecurityKeyIpcServer> ipc_server(SecurityKeyIpcServer::Create(
210 // all authenticated users. 199 new_connection_id, client_session_details_, disconnect_timeout_,
211 // presubmit: allow wstring 200 send_message_callback_,
212 std::wstring user_sid; 201 base::Bind(&SecurityKeyAuthHandlerWin::OnChannelConnected,
213 CHECK(base::win::GetUserSidString(&user_sid)); 202 base::Unretained(this)),
214 std::string user_sid_utf8 = base::WideToUTF8(user_sid); 203 base::Bind(&SecurityKeyAuthHandlerWin::CloseSecurityKeyRequestIpcChannel,
215 std::string security_descriptor = base::StringPrintf( 204 base::Unretained(this), new_connection_id)));
216 "O:%sG:%sD:(A;;GA;;;AU)", user_sid_utf8.c_str(), user_sid_utf8.c_str()); 205 ipc_server->CreateChannel(remoting::GetSecurityKeyIpcChannel(),
217 206 kSecurityKeyRequestTimeout);
218 base::win::ScopedHandle pipe; 207 active_channels_[new_connection_id] = std::move(ipc_server);
219 CHECK(CreateIpcChannel(remoting::GetSecurityKeyIpcChannelName(),
220 security_descriptor, &pipe));
221 ipc_server_channel_ =
222 IPC::Channel::CreateNamedServer(IPC::ChannelHandle(pipe.Get()), this);
223 CHECK(ipc_server_channel_->Connect());
224 }
225
226 void SecurityKeyAuthHandlerWin::RecreateIpcServerChannel() {
227 DCHECK(thread_checker_.CalledOnValidThread());
228
229 timer_.Stop();
230 ipc_server_channel_.reset();
231
232 StartIpcServerChannel();
233 } 208 }
234 209
235 void SecurityKeyAuthHandlerWin::CloseSecurityKeyRequestIpcChannel( 210 void SecurityKeyAuthHandlerWin::CloseSecurityKeyRequestIpcChannel(
236 int connection_id) { 211 int connection_id) {
237 active_channels_.erase(connection_id); 212 active_channels_.erase(connection_id);
238 } 213 }
239 214
240 SecurityKeyAuthHandlerWin::ActiveChannels::const_iterator 215 SecurityKeyAuthHandlerWin::ActiveChannels::const_iterator
241 SecurityKeyAuthHandlerWin::GetChannelForConnectionId(int connection_id) const { 216 SecurityKeyAuthHandlerWin::GetChannelForConnectionId(int connection_id) const {
242 return active_channels_.find(connection_id); 217 return active_channels_.find(connection_id);
243 } 218 }
244 219
245 std::string SecurityKeyAuthHandlerWin::GenerateUniqueChannelName() { 220 void SecurityKeyAuthHandlerWin::OnChannelConnected() {
246 return GetSecurityKeyIpcChannelName() + "." + 221 // Create another server to accept the next connection.
247 IPC::Channel::GenerateUniqueRandomChannelID(); 222 StartIpcServerChannel();
248 }
249
250 bool SecurityKeyAuthHandlerWin::OnMessageReceived(const IPC::Message& message) {
251 DCHECK(thread_checker_.CalledOnValidThread());
252 // This class does handle any IPC messages sent by the client.
253 return false;
254 }
255
256 void SecurityKeyAuthHandlerWin::OnChannelConnected(int32_t peer_pid) {
257 DCHECK(thread_checker_.CalledOnValidThread());
258
259 timer_.Start(FROM_HERE, disconnect_timeout_,
260 base::Bind(&SecurityKeyAuthHandlerWin::OnChannelError,
261 base::Unretained(this)));
262
263 // Verify the IPC connection attempt originated from the session we are
264 // currently remoting. We don't want to service requests from arbitrary
265 // Windows sessions.
266 bool close_connection = false;
267 DWORD peer_session_id;
268 if (!ProcessIdToSessionId(peer_pid, &peer_session_id)) {
269 PLOG(ERROR) << "ProcessIdToSessionId() failed";
270 close_connection = true;
271 } else if (peer_session_id != client_session_details_->desktop_session_id()) {
272 LOG(INFO) << "Ignoring connection attempt from outside remoted session.";
273 close_connection = true;
274 }
275 if (close_connection) {
276 base::ThreadTaskRunnerHandle::Get()->PostTask(
277 FROM_HERE, base::Bind(&SecurityKeyAuthHandlerWin::OnChannelError,
278 weak_factory_.GetWeakPtr()));
279 return;
280 }
281
282 int new_connection_id = ++last_connection_id_;
283 std::unique_ptr<SecurityKeyIpcServer> ipc_server(SecurityKeyIpcServer::Create(
284 new_connection_id, client_session_details_, disconnect_timeout_,
285 send_message_callback_,
286 base::Bind(&SecurityKeyAuthHandlerWin::CloseSecurityKeyRequestIpcChannel,
287 base::Unretained(this), new_connection_id)));
288
289 std::string unique_channel_name = GenerateUniqueChannelName();
290 if (ipc_server->CreateChannel(
291 unique_channel_name,
292 base::TimeDelta::FromSeconds(kSecurityKeyRequestTimeoutSeconds))) {
293 active_channels_[new_connection_id] = std::move(ipc_server);
294 ipc_server_channel_->Send(
295 new ChromotingNetworkToRemoteSecurityKeyMsg_ConnectionDetails(
296 unique_channel_name));
297 }
298 }
299
300 void SecurityKeyAuthHandlerWin::OnChannelError() {
301 DCHECK(thread_checker_.CalledOnValidThread());
302
303 // Could be an error, most likely the client disconnected though. Either way
304 // we should restart the server to prepare for the next connection.
305 RecreateIpcServerChannel();
306 } 223 }
307 224
308 } // namespace remoting 225 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698