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#ifndef SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_
6#define SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_
7
8#include <windows.h>
9#include <string>
10
11#include "base/strings/string16.h"
12#include "base/win/scoped_handle.h"
13#include "sandbox/win/src/sandbox.h"
14
15namespace sandbox {
16
17// See winerror.h for details.
18#define SEVERITY_INFO_FLAGS   0x40000000
19#define SEVERITY_ERROR_FLAGS  0xC0000000
20#define CUSTOMER_CODE         0x20000000
21#define SBOX_TESTS_FACILITY   0x05B10000
22
23// All the possible error codes returned by the child process in
24// the sandbox.
25enum SboxTestResult {
26  SBOX_TEST_FIRST_RESULT = CUSTOMER_CODE | SBOX_TESTS_FACILITY,
27  SBOX_TEST_SUCCEEDED,
28  SBOX_TEST_PING_OK,
29  SBOX_TEST_FIRST_INFO = SBOX_TEST_FIRST_RESULT | SEVERITY_INFO_FLAGS,
30  SBOX_TEST_DENIED,     // Access was denied.
31  SBOX_TEST_NOT_FOUND,  // The resource was not found.
32  SBOX_TEST_FIRST_ERROR = SBOX_TEST_FIRST_RESULT | SEVERITY_ERROR_FLAGS,
33  SBOX_TEST_SECOND_ERROR,
34  SBOX_TEST_THIRD_ERROR,
35  SBOX_TEST_FOURTH_ERROR,
36  SBOX_TEST_FIFTH_ERROR,
37  SBOX_TEST_SIXTH_ERROR,
38  SBOX_TEST_SEVENTH_ERROR,
39  SBOX_TEST_INVALID_PARAMETER,
40  SBOX_TEST_FAILED_TO_RUN_TEST,
41  SBOX_TEST_FAILED_TO_EXECUTE_COMMAND,
42  SBOX_TEST_TIMED_OUT,
43  SBOX_TEST_FAILED,
44  SBOX_TEST_LAST_RESULT
45};
46
47inline bool IsSboxTestsResult(SboxTestResult result) {
48  unsigned int code = static_cast<unsigned int>(result);
49  unsigned int first = static_cast<unsigned int>(SBOX_TEST_FIRST_RESULT);
50  unsigned int last = static_cast<unsigned int>(SBOX_TEST_LAST_RESULT);
51  return (code > first) && (code < last);
52}
53
54enum SboxTestsState {
55  MIN_STATE = 1,
56  BEFORE_INIT,
57  BEFORE_REVERT,
58  AFTER_REVERT,
59  EVERY_STATE,
60  MAX_STATE
61};
62
63#define SBOX_TESTS_API __declspec(dllexport)
64#define SBOX_TESTS_COMMAND extern "C" SBOX_TESTS_API
65
66extern "C" {
67typedef int (*CommandFunction)(int argc, wchar_t **argv);
68}
69
70// Class to facilitate the launch of a test inside the sandbox.
71class TestRunner {
72 public:
73  TestRunner(JobLevel job_level, TokenLevel startup_token,
74             TokenLevel main_token);
75
76  TestRunner();
77
78  ~TestRunner();
79
80  // Adds a rule to the policy. The parameters are the same as the AddRule
81  // function in the sandbox.
82  bool AddRule(TargetPolicy::SubSystem subsystem,
83               TargetPolicy::Semantics semantics,
84               const wchar_t* pattern);
85
86  // Adds a filesystem rules with the path of a file in system32. The function
87  // appends "pattern" to "system32" and then call AddRule. Return true if the
88  // function succeeds.
89  bool AddRuleSys32(TargetPolicy::Semantics semantics, const wchar_t* pattern);
90
91  // Adds a filesystem rules to the policy. Returns true if the functions
92  // succeeds.
93  bool AddFsRule(TargetPolicy::Semantics semantics, const wchar_t* pattern);
94
95  // Starts a child process in the sandbox and ask it to run |command|. Returns
96  // a SboxTestResult. By default, the test runs AFTER_REVERT.
97  int RunTest(const wchar_t* command);
98
99  // Sets the timeout value for the child to run the command and return.
100  void SetTimeout(DWORD timeout_ms);
101
102  // Sets TestRunner to return without waiting for the process to exit.
103  void SetAsynchronous(bool is_async) { is_async_ = is_async; }
104
105  // Sets TestRunner to return without waiting for the process to exit.
106  void SetUnsandboxed(bool is_no_sandbox) { no_sandbox_ = is_no_sandbox; }
107
108  // Sets the desired state for the test to run.
109  void SetTestState(SboxTestsState desired_state);
110
111  // Sets a flag whether the process should be killed when the TestRunner is
112  // destroyed.
113  void SetKillOnDestruction(bool value) { kill_on_destruction_ = value; }
114
115  // Returns the pointers to the policy object. It can be used to modify
116  // the policy manually.
117  TargetPolicy* GetPolicy();
118
119  BrokerServices* broker() { return broker_; }
120
121  // Returns the process handle for an asynchronous test.
122  HANDLE process() { return target_process_.Get(); }
123
124  // Returns the process ID for an asynchronous test.
125  DWORD process_id() { return target_process_id_; }
126
127 private:
128  // Initializes the data in the object. Sets is_init_ to tree if the
129  // function succeeds. This is meant to be called from the constructor.
130  void Init(JobLevel job_level, TokenLevel startup_token,
131            TokenLevel main_token);
132
133  // The actual runner.
134  int InternalRunTest(const wchar_t* command);
135
136  BrokerServices* broker_;
137  TargetPolicy* policy_;
138  DWORD timeout_;
139  SboxTestsState state_;
140  bool is_init_;
141  bool is_async_;
142  bool no_sandbox_;
143  bool kill_on_destruction_;
144  base::win::ScopedHandle target_process_;
145  DWORD target_process_id_;
146};
147
148// Returns the broker services.
149BrokerServices* GetBroker();
150
151// Constructs a full path to a file inside the system32 (or syswow64) folder.
152base::string16 MakePathToSys(const wchar_t* name, bool is_obj_man_path);
153
154// Runs the given test on the target process.
155int DispatchCall(int argc, wchar_t **argv);
156
157}  // namespace sandbox
158
159#endif  // SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_
160