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

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

Issue 2170563002: Revert of Renaming Gnubby and RemoteSecurityKey files/classes/members (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "remoting/host/security_key/security_key_auth_handler.h"
6
7 #include <cstdint>
8 #include <map>
9 #include <memory>
10 #include <string>
11
12 #include "base/bind.h"
13 #include "base/location.h"
14 #include "base/logging.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/strings/stringprintf.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/threading/thread_checker.h"
19 #include "base/threading/thread_task_runner_handle.h"
20 #include "base/time/time.h"
21 #include "base/timer/timer.h"
22 #include "base/win/win_util.h"
23 #include "ipc/ipc_channel.h"
24 #include "ipc/ipc_listener.h"
25 #include "ipc/ipc_message.h"
26 #include "ipc/ipc_message_macros.h"
27 #include "remoting/base/logging.h"
28 #include "remoting/host/chromoting_messages.h"
29 #include "remoting/host/client_session_details.h"
30 #include "remoting/host/ipc_util.h"
31 #include "remoting/host/security_key/security_key_ipc_constants.h"
32 #include "remoting/host/security_key/security_key_ipc_server.h"
33
34 namespace {
35
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.
38 const int kInitialRequestTimeoutSeconds = 5;
39
40 // This value represents the amount of time to wait for a security key request
41 // from the client before terminating the connection.
42 const int kSecurityKeyRequestTimeoutSeconds = 60;
43
44 } // namespace
45
46 namespace remoting {
47
48 // 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
50 // server, the SecurityKeyAuthHandlerWin class will create a 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
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
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
57 // can service the next client/request. This system allows multiple security
58 // key forwarding sessions to occur concurrently.
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
61 class SecurityKeyAuthHandlerWin : public SecurityKeyAuthHandler,
62 public IPC::Listener {
63 public:
64 explicit SecurityKeyAuthHandlerWin(
65 ClientSessionDetails* client_session_details);
66 ~SecurityKeyAuthHandlerWin() override;
67
68 private:
69 typedef std::map<int, std::unique_ptr<SecurityKeyIpcServer>> ActiveChannels;
70
71 // SecurityKeyAuthHandler interface.
72 void CreateSecurityKeyConnection() override;
73 bool IsValidConnectionId(int security_key_connection_id) const override;
74 void SendClientResponse(int security_key_connection_id,
75 const std::string& response) override;
76 void SendErrorAndCloseConnection(int security_key_connection_id) override;
77 void SetSendMessageCallback(const SendMessageCallback& callback) override;
78 size_t GetActiveConnectionCountForTest() const override;
79 void SetRequestTimeoutForTest(base::TimeDelta timeout) override;
80
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
87 // |ipc_server_channel_name_|.
88 void StartIpcServerChannel();
89
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.
94 void CloseSecurityKeyRequestIpcChannel(int connection_id);
95
96 // Returns the IPC Channel instance created for |connection_id|.
97 ActiveChannels::const_iterator GetChannelForConnectionId(
98 int connection_id) const;
99
100 // Creates a unique name based on the well-known IPC channel name.
101 std::string GenerateUniqueChannelName();
102
103 // Represents the last id assigned to a new security key request IPC channel.
104 int last_connection_id_ = 0;
105
106 // Sends a security key extension message to the client when called.
107 SendMessageCallback send_message_callback_;
108
109 // Interface which provides details about the client session.
110 ClientSessionDetails* client_session_details_ = nullptr;
111
112 // Tracks the IPC channel created for each security key forwarding session.
113 ActiveChannels active_channels_;
114
115 // 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.
117 base::TimeDelta disconnect_timeout_;
118
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.
127 base::ThreadChecker thread_checker_;
128
129 base::WeakPtrFactory<SecurityKeyAuthHandlerWin> weak_factory_;
130
131 DISALLOW_COPY_AND_ASSIGN(SecurityKeyAuthHandlerWin);
132 };
133
134 std::unique_ptr<SecurityKeyAuthHandler> SecurityKeyAuthHandler::Create(
135 ClientSessionDetails* client_session_details,
136 const SendMessageCallback& send_message_callback) {
137 std::unique_ptr<SecurityKeyAuthHandler> auth_handler(
138 new SecurityKeyAuthHandlerWin(client_session_details));
139 auth_handler->SetSendMessageCallback(send_message_callback);
140 return auth_handler;
141 }
142
143 SecurityKeyAuthHandlerWin::SecurityKeyAuthHandlerWin(
144 ClientSessionDetails* client_session_details)
145 : client_session_details_(client_session_details),
146 disconnect_timeout_(
147 base::TimeDelta::FromSeconds(kInitialRequestTimeoutSeconds)),
148 weak_factory_(this) {
149 DCHECK(client_session_details_);
150 }
151
152 SecurityKeyAuthHandlerWin::~SecurityKeyAuthHandlerWin() {}
153
154 void SecurityKeyAuthHandlerWin::CreateSecurityKeyConnection() {
155 DCHECK(thread_checker_.CalledOnValidThread());
156 StartIpcServerChannel();
157 }
158
159 bool SecurityKeyAuthHandlerWin::IsValidConnectionId(int connection_id) const {
160 DCHECK(thread_checker_.CalledOnValidThread());
161 return (GetChannelForConnectionId(connection_id) != active_channels_.end());
162 }
163
164 void SecurityKeyAuthHandlerWin::SendClientResponse(
165 int connection_id,
166 const std::string& response_data) {
167 DCHECK(thread_checker_.CalledOnValidThread());
168
169 ActiveChannels::const_iterator iter =
170 GetChannelForConnectionId(connection_id);
171 if (iter == active_channels_.end()) {
172 HOST_LOG << "Invalid security key connection ID received: "
173 << connection_id;
174 return;
175 }
176
177 if (!iter->second->SendResponse(response_data)) {
178 CloseSecurityKeyRequestIpcChannel(connection_id);
179 }
180 }
181
182 void SecurityKeyAuthHandlerWin::SendErrorAndCloseConnection(int connection_id) {
183 DCHECK(thread_checker_.CalledOnValidThread());
184
185 SendClientResponse(connection_id, kSecurityKeyConnectionError);
186 CloseSecurityKeyRequestIpcChannel(connection_id);
187 }
188
189 void SecurityKeyAuthHandlerWin::SetSendMessageCallback(
190 const SendMessageCallback& callback) {
191 DCHECK(thread_checker_.CalledOnValidThread());
192 send_message_callback_ = callback;
193 }
194
195 size_t SecurityKeyAuthHandlerWin::GetActiveConnectionCountForTest() const {
196 return active_channels_.size();
197 }
198
199 void SecurityKeyAuthHandlerWin::SetRequestTimeoutForTest(
200 base::TimeDelta timeout) {
201 disconnect_timeout_ = timeout;
202 }
203
204 void SecurityKeyAuthHandlerWin::StartIpcServerChannel() {
205 DCHECK(thread_checker_.CalledOnValidThread());
206
207 // Create a named pipe owned by the current user (the LocalService account
208 // (SID: S-1-5-19) when running in the network process) which is available to
209 // all authenticated users.
210 // presubmit: allow wstring
211 std::wstring user_sid;
212 CHECK(base::win::GetUserSidString(&user_sid));
213 std::string user_sid_utf8 = base::WideToUTF8(user_sid);
214 std::string security_descriptor = base::StringPrintf(
215 "O:%sG:%sD:(A;;GA;;;AU)", user_sid_utf8.c_str(), user_sid_utf8.c_str());
216
217 base::win::ScopedHandle pipe;
218 CHECK(CreateIpcChannel(remoting::GetSecurityKeyIpcChannelName(),
219 security_descriptor, &pipe));
220 ipc_server_channel_ =
221 IPC::Channel::CreateNamedServer(IPC::ChannelHandle(pipe.Get()), this);
222 CHECK(ipc_server_channel_->Connect());
223 }
224
225 void SecurityKeyAuthHandlerWin::RecreateIpcServerChannel() {
226 DCHECK(thread_checker_.CalledOnValidThread());
227
228 timer_.Stop();
229 ipc_server_channel_.reset();
230
231 StartIpcServerChannel();
232 }
233
234 void SecurityKeyAuthHandlerWin::CloseSecurityKeyRequestIpcChannel(
235 int connection_id) {
236 active_channels_.erase(connection_id);
237 }
238
239 SecurityKeyAuthHandlerWin::ActiveChannels::const_iterator
240 SecurityKeyAuthHandlerWin::GetChannelForConnectionId(int connection_id) const {
241 return active_channels_.find(connection_id);
242 }
243
244 std::string SecurityKeyAuthHandlerWin::GenerateUniqueChannelName() {
245 return GetSecurityKeyIpcChannelName() + "." +
246 IPC::Channel::GenerateUniqueRandomChannelID();
247 }
248
249 bool SecurityKeyAuthHandlerWin::OnMessageReceived(const IPC::Message& message) {
250 DCHECK(thread_checker_.CalledOnValidThread());
251 // This class does handle any IPC messages sent by the client.
252 return false;
253 }
254
255 void SecurityKeyAuthHandlerWin::OnChannelConnected(int32_t peer_pid) {
256 DCHECK(thread_checker_.CalledOnValidThread());
257
258 timer_.Start(FROM_HERE, disconnect_timeout_,
259 base::Bind(&SecurityKeyAuthHandlerWin::OnChannelError,
260 base::Unretained(this)));
261
262 // Verify the IPC connection attempt originated from the session we are
263 // currently remoting. We don't want to service requests from arbitrary
264 // Windows sessions.
265 bool close_connection = false;
266 DWORD peer_session_id;
267 if (!ProcessIdToSessionId(peer_pid, &peer_session_id)) {
268 PLOG(ERROR) << "ProcessIdToSessionId() failed";
269 close_connection = true;
270 } else if (peer_session_id != client_session_details_->desktop_session_id()) {
271 LOG(INFO) << "Ignoring connection attempt from outside remoted session.";
272 close_connection = true;
273 }
274 if (close_connection) {
275 base::ThreadTaskRunnerHandle::Get()->PostTask(
276 FROM_HERE, base::Bind(&SecurityKeyAuthHandlerWin::OnChannelError,
277 weak_factory_.GetWeakPtr()));
278 return;
279 }
280
281 int new_connection_id = ++last_connection_id_;
282 std::unique_ptr<SecurityKeyIpcServer> ipc_server(SecurityKeyIpcServer::Create(
283 new_connection_id, peer_session_id, disconnect_timeout_,
284 send_message_callback_,
285 base::Bind(&SecurityKeyAuthHandlerWin::CloseSecurityKeyRequestIpcChannel,
286 base::Unretained(this), new_connection_id)));
287
288 std::string unique_channel_name = GenerateUniqueChannelName();
289 if (ipc_server->CreateChannel(
290 unique_channel_name,
291 base::TimeDelta::FromSeconds(kSecurityKeyRequestTimeoutSeconds))) {
292 active_channels_[new_connection_id] = std::move(ipc_server);
293 ipc_server_channel_->Send(
294 new ChromotingNetworkToRemoteSecurityKeyMsg_ConnectionDetails(
295 unique_channel_name));
296 }
297 }
298
299 void SecurityKeyAuthHandlerWin::OnChannelError() {
300 DCHECK(thread_checker_.CalledOnValidThread());
301
302 // Could be an error, most likely the client disconnected though. Either way
303 // we should restart the server to prepare for the next connection.
304 RecreateIpcServerChannel();
305 }
306
307 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698