// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_ #define SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_ #include #include #include "base/strings/string16.h" #include "base/win/scoped_handle.h" #include "sandbox/win/src/sandbox.h" namespace sandbox { // See winerror.h for details. #define SEVERITY_INFO_FLAGS 0x40000000 #define SEVERITY_ERROR_FLAGS 0xC0000000 #define CUSTOMER_CODE 0x20000000 #define SBOX_TESTS_FACILITY 0x05B10000 // All the possible error codes returned by the child process in // the sandbox. enum SboxTestResult { SBOX_TEST_FIRST_RESULT = CUSTOMER_CODE | SBOX_TESTS_FACILITY, SBOX_TEST_SUCCEEDED, SBOX_TEST_PING_OK, SBOX_TEST_FIRST_INFO = SBOX_TEST_FIRST_RESULT | SEVERITY_INFO_FLAGS, SBOX_TEST_DENIED, // Access was denied. SBOX_TEST_NOT_FOUND, // The resource was not found. SBOX_TEST_FIRST_ERROR = SBOX_TEST_FIRST_RESULT | SEVERITY_ERROR_FLAGS, SBOX_TEST_SECOND_ERROR, SBOX_TEST_THIRD_ERROR, SBOX_TEST_FOURTH_ERROR, SBOX_TEST_FIFTH_ERROR, SBOX_TEST_SIXTH_ERROR, SBOX_TEST_SEVENTH_ERROR, SBOX_TEST_INVALID_PARAMETER, SBOX_TEST_FAILED_TO_RUN_TEST, SBOX_TEST_FAILED_TO_EXECUTE_COMMAND, SBOX_TEST_TIMED_OUT, SBOX_TEST_FAILED, SBOX_TEST_LAST_RESULT }; inline bool IsSboxTestsResult(SboxTestResult result) { unsigned int code = static_cast(result); unsigned int first = static_cast(SBOX_TEST_FIRST_RESULT); unsigned int last = static_cast(SBOX_TEST_LAST_RESULT); return (code > first) && (code < last); } enum SboxTestsState { MIN_STATE = 1, BEFORE_INIT, BEFORE_REVERT, AFTER_REVERT, EVERY_STATE, MAX_STATE }; #define SBOX_TESTS_API __declspec(dllexport) #define SBOX_TESTS_COMMAND extern "C" SBOX_TESTS_API extern "C" { typedef int (*CommandFunction)(int argc, wchar_t **argv); } // Class to facilitate the launch of a test inside the sandbox. class TestRunner { public: TestRunner(JobLevel job_level, TokenLevel startup_token, TokenLevel main_token); TestRunner(); ~TestRunner(); // Adds a rule to the policy. The parameters are the same as the AddRule // function in the sandbox. bool AddRule(TargetPolicy::SubSystem subsystem, TargetPolicy::Semantics semantics, const wchar_t* pattern); // Adds a filesystem rules with the path of a file in system32. The function // appends "pattern" to "system32" and then call AddRule. Return true if the // function succeeds. bool AddRuleSys32(TargetPolicy::Semantics semantics, const wchar_t* pattern); // Adds a filesystem rules to the policy. Returns true if the functions // succeeds. bool AddFsRule(TargetPolicy::Semantics semantics, const wchar_t* pattern); // Starts a child process in the sandbox and ask it to run |command|. Returns // a SboxTestResult. By default, the test runs AFTER_REVERT. int RunTest(const wchar_t* command); // Sets the timeout value for the child to run the command and return. void SetTimeout(DWORD timeout_ms); // Sets TestRunner to return without waiting for the process to exit. void SetAsynchronous(bool is_async) { is_async_ = is_async; } // Sets TestRunner to return without waiting for the process to exit. void SetUnsandboxed(bool is_no_sandbox) { no_sandbox_ = is_no_sandbox; } // Sets the desired state for the test to run. void SetTestState(SboxTestsState desired_state); // Sets a flag whether the process should be killed when the TestRunner is // destroyed. void SetKillOnDestruction(bool value) { kill_on_destruction_ = value; } // Returns the pointers to the policy object. It can be used to modify // the policy manually. TargetPolicy* GetPolicy(); BrokerServices* broker() { return broker_; } // Returns the process handle for an asynchronous test. HANDLE process() { return target_process_.Get(); } // Returns the process ID for an asynchronous test. DWORD process_id() { return target_process_id_; } private: // Initializes the data in the object. Sets is_init_ to tree if the // function succeeds. This is meant to be called from the constructor. void Init(JobLevel job_level, TokenLevel startup_token, TokenLevel main_token); // The actual runner. int InternalRunTest(const wchar_t* command); BrokerServices* broker_; TargetPolicy* policy_; DWORD timeout_; SboxTestsState state_; bool is_init_; bool is_async_; bool no_sandbox_; bool kill_on_destruction_; base::win::ScopedHandle target_process_; DWORD target_process_id_; }; // Returns the broker services. BrokerServices* GetBroker(); // Constructs a full path to a file inside the system32 (or syswow64) folder. base::string16 MakePathToSys(const wchar_t* name, bool is_obj_man_path); // Runs the given test on the target process. int DispatchCall(int argc, wchar_t **argv); } // namespace sandbox #endif // SANDBOX_WIN_TESTS_COMMON_CONTROLLER_H_