unix_domain_server_socket_posix_unittest.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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)
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)bool UserCanConnectCallback(bool allow_user, uid_t uid, gid_t gid) {
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Here peers are running in same process.
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(getuid(), uid);
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(getgid(), gid);
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return allow_user;
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)UnixDomainServerSocket::AuthCallback CreateAuthCallback(bool allow_user) {
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return base::Bind(&UserCanConnectCallback, allow_user);
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class UnixDomainServerSocketTest : public testing::Test {
395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) protected:
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UnixDomainServerSocketTest() {
415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    socket_path_ = temp_dir_.path().Append(kSocketFilename).value();
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::ScopedTempDir temp_dir_;
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  std::string socket_path_;
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(UnixDomainServerSocketTest, ListenWithInvalidPath) {
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const bool kUseAbstractNamespace = false;
515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UnixDomainServerSocket server_socket(CreateAuthCallback(true),
525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       kUseAbstractNamespace);
535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(ERR_FILE_NOT_FOUND,
545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            server_socket.ListenWithAddressAndPort(kInvalidSocketPath, 0, 1));
555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(UnixDomainServerSocketTest, ListenWithInvalidPathWithAbstractNamespace) {
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const bool kUseAbstractNamespace = true;
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UnixDomainServerSocket server_socket(CreateAuthCallback(true),
605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       kUseAbstractNamespace);
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#if defined(OS_ANDROID) || defined(OS_LINUX)
625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(OK,
635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            server_socket.ListenWithAddressAndPort(kInvalidSocketPath, 0, 1));
645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else
655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(ERR_ADDRESS_INVALID,
665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            server_socket.ListenWithAddressAndPort(kInvalidSocketPath, 0, 1));
675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif
685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)TEST_F(UnixDomainServerSocketTest, AcceptWithForbiddenUser) {
715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const bool kUseAbstractNamespace = false;
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UnixDomainServerSocket server_socket(CreateAuthCallback(false),
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                       kUseAbstractNamespace);
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(OK, server_socket.ListenWithAddressAndPort(socket_path_, 0, 1));
765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_ptr<StreamSocket> accepted_socket;
785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TestCompletionCallback accept_callback;
795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_EQ(ERR_IO_PENDING,
805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            server_socket.Accept(&accepted_socket, accept_callback.callback()));
815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(accepted_socket);
825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UnixDomainClientSocket client_socket(socket_path_, kUseAbstractNamespace);
845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(client_socket.IsConnected());
855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Connect() will return OK before the server rejects the connection.
875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TestCompletionCallback connect_callback;
885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int rv = connect_callback.GetResult(
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      client_socket.Connect(connect_callback.callback()));
905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(OK, rv);
915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Try to read from the socket.
935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const int read_buffer_size = 10;
945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  scoped_refptr<IOBuffer> read_buffer(new IOBuffer(read_buffer_size));
955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  TestCompletionCallback read_callback;
965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  rv = read_callback.GetResult(client_socket.Read(read_buffer, read_buffer_size,
975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                                                  read_callback.callback()));
985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The server should have disconnected gracefully, without sending any data.
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ASSERT_EQ(0, rv);
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(client_socket.IsConnected());
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // The server socket should not have called |accept_callback| or modified
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // |accepted_socket|.
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(accept_callback.have_result());
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  EXPECT_FALSE(accepted_socket);
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Normal cases including read/write are tested by UnixDomainClientSocketTest.
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace
1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}  // namespace net
113