15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_types.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/sandbox_nt_types.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_engine_params.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_engine_opcodes.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define INIT_GLOBAL_RTL(member) \ 13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch g_nt.member = reinterpret_cast<member##Function>( \ 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetProcAddress(ntdll, #member)); \ 15c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (NULL == g_nt.member) \ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox { 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SANDBOX_INTERCEPT NtExports g_nt; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SetupNtdllImports() { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HMODULE ntdll = ::GetModuleHandle(kNtdllName); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(RtlAllocateHeap); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(RtlAnsiStringToUnicodeString); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(RtlCompareUnicodeString); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(RtlCreateHeap); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(RtlDestroyHeap); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(RtlFreeHeap); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(_strnicmp); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(strlen); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) INIT_GLOBAL_RTL(wcslen); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, ParameterSetTest) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* pv1 = reinterpret_cast<void*>(0x477EAA5); 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* pv2 = reinterpret_cast<void*>(0x987654); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet pset1 = ParamPickerMake(pv1); 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet pset2 = ParamPickerMake(pv2); 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that we can store and retrieve a void pointer: 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* result1 =0; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long result2 = 0; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pset1.Get(&result1)); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pv1 == result1); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(pset1.Get(&result2)); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pset2.Get(&result1)); 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pv2 == result1); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(pset2.Get(&result2)); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that we can store and retrieve a ulong: 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long number = 12747; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet pset3 = ParamPickerMake(number); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(pset3.Get(&result1)); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pset3.Get(&result2)); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(number, result2); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that we can store and retrieve a string: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* txt = L"S231L"; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet pset4 = ParamPickerMake(txt); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* result3 = NULL; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(pset4.Get(&result3)); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, wcscmp(txt, result3)); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, OpcodeConstraints) { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that PolicyOpcode has no virtual functions 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because these objects are copied over to other processes 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so they cannot have vtables. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(__is_polymorphic(PolicyOpcode)); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Keep developers from adding smarts to the opcodes which should 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be pretty much a bag of bytes with a OO interface. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(__has_trivial_destructor(PolicyOpcode)); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(__has_trivial_constructor(PolicyOpcode)); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(__has_trivial_copy(PolicyOpcode)); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, TrueFalseOpcodes) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* dummy = NULL; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet ppb1 = ParamPickerMake(dummy); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char memory[1024]; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpcodeFactory opcode_maker(memory, sizeof(memory)); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This opcode always evaluates to true. 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op1 = opcode_maker.MakeOpAlwaysFalse(kPolNone); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_FALSE, op1->Evaluate(&ppb1, 1, NULL)); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(op1->IsAction()); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This opcode always evaluates to false. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op2 = opcode_maker.MakeOpAlwaysTrue(kPolNone); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op2->Evaluate(&ppb1, 1, NULL)); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Nulls not allowed on the params. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_ERROR, op2->Evaluate(NULL, 0, NULL)); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_ERROR, op2->Evaluate(NULL, 1, NULL)); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // True and False opcodes do not 'require' a number of parameters 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op2->Evaluate(&ppb1, 0, NULL)); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op2->Evaluate(&ppb1, 1, NULL)); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test Inverting the logic. Note that inversion is done outside 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any particular opcode evaluation so no need to repeat for all 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // opcodes. 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op3 = opcode_maker.MakeOpAlwaysFalse(kPolNegateEval); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op3->Evaluate(&ppb1, 1, NULL)); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op4 = opcode_maker.MakeOpAlwaysTrue(kPolNegateEval); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_FALSE, op4->Evaluate(&ppb1, 1, NULL)); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that we clear the match context 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op5 = opcode_maker.MakeOpAlwaysTrue(kPolClearContext); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext context; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context.position = 1; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context.options = kPolUseOREval; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op5->Evaluate(&ppb1, 1, &context)); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, context.position); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext context2; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(context2.options, context.options); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, OpcodeMakerCase1) { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Testing that the opcode maker does not overrun the 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // supplied buffer. It should only be able to make 'count' opcodes. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* dummy = NULL; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet ppb1 = ParamPickerMake(dummy); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char memory[256]; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpcodeFactory opcode_maker(memory, sizeof(memory)); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t count = sizeof(memory) / sizeof(PolicyOpcode); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t ix =0; ix != count; ++ix) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op = opcode_maker.MakeOpAlwaysFalse(kPolNone); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL != op); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_FALSE, op->Evaluate(&ppb1, 1, NULL)); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There should be no room more another opcode: 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op1 = opcode_maker.MakeOpAlwaysFalse(kPolNone); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL == op1); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, OpcodeMakerCase2) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetupNtdllImports(); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Testing that the opcode maker does not overrun the 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // supplied buffer. It should only be able to make 'count' opcodes. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The difference with the previous test is that this opcodes allocate 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the string 'txt2' inside the same buffer. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* txt1 = L"1234"; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t txt2[] = L"123"; 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet ppb1 = ParamPickerMake(txt1); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext mc1; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char memory[256]; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpcodeFactory opcode_maker(memory, sizeof(memory)); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t count = sizeof(memory) / (sizeof(PolicyOpcode) + sizeof(txt2)); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that it does not overrun the buffer. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t ix =0; ix != count; ++ix) { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op = opcode_maker.MakeOpWStringMatch(0, txt2, 0, 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CASE_SENSITIVE, 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPolClearContext); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL != op); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op->Evaluate(&ppb1, 1, &mc1)); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // There should be no room more another opcode: 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op1 = opcode_maker.MakeOpWStringMatch(0, txt2, 0, 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CASE_SENSITIVE, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPolNone); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(NULL == op1); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, IntegerOpcodes) { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* txt = L"abcdef"; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long num1 = 42; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long num2 = 113377; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet pp_wrong1 = ParamPickerMake(txt); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet pp_num1 = ParamPickerMake(num1); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet pp_num2 = ParamPickerMake(num2); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char memory[128]; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpcodeFactory opcode_maker(memory, sizeof(memory)); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test basic match for unsigned longs 42 == 42 and 42 != 113377. 188c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch PolicyOpcode* op_m42 = opcode_maker.MakeOpNumberMatch(0, 42UL, kPolNone); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op_m42->Evaluate(&pp_num1, 1, NULL)); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_FALSE, op_m42->Evaluate(&pp_num2, 1, NULL)); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_ERROR, op_m42->Evaluate(&pp_wrong1, 1, NULL)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test basic match for void pointers. 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* vp = NULL; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet pp_num3 = ParamPickerMake(vp); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op_vp_null = opcode_maker.MakeOpVoidPtrMatch(0, NULL, 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPolNone); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op_vp_null->Evaluate(&pp_num3, 1, NULL)); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_FALSE, op_vp_null->Evaluate(&pp_num1, 1, NULL)); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_ERROR, op_vp_null->Evaluate(&pp_wrong1, 1, NULL)); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Basic range test [41 43] (inclusive). 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op_range1 = opcode_maker.MakeOpUlongMatchRange(0, 41, 43, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPolNone); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op_range1->Evaluate(&pp_num1, 1, NULL)); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_FALSE, op_range1->Evaluate(&pp_num2, 1, NULL)); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_ERROR, op_range1->Evaluate(&pp_wrong1, 1, NULL)); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, LogicalOpcodes) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char memory[128]; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpcodeFactory opcode_maker(memory, sizeof(memory)); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long num1 = 0x10100702; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet pp_num1 = ParamPickerMake(num1); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op_and1 = opcode_maker.MakeOpUlongAndMatch(0, 0x00100000, 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPolNone); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op_and1->Evaluate(&pp_num1, 1, NULL)); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op_and2 = opcode_maker.MakeOpUlongAndMatch(0, 0x00000001, 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPolNone); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_FALSE, op_and2->Evaluate(&pp_num1, 1, NULL)); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, WCharOpcodes1) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetupNtdllImports(); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* txt1 = L"the quick fox jumps over the lazy dog"; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t txt2[] = L"the quick"; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t txt3[] = L" fox jumps"; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t txt4[] = L"the lazy dog"; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t txt5[] = L"jumps over"; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t txt6[] = L"g"; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet pp_tc1 = ParamPickerMake(txt1); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char memory[512]; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpcodeFactory opcode_maker(memory, sizeof(memory)); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op1 = opcode_maker.MakeOpWStringMatch(0, txt2, 0, 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CASE_SENSITIVE, 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPolNone); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Simplest substring match from pos 0. It should be a successful match 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and the match context should be updated. 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext mc1; 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op1->Evaluate(&pp_tc1, 1, &mc1)); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(_countof(txt2) == mc1.position + 1); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Matching again should fail and the context should be unmodified. 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_FALSE, op1->Evaluate(&pp_tc1, 1, &mc1)); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(_countof(txt2) == mc1.position + 1); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Using the same match context we should continue where we left 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the previous successful match, 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op3 = opcode_maker.MakeOpWStringMatch(0, txt3, 0, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CASE_SENSITIVE, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPolNone); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op3->Evaluate(&pp_tc1, 1, &mc1)); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(_countof(txt3) + _countof(txt2) == mc1.position + 2); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We now keep on matching but now we skip 6 characters which means 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we skip the string ' over '. And we zero the match context. This is 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the primitive that we use to build '??'. 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op4 = opcode_maker.MakeOpWStringMatch(0, txt4, 6, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CASE_SENSITIVE, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPolClearContext); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op4->Evaluate(&pp_tc1, 1, &mc1)); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, mc1.position); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that we can properly match the last part of the string 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op4b = opcode_maker.MakeOpWStringMatch(0, txt4, kSeekToEnd, 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CASE_SENSITIVE, 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPolClearContext); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op4b->Evaluate(&pp_tc1, 1, &mc1)); 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, mc1.position); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test matching 'jumps over' over the entire string. This is the 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // primitive we build '*' from. 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op5 = opcode_maker.MakeOpWStringMatch(0, txt5, kSeekForward, 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CASE_SENSITIVE, kPolNone); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op5->Evaluate(&pp_tc1, 1, &mc1)); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(24, mc1.position); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that we don't match because it is not at the end of the string 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op5b = opcode_maker.MakeOpWStringMatch(0, txt5, kSeekToEnd, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CASE_SENSITIVE, 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPolNone); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_FALSE, op5b->Evaluate(&pp_tc1, 1, &mc1)); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that we function if the string does not fit. In this case we 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // try to match 'the lazy dog' against 'he lazy dog'. 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op6 = opcode_maker.MakeOpWStringMatch(0, txt4, 2, 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CASE_SENSITIVE, kPolNone); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(24, mc1.position); 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Testing matching against 'g' which should be the last char. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext mc2; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op7 = opcode_maker.MakeOpWStringMatch(0, txt6, kSeekForward, 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CASE_SENSITIVE, kPolNone); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op7->Evaluate(&pp_tc1, 1, &mc2)); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Trying to match again should fail since we are in the last char. 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This also covers a couple of boundary conditions. 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_FALSE, op7->Evaluate(&pp_tc1, 1, &mc2)); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, WCharOpcodes2) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetupNtdllImports(); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* path1 = L"c:\\documents and settings\\Microsoft\\BLAH.txt"; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t txt1[] = L"Settings\\microsoft"; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet pp_tc1 = ParamPickerMake(path1); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char memory[256]; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpcodeFactory opcode_maker(memory, sizeof(memory)); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext mc1; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Testing case-insensitive does not buy us much since it this option 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is just passed to the Microsoft API that we use normally, but just for 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // coverage, here it is: 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op1s = opcode_maker.MakeOpWStringMatch(0, txt1, kSeekForward, 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CASE_SENSITIVE, kPolNone); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op1i = opcode_maker.MakeOpWStringMatch(0, txt1, kSeekForward, 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CASE_INSENSITIVE, 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPolNone); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_FALSE, op1s->Evaluate(&pp_tc1, 1, &mc1)); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EVAL_TRUE, op1i->Evaluate(&pp_tc1, 1, &mc1)); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(35, mc1.position); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(PolicyEngineTest, ActionOpcodes) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char memory[256]; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpcodeFactory opcode_maker(memory, sizeof(memory)); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext mc1; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* dummy = NULL; 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet ppb1 = ParamPickerMake(dummy); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode* op1 = opcode_maker.MakeOpAction(ASK_BROKER, kPolNone); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(op1->IsAction()); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ASK_BROKER, op1->Evaluate(&ppb1, 1, &mc1)); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sandbox 344