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