parent
8ce9774187
commit
585bdccf45
1
BUILD
1
BUILD
|
|
@ -1763,6 +1763,7 @@ grpc_cc_library(
|
|||
"//src/core:lib/security/credentials/plugin/plugin_credentials.cc",
|
||||
"//src/core:lib/security/security_connector/security_connector.cc",
|
||||
"//src/core:lib/security/transport/client_auth_filter.cc",
|
||||
"//src/core:lib/security/transport/legacy_server_auth_filter.cc",
|
||||
"//src/core:lib/security/transport/secure_endpoint.cc",
|
||||
"//src/core:lib/security/transport/security_handshaker.cc",
|
||||
"//src/core:lib/security/transport/server_auth_filter.cc",
|
||||
|
|
|
|||
|
|
@ -2458,6 +2458,7 @@ add_library(grpc
|
|||
src/core/lib/security/security_connector/ssl_utils.cc
|
||||
src/core/lib/security/security_connector/tls/tls_security_connector.cc
|
||||
src/core/lib/security/transport/client_auth_filter.cc
|
||||
src/core/lib/security/transport/legacy_server_auth_filter.cc
|
||||
src/core/lib/security/transport/secure_endpoint.cc
|
||||
src/core/lib/security/transport/security_handshaker.cc
|
||||
src/core/lib/security/transport/server_auth_filter.cc
|
||||
|
|
@ -3150,6 +3151,7 @@ add_library(grpc_unsecure
|
|||
src/core/lib/security/security_connector/load_system_roots_supported.cc
|
||||
src/core/lib/security/security_connector/security_connector.cc
|
||||
src/core/lib/security/transport/client_auth_filter.cc
|
||||
src/core/lib/security/transport/legacy_server_auth_filter.cc
|
||||
src/core/lib/security/transport/secure_endpoint.cc
|
||||
src/core/lib/security/transport/security_handshaker.cc
|
||||
src/core/lib/security/transport/server_auth_filter.cc
|
||||
|
|
@ -5138,6 +5140,7 @@ add_library(grpc_authorization_provider
|
|||
src/core/lib/security/security_connector/load_system_roots_supported.cc
|
||||
src/core/lib/security/security_connector/security_connector.cc
|
||||
src/core/lib/security/transport/client_auth_filter.cc
|
||||
src/core/lib/security/transport/legacy_server_auth_filter.cc
|
||||
src/core/lib/security/transport/secure_endpoint.cc
|
||||
src/core/lib/security/transport/security_handshaker.cc
|
||||
src/core/lib/security/transport/server_auth_filter.cc
|
||||
|
|
|
|||
|
|
@ -1659,6 +1659,7 @@ LIBGRPC_SRC = \
|
|||
src/core/lib/security/security_connector/ssl_utils.cc \
|
||||
src/core/lib/security/security_connector/tls/tls_security_connector.cc \
|
||||
src/core/lib/security/transport/client_auth_filter.cc \
|
||||
src/core/lib/security/transport/legacy_server_auth_filter.cc \
|
||||
src/core/lib/security/transport/secure_endpoint.cc \
|
||||
src/core/lib/security/transport/security_handshaker.cc \
|
||||
src/core/lib/security/transport/server_auth_filter.cc \
|
||||
|
|
@ -2201,6 +2202,7 @@ LIBGRPC_UNSECURE_SRC = \
|
|||
src/core/lib/security/security_connector/load_system_roots_supported.cc \
|
||||
src/core/lib/security/security_connector/security_connector.cc \
|
||||
src/core/lib/security/transport/client_auth_filter.cc \
|
||||
src/core/lib/security/transport/legacy_server_auth_filter.cc \
|
||||
src/core/lib/security/transport/secure_endpoint.cc \
|
||||
src/core/lib/security/transport/security_handshaker.cc \
|
||||
src/core/lib/security/transport/server_auth_filter.cc \
|
||||
|
|
|
|||
|
|
@ -1802,6 +1802,7 @@ let package = Package(
|
|||
"src/core/lib/security/security_connector/tls/tls_security_connector.h",
|
||||
"src/core/lib/security/transport/auth_filters.h",
|
||||
"src/core/lib/security/transport/client_auth_filter.cc",
|
||||
"src/core/lib/security/transport/legacy_server_auth_filter.cc",
|
||||
"src/core/lib/security/transport/secure_endpoint.cc",
|
||||
"src/core/lib/security/transport/secure_endpoint.h",
|
||||
"src/core/lib/security/transport/security_handshaker.cc",
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ EXPERIMENT_ENABLES = {
|
|||
"unconstrained_max_quota_buffer_size": "unconstrained_max_quota_buffer_size",
|
||||
"v3_channel_idle_filters": "v3_channel_idle_filters",
|
||||
"v3_compression_filter": "v3_compression_filter",
|
||||
"v3_server_auth_filter": "v3_server_auth_filter",
|
||||
"work_serializer_clears_time_cache": "work_serializer_clears_time_cache",
|
||||
"work_serializer_dispatch": "work_serializer_dispatch",
|
||||
"write_size_policy": "write_size_policy",
|
||||
|
|
|
|||
|
|
@ -1913,6 +1913,7 @@ libs:
|
|||
- src/core/lib/security/security_connector/ssl_utils.cc
|
||||
- src/core/lib/security/security_connector/tls/tls_security_connector.cc
|
||||
- src/core/lib/security/transport/client_auth_filter.cc
|
||||
- src/core/lib/security/transport/legacy_server_auth_filter.cc
|
||||
- src/core/lib/security/transport/secure_endpoint.cc
|
||||
- src/core/lib/security/transport/security_handshaker.cc
|
||||
- src/core/lib/security/transport/server_auth_filter.cc
|
||||
|
|
@ -2959,6 +2960,7 @@ libs:
|
|||
- src/core/lib/security/security_connector/load_system_roots_supported.cc
|
||||
- src/core/lib/security/security_connector/security_connector.cc
|
||||
- src/core/lib/security/transport/client_auth_filter.cc
|
||||
- src/core/lib/security/transport/legacy_server_auth_filter.cc
|
||||
- src/core/lib/security/transport/secure_endpoint.cc
|
||||
- src/core/lib/security/transport/security_handshaker.cc
|
||||
- src/core/lib/security/transport/server_auth_filter.cc
|
||||
|
|
@ -5002,6 +5004,7 @@ libs:
|
|||
- src/core/lib/security/security_connector/load_system_roots_supported.cc
|
||||
- src/core/lib/security/security_connector/security_connector.cc
|
||||
- src/core/lib/security/transport/client_auth_filter.cc
|
||||
- src/core/lib/security/transport/legacy_server_auth_filter.cc
|
||||
- src/core/lib/security/transport/secure_endpoint.cc
|
||||
- src/core/lib/security/transport/security_handshaker.cc
|
||||
- src/core/lib/security/transport/server_auth_filter.cc
|
||||
|
|
|
|||
|
|
@ -791,6 +791,7 @@ if test "$PHP_GRPC" != "no"; then
|
|||
src/core/lib/security/security_connector/ssl_utils.cc \
|
||||
src/core/lib/security/security_connector/tls/tls_security_connector.cc \
|
||||
src/core/lib/security/transport/client_auth_filter.cc \
|
||||
src/core/lib/security/transport/legacy_server_auth_filter.cc \
|
||||
src/core/lib/security/transport/secure_endpoint.cc \
|
||||
src/core/lib/security/transport/security_handshaker.cc \
|
||||
src/core/lib/security/transport/server_auth_filter.cc \
|
||||
|
|
|
|||
|
|
@ -756,6 +756,7 @@ if (PHP_GRPC != "no") {
|
|||
"src\\core\\lib\\security\\security_connector\\ssl_utils.cc " +
|
||||
"src\\core\\lib\\security\\security_connector\\tls\\tls_security_connector.cc " +
|
||||
"src\\core\\lib\\security\\transport\\client_auth_filter.cc " +
|
||||
"src\\core\\lib\\security\\transport\\legacy_server_auth_filter.cc " +
|
||||
"src\\core\\lib\\security\\transport\\secure_endpoint.cc " +
|
||||
"src\\core\\lib\\security\\transport\\security_handshaker.cc " +
|
||||
"src\\core\\lib\\security\\transport\\server_auth_filter.cc " +
|
||||
|
|
|
|||
|
|
@ -1901,6 +1901,7 @@ Pod::Spec.new do |s|
|
|||
'src/core/lib/security/security_connector/tls/tls_security_connector.h',
|
||||
'src/core/lib/security/transport/auth_filters.h',
|
||||
'src/core/lib/security/transport/client_auth_filter.cc',
|
||||
'src/core/lib/security/transport/legacy_server_auth_filter.cc',
|
||||
'src/core/lib/security/transport/secure_endpoint.cc',
|
||||
'src/core/lib/security/transport/secure_endpoint.h',
|
||||
'src/core/lib/security/transport/security_handshaker.cc',
|
||||
|
|
|
|||
|
|
@ -1804,6 +1804,7 @@ Gem::Specification.new do |s|
|
|||
s.files += %w( src/core/lib/security/security_connector/tls/tls_security_connector.h )
|
||||
s.files += %w( src/core/lib/security/transport/auth_filters.h )
|
||||
s.files += %w( src/core/lib/security/transport/client_auth_filter.cc )
|
||||
s.files += %w( src/core/lib/security/transport/legacy_server_auth_filter.cc )
|
||||
s.files += %w( src/core/lib/security/transport/secure_endpoint.cc )
|
||||
s.files += %w( src/core/lib/security/transport/secure_endpoint.h )
|
||||
s.files += %w( src/core/lib/security/transport/security_handshaker.cc )
|
||||
|
|
|
|||
|
|
@ -978,6 +978,7 @@
|
|||
'src/core/lib/security/security_connector/ssl_utils.cc',
|
||||
'src/core/lib/security/security_connector/tls/tls_security_connector.cc',
|
||||
'src/core/lib/security/transport/client_auth_filter.cc',
|
||||
'src/core/lib/security/transport/legacy_server_auth_filter.cc',
|
||||
'src/core/lib/security/transport/secure_endpoint.cc',
|
||||
'src/core/lib/security/transport/security_handshaker.cc',
|
||||
'src/core/lib/security/transport/server_auth_filter.cc',
|
||||
|
|
@ -1461,6 +1462,7 @@
|
|||
'src/core/lib/security/security_connector/load_system_roots_supported.cc',
|
||||
'src/core/lib/security/security_connector/security_connector.cc',
|
||||
'src/core/lib/security/transport/client_auth_filter.cc',
|
||||
'src/core/lib/security/transport/legacy_server_auth_filter.cc',
|
||||
'src/core/lib/security/transport/secure_endpoint.cc',
|
||||
'src/core/lib/security/transport/security_handshaker.cc',
|
||||
'src/core/lib/security/transport/server_auth_filter.cc',
|
||||
|
|
@ -2239,6 +2241,7 @@
|
|||
'src/core/lib/security/security_connector/load_system_roots_supported.cc',
|
||||
'src/core/lib/security/security_connector/security_connector.cc',
|
||||
'src/core/lib/security/transport/client_auth_filter.cc',
|
||||
'src/core/lib/security/transport/legacy_server_auth_filter.cc',
|
||||
'src/core/lib/security/transport/secure_endpoint.cc',
|
||||
'src/core/lib/security/transport/security_handshaker.cc',
|
||||
'src/core/lib/security/transport/server_auth_filter.cc',
|
||||
|
|
|
|||
|
|
@ -1786,6 +1786,7 @@
|
|||
<file baseinstalldir="/" name="src/core/lib/security/security_connector/tls/tls_security_connector.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/security/transport/auth_filters.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/security/transport/client_auth_filter.cc" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/security/transport/legacy_server_auth_filter.cc" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.cc" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/security/transport/secure_endpoint.h" role="src" />
|
||||
<file baseinstalldir="/" name="src/core/lib/security/transport/security_handshaker.cc" role="src" />
|
||||
|
|
|
|||
|
|
@ -63,6 +63,7 @@
|
|||
#include "src/core/lib/promise/poll.h"
|
||||
#include "src/core/lib/promise/promise.h"
|
||||
#include "src/core/lib/promise/race.h"
|
||||
#include "src/core/lib/promise/try_seq.h"
|
||||
#include "src/core/lib/resource_quota/arena.h"
|
||||
#include "src/core/lib/slice/slice_buffer.h"
|
||||
#include "src/core/lib/surface/call.h"
|
||||
|
|
@ -330,54 +331,88 @@ auto MapResult(void (Derived::Call::*fn)(ServerMetadata&), Promise x,
|
|||
});
|
||||
}
|
||||
|
||||
inline auto RunCall(const NoInterceptor*, CallArgs call_args,
|
||||
NextPromiseFactory next_promise_factory, void*) {
|
||||
return next_promise_factory(std::move(call_args));
|
||||
}
|
||||
template <typename Interceptor, typename Derived, typename SfinaeVoid = void>
|
||||
struct RunCallImpl;
|
||||
|
||||
template <typename Derived>
|
||||
inline auto RunCall(void (Derived::Call::*fn)(ClientMetadata& md),
|
||||
CallArgs call_args, NextPromiseFactory next_promise_factory,
|
||||
FilterCallData<Derived>* call_data) {
|
||||
GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientInitialMetadata);
|
||||
call_data->call.OnClientInitialMetadata(*call_args.client_initial_metadata);
|
||||
return next_promise_factory(std::move(call_args));
|
||||
}
|
||||
struct RunCallImpl<const NoInterceptor*, Derived> {
|
||||
static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
|
||||
void*) {
|
||||
return next_promise_factory(std::move(call_args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Derived>
|
||||
inline auto RunCall(
|
||||
ServerMetadataHandle (Derived::Call::*fn)(ClientMetadata& md),
|
||||
CallArgs call_args, NextPromiseFactory next_promise_factory,
|
||||
FilterCallData<Derived>* call_data) -> ArenaPromise<ServerMetadataHandle> {
|
||||
GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientInitialMetadata);
|
||||
auto return_md = call_data->call.OnClientInitialMetadata(
|
||||
*call_args.client_initial_metadata);
|
||||
if (return_md == nullptr) return next_promise_factory(std::move(call_args));
|
||||
return Immediate(std::move(return_md));
|
||||
}
|
||||
struct RunCallImpl<void (Derived::Call::*)(ClientMetadata& md), Derived> {
|
||||
static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
|
||||
FilterCallData<Derived>* call_data) {
|
||||
call_data->call.OnClientInitialMetadata(*call_args.client_initial_metadata);
|
||||
return next_promise_factory(std::move(call_args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Derived>
|
||||
inline auto RunCall(ServerMetadataHandle (Derived::Call::*fn)(
|
||||
ClientMetadata& md, Derived* channel),
|
||||
CallArgs call_args, NextPromiseFactory next_promise_factory,
|
||||
FilterCallData<Derived>* call_data)
|
||||
-> ArenaPromise<ServerMetadataHandle> {
|
||||
GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientInitialMetadata);
|
||||
auto return_md = call_data->call.OnClientInitialMetadata(
|
||||
*call_args.client_initial_metadata, call_data->channel);
|
||||
if (return_md == nullptr) return next_promise_factory(std::move(call_args));
|
||||
return Immediate(std::move(return_md));
|
||||
}
|
||||
struct RunCallImpl<ServerMetadataHandle (Derived::Call::*)(ClientMetadata& md),
|
||||
Derived> {
|
||||
static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
|
||||
FilterCallData<Derived>* call_data)
|
||||
-> ArenaPromise<ServerMetadataHandle> {
|
||||
auto return_md = call_data->call.OnClientInitialMetadata(
|
||||
*call_args.client_initial_metadata);
|
||||
if (return_md == nullptr) return next_promise_factory(std::move(call_args));
|
||||
return Immediate(std::move(return_md));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Derived>
|
||||
inline auto RunCall(void (Derived::Call::*fn)(ClientMetadata& md,
|
||||
Derived* channel),
|
||||
CallArgs call_args, NextPromiseFactory next_promise_factory,
|
||||
FilterCallData<Derived>* call_data) {
|
||||
GPR_DEBUG_ASSERT(fn == &Derived::Call::OnClientInitialMetadata);
|
||||
call_data->call.OnClientInitialMetadata(*call_args.client_initial_metadata,
|
||||
call_data->channel);
|
||||
return next_promise_factory(std::move(call_args));
|
||||
struct RunCallImpl<ServerMetadataHandle (Derived::Call::*)(ClientMetadata& md,
|
||||
Derived* channel),
|
||||
Derived> {
|
||||
static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
|
||||
FilterCallData<Derived>* call_data)
|
||||
-> ArenaPromise<ServerMetadataHandle> {
|
||||
auto return_md = call_data->call.OnClientInitialMetadata(
|
||||
*call_args.client_initial_metadata, call_data->channel);
|
||||
if (return_md == nullptr) return next_promise_factory(std::move(call_args));
|
||||
return Immediate(std::move(return_md));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Derived>
|
||||
struct RunCallImpl<
|
||||
void (Derived::Call::*)(ClientMetadata& md, Derived* channel), Derived> {
|
||||
static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
|
||||
FilterCallData<Derived>* call_data) {
|
||||
call_data->call.OnClientInitialMetadata(*call_args.client_initial_metadata,
|
||||
call_data->channel);
|
||||
return next_promise_factory(std::move(call_args));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Derived, typename Promise>
|
||||
struct RunCallImpl<
|
||||
Promise (Derived::Call::*)(ClientMetadata& md, Derived* channel), Derived,
|
||||
absl::void_t<decltype(StatusCast<ServerMetadataHandle>(
|
||||
std::declval<PromiseResult<Promise>>))>> {
|
||||
static auto Run(CallArgs call_args, NextPromiseFactory next_promise_factory,
|
||||
FilterCallData<Derived>* call_data) {
|
||||
ClientMetadata& md_ref = *call_args.client_initial_metadata;
|
||||
return TrySeq(
|
||||
call_data->call.OnClientInitialMetadata(md_ref, call_data->channel),
|
||||
[call_args = std::move(call_args),
|
||||
next_promise_factory = std::move(next_promise_factory)]() mutable {
|
||||
return next_promise_factory(std::move(call_args));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Interceptor, typename Derived>
|
||||
auto RunCall(Interceptor interceptor, CallArgs call_args,
|
||||
NextPromiseFactory next_promise_factory,
|
||||
FilterCallData<Derived>* call_data) {
|
||||
GPR_DEBUG_ASSERT(interceptor == &Derived::Call::OnClientInitialMetadata);
|
||||
return RunCallImpl<Interceptor, Derived>::Run(
|
||||
std::move(call_args), std::move(next_promise_factory), call_data);
|
||||
}
|
||||
|
||||
inline void InterceptClientToServerMessage(const NoInterceptor*, void*,
|
||||
|
|
@ -558,6 +593,30 @@ inline void InterceptClientInitialMetadata(
|
|||
});
|
||||
}
|
||||
|
||||
// Returning a promise that resolves to something that can be cast to
|
||||
// ServerMetadataHandle also counts
|
||||
template <typename Promise, typename Derived>
|
||||
absl::void_t<decltype(StatusCast<ServerMetadataHandle>(
|
||||
std::declval<PromiseResult<Promise>>))>
|
||||
InterceptClientInitialMetadata(Promise (Derived::Call::*promise_factory)(
|
||||
ClientMetadata& md, Derived* channel),
|
||||
typename Derived::Call* call, Derived* channel,
|
||||
CallSpineInterface* call_spine) {
|
||||
GPR_DEBUG_ASSERT(promise_factory == &Derived::Call::OnClientInitialMetadata);
|
||||
call_spine->client_initial_metadata().receiver.InterceptAndMap(
|
||||
[call, call_spine, channel](ClientMetadataHandle md) {
|
||||
ClientMetadata& md_ref = *md;
|
||||
return Map(call->OnClientInitialMetadata(md_ref, channel),
|
||||
[md = std::move(md),
|
||||
call_spine](PromiseResult<Promise> status) mutable
|
||||
-> absl::optional<ClientMetadataHandle> {
|
||||
if (IsStatusOk(status)) return std::move(md);
|
||||
return call_spine->Cancel(
|
||||
StatusCast<ServerMetadataHandle>(std::move(status)));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
template <typename CallArgs>
|
||||
inline void InterceptServerInitialMetadata(const NoInterceptor*, void*,
|
||||
const CallArgs&) {}
|
||||
|
|
@ -903,6 +962,8 @@ MakeFilterCall(Derived* derived) {
|
|||
// the filter can return nullptr for success, or a metadata handle for
|
||||
// failure (in which case the call will be aborted).
|
||||
// useful for cases where the exact metadata returned needs to be customized.
|
||||
// It's also acceptable to return a promise that resolves to the
|
||||
// relevant return type listed above.
|
||||
// Finally, OnFinalize can be added to intecept call finalization.
|
||||
// It must have one of the signatures:
|
||||
// - static const NoInterceptor OnFinalize:
|
||||
|
|
|
|||
|
|
@ -158,6 +158,9 @@ const char* const additional_constraints_v3_channel_idle_filters = "{}";
|
|||
const char* const description_v3_compression_filter =
|
||||
"Use the compression filter utilizing the v3 filter api";
|
||||
const char* const additional_constraints_v3_compression_filter = "{}";
|
||||
const char* const description_v3_server_auth_filter =
|
||||
"Use the server auth filter utilizing the v3 filter api";
|
||||
const char* const additional_constraints_v3_server_auth_filter = "{}";
|
||||
const char* const description_work_serializer_clears_time_cache =
|
||||
"Have the work serializer clear the time cache when it dispatches work.";
|
||||
const char* const additional_constraints_work_serializer_clears_time_cache =
|
||||
|
|
@ -274,6 +277,8 @@ const ExperimentMetadata g_experiment_metadata[] = {
|
|||
additional_constraints_v3_channel_idle_filters, nullptr, 0, false, true},
|
||||
{"v3_compression_filter", description_v3_compression_filter,
|
||||
additional_constraints_v3_compression_filter, nullptr, 0, false, true},
|
||||
{"v3_server_auth_filter", description_v3_server_auth_filter,
|
||||
additional_constraints_v3_server_auth_filter, nullptr, 0, false, true},
|
||||
{"work_serializer_clears_time_cache",
|
||||
description_work_serializer_clears_time_cache,
|
||||
additional_constraints_work_serializer_clears_time_cache, nullptr, 0, true,
|
||||
|
|
@ -427,6 +432,9 @@ const char* const additional_constraints_v3_channel_idle_filters = "{}";
|
|||
const char* const description_v3_compression_filter =
|
||||
"Use the compression filter utilizing the v3 filter api";
|
||||
const char* const additional_constraints_v3_compression_filter = "{}";
|
||||
const char* const description_v3_server_auth_filter =
|
||||
"Use the server auth filter utilizing the v3 filter api";
|
||||
const char* const additional_constraints_v3_server_auth_filter = "{}";
|
||||
const char* const description_work_serializer_clears_time_cache =
|
||||
"Have the work serializer clear the time cache when it dispatches work.";
|
||||
const char* const additional_constraints_work_serializer_clears_time_cache =
|
||||
|
|
@ -543,6 +551,8 @@ const ExperimentMetadata g_experiment_metadata[] = {
|
|||
additional_constraints_v3_channel_idle_filters, nullptr, 0, false, true},
|
||||
{"v3_compression_filter", description_v3_compression_filter,
|
||||
additional_constraints_v3_compression_filter, nullptr, 0, false, true},
|
||||
{"v3_server_auth_filter", description_v3_server_auth_filter,
|
||||
additional_constraints_v3_server_auth_filter, nullptr, 0, false, true},
|
||||
{"work_serializer_clears_time_cache",
|
||||
description_work_serializer_clears_time_cache,
|
||||
additional_constraints_work_serializer_clears_time_cache, nullptr, 0, true,
|
||||
|
|
@ -696,6 +706,9 @@ const char* const additional_constraints_v3_channel_idle_filters = "{}";
|
|||
const char* const description_v3_compression_filter =
|
||||
"Use the compression filter utilizing the v3 filter api";
|
||||
const char* const additional_constraints_v3_compression_filter = "{}";
|
||||
const char* const description_v3_server_auth_filter =
|
||||
"Use the server auth filter utilizing the v3 filter api";
|
||||
const char* const additional_constraints_v3_server_auth_filter = "{}";
|
||||
const char* const description_work_serializer_clears_time_cache =
|
||||
"Have the work serializer clear the time cache when it dispatches work.";
|
||||
const char* const additional_constraints_work_serializer_clears_time_cache =
|
||||
|
|
@ -812,6 +825,8 @@ const ExperimentMetadata g_experiment_metadata[] = {
|
|||
additional_constraints_v3_channel_idle_filters, nullptr, 0, false, true},
|
||||
{"v3_compression_filter", description_v3_compression_filter,
|
||||
additional_constraints_v3_compression_filter, nullptr, 0, false, true},
|
||||
{"v3_server_auth_filter", description_v3_server_auth_filter,
|
||||
additional_constraints_v3_server_auth_filter, nullptr, 0, false, true},
|
||||
{"work_serializer_clears_time_cache",
|
||||
description_work_serializer_clears_time_cache,
|
||||
additional_constraints_work_serializer_clears_time_cache, nullptr, 0, true,
|
||||
|
|
|
|||
|
|
@ -109,6 +109,7 @@ inline bool IsTraceRecordCallopsEnabled() { return false; }
|
|||
inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() { return false; }
|
||||
inline bool IsV3ChannelIdleFiltersEnabled() { return false; }
|
||||
inline bool IsV3CompressionFilterEnabled() { return false; }
|
||||
inline bool IsV3ServerAuthFilterEnabled() { return false; }
|
||||
#define GRPC_EXPERIMENT_IS_INCLUDED_WORK_SERIALIZER_CLEARS_TIME_CACHE
|
||||
inline bool IsWorkSerializerClearsTimeCacheEnabled() { return true; }
|
||||
inline bool IsWorkSerializerDispatchEnabled() { return false; }
|
||||
|
|
@ -173,6 +174,7 @@ inline bool IsTraceRecordCallopsEnabled() { return false; }
|
|||
inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() { return false; }
|
||||
inline bool IsV3ChannelIdleFiltersEnabled() { return false; }
|
||||
inline bool IsV3CompressionFilterEnabled() { return false; }
|
||||
inline bool IsV3ServerAuthFilterEnabled() { return false; }
|
||||
#define GRPC_EXPERIMENT_IS_INCLUDED_WORK_SERIALIZER_CLEARS_TIME_CACHE
|
||||
inline bool IsWorkSerializerClearsTimeCacheEnabled() { return true; }
|
||||
inline bool IsWorkSerializerDispatchEnabled() { return false; }
|
||||
|
|
@ -237,6 +239,7 @@ inline bool IsTraceRecordCallopsEnabled() { return false; }
|
|||
inline bool IsUnconstrainedMaxQuotaBufferSizeEnabled() { return false; }
|
||||
inline bool IsV3ChannelIdleFiltersEnabled() { return false; }
|
||||
inline bool IsV3CompressionFilterEnabled() { return false; }
|
||||
inline bool IsV3ServerAuthFilterEnabled() { return false; }
|
||||
#define GRPC_EXPERIMENT_IS_INCLUDED_WORK_SERIALIZER_CLEARS_TIME_CACHE
|
||||
inline bool IsWorkSerializerClearsTimeCacheEnabled() { return true; }
|
||||
inline bool IsWorkSerializerDispatchEnabled() { return false; }
|
||||
|
|
@ -285,6 +288,7 @@ enum ExperimentIds {
|
|||
kExperimentIdUnconstrainedMaxQuotaBufferSize,
|
||||
kExperimentIdV3ChannelIdleFilters,
|
||||
kExperimentIdV3CompressionFilter,
|
||||
kExperimentIdV3ServerAuthFilter,
|
||||
kExperimentIdWorkSerializerClearsTimeCache,
|
||||
kExperimentIdWorkSerializerDispatch,
|
||||
kExperimentIdWriteSizePolicy,
|
||||
|
|
@ -432,6 +436,10 @@ inline bool IsV3ChannelIdleFiltersEnabled() {
|
|||
inline bool IsV3CompressionFilterEnabled() {
|
||||
return IsExperimentEnabled(kExperimentIdV3CompressionFilter);
|
||||
}
|
||||
#define GRPC_EXPERIMENT_IS_INCLUDED_V3_SERVER_AUTH_FILTER
|
||||
inline bool IsV3ServerAuthFilterEnabled() {
|
||||
return IsExperimentEnabled(kExperimentIdV3ServerAuthFilter);
|
||||
}
|
||||
#define GRPC_EXPERIMENT_IS_INCLUDED_WORK_SERIALIZER_CLEARS_TIME_CACHE
|
||||
inline bool IsWorkSerializerClearsTimeCacheEnabled() {
|
||||
return IsExperimentEnabled(kExperimentIdWorkSerializerClearsTimeCache);
|
||||
|
|
|
|||
|
|
@ -265,6 +265,12 @@
|
|||
expiry: 2024/04/04
|
||||
owner: ctiller@google.com
|
||||
test_tags: ["compression_test"]
|
||||
- name: v3_server_auth_filter
|
||||
description:
|
||||
Use the server auth filter utilizing the v3 filter api
|
||||
expiry: 2024/04/04
|
||||
owner: ctiller@google.com
|
||||
test_tags: []
|
||||
- name: work_serializer_clears_time_cache
|
||||
description:
|
||||
Have the work serializer clear the time cache when it dispatches work.
|
||||
|
|
|
|||
|
|
@ -63,15 +63,18 @@ auto WrapInPoll(T&& x) -> decltype(PollWrapper<T>::Wrap(std::forward<T>(x))) {
|
|||
return PollWrapper<T>::Wrap(std::forward<T>(x));
|
||||
}
|
||||
|
||||
template <typename F, typename SfinaeVoid = void>
|
||||
class PromiseLike;
|
||||
|
||||
template <>
|
||||
class PromiseLike<void>;
|
||||
|
||||
template <typename F>
|
||||
class PromiseLike {
|
||||
class PromiseLike<F, absl::enable_if_t<!std::is_void<
|
||||
typename std::result_of<F()>::type>::value>> {
|
||||
private:
|
||||
GPR_NO_UNIQUE_ADDRESS F f_;
|
||||
|
||||
static_assert(!std::is_void<typename std::result_of<F()>::type>::value,
|
||||
"PromiseLike cannot be used with a function that returns void "
|
||||
"- return Empty{} instead");
|
||||
|
||||
public:
|
||||
// NOLINTNEXTLINE - internal detail that drastically simplifies calling code.
|
||||
PromiseLike(F&& f) : f_(std::forward<F>(f)) {}
|
||||
|
|
|
|||
|
|
@ -192,6 +192,7 @@ class Poll<Poll<T>>;
|
|||
// lambda, for example (via enable_if).
|
||||
template <typename T>
|
||||
struct PollTraits {
|
||||
using Type = T;
|
||||
static constexpr bool is_poll() { return false; }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,10 @@ auto WithResult(F f) ->
|
|||
return f;
|
||||
}
|
||||
|
||||
template <typename Promise>
|
||||
using PromiseResult = typename PollTraits<
|
||||
typename promise_detail::PromiseLike<Promise>::Result>::Type;
|
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
#endif // GRPC_SRC_CORE_LIB_PROMISE_PROMISE_H
|
||||
|
|
|
|||
|
|
@ -62,20 +62,21 @@ class ClientAuthFilter final : public ChannelFilter {
|
|||
grpc_call_credentials::GetRequestMetadataArgs args_;
|
||||
};
|
||||
|
||||
class ServerAuthFilter final : public ChannelFilter {
|
||||
class LegacyServerAuthFilter final : public ChannelFilter {
|
||||
public:
|
||||
static const grpc_channel_filter kFilter;
|
||||
|
||||
static absl::StatusOr<ServerAuthFilter> Create(const ChannelArgs& args,
|
||||
ChannelFilter::Args);
|
||||
static absl::StatusOr<LegacyServerAuthFilter> Create(const ChannelArgs& args,
|
||||
ChannelFilter::Args);
|
||||
|
||||
// Construct a promise for one call.
|
||||
ArenaPromise<ServerMetadataHandle> MakeCallPromise(
|
||||
CallArgs call_args, NextPromiseFactory next_promise_factory) override;
|
||||
|
||||
private:
|
||||
ServerAuthFilter(RefCountedPtr<grpc_server_credentials> server_credentials,
|
||||
RefCountedPtr<grpc_auth_context> auth_context);
|
||||
LegacyServerAuthFilter(
|
||||
RefCountedPtr<grpc_server_credentials> server_credentials,
|
||||
RefCountedPtr<grpc_auth_context> auth_context);
|
||||
|
||||
class RunApplicationCode;
|
||||
|
||||
|
|
@ -86,6 +87,72 @@ class ServerAuthFilter final : public ChannelFilter {
|
|||
RefCountedPtr<grpc_auth_context> auth_context_;
|
||||
};
|
||||
|
||||
class ServerAuthFilter final : public ImplementChannelFilter<ServerAuthFilter> {
|
||||
private:
|
||||
ServerAuthFilter(RefCountedPtr<grpc_server_credentials> server_credentials,
|
||||
RefCountedPtr<grpc_auth_context> auth_context);
|
||||
|
||||
class RunApplicationCode {
|
||||
public:
|
||||
RunApplicationCode(ServerAuthFilter* filter, ClientMetadata& metadata);
|
||||
|
||||
RunApplicationCode(const RunApplicationCode&) = delete;
|
||||
RunApplicationCode& operator=(const RunApplicationCode&) = delete;
|
||||
RunApplicationCode(RunApplicationCode&& other) noexcept
|
||||
: state_(std::exchange(other.state_, nullptr)) {}
|
||||
RunApplicationCode& operator=(RunApplicationCode&& other) noexcept {
|
||||
state_ = std::exchange(other.state_, nullptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Poll<absl::Status> operator()();
|
||||
|
||||
private:
|
||||
// Called from application code.
|
||||
static void OnMdProcessingDone(void* user_data,
|
||||
const grpc_metadata* consumed_md,
|
||||
size_t num_consumed_md,
|
||||
const grpc_metadata* response_md,
|
||||
size_t num_response_md,
|
||||
grpc_status_code status,
|
||||
const char* error_details);
|
||||
|
||||
struct State;
|
||||
State* state_;
|
||||
};
|
||||
|
||||
public:
|
||||
static const grpc_channel_filter kFilter;
|
||||
|
||||
static absl::StatusOr<ServerAuthFilter> Create(const ChannelArgs& args,
|
||||
ChannelFilter::Args);
|
||||
|
||||
class Call {
|
||||
public:
|
||||
explicit Call(ServerAuthFilter* filter);
|
||||
auto OnClientInitialMetadata(ClientMetadata& md, ServerAuthFilter* filter) {
|
||||
return If(
|
||||
filter->server_credentials_ == nullptr ||
|
||||
filter->server_credentials_->auth_metadata_processor().process ==
|
||||
nullptr,
|
||||
ImmediateOkStatus(),
|
||||
[filter, md = &md]() { return RunApplicationCode(filter, *md); });
|
||||
}
|
||||
static const NoInterceptor OnServerInitialMetadata;
|
||||
static const NoInterceptor OnClientToServerMessage;
|
||||
static const NoInterceptor OnServerToClientMessage;
|
||||
static const NoInterceptor OnServerTrailingMetadata;
|
||||
static const NoInterceptor OnFinalize;
|
||||
};
|
||||
|
||||
private:
|
||||
ArenaPromise<absl::StatusOr<CallArgs>> GetCallCredsMetadata(
|
||||
CallArgs call_args);
|
||||
|
||||
RefCountedPtr<grpc_server_credentials> server_credentials_;
|
||||
RefCountedPtr<grpc_auth_context> auth_context_;
|
||||
};
|
||||
|
||||
} // namespace grpc_core
|
||||
|
||||
// Exposed for testing purposes only.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,244 @@
|
|||
//
|
||||
//
|
||||
// Copyright 2015 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 <algorithm>
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/status/statusor.h"
|
||||
|
||||
#include <grpc/grpc.h>
|
||||
#include <grpc/grpc_security.h>
|
||||
#include <grpc/status.h>
|
||||
#include <grpc/support/alloc.h>
|
||||
#include <grpc/support/log.h>
|
||||
|
||||
#include "src/core/lib/channel/channel_args.h"
|
||||
#include "src/core/lib/channel/channel_fwd.h"
|
||||
#include "src/core/lib/channel/channel_stack.h"
|
||||
#include "src/core/lib/channel/context.h"
|
||||
#include "src/core/lib/channel/promise_based_filter.h"
|
||||
#include "src/core/lib/debug/trace.h"
|
||||
#include "src/core/lib/gprpp/debug_location.h"
|
||||
#include "src/core/lib/gprpp/ref_counted_ptr.h"
|
||||
#include "src/core/lib/gprpp/status_helper.h"
|
||||
#include "src/core/lib/iomgr/error.h"
|
||||
#include "src/core/lib/iomgr/exec_ctx.h"
|
||||
#include "src/core/lib/promise/activity.h"
|
||||
#include "src/core/lib/promise/arena_promise.h"
|
||||
#include "src/core/lib/promise/context.h"
|
||||
#include "src/core/lib/promise/poll.h"
|
||||
#include "src/core/lib/promise/try_seq.h"
|
||||
#include "src/core/lib/resource_quota/arena.h"
|
||||
#include "src/core/lib/security/context/security_context.h"
|
||||
#include "src/core/lib/security/credentials/credentials.h"
|
||||
#include "src/core/lib/security/transport/auth_filters.h" // IWYU pragma: keep
|
||||
#include "src/core/lib/slice/slice.h"
|
||||
#include "src/core/lib/slice/slice_internal.h"
|
||||
#include "src/core/lib/surface/call_trace.h"
|
||||
#include "src/core/lib/transport/metadata_batch.h"
|
||||
#include "src/core/lib/transport/transport.h"
|
||||
|
||||
namespace grpc_core {
|
||||
|
||||
const grpc_channel_filter LegacyServerAuthFilter::kFilter =
|
||||
MakePromiseBasedFilter<LegacyServerAuthFilter, FilterEndpoint::kServer>(
|
||||
"server-auth");
|
||||
|
||||
namespace {
|
||||
|
||||
class ArrayEncoder {
|
||||
public:
|
||||
explicit ArrayEncoder(grpc_metadata_array* result) : result_(result) {}
|
||||
|
||||
void Encode(const Slice& key, const Slice& value) {
|
||||
Append(key.Ref(), value.Ref());
|
||||
}
|
||||
|
||||
template <typename Which>
|
||||
void Encode(Which, const typename Which::ValueType& value) {
|
||||
Append(Slice(StaticSlice::FromStaticString(Which::key())),
|
||||
Slice(Which::Encode(value)));
|
||||
}
|
||||
|
||||
void Encode(HttpMethodMetadata,
|
||||
const typename HttpMethodMetadata::ValueType&) {}
|
||||
|
||||
private:
|
||||
void Append(Slice key, Slice value) {
|
||||
if (result_->count == result_->capacity) {
|
||||
result_->capacity =
|
||||
std::max(result_->capacity + 8, result_->capacity * 2);
|
||||
result_->metadata = static_cast<grpc_metadata*>(gpr_realloc(
|
||||
result_->metadata, result_->capacity * sizeof(grpc_metadata)));
|
||||
}
|
||||
auto* usr_md = &result_->metadata[result_->count++];
|
||||
usr_md->key = key.TakeCSlice();
|
||||
usr_md->value = value.TakeCSlice();
|
||||
}
|
||||
|
||||
grpc_metadata_array* result_;
|
||||
};
|
||||
|
||||
// TODO(ctiller): seek out all users of this functionality and change API so
|
||||
// that this unilateral format conversion IS NOT REQUIRED.
|
||||
grpc_metadata_array MetadataBatchToMetadataArray(
|
||||
const grpc_metadata_batch* batch) {
|
||||
grpc_metadata_array result;
|
||||
grpc_metadata_array_init(&result);
|
||||
ArrayEncoder encoder(&result);
|
||||
batch->Encode(&encoder);
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class LegacyServerAuthFilter::RunApplicationCode {
|
||||
public:
|
||||
// TODO(ctiller): Allocate state_ into a pool on the arena to reuse this
|
||||
// memory later
|
||||
RunApplicationCode(LegacyServerAuthFilter* filter, CallArgs call_args)
|
||||
: state_(GetContext<Arena>()->ManagedNew<State>(std::move(call_args))) {
|
||||
if (grpc_call_trace.enabled()) {
|
||||
gpr_log(GPR_ERROR,
|
||||
"%s[server-auth]: Delegate to application: filter=%p this=%p "
|
||||
"auth_ctx=%p",
|
||||
Activity::current()->DebugTag().c_str(), filter, this,
|
||||
filter->auth_context_.get());
|
||||
}
|
||||
filter->server_credentials_->auth_metadata_processor().process(
|
||||
filter->server_credentials_->auth_metadata_processor().state,
|
||||
filter->auth_context_.get(), state_->md.metadata, state_->md.count,
|
||||
OnMdProcessingDone, state_);
|
||||
}
|
||||
|
||||
RunApplicationCode(const RunApplicationCode&) = delete;
|
||||
RunApplicationCode& operator=(const RunApplicationCode&) = delete;
|
||||
RunApplicationCode(RunApplicationCode&& other) noexcept
|
||||
: state_(std::exchange(other.state_, nullptr)) {}
|
||||
RunApplicationCode& operator=(RunApplicationCode&& other) noexcept {
|
||||
state_ = std::exchange(other.state_, nullptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Poll<absl::StatusOr<CallArgs>> operator()() {
|
||||
if (state_->done.load(std::memory_order_acquire)) {
|
||||
return Poll<absl::StatusOr<CallArgs>>(std::move(state_->call_args));
|
||||
}
|
||||
return Pending{};
|
||||
}
|
||||
|
||||
private:
|
||||
struct State {
|
||||
explicit State(CallArgs call_args) : call_args(std::move(call_args)) {}
|
||||
Waker waker{Activity::current()->MakeOwningWaker()};
|
||||
absl::StatusOr<CallArgs> call_args;
|
||||
grpc_metadata_array md =
|
||||
MetadataBatchToMetadataArray(call_args->client_initial_metadata.get());
|
||||
std::atomic<bool> done{false};
|
||||
};
|
||||
|
||||
// Called from application code.
|
||||
static void OnMdProcessingDone(
|
||||
void* user_data, const grpc_metadata* consumed_md, size_t num_consumed_md,
|
||||
const grpc_metadata* response_md, size_t num_response_md,
|
||||
grpc_status_code status, const char* error_details) {
|
||||
ApplicationCallbackExecCtx callback_exec_ctx;
|
||||
ExecCtx exec_ctx;
|
||||
|
||||
auto* state = static_cast<State*>(user_data);
|
||||
|
||||
// TODO(ZhenLian): Implement support for response_md.
|
||||
if (response_md != nullptr && num_response_md > 0) {
|
||||
gpr_log(GPR_ERROR,
|
||||
"response_md in auth metadata processing not supported for now. "
|
||||
"Ignoring...");
|
||||
}
|
||||
|
||||
if (status == GRPC_STATUS_OK) {
|
||||
ClientMetadataHandle& md = state->call_args->client_initial_metadata;
|
||||
for (size_t i = 0; i < num_consumed_md; i++) {
|
||||
md->Remove(StringViewFromSlice(consumed_md[i].key));
|
||||
}
|
||||
} else {
|
||||
if (error_details == nullptr) {
|
||||
error_details = "Authentication metadata processing failed.";
|
||||
}
|
||||
state->call_args = grpc_error_set_int(
|
||||
absl::Status(static_cast<absl::StatusCode>(status), error_details),
|
||||
StatusIntProperty::kRpcStatus, status);
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
for (size_t i = 0; i < state->md.count; i++) {
|
||||
CSliceUnref(state->md.metadata[i].key);
|
||||
CSliceUnref(state->md.metadata[i].value);
|
||||
}
|
||||
grpc_metadata_array_destroy(&state->md);
|
||||
|
||||
auto waker = std::move(state->waker);
|
||||
state->done.store(true, std::memory_order_release);
|
||||
waker.Wakeup();
|
||||
}
|
||||
|
||||
State* state_;
|
||||
};
|
||||
|
||||
ArenaPromise<ServerMetadataHandle> LegacyServerAuthFilter::MakeCallPromise(
|
||||
CallArgs call_args, NextPromiseFactory next_promise_factory) {
|
||||
// Create server security context. Set its auth context from channel
|
||||
// data and save it in the call context.
|
||||
grpc_server_security_context* server_ctx =
|
||||
grpc_server_security_context_create(GetContext<Arena>());
|
||||
server_ctx->auth_context =
|
||||
auth_context_->Ref(DEBUG_LOCATION, "server_auth_filter");
|
||||
grpc_call_context_element& context =
|
||||
GetContext<grpc_call_context_element>()[GRPC_CONTEXT_SECURITY];
|
||||
if (context.value != nullptr) context.destroy(context.value);
|
||||
context.value = server_ctx;
|
||||
context.destroy = grpc_server_security_context_destroy;
|
||||
|
||||
if (server_credentials_ == nullptr ||
|
||||
server_credentials_->auth_metadata_processor().process == nullptr) {
|
||||
return next_promise_factory(std::move(call_args));
|
||||
}
|
||||
|
||||
return TrySeq(RunApplicationCode(this, std::move(call_args)),
|
||||
std::move(next_promise_factory));
|
||||
}
|
||||
|
||||
LegacyServerAuthFilter::LegacyServerAuthFilter(
|
||||
RefCountedPtr<grpc_server_credentials> server_credentials,
|
||||
RefCountedPtr<grpc_auth_context> auth_context)
|
||||
: server_credentials_(server_credentials), auth_context_(auth_context) {}
|
||||
|
||||
absl::StatusOr<LegacyServerAuthFilter> LegacyServerAuthFilter::Create(
|
||||
const ChannelArgs& args, ChannelFilter::Args) {
|
||||
auto auth_context = args.GetObjectRef<grpc_auth_context>();
|
||||
GPR_ASSERT(auth_context != nullptr);
|
||||
auto creds = args.GetObjectRef<grpc_server_credentials>();
|
||||
return LegacyServerAuthFilter(std::move(creds), std::move(auth_context));
|
||||
}
|
||||
|
||||
} // namespace grpc_core
|
||||
|
|
@ -66,6 +66,12 @@ const grpc_channel_filter ServerAuthFilter::kFilter =
|
|||
MakePromiseBasedFilter<ServerAuthFilter, FilterEndpoint::kServer>(
|
||||
"server-auth");
|
||||
|
||||
const NoInterceptor ServerAuthFilter::Call::OnClientToServerMessage;
|
||||
const NoInterceptor ServerAuthFilter::Call::OnServerToClientMessage;
|
||||
const NoInterceptor ServerAuthFilter::Call::OnServerInitialMetadata;
|
||||
const NoInterceptor ServerAuthFilter::Call::OnServerTrailingMetadata;
|
||||
const NoInterceptor ServerAuthFilter::Call::OnFinalize;
|
||||
|
||||
namespace {
|
||||
|
||||
class ArrayEncoder {
|
||||
|
|
@ -114,118 +120,92 @@ grpc_metadata_array MetadataBatchToMetadataArray(
|
|||
|
||||
} // namespace
|
||||
|
||||
class ServerAuthFilter::RunApplicationCode {
|
||||
public:
|
||||
// TODO(ctiller): Allocate state_ into a pool on the arena to reuse this
|
||||
// memory later
|
||||
RunApplicationCode(ServerAuthFilter* filter, CallArgs call_args)
|
||||
: state_(GetContext<Arena>()->ManagedNew<State>(std::move(call_args))) {
|
||||
if (grpc_call_trace.enabled()) {
|
||||
gpr_log(GPR_ERROR,
|
||||
"%s[server-auth]: Delegate to application: filter=%p this=%p "
|
||||
"auth_ctx=%p",
|
||||
Activity::current()->DebugTag().c_str(), filter, this,
|
||||
filter->auth_context_.get());
|
||||
}
|
||||
filter->server_credentials_->auth_metadata_processor().process(
|
||||
filter->server_credentials_->auth_metadata_processor().state,
|
||||
filter->auth_context_.get(), state_->md.metadata, state_->md.count,
|
||||
OnMdProcessingDone, state_);
|
||||
}
|
||||
|
||||
RunApplicationCode(const RunApplicationCode&) = delete;
|
||||
RunApplicationCode& operator=(const RunApplicationCode&) = delete;
|
||||
RunApplicationCode(RunApplicationCode&& other) noexcept
|
||||
: state_(std::exchange(other.state_, nullptr)) {}
|
||||
RunApplicationCode& operator=(RunApplicationCode&& other) noexcept {
|
||||
state_ = std::exchange(other.state_, nullptr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Poll<absl::StatusOr<CallArgs>> operator()() {
|
||||
if (state_->done.load(std::memory_order_acquire)) {
|
||||
return Poll<absl::StatusOr<CallArgs>>(std::move(state_->call_args));
|
||||
}
|
||||
return Pending{};
|
||||
}
|
||||
|
||||
private:
|
||||
struct State {
|
||||
explicit State(CallArgs call_args) : call_args(std::move(call_args)) {}
|
||||
Waker waker{Activity::current()->MakeOwningWaker()};
|
||||
absl::StatusOr<CallArgs> call_args;
|
||||
grpc_metadata_array md =
|
||||
MetadataBatchToMetadataArray(call_args->client_initial_metadata.get());
|
||||
std::atomic<bool> done{false};
|
||||
};
|
||||
|
||||
// Called from application code.
|
||||
static void OnMdProcessingDone(
|
||||
void* user_data, const grpc_metadata* consumed_md, size_t num_consumed_md,
|
||||
const grpc_metadata* response_md, size_t num_response_md,
|
||||
grpc_status_code status, const char* error_details) {
|
||||
ApplicationCallbackExecCtx callback_exec_ctx;
|
||||
ExecCtx exec_ctx;
|
||||
|
||||
auto* state = static_cast<State*>(user_data);
|
||||
|
||||
// TODO(ZhenLian): Implement support for response_md.
|
||||
if (response_md != nullptr && num_response_md > 0) {
|
||||
gpr_log(GPR_ERROR,
|
||||
"response_md in auth metadata processing not supported for now. "
|
||||
"Ignoring...");
|
||||
}
|
||||
|
||||
if (status == GRPC_STATUS_OK) {
|
||||
ClientMetadataHandle& md = state->call_args->client_initial_metadata;
|
||||
for (size_t i = 0; i < num_consumed_md; i++) {
|
||||
md->Remove(StringViewFromSlice(consumed_md[i].key));
|
||||
}
|
||||
} else {
|
||||
if (error_details == nullptr) {
|
||||
error_details = "Authentication metadata processing failed.";
|
||||
}
|
||||
state->call_args = grpc_error_set_int(
|
||||
absl::Status(static_cast<absl::StatusCode>(status), error_details),
|
||||
StatusIntProperty::kRpcStatus, status);
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
for (size_t i = 0; i < state->md.count; i++) {
|
||||
CSliceUnref(state->md.metadata[i].key);
|
||||
CSliceUnref(state->md.metadata[i].value);
|
||||
}
|
||||
grpc_metadata_array_destroy(&state->md);
|
||||
|
||||
auto waker = std::move(state->waker);
|
||||
state->done.store(true, std::memory_order_release);
|
||||
waker.Wakeup();
|
||||
}
|
||||
|
||||
State* state_;
|
||||
struct ServerAuthFilter::RunApplicationCode::State {
|
||||
explicit State(ClientMetadata& client_metadata)
|
||||
: client_metadata(&client_metadata) {}
|
||||
Waker waker{Activity::current()->MakeOwningWaker()};
|
||||
absl::StatusOr<ClientMetadata*> client_metadata;
|
||||
grpc_metadata_array md = MetadataBatchToMetadataArray(*client_metadata);
|
||||
std::atomic<bool> done{false};
|
||||
};
|
||||
|
||||
ArenaPromise<ServerMetadataHandle> ServerAuthFilter::MakeCallPromise(
|
||||
CallArgs call_args, NextPromiseFactory next_promise_factory) {
|
||||
ServerAuthFilter::RunApplicationCode::RunApplicationCode(
|
||||
ServerAuthFilter* filter, ClientMetadata& metadata)
|
||||
: state_(GetContext<Arena>()->ManagedNew<State>(metadata)) {
|
||||
if (grpc_call_trace.enabled()) {
|
||||
gpr_log(GPR_ERROR,
|
||||
"%s[server-auth]: Delegate to application: filter=%p this=%p "
|
||||
"auth_ctx=%p",
|
||||
Activity::current()->DebugTag().c_str(), filter, this,
|
||||
filter->auth_context_.get());
|
||||
}
|
||||
filter->server_credentials_->auth_metadata_processor().process(
|
||||
filter->server_credentials_->auth_metadata_processor().state,
|
||||
filter->auth_context_.get(), state_->md.metadata, state_->md.count,
|
||||
OnMdProcessingDone, state_);
|
||||
}
|
||||
|
||||
Poll<absl::Status> ServerAuthFilter::RunApplicationCode::operator()() {
|
||||
if (state_->done.load(std::memory_order_acquire)) {
|
||||
return Poll<absl::Status>(std::move(state_->client_metadata).status());
|
||||
}
|
||||
return Pending{};
|
||||
}
|
||||
|
||||
void ServerAuthFilter::RunApplicationCode::OnMdProcessingDone(
|
||||
void* user_data, const grpc_metadata* consumed_md, size_t num_consumed_md,
|
||||
const grpc_metadata* response_md, size_t num_response_md,
|
||||
grpc_status_code status, const char* error_details) {
|
||||
ApplicationCallbackExecCtx callback_exec_ctx;
|
||||
ExecCtx exec_ctx;
|
||||
|
||||
auto* state = static_cast<State*>(user_data);
|
||||
|
||||
// TODO(ZhenLian): Implement support for response_md.
|
||||
if (response_md != nullptr && num_response_md > 0) {
|
||||
gpr_log(GPR_ERROR,
|
||||
"response_md in auth metadata processing not supported for now. "
|
||||
"Ignoring...");
|
||||
}
|
||||
|
||||
if (status == GRPC_STATUS_OK) {
|
||||
ClientMetadata& md = **state->client_metadata;
|
||||
for (size_t i = 0; i < num_consumed_md; i++) {
|
||||
md.Remove(StringViewFromSlice(consumed_md[i].key));
|
||||
}
|
||||
} else {
|
||||
if (error_details == nullptr) {
|
||||
error_details = "Authentication metadata processing failed.";
|
||||
}
|
||||
state->client_metadata = grpc_error_set_int(
|
||||
absl::Status(static_cast<absl::StatusCode>(status), error_details),
|
||||
StatusIntProperty::kRpcStatus, status);
|
||||
}
|
||||
|
||||
// Clean up.
|
||||
for (size_t i = 0; i < state->md.count; i++) {
|
||||
CSliceUnref(state->md.metadata[i].key);
|
||||
CSliceUnref(state->md.metadata[i].value);
|
||||
}
|
||||
grpc_metadata_array_destroy(&state->md);
|
||||
|
||||
auto waker = std::move(state->waker);
|
||||
state->done.store(true, std::memory_order_release);
|
||||
waker.Wakeup();
|
||||
}
|
||||
|
||||
ServerAuthFilter::Call::Call(ServerAuthFilter* filter) {
|
||||
// Create server security context. Set its auth context from channel
|
||||
// data and save it in the call context.
|
||||
grpc_server_security_context* server_ctx =
|
||||
grpc_server_security_context_create(GetContext<Arena>());
|
||||
server_ctx->auth_context =
|
||||
auth_context_->Ref(DEBUG_LOCATION, "server_auth_filter");
|
||||
filter->auth_context_->Ref(DEBUG_LOCATION, "server_auth_filter");
|
||||
grpc_call_context_element& context =
|
||||
GetContext<grpc_call_context_element>()[GRPC_CONTEXT_SECURITY];
|
||||
if (context.value != nullptr) context.destroy(context.value);
|
||||
context.value = server_ctx;
|
||||
context.destroy = grpc_server_security_context_destroy;
|
||||
|
||||
if (server_credentials_ == nullptr ||
|
||||
server_credentials_->auth_metadata_processor().process == nullptr) {
|
||||
return next_promise_factory(std::move(call_args));
|
||||
}
|
||||
|
||||
return TrySeq(RunApplicationCode(this, std::move(call_args)),
|
||||
std::move(next_promise_factory));
|
||||
}
|
||||
|
||||
ServerAuthFilter::ServerAuthFilter(
|
||||
|
|
|
|||
|
|
@ -72,14 +72,20 @@ void RegisterSecurityFilters(CoreConfiguration::Builder* builder) {
|
|||
builder->channel_init()
|
||||
->RegisterFilter(GRPC_CLIENT_DIRECT_CHANNEL, &ClientAuthFilter::kFilter)
|
||||
.IfHasChannelArg(GRPC_ARG_SECURITY_CONNECTOR);
|
||||
builder->channel_init()
|
||||
->RegisterFilter(GRPC_SERVER_CHANNEL, &ServerAuthFilter::kFilter)
|
||||
.IfHasChannelArg(GRPC_SERVER_CREDENTIALS_ARG);
|
||||
if (IsV3ServerAuthFilterEnabled()) {
|
||||
builder->channel_init()
|
||||
->RegisterFilter(GRPC_SERVER_CHANNEL, &ServerAuthFilter::kFilter)
|
||||
.IfHasChannelArg(GRPC_SERVER_CREDENTIALS_ARG);
|
||||
} else {
|
||||
builder->channel_init()
|
||||
->RegisterFilter(GRPC_SERVER_CHANNEL, &LegacyServerAuthFilter::kFilter)
|
||||
.IfHasChannelArg(GRPC_SERVER_CREDENTIALS_ARG);
|
||||
}
|
||||
builder->channel_init()
|
||||
->RegisterFilter(GRPC_SERVER_CHANNEL,
|
||||
&GrpcServerAuthzFilter::kFilterVtable)
|
||||
.IfHasChannelArg(GRPC_ARG_AUTHORIZATION_POLICY_PROVIDER)
|
||||
.After({&ServerAuthFilter::kFilter});
|
||||
.After({&ServerAuthFilter::kFilter, &LegacyServerAuthFilter::kFilter});
|
||||
}
|
||||
} // namespace grpc_core
|
||||
|
||||
|
|
|
|||
|
|
@ -765,6 +765,7 @@ CORE_SOURCE_FILES = [
|
|||
'src/core/lib/security/security_connector/ssl_utils.cc',
|
||||
'src/core/lib/security/security_connector/tls/tls_security_connector.cc',
|
||||
'src/core/lib/security/transport/client_auth_filter.cc',
|
||||
'src/core/lib/security/transport/legacy_server_auth_filter.cc',
|
||||
'src/core/lib/security/transport/secure_endpoint.cc',
|
||||
'src/core/lib/security/transport/security_handshaker.cc',
|
||||
'src/core/lib/security/transport/server_auth_filter.cc',
|
||||
|
|
|
|||
|
|
@ -2803,6 +2803,7 @@ src/core/lib/security/security_connector/tls/tls_security_connector.cc \
|
|||
src/core/lib/security/security_connector/tls/tls_security_connector.h \
|
||||
src/core/lib/security/transport/auth_filters.h \
|
||||
src/core/lib/security/transport/client_auth_filter.cc \
|
||||
src/core/lib/security/transport/legacy_server_auth_filter.cc \
|
||||
src/core/lib/security/transport/secure_endpoint.cc \
|
||||
src/core/lib/security/transport/secure_endpoint.h \
|
||||
src/core/lib/security/transport/security_handshaker.cc \
|
||||
|
|
|
|||
|
|
@ -2582,6 +2582,7 @@ src/core/lib/security/security_connector/tls/tls_security_connector.cc \
|
|||
src/core/lib/security/security_connector/tls/tls_security_connector.h \
|
||||
src/core/lib/security/transport/auth_filters.h \
|
||||
src/core/lib/security/transport/client_auth_filter.cc \
|
||||
src/core/lib/security/transport/legacy_server_auth_filter.cc \
|
||||
src/core/lib/security/transport/secure_endpoint.cc \
|
||||
src/core/lib/security/transport/secure_endpoint.h \
|
||||
src/core/lib/security/transport/security_handshaker.cc \
|
||||
|
|
|
|||
Loading…
Reference in New Issue