#pragma once #include "envoy/config/core/v3/config_source.pb.h" #include "envoy/extensions/transport_sockets/tls/v3/cert.pb.h" #include "envoy/secret/secret_manager.h" #include "envoy/secret/secret_provider.h" #include "envoy/server/transport_socket_config.h" #include "envoy/ssl/certificate_validation_context_config.h" #include "envoy/ssl/tls_certificate_config.h" #include "common/common/logger.h" #include "common/secret/sds_api.h" #include "absl/container/node_hash_map.h" namespace Envoy { namespace Secret { class SecretManagerImpl : public SecretManager { public: SecretManagerImpl(Server::ConfigTracker& config_tracker); void addStaticSecret(const envoy::extensions::transport_sockets::tls::v3::Secret& secret) override; TlsCertificateConfigProviderSharedPtr findStaticTlsCertificateProvider(const std::string& name) const override; CertificateValidationContextConfigProviderSharedPtr findStaticCertificateValidationContextProvider(const std::string& name) const override; TlsSessionTicketKeysConfigProviderSharedPtr findStaticTlsSessionTicketKeysContextProvider(const std::string& name) const override; GenericSecretConfigProviderSharedPtr findStaticGenericSecretProvider(const std::string& name) const override; TlsCertificateConfigProviderSharedPtr createInlineTlsCertificateProvider( const envoy::extensions::transport_sockets::tls::v3::TlsCertificate& tls_certificate) override; CertificateValidationContextConfigProviderSharedPtr createInlineCertificateValidationContextProvider( const envoy::extensions::transport_sockets::tls::v3::CertificateValidationContext& certificate_validation_context) override; TlsSessionTicketKeysConfigProviderSharedPtr createInlineTlsSessionTicketKeysProvider( const envoy::extensions::transport_sockets::tls::v3::TlsSessionTicketKeys& tls_session_ticket_keys) override; GenericSecretConfigProviderSharedPtr createInlineGenericSecretProvider( const envoy::extensions::transport_sockets::tls::v3::GenericSecret& generic_secret) override; TlsCertificateConfigProviderSharedPtr findOrCreateTlsCertificateProvider( const envoy::config::core::v3::ConfigSource& config_source, const std::string& config_name, Server::Configuration::TransportSocketFactoryContext& secret_provider_context) override; CertificateValidationContextConfigProviderSharedPtr findOrCreateCertificateValidationContextProvider( const envoy::config::core::v3::ConfigSource& config_source, const std::string& config_name, Server::Configuration::TransportSocketFactoryContext& secret_provider_context) override; TlsSessionTicketKeysConfigProviderSharedPtr findOrCreateTlsSessionTicketKeysContextProvider( const envoy::config::core::v3::ConfigSource& config_source, const std::string& config_name, Server::Configuration::TransportSocketFactoryContext& secret_provider_context) override; GenericSecretConfigProviderSharedPtr findOrCreateGenericSecretProvider( const envoy::config::core::v3::ConfigSource& config_source, const std::string& config_name, Server::Configuration::TransportSocketFactoryContext& secret_provider_context) override; private: ProtobufTypes::MessagePtr dumpSecretConfigs(); template class DynamicSecretProviders : public Logger::Loggable { public: // Finds or creates SdsApi object. std::shared_ptr findOrCreate(const envoy::config::core::v3::ConfigSource& sds_config_source, const std::string& config_name, Server::Configuration::TransportSocketFactoryContext& secret_provider_context) { const std::string map_key = absl::StrCat(MessageUtil::hash(sds_config_source), ".", config_name); std::shared_ptr secret_provider = dynamic_secret_providers_[map_key].lock(); if (!secret_provider) { // SdsApi is owned by ListenerImpl and ClusterInfo which are destroyed before // SecretManagerImpl. It is safe to invoke this callback at the destructor of SdsApi. std::function unregister_secret_provider = [map_key, this]() { removeDynamicSecretProvider(map_key); }; secret_provider = SecretType::create(secret_provider_context, sds_config_source, config_name, unregister_secret_provider); dynamic_secret_providers_[map_key] = secret_provider; } return secret_provider; } std::vector> allSecretProviders() { std::vector> providers; for (const auto& secret_entry : dynamic_secret_providers_) { std::shared_ptr secret_provider = secret_entry.second.lock(); if (secret_provider) { providers.push_back(std::move(secret_provider)); } } return providers; } private: // Removes dynamic secret provider which has been deleted. void removeDynamicSecretProvider(const std::string& map_key) { ENVOY_LOG(debug, "Unregister secret provider. hash key: {}", map_key); auto num_deleted = dynamic_secret_providers_.erase(map_key); ASSERT(num_deleted == 1, ""); } absl::node_hash_map> dynamic_secret_providers_; }; // Manages pairs of secret name and TlsCertificateConfigProviderSharedPtr. absl::node_hash_map static_tls_certificate_providers_; // Manages pairs of secret name and CertificateValidationContextConfigProviderSharedPtr. absl::node_hash_map static_certificate_validation_context_providers_; absl::node_hash_map static_session_ticket_keys_providers_; // Manages pairs of secret name and GenericSecretConfigProviderSharedPtr. absl::node_hash_map static_generic_secret_providers_; // map hash code of SDS config source and SdsApi object. DynamicSecretProviders certificate_providers_; DynamicSecretProviders validation_context_providers_; DynamicSecretProviders session_ticket_keys_providers_; DynamicSecretProviders generic_secret_providers_; Server::ConfigTracker::EntryOwnerPtr config_tracker_entry_; }; } // namespace Secret } // namespace Envoy