1 // Copyright 2021 gRPC authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H 16 #define GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H 17 18 #include <grpc/support/port_platform.h> 19 20 #include <memory> 21 22 #include "src/core/lib/matchers/matchers.h" 23 #include "src/core/lib/security/authorization/evaluate_args.h" 24 #include "src/core/lib/security/authorization/rbac_policy.h" 25 26 namespace grpc_core { 27 28 // Describes the rules for matching permission or principal. 29 class AuthorizationMatcher { 30 public: 31 virtual ~AuthorizationMatcher() = default; 32 33 // Returns whether or not the permission/principal matches the rules of the 34 // matcher. 35 virtual bool Matches(const EvaluateArgs& args) const = 0; 36 37 // Creates an instance of a matcher based off the rules defined in Permission 38 // config. 39 static std::unique_ptr<AuthorizationMatcher> Create( 40 Rbac::Permission permission); 41 42 // Creates an instance of a matcher based off the rules defined in Principal 43 // config. 44 static std::unique_ptr<AuthorizationMatcher> Create( 45 Rbac::Principal principal); 46 }; 47 48 class AlwaysAuthorizationMatcher : public AuthorizationMatcher { 49 public: 50 explicit AlwaysAuthorizationMatcher() = default; 51 Matches(const EvaluateArgs &)52 bool Matches(const EvaluateArgs&) const override { return true; } 53 }; 54 55 class AndAuthorizationMatcher : public AuthorizationMatcher { 56 public: AndAuthorizationMatcher(std::vector<std::unique_ptr<AuthorizationMatcher>> matchers)57 explicit AndAuthorizationMatcher( 58 std::vector<std::unique_ptr<AuthorizationMatcher>> matchers) 59 : matchers_(std::move(matchers)) {} 60 61 bool Matches(const EvaluateArgs& args) const override; 62 63 private: 64 std::vector<std::unique_ptr<AuthorizationMatcher>> matchers_; 65 }; 66 67 class OrAuthorizationMatcher : public AuthorizationMatcher { 68 public: OrAuthorizationMatcher(std::vector<std::unique_ptr<AuthorizationMatcher>> matchers)69 explicit OrAuthorizationMatcher( 70 std::vector<std::unique_ptr<AuthorizationMatcher>> matchers) 71 : matchers_(std::move(matchers)) {} 72 73 bool Matches(const EvaluateArgs& args) const override; 74 75 private: 76 std::vector<std::unique_ptr<AuthorizationMatcher>> matchers_; 77 }; 78 79 // Negates matching the provided permission/principal. 80 class NotAuthorizationMatcher : public AuthorizationMatcher { 81 public: NotAuthorizationMatcher(std::unique_ptr<AuthorizationMatcher> matcher)82 explicit NotAuthorizationMatcher( 83 std::unique_ptr<AuthorizationMatcher> matcher) 84 : matcher_(std::move(matcher)) {} 85 86 bool Matches(const EvaluateArgs& args) const override; 87 88 private: 89 std::unique_ptr<AuthorizationMatcher> matcher_; 90 }; 91 92 // TODO(ashithasantosh): Add matcher implementation for metadata field. 93 94 // Perform a match against HTTP headers. 95 class HeaderAuthorizationMatcher : public AuthorizationMatcher { 96 public: HeaderAuthorizationMatcher(HeaderMatcher matcher)97 explicit HeaderAuthorizationMatcher(HeaderMatcher matcher) 98 : matcher_(std::move(matcher)) {} 99 100 bool Matches(const EvaluateArgs& args) const override; 101 102 private: 103 const HeaderMatcher matcher_; 104 }; 105 106 // Perform a match against IP Cidr Range. 107 class IpAuthorizationMatcher : public AuthorizationMatcher { 108 public: 109 enum class Type { 110 kDestIp, 111 kSourceIp, 112 kDirectRemoteIp, 113 kRemoteIp, 114 }; 115 116 IpAuthorizationMatcher(Type type, Rbac::CidrRange range); 117 118 bool Matches(const EvaluateArgs& args) const override; 119 120 private: 121 const Type type_; 122 // Subnet masked address. 123 grpc_resolved_address subnet_address_; 124 const uint32_t prefix_len_; 125 }; 126 127 // Perform a match against port number of the destination (local) address. 128 class PortAuthorizationMatcher : public AuthorizationMatcher { 129 public: PortAuthorizationMatcher(int port)130 explicit PortAuthorizationMatcher(int port) : port_(port) {} 131 132 bool Matches(const EvaluateArgs& args) const override; 133 134 private: 135 const int port_; 136 }; 137 138 // Matches the principal name as described in the peer certificate. Uses URI SAN 139 // or DNS SAN in that order, otherwise uses subject field. 140 class AuthenticatedAuthorizationMatcher : public AuthorizationMatcher { 141 public: AuthenticatedAuthorizationMatcher(StringMatcher auth)142 explicit AuthenticatedAuthorizationMatcher(StringMatcher auth) 143 : matcher_(std::move(auth)) {} 144 145 bool Matches(const EvaluateArgs& args) const override; 146 147 private: 148 const StringMatcher matcher_; 149 }; 150 151 // Perform a match against the request server from the client's connection 152 // request. This is typically TLS SNI. Currently unsupported. 153 class ReqServerNameAuthorizationMatcher : public AuthorizationMatcher { 154 public: ReqServerNameAuthorizationMatcher(StringMatcher requested_server_name)155 explicit ReqServerNameAuthorizationMatcher( 156 StringMatcher requested_server_name) 157 : matcher_(std::move(requested_server_name)) {} 158 159 bool Matches(const EvaluateArgs&) const override; 160 161 private: 162 const StringMatcher matcher_; 163 }; 164 165 // Perform a match against the path header of HTTP request. 166 class PathAuthorizationMatcher : public AuthorizationMatcher { 167 public: PathAuthorizationMatcher(StringMatcher path)168 explicit PathAuthorizationMatcher(StringMatcher path) 169 : matcher_(std::move(path)) {} 170 171 bool Matches(const EvaluateArgs& args) const override; 172 173 private: 174 const StringMatcher matcher_; 175 }; 176 177 // Performs a match for policy field in RBAC, which is a collection of 178 // permission and principal matchers. Policy matches iff, we find a match in one 179 // of its permissions and a match in one of its principals. 180 class PolicyAuthorizationMatcher : public AuthorizationMatcher { 181 public: PolicyAuthorizationMatcher(Rbac::Policy policy)182 explicit PolicyAuthorizationMatcher(Rbac::Policy policy) 183 : permissions_( 184 AuthorizationMatcher::Create(std::move(policy.permissions))), 185 principals_( 186 AuthorizationMatcher::Create(std::move(policy.principals))) {} 187 188 bool Matches(const EvaluateArgs& args) const override; 189 190 private: 191 std::unique_ptr<AuthorizationMatcher> permissions_; 192 std::unique_ptr<AuthorizationMatcher> principals_; 193 }; 194 195 } // namespace grpc_core 196 197 #endif // GRPC_CORE_LIB_SECURITY_AUTHORIZATION_MATCHERS_H 198