From b031bcb3297309d9d202c0f09dd9eac822deb891 Mon Sep 17 00:00:00 2001 From: Harsha Mandadi Date: Wed, 21 Sep 2022 15:01:49 -0700 Subject: [PATCH] Fixes #638. Auth logic CLI for oak use-cases. PiperOrigin-RevId: 475932707 --- .../souffle/raksha_policy_datalog_emitter.cc | 10 +++- src/ir/auth_logic/BUILD | 20 ++++++++ src/ir/auth_logic/auth_logic_prototype.sh | 51 +++++++++++++++++++ src/ir/auth_logic/souffle_emitter.h | 30 ++++++----- src/ir/auth_logic/tests/BUILD | 25 +++++++++ src/ir/auth_logic/tests/simple_query.auth | 3 ++ 6 files changed, 126 insertions(+), 13 deletions(-) create mode 100755 src/ir/auth_logic/auth_logic_prototype.sh create mode 100644 src/ir/auth_logic/tests/BUILD create mode 100755 src/ir/auth_logic/tests/simple_query.auth diff --git a/src/backends/policy_engine/souffle/raksha_policy_datalog_emitter.cc b/src/backends/policy_engine/souffle/raksha_policy_datalog_emitter.cc index 9f2bc166e..6056ea339 100644 --- a/src/backends/policy_engine/souffle/raksha_policy_datalog_emitter.cc +++ b/src/backends/policy_engine/souffle/raksha_policy_datalog_emitter.cc @@ -31,6 +31,9 @@ ABSL_FLAG(std::string, policy_rules, "", "file containing policy rules"); ABSL_FLAG(std::string, datalog_file, "", "path to policy directory"); +ABSL_FLAG(std::optional, skip_declarations, std::nullopt, + "true: Need to declare all the relations; false: No need to declare " + "pre defined relations"); constexpr char kUsageMessage[] = "This tool takes a file containing policy, converts it to datalog and " @@ -73,6 +76,10 @@ int main(int argc, char* argv[]) { LOG(ERROR) << "Error reading policy rules file: " << policy_rules.status(); return 2; } + const std::optional skip_declarations_flag = + absl::GetFlag(FLAGS_skip_declarations); + const bool skip_declarations = + skip_declarations_flag.has_value() && skip_declarations_flag.value(); std::filesystem::path datalog_file_path(absl::GetFlag(FLAGS_datalog_file)); @@ -82,7 +89,8 @@ int main(int argc, char* argv[]) { DatalogProgram datalog_program = raksha::ir::auth_logic::LoweringToDatalogPass::Lower(program); std::string datalog_policy = - raksha::ir::auth_logic::SouffleEmitter::EmitProgram(datalog_program); + raksha::ir::auth_logic::SouffleEmitter::EmitProgram(datalog_program, + skip_declarations); std::ofstream datalog_file( datalog_file_path, std::ios::out | std::ios::trunc | std::ios::binary); diff --git a/src/ir/auth_logic/BUILD b/src/ir/auth_logic/BUILD index 0d3ef13fd..99d5986b8 100644 --- a/src/ir/auth_logic/BUILD +++ b/src/ir/auth_logic/BUILD @@ -216,3 +216,23 @@ cc_test( "@absl//absl/strings", ], ) + +sh_test( + name = "authorization_logic_prototype", + srcs = [ + "auth_logic_prototype.sh", + ], + args = [ + "$(location //src/backends/policy_engine/souffle:raksha_policy_datalog_emitter)", + "$(location //src/ir/auth_logic/tests:simple_query.auth)", + ], + data = [ + "//src/backends/policy_engine/souffle:raksha_policy_datalog_emitter", + "//src/ir/auth_logic/tests:simple_query.auth", + "//third_party/mcpp", + "//third_party/souffle:main", + ], + env = { + "SOUFFLE_BIN": "$(rootpath //third_party/souffle:main)", + }, +) diff --git a/src/ir/auth_logic/auth_logic_prototype.sh b/src/ir/auth_logic/auth_logic_prototype.sh new file mode 100755 index 000000000..2dae23ab6 --- /dev/null +++ b/src/ir/auth_logic/auth_logic_prototype.sh @@ -0,0 +1,51 @@ +#!/bin/bash +# +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#------------------------------------------------------------------------------- + +function printUsageAndExit() { + echo "Usage: " + echo " auth_logic_prototype.sh \ " + echo " " + exit 1 +} + +CMD_ARG=$1 +AUTH_LOGIC_FILE_ARG=$2 +#Following args are optional +OUTPUT_SOUFFLE_FILE_ARG=${3:-$(mktemp)} +OUTPUT_QUERY_DIR_ARG=${4:-$(mktemp -d)} +#To-do make below args optional +#TEST_ONLY=${5:-0} + +$CMD_ARG --policy_rules=$AUTH_LOGIC_FILE_ARG --datalog_file=$OUTPUT_SOUFFLE_FILE_ARG --skip_declarations=true + +if [ -z "$SOUFFLE_BIN" ] +then + echo "Set SOUFFLE_BIN" + exit 1 +else + echo $SOUFFLE_BIN +fi + +PATH=$PATH:third_party/mcpp +$SOUFFLE_BIN $OUTPUT_SOUFFLE_FILE_ARG -D $OUTPUT_QUERY_DIR_ARG/ + +echo $(cat $OUTPUT_SOUFFLE_FILE_ARG) +echo $(ls $OUTPUT_QUERY_DIR_ARG) + +#Compare diff for test TEST_ONLY + diff --git a/src/ir/auth_logic/souffle_emitter.h b/src/ir/auth_logic/souffle_emitter.h index 95bc06e3b..bf6e6bafd 100644 --- a/src/ir/auth_logic/souffle_emitter.h +++ b/src/ir/auth_logic/souffle_emitter.h @@ -28,13 +28,15 @@ namespace raksha::ir::auth_logic { class SouffleEmitter { public: - static std::string EmitProgram(const datalog::Program& program) { + static std::string EmitProgram(const datalog::Program& program, + bool skip_declarations = false) { SouffleEmitter emitter; std::string body = emitter.EmitProgramBody(program); std::string outputs = emitter.EmitOutputs(program); - - std::string declarations = emitter.EmitRelationDeclarations(program); - std::string type_declarations = emitter.EmitTypeDeclarations(program); + std::string declarations = + emitter.EmitRelationDeclarations(program, skip_declarations); + std::string type_declarations = + emitter.EmitTypeDeclarations(program, skip_declarations); return absl::StrCat(std::move(type_declarations), "\n", std::move(declarations), "\n", std::move(body), "\n", std::move(outputs)); @@ -141,12 +143,14 @@ class SouffleEmitter { }); } - std::string EmitRelationDeclarations(const datalog::Program& program) { + std::string EmitRelationDeclarations(const datalog::Program& program, + const bool skip_declarations) { std::vector declaration_strings; for (const auto& declaration : program.relation_declarations()) { CHECK(!GetRelationsToNotDeclare().empty()); - if (GetRelationsToNotDeclare().find(declaration.relation_name()) != - GetRelationsToNotDeclare().end()) + if (!skip_declarations && + GetRelationsToNotDeclare().find(declaration.relation_name()) != + GetRelationsToNotDeclare().end()) continue; declaration_strings.push_back( absl::StrCat(".decl ", declaration.relation_name(), "(", @@ -156,15 +160,17 @@ class SouffleEmitter { return absl::StrJoin(declaration_strings, "\n"); } - std::string EmitTypeDeclarations(const datalog::Program& program) { + std::string EmitTypeDeclarations(const datalog::Program& program, + const bool skip_declarations) { absl::flat_hash_set type_names; for (const auto& declaration : program.relation_declarations()) { for (const auto& argument : declaration.arguments()) { - if (argument.argument_type().kind() != - datalog::ArgumentType::Kind::kCustom) + if (!skip_declarations && argument.argument_type().kind() != + datalog::ArgumentType::Kind::kCustom) continue; - if (GetRelationsToNotDeclare().find(argument.argument_type().name()) != - GetRelationsToNotDeclare().end()) + if (!skip_declarations && + GetRelationsToNotDeclare().find(argument.argument_type().name()) != + GetRelationsToNotDeclare().end()) continue; type_names.insert(absl::StrCat( ".type ", argument.argument_type().name(), " <: symbol")); diff --git a/src/ir/auth_logic/tests/BUILD b/src/ir/auth_logic/tests/BUILD new file mode 100644 index 000000000..5ec48f16f --- /dev/null +++ b/src/ir/auth_logic/tests/BUILD @@ -0,0 +1,25 @@ +#------------------------------------------------------------------------------- +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#------------------------------------------------------------------------------- +package( + default_visibility = ["//src:__subpackages__"], + features = ["layering_check"], + licenses = ["notice"], +) + +exports_files([ + "simple_query.auth", +]) diff --git a/src/ir/auth_logic/tests/simple_query.auth b/src/ir/auth_logic/tests/simple_query.auth new file mode 100755 index 000000000..fb32b38f1 --- /dev/null +++ b/src/ir/auth_logic/tests/simple_query.auth @@ -0,0 +1,3 @@ +.decl mayA(prin : Principal) +"UserA" says mayA("NotifierA"). +may_notifierA = query "UserA" says mayA(NotifierA)?