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)
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define HANDLE_EINTR(x) ({ \
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  typeof(x) eintr_wrapper_result; \
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  do { \
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    eintr_wrapper_result = (x); \
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } while (eintr_wrapper_result == -1 && errno == EINTR); \
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  eintr_wrapper_result; \
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)})
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#define IGNORE_EINTR(x) ({ \
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  typeof(x) eintr_wrapper_result; \
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  do { \
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    eintr_wrapper_result = (x); \
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (eintr_wrapper_result == -1 && errno == EINTR) { \
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      eintr_wrapper_result = 0; \
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    } \
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } while (0); \
78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  eintr_wrapper_result; \
79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)})
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ReadMessage(PlatformFile file, size_t message_len, char* message) {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(message_len < std::numeric_limits<DWORD>::max());
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD read = 0;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DWORD size = static_cast<DWORD>(message_len);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ::ReadFile(file, message, size, &read, NULL) && read == size;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(message_len <
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t total_read = 0;
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (total_read < message_len) {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssize_t read = HANDLE_EINTR(::read(file, message + total_read,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       message_len - total_read));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (read <= 0)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    total_read += read;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return total_read == message_len;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool WriteMessage(PlatformFile file, size_t message_len, const char* message) {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(message_len < std::numeric_limits<DWORD>::max());
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DWORD written = 0;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const DWORD size = static_cast<DWORD>(message_len);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ::WriteFile(file, message, size, &written, NULL) && written == size;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  assert(message_len <
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  size_t total_written = 0;
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (total_written < message_len) {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ssize_t written = HANDLE_EINTR(::write(file, message + total_written,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           message_len - total_written));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (written <= 0)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    total_written += written;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return total_written == message_len;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VerifyMessage(PlatformFile file, size_t message_len, const char* message) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char* message_received = new char[message_len];
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool success = ReadMessage(file, message_len, message_received) &&
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 !::strcmp(message_received, message);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete [] message_received;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return success;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ClosePlatformFile(PlatformFile file) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !!::CloseHandle(file);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return !IGNORE_EINTR(::close(file));
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool VerifyIsUnsandboxed() {
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FILE* file = NULL;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wchar_t temp_path[MAX_PATH] = {'\0'};
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  wchar_t file_name[MAX_PATH] = {'\0'};
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!::GetTempPath(MAX_PATH, temp_path) ||
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !::GetTempFileName(temp_path, L"test_pepper_broker", 0, file_name) ||
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ::_wfopen_s(&file, file_name, L"w"))
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (::fclose(file)) {
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::DeleteFile(file_name);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !!::DeleteFile(file_name);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char file_name[] = "/tmp/test_pepper_broker_XXXXXX";
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int fd = ::mkstemp(file_name);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (-1 == fd)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (IGNORE_EINTR(::close(fd))) {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ::remove(file_name);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !::remove(file_name);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Callback in the broker when a new broker connection occurs.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32_t OnInstanceConnected(PP_Instance instance, int32_t handle) {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformFile file = IntToPlatformFile(handle);
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (file == kInvalidPlatformFileValue)
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_FAILED;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Send hello message.
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!WriteMessage(file, sizeof(kHelloMessage), kHelloMessage)) {
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ClosePlatformFile(file);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_FAILED;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify broker is not sandboxed and send result to plugin over the pipe.
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (VerifyIsUnsandboxed()) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!WriteMessage(file, sizeof(kBrokerUnsandboxed), kBrokerUnsandboxed)) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ClosePlatformFile(file);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_ERROR_FAILED;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!WriteMessage(file, sizeof(kBrokerSandboxed), kBrokerSandboxed)) {
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ClosePlatformFile(file);
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return PP_ERROR_FAILED;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!ClosePlatformFile(file))
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return PP_ERROR_FAILED;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_OK;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_EXPORT int32_t PPP_InitializeBroker(
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PP_ConnectInstance_Func* connect_instance_func) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *connect_instance_func = &OnInstanceConnected;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return PP_OK;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PP_EXPORT void PPP_ShutdownBroker() {}
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestBroker::TestBroker(TestingInstance* instance)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : TestCase(instance),
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      broker_interface_(NULL) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool TestBroker::Init() {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  broker_interface_ = static_cast<const PPB_BrokerTrusted*>(
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pp::Module::Get()->GetBrowserInterface(PPB_BROKER_TRUSTED_INTERFACE));
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return !!broker_interface_;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestBroker::RunTests(const std::string& filter) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST(Create, filter);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST(Create, filter);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST(GetHandleFailure, filter);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST_FORCEASYNC_AND_NOT(ConnectFailure, filter);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RUN_TEST_FORCEASYNC_AND_NOT(ConnectAndPipe, filter);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The following tests require special setup, so only run them if they're
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // explicitly specified by the filter.
2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!ShouldRunAllTests(filter)) {
2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RUN_TEST(ConnectPermissionDenied, filter);
2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RUN_TEST(ConnectPermissionGranted, filter);
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RUN_TEST(IsAllowedPermissionDenied, filter);
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RUN_TEST(IsAllowedPermissionGranted, filter);
2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestBroker::TestCreate() {
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Very simplistic test to make sure we can create a broker interface.
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(raymes): All of the resources created in this file are leaked. Write
2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // a C++ wrapper for PPB_Broker_Trusted to avoid these leaks.
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource broker = broker_interface_->CreateTrusted(
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_->pp_instance());
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(broker);
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_FALSE(broker_interface_->IsBrokerTrusted(0));
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(broker_interface_->IsBrokerTrusted(broker));
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test connection on invalid resource.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestBroker::TestConnectFailure() {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback.WaitForResult(broker_interface_->Connect(0,
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.GetCallback().pp_completion_callback()));
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(PP_ERROR_BADRESOURCE, callback.result());
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestBroker::TestGetHandleFailure() {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t handle = kInvalidHandle;
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test getting the handle for an invalid resource.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(PP_ERROR_BADRESOURCE, broker_interface_->GetHandle(0, &handle));
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Connect hasn't been called so this should fail.
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource broker = broker_interface_->CreateTrusted(
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_->pp_instance());
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(broker);
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(PP_ERROR_FAILED, broker_interface_->GetHandle(broker, &handle));
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestBroker::TestConnectAndPipe() {
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource broker = broker_interface_->CreateTrusted(
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_->pp_instance());
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(broker);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback.WaitForResult(broker_interface_->Connect(broker,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.GetCallback().pp_completion_callback()));
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int32_t handle = kInvalidHandle;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(PP_OK, broker_interface_->GetHandle(broker, &handle));
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_NE(kInvalidHandle, handle);
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PlatformFile file = IntToPlatformFile(handle);
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(VerifyMessage(file, sizeof(kHelloMessage), kHelloMessage));
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(VerifyMessage(file, sizeof(kBrokerUnsandboxed),
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            kBrokerUnsandboxed));
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(ClosePlatformFile(file));
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestBroker::TestConnectPermissionDenied() {
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This assumes that the browser side is set up to deny access to the broker.
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource broker = broker_interface_->CreateTrusted(
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_->pp_instance());
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(broker);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback.WaitForResult(broker_interface_->Connect(broker,
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.GetCallback().pp_completion_callback()));
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(PP_ERROR_NOACCESS, callback.result());
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string TestBroker::TestConnectPermissionGranted() {
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This assumes that the browser side is set up to allow access to the broker.
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PP_Resource broker = broker_interface_->CreateTrusted(
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      instance_->pp_instance());
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(broker);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  callback.WaitForResult(broker_interface_->Connect(broker,
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      callback.GetCallback().pp_completion_callback()));
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_CALLBACK_BEHAVIOR(callback);
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(PP_OK, callback.result());
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PASS();
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string TestBroker::TestIsAllowedPermissionDenied() {
3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_Resource broker = broker_interface_->CreateTrusted(
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      instance_->pp_instance());
3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(broker);
3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(PP_FALSE, broker_interface_->IsAllowed(broker));
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PASS();
3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string TestBroker::TestIsAllowedPermissionGranted() {
3462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PP_Resource broker = broker_interface_->CreateTrusted(
3472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      instance_->pp_instance());
3482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_TRUE(broker);
3492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ASSERT_EQ(PP_TRUE, broker_interface_->IsAllowed(broker));
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PASS();
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
353