1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#import <Cocoa/Cocoa.h> 6 7#include "base/files/file_util.h" 8#include "base/files/scoped_file.h" 9#include "base/logging.h" 10#include "base/strings/sys_string_conversions.h" 11#include "content/common/sandbox_mac.h" 12#include "content/common/sandbox_mac_unittest_helper.h" 13#include "testing/gtest/include/gtest/gtest.h" 14 15#if defined(USE_OPENSSL) 16#include <openssl/rand.h> 17#include "crypto/openssl_util.h" 18#else 19#include "crypto/nss_util.h" 20#endif 21 22namespace content { 23 24//--------------------- Clipboard Sandboxing ---------------------- 25// Test case for checking sandboxing of clipboard access. 26class MacSandboxedClipboardTestCase : public MacSandboxTestCase { 27 public: 28 MacSandboxedClipboardTestCase(); 29 virtual ~MacSandboxedClipboardTestCase(); 30 31 virtual bool SandboxedTest() OVERRIDE; 32 33 virtual void SetTestData(const char* test_data) OVERRIDE; 34 private: 35 NSString* clipboard_name_; 36}; 37 38REGISTER_SANDBOX_TEST_CASE(MacSandboxedClipboardTestCase); 39 40MacSandboxedClipboardTestCase::MacSandboxedClipboardTestCase() : 41 clipboard_name_(nil) {} 42 43MacSandboxedClipboardTestCase::~MacSandboxedClipboardTestCase() { 44 [clipboard_name_ release]; 45} 46 47bool MacSandboxedClipboardTestCase::SandboxedTest() { 48 // Shouldn't be able to open the pasteboard in the sandbox. 49 50 if ([clipboard_name_ length] == 0) { 51 LOG(ERROR) << "Clipboard name is empty"; 52 return false; 53 } 54 55 NSPasteboard* pb = [NSPasteboard pasteboardWithName:clipboard_name_]; 56 if (pb != nil) { 57 LOG(ERROR) << "Was able to access named clipboard"; 58 return false; 59 } 60 61 pb = [NSPasteboard generalPasteboard]; 62 if (pb != nil) { 63 LOG(ERROR) << "Was able to access system clipboard"; 64 return false; 65 } 66 67 return true; 68} 69 70void MacSandboxedClipboardTestCase::SetTestData(const char* test_data) { 71 clipboard_name_ = [base::SysUTF8ToNSString(test_data) retain]; 72} 73 74TEST_F(MacSandboxTest, ClipboardAccess) { 75 NSPasteboard* pb = [NSPasteboard pasteboardWithUniqueName]; 76 EXPECT_EQ([[pb types] count], 0U); 77 78 std::string pasteboard_name = base::SysNSStringToUTF8([pb name]); 79 EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedClipboardTestCase", 80 pasteboard_name.c_str())); 81 82 // After executing the test, the clipboard should still be empty. 83 EXPECT_EQ([[pb types] count], 0U); 84} 85 86//--------------------- File Access Sandboxing ---------------------- 87// Test case for checking sandboxing of filesystem apis. 88class MacSandboxedFileAccessTestCase : public MacSandboxTestCase { 89 public: 90 virtual bool SandboxedTest() OVERRIDE; 91}; 92 93REGISTER_SANDBOX_TEST_CASE(MacSandboxedFileAccessTestCase); 94 95bool MacSandboxedFileAccessTestCase::SandboxedTest() { 96 base::ScopedFD fdes(HANDLE_EINTR(open("/etc/passwd", O_RDONLY))); 97 return !fdes.is_valid(); 98} 99 100TEST_F(MacSandboxTest, FileAccess) { 101 EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedFileAccessTestCase", NULL)); 102} 103 104//--------------------- /dev/urandom Sandboxing ---------------------- 105// /dev/urandom is available to any sandboxed process. 106class MacSandboxedUrandomTestCase : public MacSandboxTestCase { 107 public: 108 virtual bool SandboxedTest() OVERRIDE; 109}; 110 111REGISTER_SANDBOX_TEST_CASE(MacSandboxedUrandomTestCase); 112 113bool MacSandboxedUrandomTestCase::SandboxedTest() { 114 base::ScopedFD fdes(HANDLE_EINTR(open("/dev/urandom", O_RDONLY))); 115 116 // Opening /dev/urandom succeeds under the sandbox. 117 if (!fdes.is_valid()) 118 return false; 119 120 char buf[16]; 121 int rc = HANDLE_EINTR(read(fdes.get(), buf, sizeof(buf))); 122 return rc == sizeof(buf); 123} 124 125TEST_F(MacSandboxTest, UrandomAccess) { 126 EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedUrandomTestCase", NULL)); 127} 128 129#if defined(USE_OPENSSL) 130 131//--------------------- OpenSSL Sandboxing ---------------------- 132// Test case for checking sandboxing of OpenSSL initialization. 133class MacSandboxedOpenSSLTestCase : public MacSandboxTestCase { 134 public: 135 virtual bool SandboxedTest() OVERRIDE; 136}; 137 138REGISTER_SANDBOX_TEST_CASE(MacSandboxedOpenSSLTestCase); 139 140bool MacSandboxedOpenSSLTestCase::SandboxedTest() { 141 crypto::EnsureOpenSSLInit(); 142 143 // Ensure that RAND_bytes is functional within the sandbox. 144 uint8_t byte; 145 return RAND_bytes(&byte, 1) == 1; 146} 147 148TEST_F(MacSandboxTest, OpenSSLAccess) { 149 EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedOpenSSLTestCase", NULL)); 150} 151 152#else // !defined(USE_OPENSSL) 153 154//--------------------- NSS Sandboxing ---------------------- 155// Test case for checking sandboxing of NSS initialization. 156class MacSandboxedNSSTestCase : public MacSandboxTestCase { 157 public: 158 virtual bool SandboxedTest() OVERRIDE; 159}; 160 161REGISTER_SANDBOX_TEST_CASE(MacSandboxedNSSTestCase); 162 163bool MacSandboxedNSSTestCase::SandboxedTest() { 164 // If NSS cannot read from /dev/urandom, NSS initialization will call abort(), 165 // which will cause this test case to fail. 166 crypto::ForceNSSNoDBInit(); 167 crypto::EnsureNSSInit(); 168 return true; 169} 170 171TEST_F(MacSandboxTest, NSSAccess) { 172 EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedNSSTestCase", NULL)); 173} 174 175#endif // defined(USE_OPENSSL) 176 177} // namespace content 178