15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/test_broker.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_MSC_VER)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_WIN 1
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define OS_POSIX 1
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h>
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h>
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstdio>
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cstring>
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fstream>
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits>
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/pp_errors.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/trusted/ppp_broker.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/c/trusted/ppb_broker_trusted.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/test_utils.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ppapi/tests/testing_instance.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)REGISTER_TEST_CASE(Broker);
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kHelloMessage[] = "Hello Plugin! This is Broker!";
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Message sent from broker to plugin if the broker is unsandboxed.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kBrokerUnsandboxed[] = "Broker is Unsandboxed!";
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Message sent from broker to plugin if the broker is sandboxed. This message
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// needs to be longer than |kBrokerUnsandboxed| because the plugin is expecting
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// |kBrokerUnsandboxed|. If it's shorter and the broker doesn't close its handle
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// properly the plugin will hang waiting for all data of |kBrokerUnsandboxed| to
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be read.
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kBrokerSandboxed[] = "Broker is Sandboxed! Verification failed!";
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef HANDLE PlatformFile;
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PlatformFile kInvalidPlatformFileValue = INVALID_HANDLE_VALUE;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int32_t kInvalidHandle = static_cast<int32_t>(
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    reinterpret_cast<intptr_t>(INVALID_HANDLE_VALUE));
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef int PlatformFile;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const PlatformFile kInvalidPlatformFileValue = -1;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int32_t kInvalidHandle = -1;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PlatformFile IntToPlatformFile(int32_t handle) {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return reinterpret_cast<HANDLE>(static_cast<intptr_t>(handle));
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return handle;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_EINTR(x) ({ \
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typeof(x) __eintr_result__; \
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do { \
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __eintr_result__ = x; \
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } while (__eintr_result__ == -1 && errno == EINTR); \
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  __eintr_result__;\
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)})
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReadMessage(PlatformFile file, size_t message_len, char* message) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(message_len < std::numeric_limits<DWORD>::max());
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD read = 0;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DWORD size = static_cast<DWORD>(message_len);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ::ReadFile(file, message, size, &read, NULL) && read == size;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(message_len <
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t total_read = 0;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (total_read < message_len) {
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssize_t read = HANDLE_EINTR(::read(file, message + total_read,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       message_len - total_read));
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (read <= 0)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    total_read += read;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return total_read == message_len;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WriteMessage(PlatformFile file, size_t message_len, const char* message) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(message_len < std::numeric_limits<DWORD>::max());
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD written = 0;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DWORD size = static_cast<DWORD>(message_len);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ::WriteFile(file, message, size, &written, NULL) && written == size;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(message_len <
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t total_written = 0;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (total_written < message_len) {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssize_t written = HANDLE_EINTR(::write(file, message + total_written,
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           message_len - total_written));
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (written <= 0)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    total_written += written;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return total_written == message_len;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VerifyMessage(PlatformFile file, size_t message_len, const char* message) {
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* message_received = new char[message_len];
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = ReadMessage(file, message_len, message_received) &&
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 !::strcmp(message_received, message);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete [] message_received;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return success;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ClosePlatformFile(PlatformFile file) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !!::CloseHandle(file);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !HANDLE_EINTR(::close(file));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VerifyIsUnsandboxed() {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FILE* file = NULL;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wchar_t temp_path[MAX_PATH] = {'\0'};
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wchar_t file_name[MAX_PATH] = {'\0'};
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!::GetTempPath(MAX_PATH, temp_path) ||
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !::GetTempFileName(temp_path, L"test_pepper_broker", 0, file_name) ||
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::_wfopen_s(&file, file_name, L"w"))
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (::fclose(file)) {
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::DeleteFile(file_name);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !!::DeleteFile(file_name);
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char file_name[] = "/tmp/test_pepper_broker_XXXXXX";
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int fd = ::mkstemp(file_name);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (-1 == fd)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (HANDLE_EINTR(::close(fd))) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::remove(file_name);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !::remove(file_name);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Callback in the broker when a new broker connection occurs.
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t OnInstanceConnected(PP_Instance instance, int32_t handle) {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformFile file = IntToPlatformFile(handle);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (file == kInvalidPlatformFileValue)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_FAILED;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Send hello message.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!WriteMessage(file, sizeof(kHelloMessage), kHelloMessage)) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClosePlatformFile(file);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_FAILED;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify broker is not sandboxed and send result to plugin over the pipe.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (VerifyIsUnsandboxed()) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!WriteMessage(file, sizeof(kBrokerUnsandboxed), kBrokerUnsandboxed)) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ClosePlatformFile(file);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_ERROR_FAILED;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!WriteMessage(file, sizeof(kBrokerSandboxed), kBrokerSandboxed)) {
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ClosePlatformFile(file);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_ERROR_FAILED;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ClosePlatformFile(file))
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_FAILED;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_OK;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_EXPORT int32_t PPP_InitializeBroker(
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_ConnectInstance_Func* connect_instance_func) {
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *connect_instance_func = &OnInstanceConnected;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_OK;
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_EXPORT void PPP_ShutdownBroker() {}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestBroker::TestBroker(TestingInstance* instance)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : TestCase(instance),
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      broker_interface_(NULL) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestBroker::Init() {
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  broker_interface_ = static_cast<const PPB_BrokerTrusted*>(
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pp::Module::Get()->GetBrowserInterface(PPB_BROKER_TRUSTED_INTERFACE));
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !!broker_interface_;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestBroker::RunTests(const std::string& filter) {
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST(Create, filter);
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST(Create, filter);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST(GetHandleFailure, filter);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST_FORCEASYNC_AND_NOT(ConnectFailure, filter);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST_FORCEASYNC_AND_NOT(ConnectAndPipe, filter);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following tests require special setup, so only run them if they're
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // explicitly specified by the filter.
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ShouldRunAllTests(filter)) {
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RUN_TEST(ConnectPermissionDenied, filter);
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RUN_TEST(ConnectPermissionGranted, filter);
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RUN_TEST(IsAllowedPermissionDenied, filter);
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RUN_TEST(IsAllowedPermissionGranted, filter);
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestBroker::TestCreate() {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Very simplistic test to make sure we can create a broker interface.
2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(raymes): All of the resources created in this file are leaked. Write
2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // a C++ wrapper for PPB_Broker_Trusted to avoid these leaks.
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource broker = broker_interface_->CreateTrusted(
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_->pp_instance());
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(broker);
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(broker_interface_->IsBrokerTrusted(0));
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(broker_interface_->IsBrokerTrusted(broker));
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test connection on invalid resource.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestBroker::TestConnectFailure() {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback.WaitForResult(broker_interface_->Connect(0,
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.GetCallback().pp_completion_callback()));
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(PP_ERROR_BADRESOURCE, callback.result());
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestBroker::TestGetHandleFailure() {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t handle = kInvalidHandle;
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test getting the handle for an invalid resource.
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(PP_ERROR_BADRESOURCE, broker_interface_->GetHandle(0, &handle));
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Connect hasn't been called so this should fail.
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource broker = broker_interface_->CreateTrusted(
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_->pp_instance());
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(broker);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(PP_ERROR_FAILED, broker_interface_->GetHandle(broker, &handle));
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestBroker::TestConnectAndPipe() {
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource broker = broker_interface_->CreateTrusted(
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_->pp_instance());
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(broker);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback.WaitForResult(broker_interface_->Connect(broker,
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.GetCallback().pp_completion_callback()));
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t handle = kInvalidHandle;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(PP_OK, broker_interface_->GetHandle(broker, &handle));
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(kInvalidHandle, handle);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformFile file = IntToPlatformFile(handle);
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(VerifyMessage(file, sizeof(kHelloMessage), kHelloMessage));
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(VerifyMessage(file, sizeof(kBrokerUnsandboxed),
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            kBrokerUnsandboxed));
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ClosePlatformFile(file));
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestBroker::TestConnectPermissionDenied() {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This assumes that the browser side is set up to deny access to the broker.
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource broker = broker_interface_->CreateTrusted(
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_->pp_instance());
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(broker);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback.WaitForResult(broker_interface_->Connect(broker,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.GetCallback().pp_completion_callback()));
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(PP_ERROR_NOACCESS, callback.result());
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestBroker::TestConnectPermissionGranted() {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This assumes that the browser side is set up to allow access to the broker.
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource broker = broker_interface_->CreateTrusted(
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_->pp_instance());
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(broker);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback.WaitForResult(broker_interface_->Connect(broker,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.GetCallback().pp_completion_callback()));
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string TestBroker::TestIsAllowedPermissionDenied() {
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_Resource broker = broker_interface_->CreateTrusted(
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      instance_->pp_instance());
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(broker);
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(PP_FALSE, broker_interface_->IsAllowed(broker));
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PASS();
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string TestBroker::TestIsAllowedPermissionGranted() {
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_Resource broker = broker_interface_->CreateTrusted(
3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      instance_->pp_instance());
3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(broker);
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(PP_TRUE, broker_interface_->IsAllowed(broker));
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PASS();
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
340