Rbac Matcher implementation. (#25653)

pull/25946/head
Ashitha Santhosh 4 years ago committed by GitHub
parent c0a78774f8
commit 1fb4f715db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      BUILD
  2. 59
      CMakeLists.txt
  3. 52
      build_autogenerated.yaml
  4. 3
      gRPC-Core.podspec
  5. 2
      grpc.gyp
  6. 14
      src/core/lib/security/authorization/cel_authorization_engine.cc
  7. 23
      src/core/lib/security/authorization/cel_authorization_engine.h
  8. 81
      src/core/lib/security/authorization/evaluate_args.cc
  9. 18
      src/core/lib/security/authorization/evaluate_args.h
  10. 202
      src/core/lib/security/authorization/matchers.cc
  11. 206
      src/core/lib/security/authorization/matchers.h
  12. 9
      src/core/lib/security/authorization/rbac_policy.cc
  13. 2
      src/core/lib/security/authorization/rbac_policy.h
  14. 17
      test/core/security/BUILD
  15. 454
      test/core/security/authorization_matchers_test.cc
  16. 34
      test/core/security/cel_authorization_engine_test.cc
  17. 125
      test/core/security/evaluate_args_test.cc
  18. 3
      test/core/util/BUILD
  19. 119
      test/core/util/eval_args_mock_endpoint.cc
  20. 31
      test/core/util/eval_args_mock_endpoint.h
  21. 59
      test/core/util/mock_eval_args_endpoint.h
  22. 26
      tools/run_tests/generated/tests.json

@ -2062,10 +2062,12 @@ grpc_cc_library(
name = "grpc_rbac_engine",
srcs = [
"src/core/lib/security/authorization/evaluate_args.cc",
"src/core/lib/security/authorization/matchers.cc",
"src/core/lib/security/authorization/rbac_policy.cc",
],
hdrs = [
"src/core/lib/security/authorization/evaluate_args.h",
"src/core/lib/security/authorization/matchers.h",
"src/core/lib/security/authorization/rbac_policy.h",
],
language = "c++",
@ -2096,10 +2098,10 @@ grpc_cc_library(
grpc_cc_library(
name = "grpc_cel_engine",
srcs = [
"src/core/lib/security/authorization/authorization_engine.cc",
"src/core/lib/security/authorization/cel_authorization_engine.cc",
],
hdrs = [
"src/core/lib/security/authorization/authorization_engine.h",
"src/core/lib/security/authorization/cel_authorization_engine.h",
],
external_deps = [
"absl/container:flat_hash_set",

@ -737,7 +737,7 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx alts_util_test)
add_dependencies(buildtests_cxx async_end2end_test)
add_dependencies(buildtests_cxx auth_property_iterator_test)
add_dependencies(buildtests_cxx authorization_engine_test)
add_dependencies(buildtests_cxx authorization_matchers_test)
add_dependencies(buildtests_cxx aws_request_signer_test)
add_dependencies(buildtests_cxx backoff_test)
add_dependencies(buildtests_cxx bad_streaming_id_bad_client_test)
@ -811,6 +811,7 @@ if(gRPC_BUILD_TESTS)
add_dependencies(buildtests_cxx byte_buffer_test)
add_dependencies(buildtests_cxx byte_stream_test)
add_dependencies(buildtests_cxx cancel_ares_query_test)
add_dependencies(buildtests_cxx cel_authorization_engine_test)
add_dependencies(buildtests_cxx certificate_provider_registry_test)
add_dependencies(buildtests_cxx certificate_provider_store_test)
add_dependencies(buildtests_cxx cfstream_test)
@ -2160,7 +2161,6 @@ if(gRPC_BUILD_TESTS)
add_library(grpc_test_util
test/core/util/cmdline.cc
test/core/util/eval_args_mock_endpoint.cc
test/core/util/fuzzer_util.cc
test/core/util/grpc_profiler.cc
test/core/util/histogram.cc
@ -2230,7 +2230,6 @@ if(gRPC_BUILD_TESTS)
add_library(grpc_test_util_unsecure
test/core/util/cmdline.cc
test/core/util/eval_args_mock_endpoint.cc
test/core/util/fuzzer_util.cc
test/core/util/grpc_profiler.cc
test/core/util/histogram.cc
@ -8022,16 +8021,16 @@ target_link_libraries(auth_property_iterator_test
endif()
if(gRPC_BUILD_TESTS)
add_executable(authorization_engine_test
src/core/lib/security/authorization/authorization_engine.cc
add_executable(authorization_matchers_test
src/core/lib/security/authorization/evaluate_args.cc
src/core/lib/security/authorization/matchers.cc
src/core/lib/security/authorization/rbac_policy.cc
test/core/security/authorization_engine_test.cc
test/core/security/authorization_matchers_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(authorization_engine_test
target_include_directories(authorization_matchers_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
@ -8050,10 +8049,9 @@ target_include_directories(authorization_engine_test
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(authorization_engine_test
target_link_libraries(authorization_matchers_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::flat_hash_set
grpc_test_util
)
@ -9133,6 +9131,46 @@ target_link_libraries(cancel_ares_query_test
)
endif()
if(gRPC_BUILD_TESTS)
add_executable(cel_authorization_engine_test
src/core/lib/security/authorization/cel_authorization_engine.cc
src/core/lib/security/authorization/evaluate_args.cc
src/core/lib/security/authorization/matchers.cc
src/core/lib/security/authorization/rbac_policy.cc
test/core/security/cel_authorization_engine_test.cc
third_party/googletest/googletest/src/gtest-all.cc
third_party/googletest/googlemock/src/gmock-all.cc
)
target_include_directories(cel_authorization_engine_test
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/include
${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
${_gRPC_RE2_INCLUDE_DIR}
${_gRPC_SSL_INCLUDE_DIR}
${_gRPC_UPB_GENERATED_DIR}
${_gRPC_UPB_GRPC_GENERATED_DIR}
${_gRPC_UPB_INCLUDE_DIR}
${_gRPC_XXHASH_INCLUDE_DIR}
${_gRPC_ZLIB_INCLUDE_DIR}
third_party/googletest/googletest/include
third_party/googletest/googletest
third_party/googletest/googlemock/include
third_party/googletest/googlemock
${_gRPC_PROTO_GENS_DIR}
)
target_link_libraries(cel_authorization_engine_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::flat_hash_set
grpc_test_util
)
endif()
if(gRPC_BUILD_TESTS)
@ -10282,6 +10320,7 @@ if(gRPC_BUILD_TESTS)
add_executable(evaluate_args_test
src/core/lib/security/authorization/evaluate_args.cc
src/core/lib/security/authorization/matchers.cc
src/core/lib/security/authorization/rbac_policy.cc
test/core/security/evaluate_args_test.cc
third_party/googletest/googletest/src/gtest-all.cc
@ -12724,6 +12763,7 @@ if(gRPC_BUILD_TESTS)
add_executable(rbac_translator_test
src/core/lib/security/authorization/evaluate_args.cc
src/core/lib/security/authorization/matchers.cc
src/core/lib/security/authorization/rbac_policy.cc
src/core/lib/security/authorization/rbac_translator.cc
test/core/security/rbac_translator_test.cc
@ -14500,7 +14540,6 @@ if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.pb.h
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/testing/simple_messages.grpc.pb.h
test/core/util/cmdline.cc
test/core/util/eval_args_mock_endpoint.cc
test/core/util/fuzzer_util.cc
test/core/util/grpc_profiler.cc
test/core/util/histogram.cc

@ -1469,12 +1469,12 @@ libs:
public_headers: []
headers:
- test/core/util/cmdline.h
- test/core/util/eval_args_mock_endpoint.h
- test/core/util/fuzzer_util.h
- test/core/util/grpc_profiler.h
- test/core/util/histogram.h
- test/core/util/memory_counters.h
- test/core/util/mock_endpoint.h
- test/core/util/mock_eval_args_endpoint.h
- test/core/util/parse_hexstring.h
- test/core/util/passthru_endpoint.h
- test/core/util/port.h
@ -1491,7 +1491,6 @@ libs:
- test/core/util/trickle_endpoint.h
src:
- test/core/util/cmdline.cc
- test/core/util/eval_args_mock_endpoint.cc
- test/core/util/fuzzer_util.cc
- test/core/util/grpc_profiler.cc
- test/core/util/histogram.cc
@ -1524,12 +1523,12 @@ libs:
public_headers: []
headers:
- test/core/util/cmdline.h
- test/core/util/eval_args_mock_endpoint.h
- test/core/util/fuzzer_util.h
- test/core/util/grpc_profiler.h
- test/core/util/histogram.h
- test/core/util/memory_counters.h
- test/core/util/mock_endpoint.h
- test/core/util/mock_eval_args_endpoint.h
- test/core/util/parse_hexstring.h
- test/core/util/passthru_endpoint.h
- test/core/util/port.h
@ -1545,7 +1544,6 @@ libs:
- test/core/util/trickle_endpoint.h
src:
- test/core/util/cmdline.cc
- test/core/util/eval_args_mock_endpoint.cc
- test/core/util/fuzzer_util.cc
- test/core/util/grpc_profiler.cc
- test/core/util/histogram.cc
@ -4244,27 +4242,20 @@ targets:
deps:
- grpc++_test_util
uses_polling: false
- name: authorization_engine_test
- name: authorization_matchers_test
gtest: true
build: test
language: c++
headers:
- src/core/lib/security/authorization/authorization_engine.h
- src/core/lib/security/authorization/evaluate_args.h
- src/core/lib/security/authorization/mock_cel/activation.h
- src/core/lib/security/authorization/mock_cel/cel_expr_builder_factory.h
- src/core/lib/security/authorization/mock_cel/cel_expression.h
- src/core/lib/security/authorization/mock_cel/cel_value.h
- src/core/lib/security/authorization/mock_cel/evaluator_core.h
- src/core/lib/security/authorization/mock_cel/flat_expr_builder.h
- src/core/lib/security/authorization/matchers.h
- src/core/lib/security/authorization/rbac_policy.h
src:
- src/core/lib/security/authorization/authorization_engine.cc
- src/core/lib/security/authorization/evaluate_args.cc
- src/core/lib/security/authorization/matchers.cc
- src/core/lib/security/authorization/rbac_policy.cc
- test/core/security/authorization_engine_test.cc
- test/core/security/authorization_matchers_test.cc
deps:
- absl/container:flat_hash_set
- grpc_test_util
- name: aws_request_signer_test
gtest: true
@ -4670,6 +4661,30 @@ targets:
deps:
- grpc++_test_config
- grpc++_test_util
- name: cel_authorization_engine_test
gtest: true
build: test
language: c++
headers:
- src/core/lib/security/authorization/cel_authorization_engine.h
- src/core/lib/security/authorization/evaluate_args.h
- src/core/lib/security/authorization/matchers.h
- src/core/lib/security/authorization/mock_cel/activation.h
- src/core/lib/security/authorization/mock_cel/cel_expr_builder_factory.h
- src/core/lib/security/authorization/mock_cel/cel_expression.h
- src/core/lib/security/authorization/mock_cel/cel_value.h
- src/core/lib/security/authorization/mock_cel/evaluator_core.h
- src/core/lib/security/authorization/mock_cel/flat_expr_builder.h
- src/core/lib/security/authorization/rbac_policy.h
src:
- src/core/lib/security/authorization/cel_authorization_engine.cc
- src/core/lib/security/authorization/evaluate_args.cc
- src/core/lib/security/authorization/matchers.cc
- src/core/lib/security/authorization/rbac_policy.cc
- test/core/security/cel_authorization_engine_test.cc
deps:
- absl/container:flat_hash_set
- grpc_test_util
- name: certificate_provider_registry_test
gtest: true
build: test
@ -5053,9 +5068,11 @@ targets:
language: c++
headers:
- src/core/lib/security/authorization/evaluate_args.h
- src/core/lib/security/authorization/matchers.h
- src/core/lib/security/authorization/rbac_policy.h
src:
- src/core/lib/security/authorization/evaluate_args.cc
- src/core/lib/security/authorization/matchers.cc
- src/core/lib/security/authorization/rbac_policy.cc
- test/core/security/evaluate_args_test.cc
deps:
@ -5933,10 +5950,12 @@ targets:
language: c++
headers:
- src/core/lib/security/authorization/evaluate_args.h
- src/core/lib/security/authorization/matchers.h
- src/core/lib/security/authorization/rbac_policy.h
- src/core/lib/security/authorization/rbac_translator.h
src:
- src/core/lib/security/authorization/evaluate_args.cc
- src/core/lib/security/authorization/matchers.cc
- src/core/lib/security/authorization/rbac_policy.cc
- src/core/lib/security/authorization/rbac_translator.cc
- test/core/security/rbac_translator_test.cc
@ -6513,12 +6532,12 @@ targets:
language: c++
headers:
- test/core/util/cmdline.h
- test/core/util/eval_args_mock_endpoint.h
- test/core/util/fuzzer_util.h
- test/core/util/grpc_profiler.h
- test/core/util/histogram.h
- test/core/util/memory_counters.h
- test/core/util/mock_endpoint.h
- test/core/util/mock_eval_args_endpoint.h
- test/core/util/parse_hexstring.h
- test/core/util/passthru_endpoint.h
- test/core/util/port.h
@ -6537,7 +6556,6 @@ targets:
- src/proto/grpc/testing/echo_messages.proto
- src/proto/grpc/testing/simple_messages.proto
- test/core/util/cmdline.cc
- test/core/util/eval_args_mock_endpoint.cc
- test/core/util/fuzzer_util.cc
- test/core/util/grpc_profiler.cc
- test/core/util/histogram.cc

@ -2114,8 +2114,6 @@ Pod::Spec.new do |s|
'test/core/end2end/tests/write_buffering_at_end.cc',
'test/core/util/cmdline.cc',
'test/core/util/cmdline.h',
'test/core/util/eval_args_mock_endpoint.cc',
'test/core/util/eval_args_mock_endpoint.h',
'test/core/util/fuzzer_util.cc',
'test/core/util/fuzzer_util.h',
'test/core/util/grpc_profiler.cc',
@ -2126,6 +2124,7 @@ Pod::Spec.new do |s|
'test/core/util/memory_counters.h',
'test/core/util/mock_endpoint.cc',
'test/core/util/mock_endpoint.h',
'test/core/util/mock_eval_args_endpoint.h',
'test/core/util/parse_hexstring.cc',
'test/core/util/parse_hexstring.h',
'test/core/util/passthru_endpoint.cc',

@ -1027,7 +1027,6 @@
],
'sources': [
'test/core/util/cmdline.cc',
'test/core/util/eval_args_mock_endpoint.cc',
'test/core/util/fuzzer_util.cc',
'test/core/util/grpc_profiler.cc',
'test/core/util/histogram.cc',
@ -1062,7 +1061,6 @@
],
'sources': [
'test/core/util/cmdline.cc',
'test/core/util/eval_args_mock_endpoint.cc',
'test/core/util/fuzzer_util.cc',
'test/core/util/grpc_profiler.cc',
'test/core/util/histogram.cc',

@ -16,7 +16,7 @@
#include "absl/memory/memory.h"
#include "src/core/lib/security/authorization/authorization_engine.h"
#include "src/core/lib/security/authorization/cel_authorization_engine.h"
namespace grpc_core {
@ -36,8 +36,8 @@ constexpr char kCertServerName[] = "cert_server_name";
} // namespace
std::unique_ptr<AuthorizationEngine>
AuthorizationEngine::CreateAuthorizationEngine(
std::unique_ptr<CelAuthorizationEngine>
CelAuthorizationEngine::CreateCelAuthorizationEngine(
const std::vector<envoy_config_rbac_v3_RBAC*>& rbac_policies) {
if (rbac_policies.empty() || rbac_policies.size() > 2) {
gpr_log(GPR_ERROR,
@ -52,11 +52,11 @@ AuthorizationEngine::CreateAuthorizationEngine(
policy and one allow policy, in that order.");
return nullptr;
} else {
return absl::make_unique<AuthorizationEngine>(rbac_policies);
return absl::make_unique<CelAuthorizationEngine>(rbac_policies);
}
}
AuthorizationEngine::AuthorizationEngine(
CelAuthorizationEngine::CelAuthorizationEngine(
const std::vector<envoy_config_rbac_v3_RBAC*>& rbac_policies) {
for (const auto& rbac_policy : rbac_policies) {
// Extract array of policies and store their condition fields in either
@ -90,7 +90,7 @@ AuthorizationEngine::AuthorizationEngine(
}
}
std::unique_ptr<mock_cel::Activation> AuthorizationEngine::CreateActivation(
std::unique_ptr<mock_cel::Activation> CelAuthorizationEngine::CreateActivation(
const EvaluateArgs& args) {
std::unique_ptr<mock_cel::Activation> activation;
for (const auto& elem : envoy_attributes_) {
@ -158,7 +158,7 @@ std::unique_ptr<mock_cel::Activation> AuthorizationEngine::CreateActivation(
kSpiffeId, mock_cel::CelValue::CreateStringView(spiffe_id));
}
} else if (elem == kCertServerName) {
absl::string_view cert_server_name(args.GetCertServerName());
absl::string_view cert_server_name(args.GetCommonNameInPeerCert());
if (!cert_server_name.empty()) {
activation->InsertValue(
kCertServerName,

@ -13,8 +13,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_CORE_LIB_SECURITY_AUTHORIZATION_AUTHORIZATION_ENGINE_H
#define GRPC_CORE_LIB_SECURITY_AUTHORIZATION_AUTHORIZATION_ENGINE_H
#ifndef GRPC_CORE_LIB_SECURITY_AUTHORIZATION_CEL_AUTHORIZATION_ENGINE_H
#define GRPC_CORE_LIB_SECURITY_AUTHORIZATION_CEL_AUTHORIZATION_ENGINE_H
#include <grpc/support/port_platform.h>
@ -34,7 +34,7 @@
namespace grpc_core {
// AuthorizationEngine makes an AuthorizationDecision to ALLOW or DENY the
// CelAuthorizationEngine makes an AuthorizationDecision to ALLOW or DENY the
// current action based on the condition fields in provided RBAC policies.
// The engine may be constructed with one or two policies. If two polcies,
// the first policy is deny-if-matched and the second is allow-if-matched.
@ -44,19 +44,20 @@ namespace grpc_core {
// are compatible with this engine.
//
// Example:
// AuthorizationEngine*
// auth_engine = AuthorizationEngine::CreateAuthorizationEngine(rbac_policies);
// CelAuthorizationEngine*
// auth_engine =
// CelAuthorizationEngine::CreateCelAuthorizationEngine(rbac_policies);
// auth_engine->Evaluate(evaluate_args); // returns authorization decision.
class AuthorizationEngine {
class CelAuthorizationEngine {
public:
// rbac_policies must be a vector containing either a single policy of any
// kind, or one deny policy and one allow policy, in that order.
static std::unique_ptr<AuthorizationEngine> CreateAuthorizationEngine(
static std::unique_ptr<CelAuthorizationEngine> CreateCelAuthorizationEngine(
const std::vector<envoy_config_rbac_v3_RBAC*>& rbac_policies);
// Users should use the CreateAuthorizationEngine factory function
// instead of calling the AuthorizationEngine constructor directly.
explicit AuthorizationEngine(
// Users should use the CreateCelAuthorizationEngine factory function
// instead of calling the CelAuthorizationEngine constructor directly.
explicit CelAuthorizationEngine(
const std::vector<envoy_config_rbac_v3_RBAC*>& rbac_policies);
// TODO(mywang@google.com): add an Evaluate member function.
@ -81,4 +82,4 @@ class AuthorizationEngine {
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_SECURITY_AUTHORIZATION_AUTHORIZATION_ENGINE_H */
#endif /* GRPC_CORE_LIB_SECURITY_AUTHORIZATION_CEL_AUTHORIZATION_ENGINE_H */

@ -22,6 +22,7 @@
#include "absl/strings/str_join.h"
#include "src/core/lib/gprpp/host_port.h"
#include "src/core/lib/iomgr/parse_address.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
@ -82,15 +83,18 @@ absl::optional<absl::string_view> EvaluateArgs::GetHeaderValue(
return grpc_metadata_batch_get_value(metadata_, key, concatenated_value);
}
absl::string_view EvaluateArgs::GetLocalAddress() const {
absl::string_view addr = grpc_endpoint_get_local_address(endpoint_);
size_t first_colon = addr.find(":");
size_t last_colon = addr.rfind(":");
if (first_colon == std::string::npos || last_colon == std::string::npos) {
std::string EvaluateArgs::GetLocalAddress() const {
if (endpoint_ == nullptr) {
return "";
}
absl::StatusOr<URI> uri =
URI::Parse(grpc_endpoint_get_local_address(endpoint_));
absl::string_view host;
absl::string_view port;
if (!uri.ok() || !SplitHostPort(uri->path(), &host, &port)) {
return "";
} else {
return addr.substr(first_colon + 1, last_colon - first_colon - 1);
}
return std::string(host);
}
int EvaluateArgs::GetLocalPort() const {
@ -99,22 +103,29 @@ int EvaluateArgs::GetLocalPort() const {
}
absl::StatusOr<URI> uri =
URI::Parse(grpc_endpoint_get_local_address(endpoint_));
grpc_resolved_address resolved_addr;
if (!uri.ok() || !grpc_parse_uri(*uri, &resolved_addr)) {
absl::string_view host;
absl::string_view port;
if (!uri.ok() || !SplitHostPort(uri->path(), &host, &port)) {
return 0;
}
int port_num;
if (!absl::SimpleAtoi(port, &port_num)) {
return 0;
}
return grpc_sockaddr_get_port(&resolved_addr);
return port_num;
}
absl::string_view EvaluateArgs::GetPeerAddress() const {
absl::string_view addr = grpc_endpoint_get_peer(endpoint_);
size_t first_colon = addr.find(":");
size_t last_colon = addr.rfind(":");
if (first_colon == std::string::npos || last_colon == std::string::npos) {
std::string EvaluateArgs::GetPeerAddress() const {
if (endpoint_ == nullptr) {
return "";
}
absl::StatusOr<URI> uri = URI::Parse(grpc_endpoint_get_peer(endpoint_));
absl::string_view host;
absl::string_view port;
if (!uri.ok() || !SplitHostPort(uri->path(), &host, &port)) {
return "";
} else {
return addr.substr(first_colon + 1, last_colon - first_colon - 1);
}
return std::string(host);
}
int EvaluateArgs::GetPeerPort() const {
@ -122,11 +133,16 @@ int EvaluateArgs::GetPeerPort() const {
return 0;
}
absl::StatusOr<URI> uri = URI::Parse(grpc_endpoint_get_peer(endpoint_));
grpc_resolved_address resolved_addr;
if (!uri.ok() || !grpc_parse_uri(*uri, &resolved_addr)) {
absl::string_view host;
absl::string_view port;
if (!uri.ok() || !SplitHostPort(uri->path(), &host, &port)) {
return 0;
}
int port_num;
if (!absl::SimpleAtoi(port, &port_num)) {
return 0;
}
return grpc_sockaddr_get_port(&resolved_addr);
return port_num;
}
absl::string_view EvaluateArgs::GetSpiffeId() const {
@ -142,14 +158,35 @@ absl::string_view EvaluateArgs::GetSpiffeId() const {
return absl::string_view(prop->value, prop->value_length);
}
absl::string_view EvaluateArgs::GetCertServerName() const {
absl::string_view EvaluateArgs::GetCommonNameInPeerCert() const {
if (auth_context_ == nullptr) {
return "";
}
grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name(
auth_context_, GRPC_X509_CN_PROPERTY_NAME);
const grpc_auth_property* prop = grpc_auth_property_iterator_next(&it);
if (prop == nullptr || grpc_auth_property_iterator_next(&it) != nullptr) {
if (prop == nullptr) {
return "";
}
if (grpc_auth_property_iterator_next(&it) != nullptr) {
gpr_log(GPR_DEBUG, "Multiple values found for Common Name.");
return "";
}
return absl::string_view(prop->value, prop->value_length);
}
absl::string_view EvaluateArgs::GetTransportSecurityType() const {
if (auth_context_ == nullptr) {
return "";
}
grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name(
auth_context_, GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME);
const grpc_auth_property* prop = grpc_auth_property_iterator_next(&it);
if (prop == nullptr) {
return "";
}
if (grpc_auth_property_iterator_next(&it) != nullptr) {
gpr_log(GPR_DEBUG, "Multiple values found for transport security type.");
return "";
}
return absl::string_view(prop->value, prop->value_length);

@ -50,19 +50,21 @@ class EvaluateArgs {
// string_view of that string.
absl::optional<absl::string_view> GetHeaderValue(
absl::string_view key, std::string* concatenated_value) const;
absl::string_view GetLocalAddress() const;
// TODO(ashithasantosh): Modify endpoint getters, such that per-channel data
// is constructed only once. The construction can happen in authorization
// filter's channel data. Also update methods to return string_view.
std::string GetLocalAddress() const;
int GetLocalPort() const;
absl::string_view GetPeerAddress() const;
std::string GetPeerAddress() const;
int GetPeerPort() const;
absl::string_view GetSpiffeId() const;
absl::string_view GetCertServerName() const;
// TODO(unknown): Add a getter function for source.principal
absl::string_view GetCommonNameInPeerCert() const;
absl::string_view GetTransportSecurityType() const;
private:
grpc_metadata_batch* metadata_;
grpc_auth_context* auth_context_;
grpc_endpoint* endpoint_;
grpc_metadata_batch* metadata_ = nullptr;
grpc_auth_context* auth_context_ = nullptr;
grpc_endpoint* endpoint_ = nullptr;
};
} // namespace grpc_core

@ -0,0 +1,202 @@
// Copyright 2021 gRPC authors.
//
// 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.
#include <grpc/support/port_platform.h>
#include "src/core/lib/security/authorization/matchers.h"
namespace grpc_core {
namespace {
bool AuthenticatedMatchesHelper(const EvaluateArgs& args,
const StringMatcher& matcher) {
if (args.GetTransportSecurityType() != GRPC_SSL_TRANSPORT_SECURITY_TYPE) {
// Connection is not authenticated.
return false;
}
if (matcher.string_matcher().empty()) {
// Allows any authenticated user.
return true;
}
absl::string_view spiffe_id = args.GetSpiffeId();
if (!spiffe_id.empty()) {
return matcher.Match(spiffe_id);
}
// TODO(ashithasantosh): Check principal matches DNS SAN, followed by Subject
// field from certificate. This requires updating tsi_peer to expose these
// fields.
return false;
}
} // namespace
std::unique_ptr<AuthorizationMatcher> AuthorizationMatcher::Create(
Rbac::Permission permission) {
switch (permission.type) {
case Rbac::Permission::RuleType::AND:
return absl::make_unique<AndAuthorizationMatcher>(
std::move(permission.permissions), permission.not_rule);
case Rbac::Permission::RuleType::OR:
return absl::make_unique<OrAuthorizationMatcher>(
std::move(permission.permissions), permission.not_rule);
case Rbac::Permission::RuleType::ANY:
return absl::make_unique<AlwaysAuthorizationMatcher>(permission.not_rule);
case Rbac::Permission::RuleType::HEADER:
return absl::make_unique<HeaderAuthorizationMatcher>(
std::move(permission.header_matcher), permission.not_rule);
case Rbac::Permission::RuleType::PATH:
return absl::make_unique<PathAuthorizationMatcher>(
std::move(permission.string_matcher), permission.not_rule);
case Rbac::Permission::RuleType::DEST_IP:
return absl::make_unique<IpAuthorizationMatcher>(std::move(permission.ip),
permission.not_rule);
case Rbac::Permission::RuleType::DEST_PORT:
return absl::make_unique<PortAuthorizationMatcher>(permission.port,
permission.not_rule);
case Rbac::Permission::RuleType::REQ_SERVER_NAME:
return absl::make_unique<ReqServerNameAuthorizationMatcher>(
std::move(permission.string_matcher), permission.not_rule);
}
return nullptr;
}
std::unique_ptr<AuthorizationMatcher> AuthorizationMatcher::Create(
Rbac::Principal principal) {
switch (principal.type) {
case Rbac::Principal::RuleType::AND:
return absl::make_unique<AndAuthorizationMatcher>(
std::move(principal.principals), principal.not_rule);
case Rbac::Principal::RuleType::OR:
return absl::make_unique<OrAuthorizationMatcher>(
std::move(principal.principals), principal.not_rule);
case Rbac::Principal::RuleType::ANY:
return absl::make_unique<AlwaysAuthorizationMatcher>(principal.not_rule);
case Rbac::Principal::RuleType::PRINCIPAL_NAME:
return absl::make_unique<AuthenticatedAuthorizationMatcher>(
std::move(principal.string_matcher), principal.not_rule);
case Rbac::Principal::RuleType::SOURCE_IP:
case Rbac::Principal::RuleType::DIRECT_REMOTE_IP:
case Rbac::Principal::RuleType::REMOTE_IP:
return absl::make_unique<IpAuthorizationMatcher>(std::move(principal.ip),
principal.not_rule);
case Rbac::Principal::RuleType::HEADER:
return absl::make_unique<HeaderAuthorizationMatcher>(
std::move(principal.header_matcher), principal.not_rule);
case Rbac::Principal::RuleType::PATH:
return absl::make_unique<PathAuthorizationMatcher>(
std::move(principal.string_matcher), principal.not_rule);
}
return nullptr;
}
AndAuthorizationMatcher::AndAuthorizationMatcher(
std::vector<std::unique_ptr<Rbac::Permission>> rules, bool not_rule)
: not_rule_(not_rule) {
for (auto& rule : rules) {
matchers_.push_back(AuthorizationMatcher::Create(std::move(*rule)));
}
}
AndAuthorizationMatcher::AndAuthorizationMatcher(
std::vector<std::unique_ptr<Rbac::Principal>> ids, bool not_rule)
: not_rule_(not_rule) {
for (const auto& id : ids) {
matchers_.push_back(AuthorizationMatcher::Create(std::move(*id)));
}
}
bool AndAuthorizationMatcher::Matches(const EvaluateArgs& args) const {
bool matches = true;
for (const auto& matcher : matchers_) {
if (!matcher->Matches(args)) {
matches = false;
break;
}
}
return matches != not_rule_;
}
OrAuthorizationMatcher::OrAuthorizationMatcher(
std::vector<std::unique_ptr<Rbac::Permission>> rules, bool not_rule)
: not_rule_(not_rule) {
for (const auto& rule : rules) {
matchers_.push_back(AuthorizationMatcher::Create(std::move(*rule)));
}
}
OrAuthorizationMatcher::OrAuthorizationMatcher(
std::vector<std::unique_ptr<Rbac::Principal>> ids, bool not_rule)
: not_rule_(not_rule) {
for (const auto& id : ids) {
matchers_.push_back(AuthorizationMatcher::Create(std::move(*id)));
}
}
bool OrAuthorizationMatcher::Matches(const EvaluateArgs& args) const {
bool matches = false;
for (const auto& matcher : matchers_) {
if (matcher->Matches(args)) {
matches = true;
break;
}
}
return matches != not_rule_;
}
bool HeaderAuthorizationMatcher::Matches(const EvaluateArgs& args) const {
std::string concatenated_value;
bool matches =
matcher_.Match(args.GetHeaderValue(matcher_.name(), &concatenated_value));
return matches != not_rule_;
}
// TODO(ashithasantosh): Implement IpAuthorizationMatcher::Matches.
bool IpAuthorizationMatcher::Matches(const EvaluateArgs&) const {
bool matches = false;
return matches != not_rule_;
}
bool PortAuthorizationMatcher::Matches(const EvaluateArgs& args) const {
bool matches = (port_ == args.GetLocalPort());
return matches != not_rule_;
}
bool AuthenticatedAuthorizationMatcher::Matches(
const EvaluateArgs& args) const {
bool matches = AuthenticatedMatchesHelper(args, matcher_);
return matches != not_rule_;
}
bool ReqServerNameAuthorizationMatcher::Matches(const EvaluateArgs&) const {
// Currently we do not support matching rules containing
// "requested_server_name".
bool matches = false;
return matches != not_rule_;
}
bool PathAuthorizationMatcher::Matches(const EvaluateArgs& args) const {
bool matches = false;
absl::string_view path = args.GetPath();
if (!path.empty()) {
matches = matcher_.Match(path);
}
return matches != not_rule_;
}
bool PolicyAuthorizationMatcher::Matches(const EvaluateArgs& args) const {
return permissions_->Matches(args) && principals_->Matches(args);
}
} // namespace grpc_core

@ -0,0 +1,206 @@
// Copyright 2021 gRPC authors.
//
// 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.
#ifndef GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H
#define GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H
#include <grpc/support/port_platform.h>
#include <memory>
#include "src/core/lib/matchers/matchers.h"
#include "src/core/lib/security/authorization/evaluate_args.h"
#include "src/core/lib/security/authorization/rbac_policy.h"
namespace grpc_core {
// Describes the rules for matching permission or principal.
class AuthorizationMatcher {
public:
virtual ~AuthorizationMatcher() = default;
// Returns whether or not the permission/principal matches the rules of the
// matcher.
virtual bool Matches(const EvaluateArgs& args) const = 0;
// Creates an instance of a matcher based off the rules defined in Permission
// config.
static std::unique_ptr<AuthorizationMatcher> Create(
Rbac::Permission permission);
// Creates an instance of a matcher based off the rules defined in Principal
// config.
static std::unique_ptr<AuthorizationMatcher> Create(
Rbac::Principal principal);
};
class AlwaysAuthorizationMatcher : public AuthorizationMatcher {
public:
explicit AlwaysAuthorizationMatcher(bool not_rule = false)
: not_rule_(not_rule) {}
bool Matches(const EvaluateArgs&) const override { return !not_rule_; }
private:
// Negates matching the provided permission/principal.
const bool not_rule_;
};
class AndAuthorizationMatcher : public AuthorizationMatcher {
public:
explicit AndAuthorizationMatcher(
std::vector<std::unique_ptr<Rbac::Permission>> rules,
bool not_rule = false);
explicit AndAuthorizationMatcher(
std::vector<std::unique_ptr<Rbac::Principal>> ids, bool not_rule = false);
bool Matches(const EvaluateArgs& args) const override;
private:
std::vector<std::unique_ptr<AuthorizationMatcher>> matchers_;
// Negates matching the provided permission/principal.
const bool not_rule_;
};
class OrAuthorizationMatcher : public AuthorizationMatcher {
public:
explicit OrAuthorizationMatcher(
std::vector<std::unique_ptr<Rbac::Permission>> rules,
bool not_rule = false);
explicit OrAuthorizationMatcher(
std::vector<std::unique_ptr<Rbac::Principal>> ids, bool not_rule = false);
bool Matches(const EvaluateArgs& args) const override;
private:
std::vector<std::unique_ptr<AuthorizationMatcher>> matchers_;
// Negates matching the provided permission/principal.
const bool not_rule_;
};
// TODO(ashithasantosh): Add matcher implementation for metadata field.
// Perform a match against HTTP headers.
class HeaderAuthorizationMatcher : public AuthorizationMatcher {
public:
explicit HeaderAuthorizationMatcher(HeaderMatcher matcher,
bool not_rule = false)
: matcher_(std::move(matcher)), not_rule_(not_rule) {}
bool Matches(const EvaluateArgs& args) const override;
private:
const HeaderMatcher matcher_;
// Negates matching the provided permission/principal.
const bool not_rule_;
};
// Perform a match against IP Cidr Range.
// TODO(ashithasantosh): Handle type of Ip or use seperate matchers for each
// type. Implement Match functionality, this would require updating EvaluateArgs
// getters, to return format of IP as well.
class IpAuthorizationMatcher : public AuthorizationMatcher {
public:
explicit IpAuthorizationMatcher(Rbac::CidrRange range, bool not_rule = false)
: range_(std::move(range)), not_rule_(not_rule) {}
bool Matches(const EvaluateArgs&) const override;
private:
const Rbac::CidrRange range_;
// Negates matching the provided permission/principal.
const bool not_rule_;
};
// Perform a match against port number of the destination (local) address.
class PortAuthorizationMatcher : public AuthorizationMatcher {
public:
explicit PortAuthorizationMatcher(int port, bool not_rule = false)
: port_(port), not_rule_(not_rule) {}
bool Matches(const EvaluateArgs& args) const override;
private:
const int port_;
// Negates matching the provided permission/principal.
const bool not_rule_;
};
// Matches the principal name as described in the peer certificate. Uses URI SAN
// or DNS SAN in that order, otherwise uses subject field.
class AuthenticatedAuthorizationMatcher : public AuthorizationMatcher {
public:
explicit AuthenticatedAuthorizationMatcher(StringMatcher auth,
bool not_rule = false)
: matcher_(std::move(auth)), not_rule_(not_rule) {}
bool Matches(const EvaluateArgs& args) const override;
private:
const StringMatcher matcher_;
// Negates matching the provided permission/principal.
const bool not_rule_;
};
// Perform a match against the request server from the client's connection
// request. This is typically TLS SNI. Currently unsupported.
class ReqServerNameAuthorizationMatcher : public AuthorizationMatcher {
public:
explicit ReqServerNameAuthorizationMatcher(
StringMatcher requested_server_name, bool not_rule = false)
: matcher_(std::move(requested_server_name)), not_rule_(not_rule) {}
bool Matches(const EvaluateArgs&) const override;
private:
const StringMatcher matcher_;
// Negates matching the provided permission/principal.
const bool not_rule_;
};
// Perform a match against the path header of HTTP request.
class PathAuthorizationMatcher : public AuthorizationMatcher {
public:
explicit PathAuthorizationMatcher(StringMatcher path, bool not_rule = false)
: matcher_(std::move(path)), not_rule_(not_rule) {}
bool Matches(const EvaluateArgs& args) const override;
private:
const StringMatcher matcher_;
// Negates matching the provided permission/principal.
const bool not_rule_;
};
// Performs a match for policy field in RBAC, which is a collection of
// permission and principal matchers. Policy matches iff, we find a match in one
// of its permissions and a match in one of its principals.
class PolicyAuthorizationMatcher : public AuthorizationMatcher {
public:
explicit PolicyAuthorizationMatcher(Rbac::Policy policy)
: permissions_(
AuthorizationMatcher::Create(std::move(policy.permissions))),
principals_(
AuthorizationMatcher::Create(std::move(policy.principals))) {}
bool Matches(const EvaluateArgs& args) const override;
private:
std::unique_ptr<AuthorizationMatcher> permissions_;
std::unique_ptr<AuthorizationMatcher> principals_;
};
} // namespace grpc_core
#endif // GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H

@ -56,6 +56,15 @@ std::string Rbac::ToString() const {
Rbac::CidrRange::CidrRange(std::string address_prefix, uint32_t prefix_len)
: address_prefix(std::move(address_prefix)), prefix_len(prefix_len) {}
Rbac::CidrRange::CidrRange(const Rbac::CidrRange& other)
: address_prefix(other.address_prefix), prefix_len(other.prefix_len) {}
Rbac::CidrRange& Rbac::CidrRange::operator=(const Rbac::CidrRange& other) {
address_prefix = other.address_prefix;
prefix_len = other.prefix_len;
return *this;
}
Rbac::CidrRange::CidrRange(Rbac::CidrRange&& other) noexcept
: address_prefix(std::move(other.address_prefix)),
prefix_len(other.prefix_len) {}

@ -37,6 +37,8 @@ struct Rbac {
CidrRange(CidrRange&& other) noexcept;
CidrRange& operator=(CidrRange&& other) noexcept;
CidrRange(const CidrRange& other);
CidrRange& operator=(const CidrRange& other);
std::string ToString() const;

@ -73,8 +73,8 @@ grpc_cc_test(
)
grpc_cc_test(
name = "authorization_engine_test",
srcs = ["authorization_engine_test.cc"],
name = "cel_authorization_engine_test",
srcs = ["cel_authorization_engine_test.cc"],
external_deps = ["gtest"],
language = "C++",
deps = [
@ -425,3 +425,16 @@ grpc_cc_test(
"//test/core/util:grpc_test_util",
],
)
grpc_cc_test(
name = "authorization_matchers_test",
srcs = ["authorization_matchers_test.cc"],
external_deps = ["gtest"],
language = "C++",
deps = [
"//:gpr",
"//:grpc",
"//:grpc_rbac_engine",
"//test/core/util:grpc_test_util",
],
)

@ -0,0 +1,454 @@
// Copyright 2021 gRPC authors.
//
// 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.
#include <grpc/support/port_platform.h>
#include <list>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "src/core/lib/security/authorization/evaluate_args.h"
#include "src/core/lib/security/authorization/matchers.h"
#include "test/core/util/mock_eval_args_endpoint.h"
namespace grpc_core {
class AuthorizationMatchersTest : public ::testing::Test {
protected:
void SetUp() override { grpc_metadata_batch_init(&metadata_); }
void TearDown() override { grpc_metadata_batch_destroy(&metadata_); }
void AddPairToMetadata(const char* key, const char* value) {
metadata_storage_.emplace_back();
auto& storage = metadata_storage_.back();
ASSERT_EQ(grpc_metadata_batch_add_tail(
&metadata_, &storage,
grpc_mdelem_from_slices(
grpc_slice_intern(grpc_slice_from_static_string(key)),
grpc_slice_intern(grpc_slice_from_static_string(value)))),
GRPC_ERROR_NONE);
}
void SetLocalEndpoint(absl::string_view local_uri) {
endpoint_.SetLocalAddress(local_uri);
}
void SetPeerEndpoint(absl::string_view peer_uri) {
endpoint_.SetPeer(peer_uri);
}
void AddPropertyToAuthContext(const char* name, const char* value) {
auth_context_.add_cstring_property(name, value);
}
EvaluateArgs MakeEvaluateArgs() {
return EvaluateArgs(&metadata_, &auth_context_, &endpoint_);
}
std::list<grpc_linked_mdelem> metadata_storage_;
grpc_metadata_batch metadata_;
MockEvalArgsEndpoint endpoint_{/*local_uri=*/"", /*peer_uri=*/""};
grpc_auth_context auth_context_{nullptr};
};
TEST_F(AuthorizationMatchersTest, AlwaysAuthorizationMatcher) {
EvaluateArgs args = MakeEvaluateArgs();
AlwaysAuthorizationMatcher matcher;
EXPECT_TRUE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, NotAlwaysAuthorizationMatcher) {
EvaluateArgs args = MakeEvaluateArgs();
AlwaysAuthorizationMatcher matcher(/*not_rule=*/true);
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, AndAuthorizationMatcherSuccessfulMatch) {
AddPairToMetadata("foo", "bar");
SetLocalEndpoint("ipv4:255.255.255.255:123");
EvaluateArgs args = MakeEvaluateArgs();
std::vector<std::unique_ptr<Rbac::Permission>> rules;
rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::HEADER,
HeaderMatcher::Create(/*name=*/"foo", HeaderMatcher::Type::EXACT,
/*matcher=*/"bar")
.value()));
rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::DEST_PORT, /*port=*/123));
AndAuthorizationMatcher matcher(std::move(rules));
EXPECT_TRUE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, AndAuthorizationMatcherFailedMatch) {
AddPairToMetadata("foo", "not_bar");
SetLocalEndpoint("ipv4:255.255.255.255:123");
EvaluateArgs args = MakeEvaluateArgs();
std::vector<std::unique_ptr<Rbac::Permission>> rules;
rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::HEADER,
HeaderMatcher::Create(/*name=*/"foo", HeaderMatcher::Type::EXACT,
/*matcher=*/"bar")
.value()));
rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::DEST_PORT, /*port=*/123));
AndAuthorizationMatcher matcher(std::move(rules));
// Header rule fails. Expected value "bar", got "not_bar" for key "foo".
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, NotAndAuthorizationMatcher) {
AddPairToMetadata(":path", "/expected/foo");
EvaluateArgs args = MakeEvaluateArgs();
StringMatcher string_matcher =
StringMatcher::Create(StringMatcher::Type::EXACT,
/*matcher=*/"/expected/foo",
/*case_sensitive=*/false)
.value();
std::vector<std::unique_ptr<Rbac::Permission>> ids;
ids.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::PATH, std::move(string_matcher)));
AndAuthorizationMatcher matcher(std::move(ids), /*not_rule=*/true);
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, OrAuthorizationMatcherSuccessfulMatch) {
AddPairToMetadata("foo", "bar");
SetLocalEndpoint("ipv4:255.255.255.255:123");
EvaluateArgs args = MakeEvaluateArgs();
HeaderMatcher header_matcher =
HeaderMatcher::Create(/*name=*/"foo", HeaderMatcher::Type::EXACT,
/*matcher=*/"bar")
.value();
std::vector<std::unique_ptr<Rbac::Permission>> rules;
rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::HEADER, header_matcher));
rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::DEST_PORT, /*port=*/456));
OrAuthorizationMatcher matcher(std::move(rules));
// Matches as header rule matches even though port rule fails.
EXPECT_TRUE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, OrAuthorizationMatcherFailedMatch) {
AddPairToMetadata("foo", "not_bar");
EvaluateArgs args = MakeEvaluateArgs();
std::vector<std::unique_ptr<Rbac::Permission>> rules;
rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::HEADER,
HeaderMatcher::Create(/*name=*/"foo", HeaderMatcher::Type::EXACT,
/*matcher=*/"bar")
.value()));
OrAuthorizationMatcher matcher(std::move(rules));
// Header rule fails. Expected value "bar", got "not_bar" for key "foo".
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, NotOrAuthorizationMatcher) {
AddPairToMetadata("foo", "not_bar");
EvaluateArgs args = MakeEvaluateArgs();
std::vector<std::unique_ptr<Rbac::Permission>> rules;
rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::HEADER,
HeaderMatcher::Create(/*name=*/"foo", HeaderMatcher::Type::EXACT,
/*matcher=*/"bar")
.value()));
OrAuthorizationMatcher matcher(std::move(rules), /*not_rule=*/true);
EXPECT_TRUE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, HybridAuthorizationMatcherSuccessfulMatch) {
AddPairToMetadata("foo", "bar");
SetLocalEndpoint("ipv4:255.255.255.255:123");
EvaluateArgs args = MakeEvaluateArgs();
std::vector<std::unique_ptr<Rbac::Permission>> sub_and_rules;
sub_and_rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::HEADER,
HeaderMatcher::Create(/*name=*/"foo", HeaderMatcher::Type::EXACT,
/*matcher=*/"bar")
.value()));
std::vector<std::unique_ptr<Rbac::Permission>> sub_or_rules;
sub_or_rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::DEST_PORT, /*port=*/123));
std::vector<std::unique_ptr<Rbac::Permission>> and_rules;
and_rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::AND, std::move(sub_and_rules)));
and_rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::OR, std::move(std::move(sub_or_rules))));
AndAuthorizationMatcher matcher(std::move(and_rules));
EXPECT_TRUE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, HybridAuthorizationMatcherFailedMatch) {
AddPairToMetadata("foo", "bar");
SetLocalEndpoint("ipv4:255.255.255.255:123");
EvaluateArgs args = MakeEvaluateArgs();
std::vector<std::unique_ptr<Rbac::Permission>> sub_and_rules;
sub_and_rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::HEADER,
HeaderMatcher::Create(/*name=*/"foo", HeaderMatcher::Type::EXACT,
/*matcher=*/"bar")
.value()));
sub_and_rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::HEADER,
HeaderMatcher::Create(/*name=*/"absent_key", HeaderMatcher::Type::EXACT,
/*matcher=*/"some_value")
.value()));
std::vector<std::unique_ptr<Rbac::Permission>> sub_or_rules;
sub_or_rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::DEST_PORT, /*port=*/123));
std::vector<std::unique_ptr<Rbac::Permission>> and_rules;
and_rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::AND, std::move(sub_and_rules)));
and_rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::OR, std::move(std::move(sub_or_rules))));
AndAuthorizationMatcher matcher(std::move(and_rules));
// Fails as "absent_key" header was not present.
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, PathAuthorizationMatcherSuccessfulMatch) {
AddPairToMetadata(":path", "expected/path");
EvaluateArgs args = MakeEvaluateArgs();
PathAuthorizationMatcher matcher(
StringMatcher::Create(StringMatcher::Type::EXACT,
/*matcher=*/"expected/path",
/*case_sensitive=*/false)
.value());
EXPECT_TRUE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, PathAuthorizationMatcherFailedMatch) {
AddPairToMetadata(":path", "different/path");
EvaluateArgs args = MakeEvaluateArgs();
PathAuthorizationMatcher matcher(
StringMatcher::Create(StringMatcher::Type::EXACT,
/*matcher=*/"expected/path",
/*case_sensitive=*/false)
.value());
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, NotPathAuthorizationMatcher) {
AddPairToMetadata(":path", "expected/path");
EvaluateArgs args = MakeEvaluateArgs();
PathAuthorizationMatcher matcher(
StringMatcher::Create(StringMatcher::Type::EXACT, "expected/path", false)
.value(),
/*not_rule=*/true);
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest,
PathAuthorizationMatcherFailedMatchMissingPath) {
EvaluateArgs args = MakeEvaluateArgs();
PathAuthorizationMatcher matcher(
StringMatcher::Create(StringMatcher::Type::EXACT,
/*matcher=*/"expected/path",
/*case_sensitive=*/false)
.value());
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, HeaderAuthorizationMatcherSuccessfulMatch) {
AddPairToMetadata("key123", "foo_xxx");
EvaluateArgs args = MakeEvaluateArgs();
HeaderAuthorizationMatcher matcher(
HeaderMatcher::Create(/*name=*/"key123", HeaderMatcher::Type::PREFIX,
/*matcher=*/"foo")
.value());
EXPECT_TRUE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, HeaderAuthorizationMatcherFailedMatch) {
AddPairToMetadata("key123", "foo");
EvaluateArgs args = MakeEvaluateArgs();
HeaderAuthorizationMatcher matcher(
HeaderMatcher::Create(/*name=*/"key123", HeaderMatcher::Type::EXACT,
/*matcher=*/"bar")
.value());
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest,
HeaderAuthorizationMatcherFailedMatchMultivaluedHeader) {
AddPairToMetadata("key123", "foo");
AddPairToMetadata("key123", "bar");
EvaluateArgs args = MakeEvaluateArgs();
HeaderAuthorizationMatcher matcher(
HeaderMatcher::Create(/*name=*/"key123", HeaderMatcher::Type::EXACT,
/*matcher=*/"foo")
.value());
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest,
HeaderAuthorizationMatcherFailedMatchMissingHeader) {
EvaluateArgs args = MakeEvaluateArgs();
HeaderAuthorizationMatcher matcher(
HeaderMatcher::Create(/*name=*/"key123", HeaderMatcher::Type::SUFFIX,
/*matcher=*/"foo")
.value());
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, NotHeaderAuthorizationMatcher) {
AddPairToMetadata("key123", "foo");
EvaluateArgs args = MakeEvaluateArgs();
HeaderAuthorizationMatcher matcher(
HeaderMatcher::Create(/*name=*/"key123", HeaderMatcher::Type::EXACT,
/*matcher=*/"bar")
.value(),
/*not_rule=*/true);
EXPECT_TRUE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, PortAuthorizationMatcherSuccessfulMatch) {
SetLocalEndpoint("ipv4:255.255.255.255:123");
EvaluateArgs args = MakeEvaluateArgs();
PortAuthorizationMatcher matcher(/*port=*/123);
EXPECT_TRUE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, PortAuthorizationMatcherFailedMatch) {
SetLocalEndpoint("ipv4:255.255.255.255:123");
EvaluateArgs args = MakeEvaluateArgs();
PortAuthorizationMatcher matcher(/*port=*/456);
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, NotPortAuthorizationMatcher) {
SetLocalEndpoint("ipv4:255.255.255.255:123");
EvaluateArgs args = MakeEvaluateArgs();
PortAuthorizationMatcher matcher(/*port=*/123, /*not_rule=*/true);
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest,
AuthenticatedMatcherUnAuthenticatedConnection) {
EvaluateArgs args = MakeEvaluateArgs();
AuthenticatedAuthorizationMatcher matcher(
StringMatcher::Create(StringMatcher::Type::EXACT,
/*matcher=*/"foo.com",
/*case_sensitive=*/false)
.value());
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest,
AuthenticatedMatcherAuthenticatedConnectionMatcherUnset) {
AddPropertyToAuthContext(GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
GRPC_SSL_TRANSPORT_SECURITY_TYPE);
EvaluateArgs args = MakeEvaluateArgs();
AuthenticatedAuthorizationMatcher matcher(
StringMatcher::Create(StringMatcher::Type::EXACT,
/*matcher=*/"",
/*case_sensitive=*/false)
.value());
EXPECT_TRUE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest,
AuthenticatedMatcherSuccessfulSpiffeIdMatches) {
AddPropertyToAuthContext(GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
GRPC_SSL_TRANSPORT_SECURITY_TYPE);
AddPropertyToAuthContext(GRPC_PEER_SPIFFE_ID_PROPERTY_NAME,
"spiffe://foo.abc");
EvaluateArgs args = MakeEvaluateArgs();
AuthenticatedAuthorizationMatcher matcher(
StringMatcher::Create(StringMatcher::Type::EXACT,
/*matcher=*/"spiffe://foo.abc",
/*case_sensitive=*/false)
.value());
EXPECT_TRUE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, AuthenticatedMatcherFailedSpiffeIdMatches) {
AddPropertyToAuthContext(GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
GRPC_SSL_TRANSPORT_SECURITY_TYPE);
AddPropertyToAuthContext(GRPC_PEER_SPIFFE_ID_PROPERTY_NAME,
"spiffe://bar.abc");
EvaluateArgs args = MakeEvaluateArgs();
AuthenticatedAuthorizationMatcher matcher(
StringMatcher::Create(StringMatcher::Type::EXACT,
/*matcher=*/"spiffe://foo.abc",
/*case_sensitive=*/false)
.value());
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, AuthenticatedMatcherFailedNothingMatches) {
AddPropertyToAuthContext(GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
GRPC_SSL_TRANSPORT_SECURITY_TYPE);
EvaluateArgs args = MakeEvaluateArgs();
AuthenticatedAuthorizationMatcher matcher(
StringMatcher::Create(StringMatcher::Type::EXACT,
/*matcher=*/"foo",
/*case_sensitive=*/false)
.value());
EXPECT_FALSE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, NotAuthenticatedMatcher) {
AddPropertyToAuthContext(GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
GRPC_SSL_TRANSPORT_SECURITY_TYPE);
EvaluateArgs args = MakeEvaluateArgs();
AuthenticatedAuthorizationMatcher matcher(
StringMatcher::Create(StringMatcher::Type::EXACT, /*matcher=*/"foo",
/*case_sensitive=*/false)
.value(),
/*not_rule=*/true);
EXPECT_TRUE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, PolicyAuthorizationMatcherSuccessfulMatch) {
AddPairToMetadata("key123", "foo");
EvaluateArgs args = MakeEvaluateArgs();
std::vector<std::unique_ptr<Rbac::Permission>> rules;
rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::HEADER,
HeaderMatcher::Create(/*name=*/"key123", HeaderMatcher::Type::EXACT,
/*matcher=*/"foo")
.value()));
PolicyAuthorizationMatcher matcher(Rbac::Policy(
Rbac::Permission(Rbac::Permission::RuleType::OR, std::move(rules)),
Rbac::Principal(Rbac::Principal::RuleType::ANY)));
EXPECT_TRUE(matcher.Matches(args));
}
TEST_F(AuthorizationMatchersTest, PolicyAuthorizationMatcherFailedMatch) {
AddPairToMetadata("key123", "foo");
EvaluateArgs args = MakeEvaluateArgs();
std::vector<std::unique_ptr<Rbac::Permission>> rules;
rules.push_back(absl::make_unique<Rbac::Permission>(
Rbac::Permission::RuleType::HEADER,
HeaderMatcher::Create(/*name=*/"key123", HeaderMatcher::Type::EXACT,
/*matcher=*/"bar")
.value()));
PolicyAuthorizationMatcher matcher(Rbac::Policy(
Rbac::Permission(Rbac::Permission::RuleType::OR, std::move(rules)),
Rbac::Principal(Rbac::Principal::RuleType::ANY)));
EXPECT_FALSE(matcher.Matches(args));
}
} // namespace grpc_core
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
grpc_init();
int ret = RUN_ALL_TESTS();
grpc_shutdown();
return ret;
}

@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
#include "src/core/lib/security/authorization/authorization_engine.h"
#include "src/core/lib/security/authorization/cel_authorization_engine.h"
#include <gtest/gtest.h>
namespace grpc_core {
class AuthorizationEngineTest : public ::testing::Test {
class CelAuthorizationEngineTest : public ::testing::Test {
protected:
void SetUp() override {
deny_policy_ = envoy_config_rbac_v3_RBAC_new(arena_.ptr());
@ -31,43 +31,43 @@ class AuthorizationEngineTest : public ::testing::Test {
envoy_config_rbac_v3_RBAC* allow_policy_;
};
TEST_F(AuthorizationEngineTest, CreateEngineSuccessOnePolicy) {
TEST_F(CelAuthorizationEngineTest, CreateEngineSuccessOnePolicy) {
std::vector<envoy_config_rbac_v3_RBAC*> policies{allow_policy_};
std::unique_ptr<AuthorizationEngine> engine =
AuthorizationEngine::CreateAuthorizationEngine(policies);
std::unique_ptr<CelAuthorizationEngine> engine =
CelAuthorizationEngine::CreateCelAuthorizationEngine(policies);
EXPECT_NE(engine, nullptr)
<< "Error: Failed to create an AuthorizationEngine with one policy.";
}
TEST_F(AuthorizationEngineTest, CreateEngineSuccessTwoPolicies) {
TEST_F(CelAuthorizationEngineTest, CreateEngineSuccessTwoPolicies) {
std::vector<envoy_config_rbac_v3_RBAC*> policies{deny_policy_, allow_policy_};
std::unique_ptr<AuthorizationEngine> engine =
AuthorizationEngine::CreateAuthorizationEngine(policies);
std::unique_ptr<CelAuthorizationEngine> engine =
CelAuthorizationEngine::CreateCelAuthorizationEngine(policies);
EXPECT_NE(engine, nullptr)
<< "Error: Failed to create an AuthorizationEngine with two policies.";
}
TEST_F(AuthorizationEngineTest, CreateEngineFailNoPolicies) {
TEST_F(CelAuthorizationEngineTest, CreateEngineFailNoPolicies) {
std::vector<envoy_config_rbac_v3_RBAC*> policies{};
std::unique_ptr<AuthorizationEngine> engine =
AuthorizationEngine::CreateAuthorizationEngine(policies);
std::unique_ptr<CelAuthorizationEngine> engine =
CelAuthorizationEngine::CreateCelAuthorizationEngine(policies);
EXPECT_EQ(engine, nullptr)
<< "Error: Created an AuthorizationEngine without policies.";
}
TEST_F(AuthorizationEngineTest, CreateEngineFailTooManyPolicies) {
TEST_F(CelAuthorizationEngineTest, CreateEngineFailTooManyPolicies) {
std::vector<envoy_config_rbac_v3_RBAC*> policies{deny_policy_, allow_policy_,
deny_policy_};
std::unique_ptr<AuthorizationEngine> engine =
AuthorizationEngine::CreateAuthorizationEngine(policies);
std::unique_ptr<CelAuthorizationEngine> engine =
CelAuthorizationEngine::CreateCelAuthorizationEngine(policies);
EXPECT_EQ(engine, nullptr)
<< "Error: Created an AuthorizationEngine with more than two policies.";
}
TEST_F(AuthorizationEngineTest, CreateEngineFailWrongPolicyOrder) {
TEST_F(CelAuthorizationEngineTest, CreateEngineFailWrongPolicyOrder) {
std::vector<envoy_config_rbac_v3_RBAC*> policies{allow_policy_, deny_policy_};
std::unique_ptr<AuthorizationEngine> engine =
AuthorizationEngine::CreateAuthorizationEngine(policies);
std::unique_ptr<CelAuthorizationEngine> engine =
CelAuthorizationEngine::CreateCelAuthorizationEngine(policies);
EXPECT_EQ(engine, nullptr) << "Error: Created an AuthorizationEngine with "
"policies in the wrong order.";
}

@ -20,50 +20,75 @@
#include "absl/strings/string_view.h"
#include "src/core/lib/security/authorization/evaluate_args.h"
#include "test/core/util/eval_args_mock_endpoint.h"
#include "test/core/util/mock_eval_args_endpoint.h"
#include "test/core/util/test_config.h"
namespace grpc_core {
class EvaluateArgsTest : public ::testing::Test {
protected:
void SetUp() override {
local_address_ = "255.255.255.255";
peer_address_ = "128.128.128.128";
local_port_ = 413;
peer_port_ = 314;
endpoint_ = CreateEvalArgsMockEndpoint(local_address_.c_str(), local_port_,
peer_address_.c_str(), peer_port_);
evaluate_args_ =
absl::make_unique<EvaluateArgs>(nullptr, nullptr, endpoint_);
}
void TearDown() override { grpc_endpoint_destroy(endpoint_); }
grpc_endpoint* endpoint_;
std::unique_ptr<EvaluateArgs> evaluate_args_;
std::string local_address_;
std::string peer_address_;
int local_port_;
int peer_port_;
};
namespace {
TEST_F(EvaluateArgsTest, TestEvaluateArgsLocalAddress) {
absl::string_view src_address = evaluate_args_->GetLocalAddress();
EXPECT_EQ(src_address, local_address_);
constexpr char kIpv4LocalUri[] = "ipv4:255.255.255.255:123";
constexpr char kIpv4LocalAddress[] = "255.255.255.255";
constexpr int kIpv4LocalPort = 123;
constexpr char kIpv4PeerUri[] = "ipv4:128.128.128.128:321";
constexpr char kIpv4PeerAddress[] = "128.128.128.128";
constexpr int kIpv4PeerPort = 321;
constexpr char kIpv6LocalUri[] =
"ipv6:[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:456";
constexpr char kIpv6LocalAddress[] = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
constexpr int kIpv6LocalPort = 456;
constexpr char kIpv6PeerUri[] = "ipv6:[2001:db8::1]:654";
constexpr char kIpv6PeerAddress[] = "2001:db8::1";
constexpr int kIpv6PeerPort = 654;
} // namespace
TEST(EvaluateArgsEndpointTest, TestEvaluateArgsIpv4LocalAddress) {
MockEvalArgsEndpoint endpoint(kIpv4LocalUri, kIpv4PeerUri);
EvaluateArgs args(nullptr, nullptr, &endpoint);
EXPECT_EQ(args.GetLocalAddress(), kIpv4LocalAddress);
}
TEST(EvaluateArgsEndpointTest, TestEvaluateArgsIpv4LocalPort) {
MockEvalArgsEndpoint endpoint(kIpv4LocalUri, kIpv4PeerUri);
EvaluateArgs args(nullptr, nullptr, &endpoint);
EXPECT_EQ(args.GetLocalPort(), kIpv4LocalPort);
}
TEST(EvaluateArgsEndpointTest, TestEvaluateArgsIpv4PeerAddress) {
MockEvalArgsEndpoint endpoint(kIpv4LocalUri, kIpv4PeerUri);
EvaluateArgs args(nullptr, nullptr, &endpoint);
EXPECT_EQ(args.GetPeerAddress(), kIpv4PeerAddress);
}
TEST(EvaluateArgsEndpointTest, TestEvaluateArgsIpv4PeerPort) {
MockEvalArgsEndpoint endpoint(kIpv4LocalUri, kIpv4PeerUri);
EvaluateArgs args(nullptr, nullptr, &endpoint);
EXPECT_EQ(args.GetPeerPort(), kIpv4PeerPort);
}
TEST(EvaluateArgsEndpointTest, TestEvaluateArgsIpv6LocalAddress) {
MockEvalArgsEndpoint endpoint(kIpv6LocalUri, kIpv6PeerUri);
EvaluateArgs args(nullptr, nullptr, &endpoint);
EXPECT_EQ(args.GetLocalAddress(), kIpv6LocalAddress);
}
TEST_F(EvaluateArgsTest, TestEvaluateArgsLocalPort) {
int src_port = evaluate_args_->GetLocalPort();
EXPECT_EQ(src_port, local_port_);
TEST(EvaluateArgsEndpointTest, TestEvaluateArgsIpv6LocalPort) {
MockEvalArgsEndpoint endpoint(kIpv6LocalUri, kIpv6PeerUri);
EvaluateArgs args(nullptr, nullptr, &endpoint);
EXPECT_EQ(args.GetLocalPort(), kIpv6LocalPort);
}
TEST_F(EvaluateArgsTest, TestEvaluateArgsPeerAddress) {
absl::string_view dest_address = evaluate_args_->GetPeerAddress();
EXPECT_EQ(dest_address, peer_address_);
TEST(EvaluateArgsEndpointTest, TestEvaluateArgsIpv6PeerAddress) {
MockEvalArgsEndpoint endpoint(kIpv6LocalUri, kIpv6PeerUri);
EvaluateArgs args(nullptr, nullptr, &endpoint);
EXPECT_EQ(args.GetPeerAddress(), kIpv6PeerAddress);
}
TEST_F(EvaluateArgsTest, TestEvaluateArgsPeerPort) {
int dest_port = evaluate_args_->GetPeerPort();
EXPECT_EQ(dest_port, peer_port_);
TEST(EvaluateArgsEndpointTest, TestEvaluateArgsIpv6PeerPort) {
MockEvalArgsEndpoint endpoint(kIpv6LocalUri, kIpv6PeerUri);
EvaluateArgs args(nullptr, nullptr, &endpoint);
EXPECT_EQ(args.GetPeerPort(), kIpv6PeerPort);
}
TEST(EvaluateArgsMetadataTest, HandlesNullMetadata) {
@ -198,14 +223,15 @@ TEST(EvaluateArgsMetadataTest, GetHeaderValueSuccess) {
TEST(EvaluateArgsAuthContextTest, HandlesNullAuthContext) {
EvaluateArgs eval_args(nullptr, nullptr, nullptr);
EXPECT_EQ(eval_args.GetSpiffeId(), nullptr);
EXPECT_EQ(eval_args.GetCertServerName(), nullptr);
EXPECT_EQ(eval_args.GetCommonNameInPeerCert(), nullptr);
EXPECT_EQ(eval_args.GetTransportSecurityType(), nullptr);
}
TEST(EvaluateArgsAuthContextTest, HandlesEmptyAuthCtx) {
grpc_auth_context auth_context(nullptr);
EvaluateArgs eval_args(nullptr, &auth_context, nullptr);
EXPECT_EQ(eval_args.GetSpiffeId(), nullptr);
EXPECT_EQ(eval_args.GetCertServerName(), nullptr);
EXPECT_EQ(eval_args.GetCommonNameInPeerCert(), nullptr);
}
TEST(EvaluateArgsAuthContextTest, GetSpiffeIdSuccessOneProperty) {
@ -224,20 +250,41 @@ TEST(EvaluateArgsAuthContextTest, GetSpiffeIdFailDuplicateProperty) {
EXPECT_EQ(eval_args.GetSpiffeId(), nullptr);
}
TEST(EvaluateArgsAuthContextTest, GetCertServerNameSuccessOneProperty) {
TEST(EvaluateArgsAuthContextTest, GetCommonNameInPeerCertSuccessOneProperty) {
grpc_auth_context auth_context(nullptr);
const char* kServer = "server";
auth_context.add_cstring_property(GRPC_X509_CN_PROPERTY_NAME, kServer);
EvaluateArgs eval_args(nullptr, &auth_context, nullptr);
EXPECT_EQ(eval_args.GetCertServerName(), kServer);
EXPECT_EQ(eval_args.GetCommonNameInPeerCert(), kServer);
}
TEST(EvaluateArgsAuthContextTest, GetCertServerNameFailDuplicateProperty) {
TEST(EvaluateArgsAuthContextTest,
GetCommonNameInPeerCertFailDuplicateProperty) {
grpc_auth_context auth_context(nullptr);
auth_context.add_cstring_property(GRPC_X509_CN_PROPERTY_NAME, "server1");
auth_context.add_cstring_property(GRPC_X509_CN_PROPERTY_NAME, "server2");
EvaluateArgs eval_args(nullptr, &auth_context, nullptr);
EXPECT_EQ(eval_args.GetCertServerName(), nullptr);
EXPECT_EQ(eval_args.GetCommonNameInPeerCert(), nullptr);
}
TEST(EvaluateArgsAuthContextTest, GetTransportSecurityTypeSuccessOneProperty) {
grpc_auth_context auth_context(nullptr);
const char* kType = "ssl";
auth_context.add_cstring_property(GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
kType);
EvaluateArgs eval_args(nullptr, &auth_context, nullptr);
EXPECT_EQ(eval_args.GetTransportSecurityType(), kType);
}
TEST(EvaluateArgsAuthContextTest,
GetTransportSecurityTypeFailDuplicateProperty) {
grpc_auth_context auth_context(nullptr);
auth_context.add_cstring_property(GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
"type1");
auth_context.add_cstring_property(GRPC_TRANSPORT_SECURITY_TYPE_PROPERTY_NAME,
"type2");
EvaluateArgs eval_args(nullptr, &auth_context, nullptr);
EXPECT_EQ(eval_args.GetTransportSecurityType(), nullptr);
}
} // namespace grpc_core

@ -25,7 +25,6 @@ grpc_cc_library(
name = "grpc_test_util_base",
srcs = [
"cmdline.cc",
"eval_args_mock_endpoint.cc",
"fuzzer_util.cc",
"grpc_profiler.cc",
"histogram.cc",
@ -48,12 +47,12 @@ grpc_cc_library(
],
hdrs = [
"cmdline.h",
"eval_args_mock_endpoint.h",
"fuzzer_util.h",
"grpc_profiler.h",
"histogram.h",
"memory_counters.h",
"mock_endpoint.h",
"mock_eval_args_endpoint.h",
"parse_hexstring.h",
"passthru_endpoint.h",
"port.h",

@ -1,119 +0,0 @@
// Copyright 2020 gRPC authors.
//
// 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.
#include <grpc/support/port_platform.h>
#include "test/core/util/eval_args_mock_endpoint.h"
#include <inttypes.h>
#include <string>
#include "absl/strings/str_format.h"
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
namespace grpc_core {
class EvalArgsMockEndpoint {
public:
EvalArgsMockEndpoint(absl::string_view local_uri, absl::string_view peer_uri)
: local_address_(local_uri), peer_(peer_uri) {
base_.vtable = &vtable_;
}
grpc_endpoint* base() const { return const_cast<grpc_endpoint*>(&base_); }
static void Read(grpc_endpoint* /*ep*/, grpc_slice_buffer* /*slices*/,
grpc_closure* /*cb*/, bool /*unused*/) {}
static void Write(grpc_endpoint* /*ep*/, grpc_slice_buffer* /*slices*/,
grpc_closure* /*cb*/, void* /*unused*/) {}
static void AddToPollset(grpc_endpoint* /*ep*/, grpc_pollset* /*unused*/) {}
static void AddToPollsetSet(grpc_endpoint* /*ep*/,
grpc_pollset_set* /*unused*/) {}
static void DeleteFromPollsetSet(grpc_endpoint* /*ep*/,
grpc_pollset_set* /*unused*/) {}
static void Shutdown(grpc_endpoint* /*ep*/, grpc_error* /*why*/) {}
static void Destroy(grpc_endpoint* ep) {
EvalArgsMockEndpoint* m = reinterpret_cast<EvalArgsMockEndpoint*>(ep);
delete m;
}
static absl::string_view GetPeer(grpc_endpoint* ep) {
EvalArgsMockEndpoint* m = reinterpret_cast<EvalArgsMockEndpoint*>(ep);
return m->peer_;
}
static absl::string_view GetLocalAddress(grpc_endpoint* ep) {
EvalArgsMockEndpoint* m = reinterpret_cast<EvalArgsMockEndpoint*>(ep);
return m->local_address_;
}
static grpc_resource_user* GetResourceUser(grpc_endpoint* /*ep*/) {
return nullptr;
}
static int GetFd(grpc_endpoint* /*unused*/) { return -1; }
static bool CanTrackErr(grpc_endpoint* /*unused*/) { return false; }
private:
static constexpr grpc_endpoint_vtable vtable_ = {
EvalArgsMockEndpoint::Read,
EvalArgsMockEndpoint::Write,
EvalArgsMockEndpoint::AddToPollset,
EvalArgsMockEndpoint::AddToPollsetSet,
EvalArgsMockEndpoint::DeleteFromPollsetSet,
EvalArgsMockEndpoint::Shutdown,
EvalArgsMockEndpoint::Destroy,
EvalArgsMockEndpoint::GetResourceUser,
EvalArgsMockEndpoint::GetPeer,
EvalArgsMockEndpoint::GetLocalAddress,
EvalArgsMockEndpoint::GetFd,
EvalArgsMockEndpoint::CanTrackErr};
grpc_endpoint base_;
std::string local_address_;
std::string peer_;
};
constexpr grpc_endpoint_vtable EvalArgsMockEndpoint::vtable_;
namespace {
std::string NameAndPortToURI(const char* addr, const int port) {
grpc_sockaddr_in address;
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_port = htons(port);
inet_pton(AF_INET, addr, &address.sin_addr);
grpc_resolved_address resolved;
memset(&resolved, 0, sizeof(resolved));
memcpy(resolved.addr, &address, sizeof(address));
resolved.len = sizeof(address);
return grpc_sockaddr_to_uri(&resolved);
}
} // namespace
grpc_endpoint* CreateEvalArgsMockEndpoint(const char* local_address,
const int local_port,
const char* peer_address,
const int peer_port) {
EvalArgsMockEndpoint* m =
new EvalArgsMockEndpoint(NameAndPortToURI(local_address, local_port),
NameAndPortToURI(peer_address, peer_port));
return m->base();
}
} // namespace grpc_core

@ -1,31 +0,0 @@
// Copyright 2020 gRPC authors.
//
// 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.
#ifndef GRPC_TEST_CORE_UTIL_EVAL_ARGS_MOCK_ENDPOINT_H
#define GRPC_TEST_CORE_UTIL_EVAL_ARGS_MOCK_ENDPOINT_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/endpoint.h"
namespace grpc_core {
grpc_endpoint* CreateEvalArgsMockEndpoint(const char* local_address,
const int local_port,
const char* peer_address,
const int peer_port);
} // namespace grpc_core
#endif // GRPC_TEST_CORE_UTIL_EVAL_ARGS_MOCK_ENDPOINT_H

@ -0,0 +1,59 @@
// Copyright 2021 gRPC authors.
//
// 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.
#ifndef GRPC_TEST_CORE_UTIL_MOCK_EVAL_ARGS_ENDPOINT_H
#define GRPC_TEST_CORE_UTIL_MOCK_EVAL_ARGS_ENDPOINT_H
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/endpoint.h"
namespace grpc_core {
class MockEvalArgsEndpoint : public grpc_endpoint {
public:
MockEvalArgsEndpoint(absl::string_view local_uri, absl::string_view peer_uri)
: local_address_(local_uri), peer_address_(peer_uri) {
static constexpr grpc_endpoint_vtable vtable = {
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr,
nullptr, nullptr, GetPeer, GetLocalAddress, nullptr, nullptr};
grpc_endpoint::vtable = &vtable;
}
static absl::string_view GetPeer(grpc_endpoint* ep) {
MockEvalArgsEndpoint* m = reinterpret_cast<MockEvalArgsEndpoint*>(ep);
return m->peer_address_;
}
static absl::string_view GetLocalAddress(grpc_endpoint* ep) {
MockEvalArgsEndpoint* m = reinterpret_cast<MockEvalArgsEndpoint*>(ep);
return m->local_address_;
}
void SetPeer(absl::string_view peer_address) {
peer_address_ = std::string(peer_address);
}
void SetLocalAddress(absl::string_view local_address) {
local_address_ = std::string(local_address);
}
private:
std::string local_address_;
std::string peer_address_;
};
} // namespace grpc_core
#endif // GRPC_TEST_CORE_UTIL_MOCK_EVAL_ARGS_ENDPOINT_H

@ -3300,7 +3300,7 @@
"flaky": false,
"gtest": true,
"language": "c++",
"name": "authorization_engine_test",
"name": "authorization_matchers_test",
"platforms": [
"linux",
"mac",
@ -3839,6 +3839,30 @@
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
"gtest": true,
"language": "c++",
"name": "cel_authorization_engine_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
],
"uses_polling": true
},
{
"args": [],
"benchmark": false,

Loading…
Cancel
Save