15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// found in the LICENSE file. 45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/socket/unix_domain_server_socket_posix.h" 65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <vector> 85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 95f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/bind.h" 105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/files/file_path.h" 115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/files/scoped_temp_dir.h" 125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/run_loop.h" 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/stl_util.h" 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/io_buffer.h" 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/net_errors.h" 175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/base/test_completion_callback.h" 185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/socket/unix_domain_client_socket_posix.h" 195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace net { 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)namespace { 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kSocketFilename[] = "socket_for_testing"; 255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)const char kInvalidSocketPath[] = "/invalid/path"; 265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool UserCanConnectCallback(bool allow_user, 286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const UnixDomainServerSocket::Credentials& credentials) { 295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Here peers are running in same process. 306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#if defined(OS_LINUX) || defined(OS_ANDROID) 316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(getpid(), credentials.process_id); 326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#endif 336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(getuid(), credentials.user_id); 346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) EXPECT_EQ(getgid(), credentials.group_id); 355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return allow_user; 365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)UnixDomainServerSocket::AuthCallback CreateAuthCallback(bool allow_user) { 395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return base::Bind(&UserCanConnectCallback, allow_user); 405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class UnixDomainServerSocketTest : public testing::Test { 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) protected: 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UnixDomainServerSocketTest() { 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_TRUE(temp_dir_.CreateUniqueTempDir()); 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) socket_path_ = temp_dir_.path().Append(kSocketFilename).value(); 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::ScopedTempDir temp_dir_; 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) std::string socket_path_; 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}; 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(UnixDomainServerSocketTest, ListenWithInvalidPath) { 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const bool kUseAbstractNamespace = false; 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UnixDomainServerSocket server_socket(CreateAuthCallback(true), 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kUseAbstractNamespace); 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(ERR_FILE_NOT_FOUND, 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) server_socket.ListenWithAddressAndPort(kInvalidSocketPath, 0, 1)); 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(UnixDomainServerSocketTest, ListenWithInvalidPathWithAbstractNamespace) { 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const bool kUseAbstractNamespace = true; 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UnixDomainServerSocket server_socket(CreateAuthCallback(true), 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kUseAbstractNamespace); 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_ANDROID) || defined(OS_LINUX) 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(OK, 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) server_socket.ListenWithAddressAndPort(kInvalidSocketPath, 0, 1)); 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else 695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(ERR_ADDRESS_INVALID, 705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) server_socket.ListenWithAddressAndPort(kInvalidSocketPath, 0, 1)); 715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST_F(UnixDomainServerSocketTest, ListenAgainAfterFailureWithInvalidPath) { 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const bool kUseAbstractNamespace = false; 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UnixDomainServerSocket server_socket(CreateAuthCallback(true), 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci kUseAbstractNamespace); 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(ERR_FILE_NOT_FOUND, 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci server_socket.ListenWithAddressAndPort(kInvalidSocketPath, 0, 1)); 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1)); 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(UnixDomainServerSocketTest, AcceptWithForbiddenUser) { 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const bool kUseAbstractNamespace = false; 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UnixDomainServerSocket server_socket(CreateAuthCallback(false), 875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) kUseAbstractNamespace); 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1)); 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<StreamSocket> accepted_socket; 915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TestCompletionCallback accept_callback; 925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_EQ(ERR_IO_PENDING, 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) server_socket.Accept(&accepted_socket, accept_callback.callback())); 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_FALSE(accepted_socket); 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace); 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_FALSE(client_socket.IsConnected()); 985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Connect() will return OK before the server rejects the connection. 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TestCompletionCallback connect_callback; 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int rv = connect_callback.GetResult( 1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) client_socket.Connect(connect_callback.callback())); 1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_EQ(OK, rv); 1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // Try to read from the socket. 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) const int read_buffer_size = 10; 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_refptr<IOBuffer> read_buffer(new IOBuffer(read_buffer_size)); 1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) TestCompletionCallback read_callback; 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci rv = read_callback.GetResult(client_socket.Read( 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci read_buffer.get(), read_buffer_size, read_callback.callback())); 1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The server should have disconnected gracefully, without sending any data. 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_EQ(0, rv); 1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_FALSE(client_socket.IsConnected()); 1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // The server socket should not have called |accept_callback| or modified 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // |accepted_socket|. 1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_FALSE(accept_callback.have_result()); 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) EXPECT_FALSE(accepted_socket); 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Normal cases including read/write are tested by UnixDomainClientSocketTest. 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace 1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} // namespace net 126