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/file_util.h"
8#include "base/logging.h"
9#include "base/strings/sys_string_conversions.h"
10#include "content/common/sandbox_mac.h"
11#include "content/common/sandbox_mac_unittest_helper.h"
12#include "crypto/nss_util.h"
13#include "testing/gtest/include/gtest/gtest.h"
14
15namespace content {
16
17//--------------------- Clipboard Sandboxing ----------------------
18// Test case for checking sandboxing of clipboard access.
19class MacSandboxedClipboardTestCase : public MacSandboxTestCase {
20 public:
21  MacSandboxedClipboardTestCase();
22  virtual ~MacSandboxedClipboardTestCase();
23
24  virtual bool SandboxedTest() OVERRIDE;
25
26  virtual void SetTestData(const char* test_data) OVERRIDE;
27 private:
28  NSString* clipboard_name_;
29};
30
31REGISTER_SANDBOX_TEST_CASE(MacSandboxedClipboardTestCase);
32
33MacSandboxedClipboardTestCase::MacSandboxedClipboardTestCase() :
34    clipboard_name_(nil) {}
35
36MacSandboxedClipboardTestCase::~MacSandboxedClipboardTestCase() {
37  [clipboard_name_ release];
38}
39
40bool MacSandboxedClipboardTestCase::SandboxedTest() {
41  // Shouldn't be able to open the pasteboard in the sandbox.
42
43  if ([clipboard_name_ length] == 0) {
44    LOG(ERROR) << "Clipboard name is empty";
45    return false;
46  }
47
48  NSPasteboard* pb = [NSPasteboard pasteboardWithName:clipboard_name_];
49  if (pb != nil) {
50    LOG(ERROR) << "Was able to access named clipboard";
51    return false;
52  }
53
54  pb = [NSPasteboard generalPasteboard];
55  if (pb != nil) {
56    LOG(ERROR) << "Was able to access system clipboard";
57    return false;
58  }
59
60  return true;
61}
62
63void MacSandboxedClipboardTestCase::SetTestData(const char* test_data) {
64  clipboard_name_ = [base::SysUTF8ToNSString(test_data) retain];
65}
66
67TEST_F(MacSandboxTest, ClipboardAccess) {
68  NSPasteboard* pb = [NSPasteboard pasteboardWithUniqueName];
69  EXPECT_EQ([[pb types] count], 0U);
70
71  std::string pasteboard_name = base::SysNSStringToUTF8([pb name]);
72  EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedClipboardTestCase",
73                                       pasteboard_name.c_str()));
74
75  // After executing the test, the clipboard should still be empty.
76  EXPECT_EQ([[pb types] count], 0U);
77}
78
79//--------------------- File Access Sandboxing ----------------------
80// Test case for checking sandboxing of filesystem apis.
81class MacSandboxedFileAccessTestCase : public MacSandboxTestCase {
82 public:
83  virtual bool SandboxedTest() OVERRIDE;
84};
85
86REGISTER_SANDBOX_TEST_CASE(MacSandboxedFileAccessTestCase);
87
88bool MacSandboxedFileAccessTestCase::SandboxedTest() {
89  int fdes = open("/etc/passwd", O_RDONLY);
90  file_util::ScopedFD file_closer(&fdes);
91  return fdes == -1;
92}
93
94TEST_F(MacSandboxTest, FileAccess) {
95  EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedFileAccessTestCase", NULL));
96}
97
98//--------------------- /dev/urandom Sandboxing ----------------------
99// /dev/urandom is available to any sandboxed process.
100class MacSandboxedUrandomTestCase : public MacSandboxTestCase {
101 public:
102  virtual bool SandboxedTest() OVERRIDE;
103};
104
105REGISTER_SANDBOX_TEST_CASE(MacSandboxedUrandomTestCase);
106
107bool MacSandboxedUrandomTestCase::SandboxedTest() {
108  int fdes = open("/dev/urandom", O_RDONLY);
109  file_util::ScopedFD file_closer(&fdes);
110
111  // Opening /dev/urandom succeeds under the sandbox.
112  if (fdes == -1)
113    return false;
114
115  char buf[16];
116  int rc = read(fdes, buf, sizeof(buf));
117  return rc == sizeof(buf);
118}
119
120TEST_F(MacSandboxTest, UrandomAccess) {
121  EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedUrandomTestCase", NULL));
122}
123
124//--------------------- NSS Sandboxing ----------------------
125// Test case for checking sandboxing of NSS initialization.
126class MacSandboxedNSSTestCase : public MacSandboxTestCase {
127 public:
128  virtual bool SandboxedTest() OVERRIDE;
129};
130
131REGISTER_SANDBOX_TEST_CASE(MacSandboxedNSSTestCase);
132
133bool MacSandboxedNSSTestCase::SandboxedTest() {
134  // If NSS cannot read from /dev/urandom, NSS initialization will call abort(),
135  // which will cause this test case to fail.
136  crypto::ForceNSSNoDBInit();
137  crypto::EnsureNSSInit();
138  return true;
139}
140
141TEST_F(MacSandboxTest, NSSAccess) {
142  EXPECT_TRUE(RunTestInAllSandboxTypes("MacSandboxedNSSTestCase", NULL));
143}
144
145}  // namespace content
146