1// Copyright (c) 2006-2008 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#include "sandbox/win/src/named_pipe_policy.h"
6
7#include <string>
8
9#include "sandbox/win/src/ipc_tags.h"
10#include "sandbox/win/src/policy_engine_opcodes.h"
11#include "sandbox/win/src/policy_params.h"
12#include "sandbox/win/src/sandbox_types.h"
13
14namespace {
15
16// Creates a named pipe and duplicates the handle to 'target_process'. The
17// remaining parameters are the same as CreateNamedPipeW().
18HANDLE CreateNamedPipeHelper(HANDLE target_process, LPCWSTR pipe_name,
19                              DWORD open_mode, DWORD pipe_mode,
20                              DWORD max_instances, DWORD out_buffer_size,
21                              DWORD in_buffer_size, DWORD default_timeout,
22                              LPSECURITY_ATTRIBUTES security_attributes) {
23  HANDLE pipe = ::CreateNamedPipeW(pipe_name, open_mode, pipe_mode,
24                                   max_instances, out_buffer_size,
25                                   in_buffer_size, default_timeout,
26                                   security_attributes);
27  if (INVALID_HANDLE_VALUE == pipe)
28    return pipe;
29
30  HANDLE new_pipe;
31  if (!::DuplicateHandle(::GetCurrentProcess(), pipe,
32                         target_process, &new_pipe,
33                         0, FALSE,
34                         DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
35    return INVALID_HANDLE_VALUE;
36  }
37
38  return new_pipe;
39}
40
41}  // namespace
42
43namespace sandbox {
44
45bool NamedPipePolicy::GenerateRules(const wchar_t* name,
46                                    TargetPolicy::Semantics semantics,
47                                    LowLevelPolicy* policy) {
48  if (TargetPolicy::NAMEDPIPES_ALLOW_ANY != semantics) {
49    return false;
50  }
51  PolicyRule pipe(ASK_BROKER);
52  if (!pipe.AddStringMatch(IF, NameBased::NAME, name, CASE_INSENSITIVE)) {
53    return false;
54  }
55  if (!policy->AddRule(IPC_CREATENAMEDPIPEW_TAG, &pipe)) {
56    return false;
57  }
58  return true;
59}
60
61DWORD NamedPipePolicy::CreateNamedPipeAction(EvalResult eval_result,
62                                             const ClientInfo& client_info,
63                                             const base::string16 &name,
64                                             DWORD open_mode, DWORD pipe_mode,
65                                             DWORD max_instances,
66                                             DWORD out_buffer_size,
67                                             DWORD in_buffer_size,
68                                             DWORD default_timeout,
69                                             HANDLE* pipe) {
70  // The only action supported is ASK_BROKER which means create the pipe.
71  if (ASK_BROKER != eval_result) {
72    return ERROR_ACCESS_DENIED;
73  }
74
75  *pipe = CreateNamedPipeHelper(client_info.process, name.c_str(),
76                                open_mode, pipe_mode, max_instances,
77                                out_buffer_size, in_buffer_size,
78                                default_timeout, NULL);
79
80  if (INVALID_HANDLE_VALUE == *pipe)
81    return ERROR_ACCESS_DENIED;
82
83  return ERROR_SUCCESS;
84}
85
86}  // namespace sandbox
87