// Copyright (c) 2006-2008 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_SRC_POLICY_LOW_LEVEL_H__
#define SANDBOX_SRC_POLICY_LOW_LEVEL_H__

#include <list>

#include "base/basictypes.h"
#include "base/strings/string16.h"
#include "sandbox/win/src/ipc_tags.h"
#include "sandbox/win/src/policy_engine_params.h"
#include "sandbox/win/src/policy_engine_opcodes.h"

// Low level policy classes.
// Built on top of the PolicyOpcode and OpcodeFatory, the low level policy
// provides a way to define rules on strings and numbers but it is unaware
// of Windows specific details or how the Interceptions must be set up.
// To use these classes you construct one or more rules and add them to the
// LowLevelPolicy object like this:
//
//   PolicyRule rule1(ASK_BROKER);
//   rule1.AddStringMatch(IF, 0, L"\\\\/?/?\\c:\\*Microsoft*\\*.exe", true);
//   rule1.AddNumberMatch(IF_NOT, 1, CREATE_ALWAYS, EQUAL);
//   rule1.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL);
//
//   PolicyRule rule2(FAKE_SUCCESS);
//   rule2.AddStringMatch(IF, 0, L"\\\\/?/?\\Pipe\\Chrome.*", false));
//   rule2.AddNumberMatch(IF, 1, OPEN_EXISTING, EQUAL));
//
//   LowLevelPolicy policyGen(*policy_memory);
//   policyGen.AddRule(kNtCreateFileSvc, &rule1);
//   policyGen.AddRule(kNtCreateFileSvc, &rule2);
//   policyGen.Done();
//
// At this point (error checking omitted) the policy_memory can be copied
// to the target process where it can be evaluated.

namespace sandbox {

// TODO(cpu): Move this constant to crosscall_client.h.
const size_t kMaxServiceCount = 32;
COMPILE_ASSERT(IPC_LAST_TAG <= kMaxServiceCount, kMaxServiceCount_is_too_low);

// Defines the memory layout of the policy. This memory is filled by
// LowLevelPolicy object.
// For example:
//
//  [Service 0] --points to---\
//  [Service 1] --------------|-----\
//   ......                   |     |
//  [Service N]               |     |
//  [data_size]               |     |
//  [Policy Buffer 0] <-------/     |
//  [opcodes of]                    |
//  .......                         |
//  [Policy Buffer 1] <-------------/
//  [opcodes]
//  .......
//  .......
//  [Policy Buffer N]
//  [opcodes]
//  .......
//   <possibly unused space here>
//  .......
//  [opcode string ]
//  [opcode string ]
//  .......
//  [opcode string ]
struct PolicyGlobal {
  PolicyBuffer* entry[kMaxServiceCount];
  size_t data_size;
  PolicyBuffer data[1];
};

class PolicyRule;

// Provides the means to collect rules into a policy store (memory)
class LowLevelPolicy {
 public:
  // policy_store: must contain allocated memory and the internal
  // size fields set to correct values.
  explicit LowLevelPolicy(PolicyGlobal* policy_store)
      : policy_store_(policy_store) {
  }

  // Destroys all the policy rules.
  ~LowLevelPolicy();

  // Adds a rule to be generated when Done() is called.
  // service: The id of the service that this rule is associated with,
  // for example the 'Open Thread' service or the "Create File" service.
  // returns false on error.
  bool AddRule(int service, PolicyRule* rule);

  // Generates all the rules added with AddRule() into the memory area
  // passed on the constructor. Returns false on error.
  bool Done();

 private:
  struct RuleNode {
    const PolicyRule* rule;
    int service;
  };
  std::list<RuleNode> rules_;
  PolicyGlobal* policy_store_;
  DISALLOW_IMPLICIT_CONSTRUCTORS(LowLevelPolicy);
};

// There are 'if' rules and 'if not' comparisons
enum RuleType {
  IF = 0,
  IF_NOT = 1,
};

// Possible comparisons for numbers
enum RuleOp {
  EQUAL,
  AND,
  RANGE   // TODO(cpu): Implement this option.
};

// Provides the means to collect a set of comparisons into a single
// rule and its associated action.
class PolicyRule {
  friend class LowLevelPolicy;

 public:
  explicit PolicyRule(EvalResult action);
  PolicyRule(const PolicyRule& other);
  ~PolicyRule();

  // Adds a string comparison to the rule.
  // rule_type: possible values are IF and IF_NOT.
  // parameter: the expected index of the argument for this rule. For example
  // in a 'create file' service the file name argument can be at index 0.
  // string: is the desired matching pattern.
  // match_opts: if the pattern matching is case sensitive or not.
  bool AddStringMatch(RuleType rule_type, int16 parameter,
                      const wchar_t* string, StringMatchOptions match_opts);

  // Adds a number match comparison to the rule.
  // rule_type: possible values are IF and IF_NOT.
  // parameter: the expected index of the argument for this rule.
  // number: the value to compare the input to.
  // comparison_op: the comparison kind (equal, logical and, etc).
  bool AddNumberMatch(RuleType rule_type, int16 parameter,
                      unsigned long number, RuleOp comparison_op);

  // Returns the number of opcodes generated so far.
  size_t GetOpcodeCount() const {
    return buffer_->opcode_count;
  }

  // Called when there is no more comparisons to add. Internally it generates
  // the last opcode (the action opcode). Returns false if this operation fails.
  bool Done();

 private:
  void operator=(const PolicyRule&);
  // Called in a loop from AddStringMatch to generate the required string
  // match opcodes. rule_type, match_opts and parameter are the same as
  // in AddStringMatch.
  bool GenStringOpcode(RuleType rule_type, StringMatchOptions match_opts,
                       uint16 parameter, int state, bool last_call,
                       int* skip_count, base::string16* fragment);

  // Loop over all generated opcodes and copy them to increasing memory
  // addresses from opcode_start and copy the extra data (strings usually) into
  // decreasing addresses from data_start. Extra data is only present in the
  // string evaluation opcodes.
  bool RebindCopy(PolicyOpcode* opcode_start, size_t opcode_size,
                  char* data_start, size_t* data_size) const;
  PolicyBuffer* buffer_;
  OpcodeFactory* opcode_factory_;
  EvalResult action_;
  bool done_;
};

}  // namespace sandbox

#endif  // SANDBOX_SRC_POLICY_LOW_LEVEL_H__
