| 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 "remoting/host/security_key/security_key_ipc_client.h" | 5 #include "remoting/host/security_key/security_key_ipc_client.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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 void ClientMessageReceived(const std::string& response_payload); | 51 void ClientMessageReceived(const std::string& response_payload); |
| 52 | 52 |
| 53 protected: | 53 protected: |
| 54 // testing::Test interface. | 54 // testing::Test interface. |
| 55 void SetUp() override; | 55 void SetUp() override; |
| 56 | 56 |
| 57 // Waits until the current |run_loop_| instance is signaled, then resets it. | 57 // Waits until the current |run_loop_| instance is signaled, then resets it. |
| 58 void WaitForOperationComplete(); | 58 void WaitForOperationComplete(); |
| 59 | 59 |
| 60 // Sets up an active IPC connection between |security_key_ipc_client_| | 60 // Sets up an active IPC connection between |security_key_ipc_client_| |
| 61 // and |fake_ipc_server_|. |expect_success| defines whether the operation | 61 // and |fake_ipc_server_|. |expect_connected| defines whether the operation |
| 62 // is expected to succeed or fail. | 62 // is result in a usable IPC connection. |expect_error| defines whether the |
| 63 void EstablishConnection(bool expect_success); | 63 // the error callback should be invoked during the connection process. |
| 64 void EstablishConnection(bool expect_connected, bool expect_error); |
| 64 | 65 |
| 65 // Sends a security key request from |security_key_ipc_client_| and | 66 // Sends a security key request from |security_key_ipc_client_| and |
| 66 // a response from |fake_ipc_server_| and verifies the payloads for both. | 67 // a response from |fake_ipc_server_| and verifies the payloads for both. |
| 67 void SendRequestAndResponse(const std::string& request_data, | 68 void SendRequestAndResponse(const std::string& request_data, |
| 68 const std::string& response_data); | 69 const std::string& response_data); |
| 69 | 70 |
| 70 // Creates a unique IPC channel name to use for testing. | 71 // Creates a unique IPC channel name to use for testing. |
| 71 std::string GenerateUniqueTestChannelName(); | 72 std::string GenerateUniqueTestChannelName(); |
| 72 | 73 |
| 73 // IPC tests require a valid MessageLoop to run. | 74 // IPC tests require a valid MessageLoop to run. |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 const std::string& response_payload) { | 171 const std::string& response_payload) { |
| 171 last_message_received_ = response_payload; | 172 last_message_received_ = response_payload; |
| 172 OperationComplete(/*failed=*/false); | 173 OperationComplete(/*failed=*/false); |
| 173 } | 174 } |
| 174 | 175 |
| 175 std::string SecurityKeyIpcClientTest::GenerateUniqueTestChannelName() { | 176 std::string SecurityKeyIpcClientTest::GenerateUniqueTestChannelName() { |
| 176 return GetChannelNamePathPrefixForTest() + kValidIpcChannelName + | 177 return GetChannelNamePathPrefixForTest() + kValidIpcChannelName + |
| 177 IPC::Channel::GenerateUniqueRandomChannelID(); | 178 IPC::Channel::GenerateUniqueRandomChannelID(); |
| 178 } | 179 } |
| 179 | 180 |
| 180 void SecurityKeyIpcClientTest::EstablishConnection(bool expect_success) { | 181 void SecurityKeyIpcClientTest::EstablishConnection(bool expect_connected, |
| 182 bool expect_error) { |
| 181 // Start up the security key forwarding session IPC channel first, that way | 183 // Start up the security key forwarding session IPC channel first, that way |
| 182 // we can provide the channel using the fake SecurityKeyAuthHandler later on. | 184 // we can provide the channel using the fake SecurityKeyAuthHandler later on. |
| 183 mojo::edk::NamedPlatformHandle channel_handle( | 185 mojo::edk::NamedPlatformHandle channel_handle( |
| 184 GenerateUniqueTestChannelName()); | 186 GenerateUniqueTestChannelName()); |
| 185 security_key_ipc_client_.SetIpcChannelHandleForTest(channel_handle); | 187 security_key_ipc_client_.SetIpcChannelHandleForTest(channel_handle); |
| 186 ASSERT_TRUE(fake_ipc_server_.CreateChannel( | 188 ASSERT_TRUE(fake_ipc_server_.CreateChannel( |
| 187 channel_handle, | 189 channel_handle, |
| 188 /*request_timeout=*/base::TimeDelta::FromMilliseconds(500))); | 190 /*request_timeout=*/base::TimeDelta::FromMilliseconds(500))); |
| 189 | 191 |
| 190 ASSERT_TRUE(security_key_ipc_client_.CheckForSecurityKeyIpcServerChannel()); | 192 ASSERT_TRUE(security_key_ipc_client_.CheckForSecurityKeyIpcServerChannel()); |
| 191 | 193 |
| 192 // Establish the IPC channel so we can begin sending and receiving security | 194 // Establish the IPC channel so we can begin sending and receiving security |
| 193 // key messages. | 195 // key messages. |
| 194 security_key_ipc_client_.EstablishIpcConnection( | 196 security_key_ipc_client_.EstablishIpcConnection( |
| 195 base::Bind(&SecurityKeyIpcClientTest::ConnectionStateHandler, | 197 base::Bind(&SecurityKeyIpcClientTest::ConnectionStateHandler, |
| 196 base::Unretained(this)), | 198 base::Unretained(this)), |
| 197 base::Bind(&SecurityKeyIpcClientTest::OperationComplete, | 199 base::Bind(&SecurityKeyIpcClientTest::OperationComplete, |
| 198 base::Unretained(this), /*failed=*/true)); | 200 base::Unretained(this), /*failed=*/true)); |
| 199 WaitForOperationComplete(); | 201 WaitForOperationComplete(); |
| 200 ASSERT_EQ(connection_established_, expect_success); | 202 ASSERT_EQ(expect_connected, connection_established_); |
| 201 ASSERT_NE(operation_failed_, expect_success); | 203 ASSERT_EQ(expect_error, operation_failed_); |
| 202 } | 204 } |
| 203 | 205 |
| 204 void SecurityKeyIpcClientTest::SendRequestAndResponse( | 206 void SecurityKeyIpcClientTest::SendRequestAndResponse( |
| 205 const std::string& request_data, | 207 const std::string& request_data, |
| 206 const std::string& response_data) { | 208 const std::string& response_data) { |
| 207 ASSERT_TRUE(security_key_ipc_client_.SendSecurityKeyRequest( | 209 ASSERT_TRUE(security_key_ipc_client_.SendSecurityKeyRequest( |
| 208 request_data, base::Bind(&SecurityKeyIpcClientTest::ClientMessageReceived, | 210 request_data, base::Bind(&SecurityKeyIpcClientTest::ClientMessageReceived, |
| 209 base::Unretained(this)))); | 211 base::Unretained(this)))); |
| 210 WaitForOperationComplete(); | 212 WaitForOperationComplete(); |
| 211 ASSERT_FALSE(operation_failed_); | 213 ASSERT_FALSE(operation_failed_); |
| 212 ASSERT_EQ(last_connection_id_received_, kTestConnectionId); | 214 ASSERT_EQ(kTestConnectionId, last_connection_id_received_); |
| 213 ASSERT_EQ(last_message_received_, request_data); | 215 ASSERT_EQ(request_data, last_message_received_); |
| 214 | 216 |
| 215 ASSERT_TRUE(fake_ipc_server_.SendResponse(response_data)); | 217 ASSERT_TRUE(fake_ipc_server_.SendResponse(response_data)); |
| 216 WaitForOperationComplete(); | 218 WaitForOperationComplete(); |
| 217 ASSERT_FALSE(operation_failed_); | 219 ASSERT_FALSE(operation_failed_); |
| 218 ASSERT_EQ(last_message_received_, response_data); | 220 ASSERT_EQ(response_data, last_message_received_); |
| 219 } | 221 } |
| 220 | 222 |
| 221 TEST_F(SecurityKeyIpcClientTest, GenerateSingleSecurityKeyRequest) { | 223 TEST_F(SecurityKeyIpcClientTest, GenerateSingleSecurityKeyRequest) { |
| 222 EstablishConnection(/*expect_success=*/true); | 224 EstablishConnection(/*expect_connected=*/true, /*expect_error=*/false); |
| 223 | 225 |
| 224 SendRequestAndResponse("Auth me!", "You've been authed!"); | 226 SendRequestAndResponse("Auth me!", "You've been authed!"); |
| 225 | 227 |
| 226 security_key_ipc_client_.CloseIpcConnection(); | 228 security_key_ipc_client_.CloseIpcConnection(); |
| 227 } | 229 } |
| 228 | 230 |
| 229 TEST_F(SecurityKeyIpcClientTest, GenerateLargeSecurityKeyRequest) { | 231 TEST_F(SecurityKeyIpcClientTest, GenerateLargeSecurityKeyRequest) { |
| 230 EstablishConnection(/*expect_success=*/true); | 232 EstablishConnection(/*expect_connected=*/true, /*expect_error=*/false); |
| 231 | 233 |
| 232 SendRequestAndResponse(std::string(kLargeMessageSizeBytes, 'Y'), | 234 SendRequestAndResponse(std::string(kLargeMessageSizeBytes, 'Y'), |
| 233 std::string(kLargeMessageSizeBytes, 'Z')); | 235 std::string(kLargeMessageSizeBytes, 'Z')); |
| 234 | 236 |
| 235 security_key_ipc_client_.CloseIpcConnection(); | 237 security_key_ipc_client_.CloseIpcConnection(); |
| 236 } | 238 } |
| 237 | 239 |
| 238 TEST_F(SecurityKeyIpcClientTest, GenerateReallyLargeSecurityKeyRequest) { | 240 TEST_F(SecurityKeyIpcClientTest, GenerateReallyLargeSecurityKeyRequest) { |
| 239 EstablishConnection(/*expect_success=*/true); | 241 EstablishConnection(/*expect_connected=*/true, /*expect_error=*/false); |
| 240 | 242 |
| 241 SendRequestAndResponse(std::string(kLargeMessageSizeBytes * 2, 'Y'), | 243 SendRequestAndResponse(std::string(kLargeMessageSizeBytes * 2, 'Y'), |
| 242 std::string(kLargeMessageSizeBytes * 2, 'Z')); | 244 std::string(kLargeMessageSizeBytes * 2, 'Z')); |
| 243 | 245 |
| 244 security_key_ipc_client_.CloseIpcConnection(); | 246 security_key_ipc_client_.CloseIpcConnection(); |
| 245 } | 247 } |
| 246 | 248 |
| 247 TEST_F(SecurityKeyIpcClientTest, GenerateMultipleSecurityKeyRequest) { | 249 TEST_F(SecurityKeyIpcClientTest, GenerateMultipleSecurityKeyRequest) { |
| 248 EstablishConnection(/*expect_success=*/true); | 250 EstablishConnection(/*expect_connected=*/true, /*expect_error=*/false); |
| 249 | 251 |
| 250 SendRequestAndResponse("Auth me 1!", "You've been authed once!"); | 252 SendRequestAndResponse("Auth me 1!", "You've been authed once!"); |
| 251 SendRequestAndResponse("Auth me 2!", "You've been authed twice!"); | 253 SendRequestAndResponse("Auth me 2!", "You've been authed twice!"); |
| 252 SendRequestAndResponse("Auth me 3!", "You've been authed thrice!"); | 254 SendRequestAndResponse("Auth me 3!", "You've been authed thrice!"); |
| 253 | 255 |
| 254 security_key_ipc_client_.CloseIpcConnection(); | 256 security_key_ipc_client_.CloseIpcConnection(); |
| 255 } | 257 } |
| 256 | 258 |
| 257 TEST_F(SecurityKeyIpcClientTest, ServerClosesConnectionAfterRequestTimeout) { | 259 TEST_F(SecurityKeyIpcClientTest, ServerClosesConnectionAfterRequestTimeout) { |
| 258 EstablishConnection(/*expect_success=*/true); | 260 EstablishConnection(/*expect_connected=*/true, /*expect_error=*/false); |
| 259 fake_ipc_server_.CloseChannel(); | 261 fake_ipc_server_.CloseChannel(); |
| 260 WaitForOperationComplete(); | 262 WaitForOperationComplete(); |
| 261 ASSERT_FALSE(operation_failed_); | 263 ASSERT_FALSE(operation_failed_); |
| 262 } | 264 } |
| 263 | 265 |
| 264 TEST_F(SecurityKeyIpcClientTest, | 266 TEST_F(SecurityKeyIpcClientTest, |
| 265 SecondSecurityKeyRequestBeforeFirstResponseReceived) { | 267 SecondSecurityKeyRequestBeforeFirstResponseReceived) { |
| 266 EstablishConnection(/*expect_success=*/true); | 268 EstablishConnection(/*expect_connected=*/true, /*expect_error=*/false); |
| 267 | 269 |
| 268 ASSERT_TRUE(security_key_ipc_client_.SendSecurityKeyRequest( | 270 ASSERT_TRUE(security_key_ipc_client_.SendSecurityKeyRequest( |
| 269 "First Request", | 271 "First Request", |
| 270 base::Bind(&SecurityKeyIpcClientTest::ClientMessageReceived, | 272 base::Bind(&SecurityKeyIpcClientTest::ClientMessageReceived, |
| 271 base::Unretained(this)))); | 273 base::Unretained(this)))); |
| 272 WaitForOperationComplete(); | 274 WaitForOperationComplete(); |
| 273 ASSERT_FALSE(operation_failed_); | 275 ASSERT_FALSE(operation_failed_); |
| 274 | 276 |
| 275 ASSERT_FALSE(security_key_ipc_client_.SendSecurityKeyRequest( | 277 ASSERT_FALSE(security_key_ipc_client_.SendSecurityKeyRequest( |
| 276 "Second Request", | 278 "Second Request", |
| 277 base::Bind(&SecurityKeyIpcClientTest::ClientMessageReceived, | 279 base::Bind(&SecurityKeyIpcClientTest::ClientMessageReceived, |
| 278 base::Unretained(this)))); | 280 base::Unretained(this)))); |
| 279 } | 281 } |
| 280 | 282 |
| 281 TEST_F(SecurityKeyIpcClientTest, ReceiveSecurityKeyResponseWithEmptyPayload) { | 283 TEST_F(SecurityKeyIpcClientTest, ReceiveSecurityKeyResponseWithEmptyPayload) { |
| 282 EstablishConnection(/*expect_success=*/true); | 284 EstablishConnection(/*expect_connected=*/true, /*expect_error=*/false); |
| 283 | 285 |
| 284 ASSERT_TRUE(security_key_ipc_client_.SendSecurityKeyRequest( | 286 ASSERT_TRUE(security_key_ipc_client_.SendSecurityKeyRequest( |
| 285 "Valid request", | 287 "Valid request", |
| 286 base::Bind(&SecurityKeyIpcClientTest::ClientMessageReceived, | 288 base::Bind(&SecurityKeyIpcClientTest::ClientMessageReceived, |
| 287 base::Unretained(this)))); | 289 base::Unretained(this)))); |
| 288 WaitForOperationComplete(); | 290 WaitForOperationComplete(); |
| 289 ASSERT_FALSE(operation_failed_); | 291 ASSERT_FALSE(operation_failed_); |
| 290 | 292 |
| 291 ASSERT_TRUE(fake_ipc_server_.SendResponse("")); | 293 ASSERT_TRUE(fake_ipc_server_.SendResponse("")); |
| 292 WaitForOperationComplete(); | 294 WaitForOperationComplete(); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 309 // not exist). | 311 // not exist). |
| 310 security_key_ipc_client_.EstablishIpcConnection( | 312 security_key_ipc_client_.EstablishIpcConnection( |
| 311 base::Bind(&SecurityKeyIpcClientTest::ConnectionStateHandler, | 313 base::Bind(&SecurityKeyIpcClientTest::ConnectionStateHandler, |
| 312 base::Unretained(this)), | 314 base::Unretained(this)), |
| 313 base::Bind(&SecurityKeyIpcClientTest::OperationComplete, | 315 base::Bind(&SecurityKeyIpcClientTest::OperationComplete, |
| 314 base::Unretained(this), /*failed=*/true)); | 316 base::Unretained(this), /*failed=*/true)); |
| 315 WaitForOperationComplete(); | 317 WaitForOperationComplete(); |
| 316 ASSERT_TRUE(operation_failed_); | 318 ASSERT_TRUE(operation_failed_); |
| 317 } | 319 } |
| 318 | 320 |
| 321 TEST_F(SecurityKeyIpcClientTest, MultipleConnectionReadyMessagesReceived) { |
| 322 EstablishConnection(/*expect_connected=*/true, /*expect_error=*/false); |
| 323 ASSERT_FALSE(operation_failed_); |
| 324 |
| 325 // Send a second ConnectionReady message to trigger the error callback. |
| 326 SendConnectionMessage(); |
| 327 WaitForOperationComplete(); |
| 328 ASSERT_TRUE(operation_failed_); |
| 329 |
| 330 // Send a third message to ensure no crash occurs both callbacks will have |
| 331 // been called and cleared so we don't wait for the operation to complete. |
| 332 SendConnectionMessage(); |
| 333 ASSERT_TRUE(operation_failed_); |
| 334 } |
| 335 |
| 336 TEST_F(SecurityKeyIpcClientTest, UnexpectedInvalidSessionMessagesReceived) { |
| 337 EstablishConnection(/*expect_connected=*/true, /*expect_error=*/false); |
| 338 ASSERT_FALSE(operation_failed_); |
| 339 |
| 340 // Send an InvalidSession message to trigger the error callback. |
| 341 simulate_invalid_session_ = true; |
| 342 SendConnectionMessage(); |
| 343 WaitForOperationComplete(); |
| 344 ASSERT_TRUE(operation_failed_); |
| 345 |
| 346 // Send a third message to ensure no crash occurs both callbacks will have |
| 347 // been called and cleared so we don't wait for the operation to complete. |
| 348 SendConnectionMessage(); |
| 349 ASSERT_TRUE(operation_failed_); |
| 350 } |
| 351 |
| 319 #if defined(OS_WIN) | 352 #if defined(OS_WIN) |
| 320 TEST_F(SecurityKeyIpcClientTest, SecurityKeyIpcServerRunningInWrongSession) { | 353 TEST_F(SecurityKeyIpcClientTest, SecurityKeyIpcServerRunningInWrongSession) { |
| 321 // Set the expected session Id to a different session than we are running in. | 354 // Set the expected session Id to a different session than we are running in. |
| 322 security_key_ipc_client_.SetExpectedIpcServerSessionIdForTest(session_id_ + | 355 security_key_ipc_client_.SetExpectedIpcServerSessionIdForTest(session_id_ + |
| 323 1); | 356 1); |
| 324 simulate_invalid_session_ = true; | |
| 325 | 357 |
| 326 // Attempting to establish a connection should fail here since the IPC Server | 358 // Attempting to establish a connection should fail here since the IPC Server |
| 359 // is 'running' in a different session than expected. The success callback |
| 360 // will be called by the IPC server since it thinks the connection is valid, |
| 361 // but we will have already started tearing down the connection since it |
| 362 // failed at the client end. |
| 363 EstablishConnection(/*expect_connected=*/true, /*expect_error=*/true); |
| 364 } |
| 365 |
| 366 TEST_F(SecurityKeyIpcClientTest, SecurityKeyIpcClientRunningInWrongSession) { |
| 367 // Attempting to establish a connection should fail here since the IPC Client |
| 368 // is 'running' in the non-remoted session. |
| 369 simulate_invalid_session_ = true; |
| 370 EstablishConnection(/*expect_connected=*/false, /*expect_error=*/false); |
| 371 } |
| 372 |
| 373 TEST_F(SecurityKeyIpcClientTest, MultipleInvalidSessionMessagesReceived) { |
| 374 // Attempting to establish a connection should fail here since the IPC Server |
| 327 // is 'running' in a different session than expected. | 375 // is 'running' in a different session than expected. |
| 328 EstablishConnection(/*expect_success=*/false); | 376 simulate_invalid_session_ = true; |
| 377 EstablishConnection(/*expect_connected=*/false, /*expect_error=*/false); |
| 378 |
| 379 SendConnectionMessage(); |
| 380 WaitForOperationComplete(); |
| 381 ASSERT_TRUE(operation_failed_); |
| 382 |
| 383 // Send a third message to ensure no crash occurs both callbacks will have |
| 384 // been called and cleared so we don't wait for the operation to complete. |
| 385 SendConnectionMessage(); |
| 386 ASSERT_TRUE(operation_failed_); |
| 387 } |
| 388 |
| 389 TEST_F(SecurityKeyIpcClientTest, UnexpectedConnectionReadyMessagesReceived) { |
| 390 // Attempting to establish a connection should fail here since the IPC Server |
| 391 // is 'running' in a different session than expected. |
| 392 simulate_invalid_session_ = true; |
| 393 EstablishConnection(/*expect_connected=*/false, /*expect_error=*/false); |
| 394 |
| 395 // Send an InvalidSession message to trigger the error callback. |
| 396 simulate_invalid_session_ = false; |
| 397 SendConnectionMessage(); |
| 398 WaitForOperationComplete(); |
| 399 ASSERT_TRUE(operation_failed_); |
| 400 |
| 401 // Send a third message to ensure no crash occurs both callbacks will have |
| 402 // been called and cleared so we don't wait for the operation to complete. |
| 403 SendConnectionMessage(); |
| 404 ASSERT_TRUE(operation_failed_); |
| 329 } | 405 } |
| 330 #endif // defined(OS_WIN) | 406 #endif // defined(OS_WIN) |
| 331 | 407 |
| 332 } // namespace remoting | 408 } // namespace remoting |
| OLD | NEW |