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

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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 // SecurityKeyIpcServer instance that will service that request. The new 51 // SecurityKeyIpcServer instance that will service that request. The new
52 // instance will exist for the lifetime of the security key request and will be 52 // 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 53 // 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 54 // 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 55 // 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 56 // 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 57 // can service the next client/request. This system allows multiple security
58 // key forwarding sessions to occur concurrently. 58 // key forwarding sessions to occur concurrently.
59 // TODO(joedow): Update SecurityKeyAuthHandler impls to run on a separate IO 59 // TODO(joedow): Update SecurityKeyAuthHandler impls to run on a separate IO
60 // thread instead of the thread it was created on: crbug.com/591739 60 // thread instead of the thread it was created on: crbug.com/591739
61 class SecurityKeyAuthHandlerWin : public SecurityKeyAuthHandler, 61 class SecurityKeyAuthHandlerWin : public SecurityKeyAuthHandler {
62 public IPC::Listener {
63 public: 62 public:
64 explicit SecurityKeyAuthHandlerWin( 63 explicit SecurityKeyAuthHandlerWin(
65 ClientSessionDetails* client_session_details); 64 ClientSessionDetails* client_session_details);
66 ~SecurityKeyAuthHandlerWin() override; 65 ~SecurityKeyAuthHandlerWin() override;
67 66
68 private: 67 private:
69 typedef std::map<int, std::unique_ptr<SecurityKeyIpcServer>> ActiveChannels; 68 typedef std::map<int, std::unique_ptr<SecurityKeyIpcServer>> ActiveChannels;
70 69
71 // SecurityKeyAuthHandler interface. 70 // SecurityKeyAuthHandler interface.
72 void CreateSecurityKeyConnection() override; 71 void CreateSecurityKeyConnection() override;
73 bool IsValidConnectionId(int security_key_connection_id) const override; 72 bool IsValidConnectionId(int security_key_connection_id) const override;
74 void SendClientResponse(int security_key_connection_id, 73 void SendClientResponse(int security_key_connection_id,
75 const std::string& response) override; 74 const std::string& response) override;
76 void SendErrorAndCloseConnection(int security_key_connection_id) override; 75 void SendErrorAndCloseConnection(int security_key_connection_id) override;
77 void SetSendMessageCallback(const SendMessageCallback& callback) override; 76 void SetSendMessageCallback(const SendMessageCallback& callback) override;
78 size_t GetActiveConnectionCountForTest() const override; 77 size_t GetActiveConnectionCountForTest() const override;
79 void SetRequestTimeoutForTest(base::TimeDelta timeout) override; 78 void SetRequestTimeoutForTest(base::TimeDelta timeout) override;
80 79
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 80 // Creates the IPC server channel and waits for a connection using
87 // |ipc_server_channel_name_|. 81 // |ipc_server_channel_name_|.
88 void StartIpcServerChannel(); 82 void StartIpcServerChannel();
89 83
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. 84 // Closes the IPC channel created for a security key forwarding session.
94 void CloseSecurityKeyRequestIpcChannel(int connection_id); 85 void CloseSecurityKeyRequestIpcChannel(int connection_id);
95 86
96 // Returns the IPC Channel instance created for |connection_id|. 87 // Returns the IPC Channel instance created for |connection_id|.
97 ActiveChannels::const_iterator GetChannelForConnectionId( 88 ActiveChannels::const_iterator GetChannelForConnectionId(
98 int connection_id) const; 89 int connection_id) const;
99 90
100 // Creates a unique name based on the well-known IPC channel name. 91 void OnChannelConnected();
101 std::string GenerateUniqueChannelName();
102 92
103 // Represents the last id assigned to a new security key request IPC channel. 93 // Represents the last id assigned to a new security key request IPC channel.
104 int last_connection_id_ = 0; 94 int last_connection_id_ = 0;
105 95
106 // Sends a security key extension message to the client when called. 96 // Sends a security key extension message to the client when called.
107 SendMessageCallback send_message_callback_; 97 SendMessageCallback send_message_callback_;
108 98
109 // Interface which provides details about the client session. 99 // Interface which provides details about the client session.
110 ClientSessionDetails* client_session_details_ = nullptr; 100 ClientSessionDetails* client_session_details_ = nullptr;
111 101
112 // Tracks the IPC channel created for each security key forwarding session. 102 // Tracks the IPC channel created for each security key forwarding session.
113 ActiveChannels active_channels_; 103 ActiveChannels active_channels_;
114 104
115 // The amount of time to wait for a client to process the connection details 105 // 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. 106 // message and disconnect from the IPC server channel before disconnecting it.
117 base::TimeDelta disconnect_timeout_; 107 base::TimeDelta disconnect_timeout_;
118 108
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. 109 // Ensures SecurityKeyAuthHandlerWin methods are called on the same thread.
127 base::ThreadChecker thread_checker_; 110 base::ThreadChecker thread_checker_;
128 111
129 base::WeakPtrFactory<SecurityKeyAuthHandlerWin> weak_factory_; 112 base::WeakPtrFactory<SecurityKeyAuthHandlerWin> weak_factory_;
130 113
131 DISALLOW_COPY_AND_ASSIGN(SecurityKeyAuthHandlerWin); 114 DISALLOW_COPY_AND_ASSIGN(SecurityKeyAuthHandlerWin);
132 }; 115 };
133 116
134 std::unique_ptr<SecurityKeyAuthHandler> SecurityKeyAuthHandler::Create( 117 std::unique_ptr<SecurityKeyAuthHandler> SecurityKeyAuthHandler::Create(
135 ClientSessionDetails* client_session_details, 118 ClientSessionDetails* client_session_details,
(...skipping 16 matching lines...) Expand all
152 135
153 SecurityKeyAuthHandlerWin::~SecurityKeyAuthHandlerWin() {} 136 SecurityKeyAuthHandlerWin::~SecurityKeyAuthHandlerWin() {}
154 137
155 void SecurityKeyAuthHandlerWin::CreateSecurityKeyConnection() { 138 void SecurityKeyAuthHandlerWin::CreateSecurityKeyConnection() {
156 DCHECK(thread_checker_.CalledOnValidThread()); 139 DCHECK(thread_checker_.CalledOnValidThread());
157 StartIpcServerChannel(); 140 StartIpcServerChannel();
158 } 141 }
159 142
160 bool SecurityKeyAuthHandlerWin::IsValidConnectionId(int connection_id) const { 143 bool SecurityKeyAuthHandlerWin::IsValidConnectionId(int connection_id) const {
161 DCHECK(thread_checker_.CalledOnValidThread()); 144 DCHECK(thread_checker_.CalledOnValidThread());
162 return (GetChannelForConnectionId(connection_id) != active_channels_.end()); 145 return connection_id != last_connection_id_ &&
146 (GetChannelForConnectionId(connection_id) != active_channels_.end());
163 } 147 }
164 148
165 void SecurityKeyAuthHandlerWin::SendClientResponse( 149 void SecurityKeyAuthHandlerWin::SendClientResponse(
166 int connection_id, 150 int connection_id,
167 const std::string& response_data) { 151 const std::string& response_data) {
168 DCHECK(thread_checker_.CalledOnValidThread()); 152 DCHECK(thread_checker_.CalledOnValidThread());
169 153
170 ActiveChannels::const_iterator iter = 154 ActiveChannels::const_iterator iter =
171 GetChannelForConnectionId(connection_id); 155 GetChannelForConnectionId(connection_id);
172 if (iter == active_channels_.end()) { 156 if (iter == active_channels_.end()) {
(...skipping 14 matching lines...) Expand all
187 CloseSecurityKeyRequestIpcChannel(connection_id); 171 CloseSecurityKeyRequestIpcChannel(connection_id);
188 } 172 }
189 173
190 void SecurityKeyAuthHandlerWin::SetSendMessageCallback( 174 void SecurityKeyAuthHandlerWin::SetSendMessageCallback(
191 const SendMessageCallback& callback) { 175 const SendMessageCallback& callback) {
192 DCHECK(thread_checker_.CalledOnValidThread()); 176 DCHECK(thread_checker_.CalledOnValidThread());
193 send_message_callback_ = callback; 177 send_message_callback_ = callback;
194 } 178 }
195 179
196 size_t SecurityKeyAuthHandlerWin::GetActiveConnectionCountForTest() const { 180 size_t SecurityKeyAuthHandlerWin::GetActiveConnectionCountForTest() const {
197 return active_channels_.size(); 181 if (active_channels_.empty()) {
182 return 0u;
183 }
184 // One channel is waiting for a connection.
185 return active_channels_.size() - 1;
198 } 186 }
199 187
200 void SecurityKeyAuthHandlerWin::SetRequestTimeoutForTest( 188 void SecurityKeyAuthHandlerWin::SetRequestTimeoutForTest(
201 base::TimeDelta timeout) { 189 base::TimeDelta timeout) {
202 disconnect_timeout_ = timeout; 190 disconnect_timeout_ = timeout;
203 } 191 }
204 192
205 void SecurityKeyAuthHandlerWin::StartIpcServerChannel() { 193 void SecurityKeyAuthHandlerWin::StartIpcServerChannel() {
206 DCHECK(thread_checker_.CalledOnValidThread()); 194 DCHECK(thread_checker_.CalledOnValidThread());
207 195
208 // Create a named pipe owned by the current user (the LocalService account 196 int new_connection_id = ++last_connection_id_;
209 // (SID: S-1-5-19) when running in the network process) which is available to 197 std::unique_ptr<SecurityKeyIpcServer> ipc_server(SecurityKeyIpcServer::Create(
210 // all authenticated users. 198 new_connection_id, client_session_details_, disconnect_timeout_,
211 // presubmit: allow wstring 199 send_message_callback_,
212 std::wstring user_sid; 200 base::Bind(&SecurityKeyAuthHandlerWin::OnChannelConnected,
213 CHECK(base::win::GetUserSidString(&user_sid)); 201 base::Unretained(this)),
214 std::string user_sid_utf8 = base::WideToUTF8(user_sid); 202 base::Bind(&SecurityKeyAuthHandlerWin::CloseSecurityKeyRequestIpcChannel,
215 std::string security_descriptor = base::StringPrintf( 203 base::Unretained(this), new_connection_id)));
216 "O:%sG:%sD:(A;;GA;;;AU)", user_sid_utf8.c_str(), user_sid_utf8.c_str()); 204 ipc_server->CreateChannel(
217 205 remoting::GetSecurityKeyIpcChannel(),
218 base::win::ScopedHandle pipe; 206 base::TimeDelta::FromSeconds(kSecurityKeyRequestTimeoutSeconds));
dcheng 2016/11/08 07:54:04 I know this wasn't introduced by this CL, but cons
Sam McNally 2016/11/08 08:37:22 Done.
219 CHECK(CreateIpcChannel(remoting::GetSecurityKeyIpcChannelName(), 207 active_channels_[new_connection_id] = std::move(ipc_server);
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