Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 <stddef.h> | 5 #include <stddef.h> |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 38 0x47, 0x2f, 0xdf, 0x6e, 0xed, 0x7b, 0xf3, 0xc3, 0x37, 0x20, 0xf2, 0x36, | 38 0x47, 0x2f, 0xdf, 0x6e, 0xed, 0x7b, 0xf3, 0xc3, 0x37, 0x20, 0xf2, 0x36, |
| 39 0x67, 0x6c, 0x36, 0xe1, 0xb4, 0x5e, 0xbe, 0x04, 0x85, 0xdb, 0x89, 0xa3, | 39 0x67, 0x6c, 0x36, 0xe1, 0xb4, 0x5e, 0xbe, 0x04, 0x85, 0xdb, 0x89, 0xa3, |
| 40 0xcd, 0xfd, 0xd2, 0x4b, 0xd6, 0x9f, 0x00, 0x00, 0x00, 0x40, 0x38, 0x35, | 40 0xcd, 0xfd, 0xd2, 0x4b, 0xd6, 0x9f, 0x00, 0x00, 0x00, 0x40, 0x38, 0x35, |
| 41 0x05, 0x75, 0x1d, 0x13, 0x6e, 0xb3, 0x6b, 0x1d, 0x29, 0xae, 0xd3, 0x43, | 41 0x05, 0x75, 0x1d, 0x13, 0x6e, 0xb3, 0x6b, 0x1d, 0x29, 0xae, 0xd3, 0x43, |
| 42 0xe6, 0x84, 0x8f, 0xa3, 0x9d, 0x65, 0x4e, 0x2f, 0x57, 0xe3, 0xf6, 0xe6, | 42 0xe6, 0x84, 0x8f, 0xa3, 0x9d, 0x65, 0x4e, 0x2f, 0x57, 0xe3, 0xf6, 0xe6, |
| 43 0x20, 0x3c, 0x00, 0xc6, 0xe1, 0x73, 0x34, 0xe2, 0x23, 0x99, 0xc4, 0xfa, | 43 0x20, 0x3c, 0x00, 0xc6, 0xe1, 0x73, 0x34, 0xe2, 0x23, 0x99, 0xc4, 0xfa, |
| 44 0x91, 0xc2, 0xd5, 0x97, 0xc1, 0x8b, 0xd0, 0x3c, 0x13, 0xba, 0xf0, 0xd7, | 44 0x91, 0xc2, 0xd5, 0x97, 0xc1, 0x8b, 0xd0, 0x3c, 0x13, 0xba, 0xf0, 0xd7, |
| 45 0x5e, 0xa3, 0xbc, 0x02, 0x5b, 0xec, 0xe4, 0x4b, 0xae, 0x0e, 0xf2, 0xbd, | 45 0x5e, 0xa3, 0xbc, 0x02, 0x5b, 0xec, 0xe4, 0x4b, 0xae, 0x0e, 0xf2, 0xbd, |
| 46 0xc8, 0xaa}; | 46 0xc8, 0xaa}; |
| 47 | 47 |
| 48 const unsigned char kSshErrorData[] = {0x00, 0x00, 0x00, 0x01, 0x05}; | |
|
Sergey Ulanov
2016/12/14 00:17:03
Pleaes use uint8_t instead of unsigned char
joedow
2016/12/14 00:41:35
Done.
| |
| 49 | |
| 48 void RunUntilIdle() { | 50 void RunUntilIdle() { |
| 49 base::RunLoop run_loop; | 51 base::RunLoop run_loop; |
| 50 run_loop.RunUntilIdle(); | 52 run_loop.RunUntilIdle(); |
| 51 } | 53 } |
| 52 | 54 |
| 53 } // namespace | 55 } // namespace |
| 54 | 56 |
| 55 class SecurityKeyAuthHandlerPosixTest : public testing::Test { | 57 class SecurityKeyAuthHandlerPosixTest : public testing::Test { |
| 56 public: | 58 public: |
| 57 SecurityKeyAuthHandlerPosixTest() | 59 SecurityKeyAuthHandlerPosixTest() |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 118 write_callback.callback()); | 120 write_callback.callback()); |
| 119 write_result = write_callback.GetResult(write_result); | 121 write_result = write_callback.GetResult(write_result); |
| 120 ASSERT_GT(write_result, 0); | 122 ASSERT_GT(write_result, 0); |
| 121 bytes_written += write_result; | 123 bytes_written += write_result; |
| 122 ASSERT_LE(bytes_written, request_len); | 124 ASSERT_LE(bytes_written, request_len); |
| 123 request_buffer->DidConsume(write_result); | 125 request_buffer->DidConsume(write_result); |
| 124 } | 126 } |
| 125 ASSERT_EQ(request_len, bytes_written); | 127 ASSERT_EQ(request_len, bytes_written); |
| 126 } | 128 } |
| 127 | 129 |
| 128 void WaitForAndVerifyHostMessage(int connection_id) { | 130 void WaitForResponseData(net::UnixDomainClientSocket* client_socket) { |
| 129 WaitForSendMessageToClient(); | 131 // The request data is reused for the response data. |
| 130 std::string expected_data; | 132 WaitForData(client_socket, sizeof(kRequestData)); |
| 131 expected_data.reserve(sizeof(kRequestData) - 4); | 133 } |
| 132 | 134 |
| 133 // Skip first four bytes and build up the response string. | 135 void WaitForErrorData(net::UnixDomainClientSocket* client_socket) { |
| 134 for (size_t i = 4; i < sizeof(kRequestData); ++i) { | 136 WaitForData(client_socket, sizeof(kSshErrorData)); |
| 135 expected_data.append(1, static_cast<unsigned char>(kRequestData[i])); | 137 } |
| 138 | |
| 139 void WaitForData(net::UnixDomainClientSocket* socket, int request_len) { | |
| 140 scoped_refptr<net::IOBuffer> buffer(new net::IOBuffer(request_len)); | |
| 141 scoped_refptr<net::DrainableIOBuffer> read_buffer( | |
| 142 new net::DrainableIOBuffer(buffer.get(), request_len)); | |
| 143 net::TestCompletionCallback read_callback; | |
| 144 int bytes_read = 0; | |
| 145 while (bytes_read < request_len) { | |
| 146 int read_result = | |
| 147 socket->Read(read_buffer.get(), read_buffer->BytesRemaining(), | |
| 148 read_callback.callback()); | |
| 149 read_result = read_callback.GetResult(read_result); | |
| 150 ASSERT_GT(read_result, 0); | |
| 151 bytes_read += read_result; | |
| 152 ASSERT_LE(bytes_read, request_len); | |
| 153 read_buffer->DidConsume(bytes_read); | |
| 154 } | |
| 155 ASSERT_EQ(request_len, bytes_read); | |
| 156 } | |
| 157 | |
| 158 const std::string& GetExpectedRequestData() { | |
| 159 static std::string expected_data; | |
|
Sergey Ulanov
2016/12/14 00:17:03
Any reason this needs to be static?
Style guide do
joedow
2016/12/14 00:41:35
No, I'll make it a class member.
| |
| 160 if (expected_data.empty()) { | |
| 161 expected_data.reserve(sizeof(kRequestData) - 4); | |
| 162 | |
| 163 // Skip first four bytes and build up the response string. | |
| 164 for (size_t i = 4; i < sizeof(kRequestData); ++i) { | |
|
Sergey Ulanov
2016/12/14 00:17:03
This loop can be expressed with one assign() call:
joedow
2016/12/14 00:41:35
This is much cleaner, thanks!
| |
| 165 expected_data.append(1, static_cast<unsigned char>(kRequestData[i])); | |
| 166 } | |
| 136 } | 167 } |
| 137 | 168 |
| 138 CheckHostDataMessage(connection_id, expected_data); | 169 return expected_data; |
| 139 } | 170 } |
| 140 | 171 |
| 141 protected: | 172 protected: |
| 142 base::MessageLoopForIO message_loop_; | 173 base::MessageLoopForIO message_loop_; |
| 143 std::unique_ptr<base::RunLoop> run_loop_; | 174 std::unique_ptr<base::RunLoop> run_loop_; |
| 144 | 175 |
| 145 base::Thread file_thread_; | 176 base::Thread file_thread_; |
| 146 | 177 |
| 147 // Object under test. | 178 // Object under test. |
| 148 std::unique_ptr<SecurityKeyAuthHandler> auth_handler_; | 179 std::unique_ptr<SecurityKeyAuthHandler> auth_handler_; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 164 CreateSocketAndWait(); | 195 CreateSocketAndWait(); |
| 165 | 196 |
| 166 net::UnixDomainClientSocket client_socket(socket_path_.value(), false); | 197 net::UnixDomainClientSocket client_socket(socket_path_.value(), false); |
| 167 net::TestCompletionCallback connect_callback; | 198 net::TestCompletionCallback connect_callback; |
| 168 | 199 |
| 169 int rv = client_socket.Connect(connect_callback.callback()); | 200 int rv = client_socket.Connect(connect_callback.callback()); |
| 170 ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); | 201 ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); |
| 171 | 202 |
| 172 // Write the request and verify the response. | 203 // Write the request and verify the response. |
| 173 WriteRequestData(&client_socket); | 204 WriteRequestData(&client_socket); |
| 174 WaitForAndVerifyHostMessage(1); | 205 WaitForSendMessageToClient(); |
| 206 CheckHostDataMessage(1, GetExpectedRequestData()); | |
| 207 | |
| 208 auth_handler_->SendClientResponse(1, GetExpectedRequestData()); | |
| 209 WaitForResponseData(&client_socket); | |
| 175 | 210 |
| 176 // Verify the connection is now valid. | 211 // Verify the connection is now valid. |
| 177 ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); | 212 ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); |
| 178 | 213 |
| 179 // Verify that completing a request/response cycle didn't close the socket. | 214 // Verify that completing a request/response cycle didn't close the socket. |
| 180 ASSERT_EQ(1u, auth_handler_->GetActiveConnectionCountForTest()); | 215 ASSERT_EQ(1u, auth_handler_->GetActiveConnectionCountForTest()); |
| 181 } | 216 } |
| 182 | 217 |
| 183 TEST_F(SecurityKeyAuthHandlerPosixTest, HandleTwoRequests) { | 218 TEST_F(SecurityKeyAuthHandlerPosixTest, HandleTwoRequests) { |
| 184 CreateSocketAndWait(); | 219 CreateSocketAndWait(); |
| 185 | 220 |
| 186 net::UnixDomainClientSocket client_socket(socket_path_.value(), false); | 221 net::UnixDomainClientSocket client_socket(socket_path_.value(), false); |
| 187 net::TestCompletionCallback connect_callback; | 222 net::TestCompletionCallback connect_callback; |
| 188 | 223 |
| 189 int rv = client_socket.Connect(connect_callback.callback()); | 224 int rv = client_socket.Connect(connect_callback.callback()); |
| 190 ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); | 225 ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); |
| 191 | 226 |
| 192 // Write the request and verify the response. | 227 // Write the request and verify the response. |
| 193 WriteRequestData(&client_socket); | 228 WriteRequestData(&client_socket); |
| 194 WaitForAndVerifyHostMessage(1); | 229 WaitForSendMessageToClient(); |
| 230 CheckHostDataMessage(1, GetExpectedRequestData()); | |
| 195 | 231 |
| 196 // Verify the connection is now valid. | 232 // Verify the connection is now valid. |
| 197 ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); | 233 ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); |
| 198 | 234 |
| 199 // Repeat the request/response cycle. | 235 // Send a 'client' response to the socket and verify the data is received. |
| 200 WriteRequestData(&client_socket); | 236 auth_handler_->SendClientResponse(1, GetExpectedRequestData()); |
| 201 WaitForAndVerifyHostMessage(1); | 237 WaitForResponseData(&client_socket); |
| 202 | 238 |
| 203 // Verify the connection is still valid. | 239 // Verify the connection is still valid. |
| 204 ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); | 240 ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); |
| 241 | |
| 242 // Repeat the request/response cycle. | |
| 243 WriteRequestData(&client_socket); | |
| 244 WaitForSendMessageToClient(); | |
| 245 CheckHostDataMessage(1, GetExpectedRequestData()); | |
| 246 | |
| 247 // Verify the connection is still valid. | |
| 248 ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); | |
| 249 | |
| 250 auth_handler_->SendClientResponse(1, GetExpectedRequestData()); | |
| 251 WaitForResponseData(&client_socket); | |
| 252 | |
| 253 // Verify the connection is still valid. | |
| 254 ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); | |
| 205 | 255 |
| 206 // Verify that completing two request/response cycles didn't close the | 256 // Verify that completing two request/response cycles didn't close the |
| 207 // socket. | 257 // socket. |
| 208 ASSERT_EQ(1u, auth_handler_->GetActiveConnectionCountForTest()); | 258 ASSERT_EQ(1u, auth_handler_->GetActiveConnectionCountForTest()); |
| 209 } | 259 } |
| 210 | 260 |
| 211 TEST_F(SecurityKeyAuthHandlerPosixTest, HandleTwoIndependentRequests) { | 261 TEST_F(SecurityKeyAuthHandlerPosixTest, HandleTwoIndependentRequests) { |
| 212 CreateSocketAndWait(); | 262 CreateSocketAndWait(); |
| 213 | 263 |
| 214 net::UnixDomainClientSocket client_socket(socket_path_.value(), false); | 264 net::UnixDomainClientSocket client_socket(socket_path_.value(), false); |
| 215 net::TestCompletionCallback connect_callback; | 265 net::TestCompletionCallback connect_callback; |
| 216 | 266 |
| 217 int rv = client_socket.Connect(connect_callback.callback()); | 267 int rv = client_socket.Connect(connect_callback.callback()); |
| 218 ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); | 268 ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); |
| 219 | 269 |
| 220 // Write the request and verify the response. | 270 // Write the request and verify the response. |
| 221 WriteRequestData(&client_socket); | 271 WriteRequestData(&client_socket); |
| 222 WaitForAndVerifyHostMessage(1); | 272 WaitForSendMessageToClient(); |
| 273 CheckHostDataMessage(1, GetExpectedRequestData()); | |
| 223 | 274 |
| 224 // Verify the first connection is now valid. | 275 // Verify the first connection is now valid. |
| 225 ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); | 276 ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); |
| 226 | 277 |
| 278 // Send a 'client' response to the socket and verify the data is received. | |
| 279 auth_handler_->SendClientResponse(1, GetExpectedRequestData()); | |
| 280 WaitForResponseData(&client_socket); | |
| 281 | |
| 282 // Verify the connection is still valid. | |
| 283 ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); | |
| 284 | |
| 227 // Disconnect and establish a new connection. | 285 // Disconnect and establish a new connection. |
| 228 client_socket.Disconnect(); | 286 client_socket.Disconnect(); |
| 287 | |
| 229 rv = client_socket.Connect(connect_callback.callback()); | 288 rv = client_socket.Connect(connect_callback.callback()); |
| 230 ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); | 289 ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); |
| 231 | 290 |
| 232 // Repeat the request/response cycle. | 291 // Repeat the request/response cycle. |
| 233 WriteRequestData(&client_socket); | 292 WriteRequestData(&client_socket); |
| 234 WaitForAndVerifyHostMessage(2); | 293 WaitForSendMessageToClient(); |
| 294 CheckHostDataMessage(2, GetExpectedRequestData()); | |
| 295 | |
| 296 // Verify the connection is now valid. | |
| 297 ASSERT_TRUE(auth_handler_->IsValidConnectionId(2)); | |
| 298 | |
| 299 // Send a 'client' response to the socket and verify the data is received. | |
| 300 auth_handler_->SendClientResponse(2, GetExpectedRequestData()); | |
| 301 WaitForResponseData(&client_socket); | |
| 235 | 302 |
| 236 // Verify the second connection is valid and the first is not. | 303 // Verify the second connection is valid and the first is not. |
| 237 ASSERT_TRUE(auth_handler_->IsValidConnectionId(2)); | 304 ASSERT_TRUE(auth_handler_->IsValidConnectionId(2)); |
| 238 ASSERT_FALSE(auth_handler_->IsValidConnectionId(1)); | 305 ASSERT_FALSE(auth_handler_->IsValidConnectionId(1)); |
| 239 | |
| 240 // Verify that the initial socket was released properly. | |
| 241 ASSERT_EQ(1u, auth_handler_->GetActiveConnectionCountForTest()); | 306 ASSERT_EQ(1u, auth_handler_->GetActiveConnectionCountForTest()); |
| 242 } | 307 } |
| 243 | 308 |
| 244 TEST_F(SecurityKeyAuthHandlerPosixTest, DidReadTimeout) { | 309 TEST_F(SecurityKeyAuthHandlerPosixTest, DoReadTimeout) { |
| 245 CreateSocketAndWait(); | 310 CreateSocketAndWait(); |
| 246 | 311 |
| 312 auth_handler_->SetRequestTimeoutForTest(base::TimeDelta()); | |
| 313 | |
| 247 net::UnixDomainClientSocket client_socket(socket_path_.value(), false); | 314 net::UnixDomainClientSocket client_socket(socket_path_.value(), false); |
| 248 net::TestCompletionCallback connect_callback; | 315 net::TestCompletionCallback connect_callback; |
| 249 int rv = client_socket.Connect(connect_callback.callback()); | 316 int rv = client_socket.Connect(connect_callback.callback()); |
| 250 ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); | 317 ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); |
| 251 auth_handler_->SetRequestTimeoutForTest(base::TimeDelta()); | 318 |
| 319 // SSH Error should be received when the connection times out. | |
| 320 WaitForErrorData(&client_socket); | |
| 321 | |
| 322 // Connection should no longer be valid. | |
| 323 ASSERT_FALSE(auth_handler_->IsValidConnectionId(1)); | |
| 252 ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest()); | 324 ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest()); |
| 253 } | 325 } |
| 254 | 326 |
| 255 TEST_F(SecurityKeyAuthHandlerPosixTest, ClientErrorMessageDelivered) { | 327 TEST_F(SecurityKeyAuthHandlerPosixTest, ClientErrorMessageDelivered) { |
| 256 CreateSocketAndWait(); | 328 CreateSocketAndWait(); |
| 257 | 329 |
| 258 net::UnixDomainClientSocket client_socket(socket_path_.value(), false); | 330 net::UnixDomainClientSocket client_socket(socket_path_.value(), false); |
| 259 net::TestCompletionCallback connect_callback; | 331 net::TestCompletionCallback connect_callback; |
| 260 int rv = client_socket.Connect(connect_callback.callback()); | 332 int rv = client_socket.Connect(connect_callback.callback()); |
| 261 ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); | 333 ASSERT_EQ(net::OK, connect_callback.GetResult(rv)); |
| 262 | 334 |
| 335 // Write the request and verify the response. This ensures the socket has | |
| 336 // been created and is working before sending the error to tear it down. | |
| 337 WriteRequestData(&client_socket); | |
| 338 WaitForSendMessageToClient(); | |
| 339 CheckHostDataMessage(1, GetExpectedRequestData()); | |
| 340 | |
| 341 // Send a 'client' response to the socket and verify the data is received. | |
| 342 auth_handler_->SendClientResponse(1, GetExpectedRequestData()); | |
| 343 WaitForResponseData(&client_socket); | |
| 344 | |
| 345 ASSERT_TRUE(auth_handler_->IsValidConnectionId(1)); | |
| 346 ASSERT_EQ(1u, auth_handler_->GetActiveConnectionCountForTest()); | |
| 347 | |
| 263 auth_handler_->SendErrorAndCloseConnection(1); | 348 auth_handler_->SendErrorAndCloseConnection(1); |
| 349 | |
| 350 // Connection should be removed immediately. | |
| 351 ASSERT_FALSE(auth_handler_->IsValidConnectionId(1)); | |
| 264 ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest()); | 352 ASSERT_EQ(0u, auth_handler_->GetActiveConnectionCountForTest()); |
| 353 | |
| 354 // SSH Error should be received. | |
| 355 WaitForErrorData(&client_socket); | |
| 265 } | 356 } |
| 266 | 357 |
| 267 } // namespace remoting | 358 } // namespace remoting |
| OLD | NEW |