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

Side by Side Diff: remoting/host/security_key/security_key_auth_handler_linux.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 <stdint.h>
8 #include <unistd.h>
9
10 #include <memory>
11
12 #include "base/bind.h"
13 #include "base/files/file_util.h"
14 #include "base/lazy_instance.h"
15 #include "base/logging.h"
16 #include "base/stl_util.h"
17 #include "base/threading/thread_checker.h"
18 #include "base/threading/thread_restrictions.h"
19 #include "base/values.h"
20 #include "net/base/completion_callback.h"
21 #include "net/base/net_errors.h"
22 #include "net/socket/stream_socket.h"
23 #include "net/socket/unix_domain_server_socket_posix.h"
24 #include "remoting/base/logging.h"
25 #include "remoting/host/security_key/security_key_socket.h"
26
27 namespace {
28
29 const int64_t kDefaultRequestTimeoutSeconds = 60;
30
31 // The name of the socket to listen for security key requests on.
32 base::LazyInstance<base::FilePath>::Leaky g_security_key_socket_name =
33 LAZY_INSTANCE_INITIALIZER;
34
35 // Socket authentication function that only allows connections from callers with
36 // the current uid.
37 bool MatchUid(const net::UnixDomainServerSocket::Credentials& credentials) {
38 bool allowed = credentials.user_id == getuid();
39 if (!allowed)
40 HOST_LOG << "Refused socket connection from uid " << credentials.user_id;
41 return allowed;
42 }
43
44 // Returns the command code (the first byte of the data) if it exists, or -1 if
45 // the data is empty.
46 unsigned int GetCommandCode(const std::string& data) {
47 return data.empty() ? -1 : static_cast<unsigned int>(data[0]);
48 }
49
50 } // namespace
51
52 namespace remoting {
53
54 class SecurityKeyAuthHandlerLinux : public SecurityKeyAuthHandler {
55 public:
56 SecurityKeyAuthHandlerLinux();
57 ~SecurityKeyAuthHandlerLinux() override;
58
59 private:
60 typedef std::map<int, SecurityKeySocket*> ActiveSockets;
61
62 // SecurityKeyAuthHandler interface.
63 void CreateSecurityKeyConnection() override;
64 bool IsValidConnectionId(int security_key_connection_id) const override;
65 void SendClientResponse(int security_key_connection_id,
66 const std::string& response) override;
67 void SendErrorAndCloseConnection(int security_key_connection_id) override;
68 void SetSendMessageCallback(const SendMessageCallback& callback) override;
69 size_t GetActiveConnectionCountForTest() const override;
70 void SetRequestTimeoutForTest(base::TimeDelta timeout) override;
71
72 // Starts listening for connection.
73 void DoAccept();
74
75 // Called when a connection is accepted.
76 void OnAccepted(int result);
77
78 // Called when a SecurityKeySocket has done reading.
79 void OnReadComplete(int security_key_connection_id);
80
81 // Gets an active socket iterator for |security_key_connection_id|.
82 ActiveSockets::const_iterator GetSocketForConnectionId(
83 int security_key_connection_id) const;
84
85 // Send an error and closes an active socket.
86 void SendErrorAndCloseActiveSocket(const ActiveSockets::const_iterator& iter);
87
88 // A request timed out.
89 void RequestTimedOut(int security_key_connection_id);
90
91 // Ensures SecurityKeyAuthHandlerLinux methods are called on the same thread.
92 base::ThreadChecker thread_checker_;
93
94 // Socket used to listen for authorization requests.
95 std::unique_ptr<net::UnixDomainServerSocket> auth_socket_;
96
97 // A temporary holder for an accepted connection.
98 std::unique_ptr<net::StreamSocket> accept_socket_;
99
100 // Used to pass security key extension messages to the client.
101 SendMessageCallback send_message_callback_;
102
103 // The last assigned security key connection id.
104 int last_connection_id_;
105
106 // Sockets by connection id used to process gnubbyd requests.
107 ActiveSockets active_sockets_;
108
109 // Timeout used for a request.
110 base::TimeDelta request_timeout_;
111
112 DISALLOW_COPY_AND_ASSIGN(SecurityKeyAuthHandlerLinux);
113 };
114
115 std::unique_ptr<SecurityKeyAuthHandler> SecurityKeyAuthHandler::Create(
116 ClientSessionDetails* client_session_details,
117 const SendMessageCallback& send_message_callback) {
118 std::unique_ptr<SecurityKeyAuthHandler> auth_handler(
119 new SecurityKeyAuthHandlerLinux());
120 auth_handler->SetSendMessageCallback(send_message_callback);
121 return auth_handler;
122 }
123
124 void SecurityKeyAuthHandler::SetSecurityKeySocketName(
125 const base::FilePath& security_key_socket_name) {
126 g_security_key_socket_name.Get() = security_key_socket_name;
127 }
128
129 SecurityKeyAuthHandlerLinux::SecurityKeyAuthHandlerLinux()
130 : last_connection_id_(0),
131 request_timeout_(
132 base::TimeDelta::FromSeconds(kDefaultRequestTimeoutSeconds)) {}
133
134 SecurityKeyAuthHandlerLinux::~SecurityKeyAuthHandlerLinux() {
135 STLDeleteValues(&active_sockets_);
136 }
137
138 void SecurityKeyAuthHandlerLinux::CreateSecurityKeyConnection() {
139 DCHECK(thread_checker_.CalledOnValidThread());
140 DCHECK(!g_security_key_socket_name.Get().empty());
141
142 {
143 // DeleteFile() is a blocking operation, but so is creation of the unix
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
150 // If the file already exists, a socket in use error is returned.
151 base::DeleteFile(g_security_key_socket_name.Get(), false);
152 }
153
154 HOST_LOG << "Listening for security key requests on "
155 << g_security_key_socket_name.Get().value();
156
157 auth_socket_.reset(
158 new net::UnixDomainServerSocket(base::Bind(MatchUid), false));
159 int rv = auth_socket_->BindAndListen(g_security_key_socket_name.Get().value(),
160 /*backlog=*/1);
161 if (rv != net::OK) {
162 LOG(ERROR) << "Failed to open socket for auth requests: '" << rv << "'";
163 return;
164 }
165 DoAccept();
166 }
167
168 bool SecurityKeyAuthHandlerLinux::IsValidConnectionId(
169 int security_key_connection_id) const {
170 return GetSocketForConnectionId(security_key_connection_id) !=
171 active_sockets_.end();
172 }
173
174 void SecurityKeyAuthHandlerLinux::SendClientResponse(
175 int security_key_connection_id,
176 const std::string& response) {
177 ActiveSockets::const_iterator iter =
178 GetSocketForConnectionId(security_key_connection_id);
179 if (iter != active_sockets_.end()) {
180 iter->second->SendResponse(response);
181 } else {
182 LOG(WARNING) << "Unknown gnubby-auth data connection: '"
183 << security_key_connection_id << "'";
184 }
185 }
186
187 void SecurityKeyAuthHandlerLinux::SendErrorAndCloseConnection(
188 int security_key_connection_id) {
189 ActiveSockets::const_iterator iter =
190 GetSocketForConnectionId(security_key_connection_id);
191 if (iter != active_sockets_.end()) {
192 HOST_LOG << "Sending security key error";
193 SendErrorAndCloseActiveSocket(iter);
194 } else {
195 LOG(WARNING) << "Unknown gnubby-auth data connection: '"
196 << security_key_connection_id << "'";
197 }
198 }
199
200 void SecurityKeyAuthHandlerLinux::SetSendMessageCallback(
201 const SendMessageCallback& callback) {
202 send_message_callback_ = callback;
203 }
204
205 size_t SecurityKeyAuthHandlerLinux::GetActiveConnectionCountForTest() const {
206 return active_sockets_.size();
207 }
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());
224 DCHECK_NE(net::ERR_IO_PENDING, result);
225
226 if (result < 0) {
227 LOG(ERROR) << "Error in accepting a new connection";
228 return;
229 }
230
231 int security_key_connection_id = ++last_connection_id_;
232 SecurityKeySocket* socket = new SecurityKeySocket(
233 std::move(accept_socket_), request_timeout_,
234 base::Bind(&SecurityKeyAuthHandlerLinux::RequestTimedOut,
235 base::Unretained(this), security_key_connection_id));
236 active_sockets_[security_key_connection_id] = socket;
237 socket->StartReadingRequest(
238 base::Bind(&SecurityKeyAuthHandlerLinux::OnReadComplete,
239 base::Unretained(this), security_key_connection_id));
240
241 // Continue accepting new connections.
242 DoAccept();
243 }
244
245 void SecurityKeyAuthHandlerLinux::OnReadComplete(
246 int security_key_connection_id) {
247 DCHECK(thread_checker_.CalledOnValidThread());
248
249 ActiveSockets::const_iterator iter =
250 active_sockets_.find(security_key_connection_id);
251 DCHECK(iter != active_sockets_.end());
252 std::string request_data;
253 if (!iter->second->GetAndClearRequestData(&request_data)) {
254 SendErrorAndCloseActiveSocket(iter);
255 return;
256 }
257
258 HOST_LOG << "Received security key request: " << GetCommandCode(request_data);
259 send_message_callback_.Run(security_key_connection_id, request_data);
260
261 iter->second->StartReadingRequest(
262 base::Bind(&SecurityKeyAuthHandlerLinux::OnReadComplete,
263 base::Unretained(this), security_key_connection_id));
264 }
265
266 SecurityKeyAuthHandlerLinux::ActiveSockets::const_iterator
267 SecurityKeyAuthHandlerLinux::GetSocketForConnectionId(
268 int security_key_connection_id) const {
269 return active_sockets_.find(security_key_connection_id);
270 }
271
272 void SecurityKeyAuthHandlerLinux::SendErrorAndCloseActiveSocket(
273 const ActiveSockets::const_iterator& iter) {
274 iter->second->SendSshError();
275 delete iter->second;
276 active_sockets_.erase(iter);
277 }
278
279 void SecurityKeyAuthHandlerLinux::RequestTimedOut(
280 int security_key_connection_id) {
281 HOST_LOG << "SecurityKey request timed out";
282 ActiveSockets::const_iterator iter =
283 active_sockets_.find(security_key_connection_id);
284 if (iter != active_sockets_.end())
285 SendErrorAndCloseActiveSocket(iter);
286 }
287
288 } // namespace remoting
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698