Skip to content

Commit efddfed

Browse files
committed
CXXCBC-739: Support mTLS Cert Refresh (without restart)
1 parent 4952733 commit efddfed

12 files changed

+168
-0
lines changed

core/cluster.cxx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "core/app_telemetry_meter.hxx"
2525
#include "core/app_telemetry_reporter.hxx"
2626
#include "core/diagnostics.hxx"
27+
#include "core/error.hxx"
2728
#include "core/impl/get_replica.hxx"
2829
#include "core/impl/lookup_in_replica.hxx"
2930
#include "core/impl/observe_seqno.hxx"
@@ -521,6 +522,21 @@ class cluster_impl : public std::enable_shared_from_this<cluster_impl>
521522
return handler({});
522523
}
523524

525+
auto update_credentials(cluster_credentials auth) -> core::error
526+
{
527+
if (stopped_) {
528+
return { errc::network::cluster_closed, {} };
529+
}
530+
531+
if (auth.requires_tls() && !origin_.options().enable_tls) {
532+
return { errc::common::invalid_argument,
533+
"TLS not enabled but the provided authenticator requires TLS" };
534+
}
535+
536+
origin_.update_credentials(std::move(auth));
537+
return {};
538+
}
539+
524540
auto origin() const -> std::pair<std::error_code, couchbase::core::origin>
525541
{
526542
if (stopped_) {
@@ -1437,6 +1453,15 @@ cluster::origin() const -> std::pair<std::error_code, couchbase::core::origin>
14371453
return { errc::network::cluster_closed, {} };
14381454
}
14391455

1456+
auto
1457+
cluster::update_credentials(core::cluster_credentials auth) -> core::error
1458+
{
1459+
if (impl_) {
1460+
return impl_->update_credentials(std::move(auth));
1461+
}
1462+
return { errc::network::cluster_closed, {} };
1463+
}
1464+
14401465
auto
14411466
cluster::io_context() const -> asio::io_context&
14421467
{

core/cluster.hxx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#pragma once
1919

2020
#include "diagnostics.hxx"
21+
#include "error.hxx"
2122
#include "operations_fwd.hxx"
2223
#include "origin.hxx"
2324
#include "topology/configuration.hxx"
@@ -85,6 +86,8 @@ public:
8586
utils::movable_function<void(std::error_code, std::shared_ptr<topology::configuration>)>&&
8687
handler) const;
8788

89+
[[nodiscard]] auto update_credentials(core::cluster_credentials auth) -> core::error;
90+
8891
void execute(o::analytics_request request, mf<void(o::analytics_response)>&& handler) const;
8992
void execute(o::append_request request, mf<void(o::append_response)>&& handler) const;
9093
void execute(o::decrement_request request, mf<void(o::decrement_response)>&& handler) const;

core/cluster_credentials.cxx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,11 @@ cluster_credentials::uses_certificate() const -> bool
2424
{
2525
return !certificate_path.empty();
2626
}
27+
28+
auto
29+
cluster_credentials::requires_tls() const -> bool
30+
{
31+
return !certificate_path.empty() && !key_path.empty();
32+
}
33+
2734
} // namespace couchbase::core

core/cluster_credentials.hxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct cluster_credentials {
3131
std::optional<std::vector<std::string>> allowed_sasl_mechanisms{};
3232

3333
[[nodiscard]] auto uses_certificate() const -> bool;
34+
[[nodiscard]] auto requires_tls() const -> bool;
3435
};
3536

3637
} // namespace couchbase::core

core/impl/public_cluster.cxx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,15 @@ class cluster_impl : public std::enable_shared_from_this<cluster_impl>
416416
});
417417
}
418418

419+
auto set_authenticator(core::cluster_credentials auth) -> error
420+
{
421+
auto e = core_.update_credentials(std::move(auth));
422+
if (e.ec) {
423+
return core::impl::make_error(e);
424+
}
425+
return {};
426+
}
427+
419428
void notify_fork(fork_event event)
420429
{
421430
if (event == fork_event::prepare) {
@@ -700,6 +709,29 @@ cluster::close() -> std::future<void>
700709
return future;
701710
}
702711

712+
auto
713+
cluster::set_authenticator(const password_authenticator& authenticator) -> couchbase::error
714+
{
715+
core::cluster_credentials auth;
716+
auth.username = authenticator.username_;
717+
auth.password = authenticator.password_;
718+
if (authenticator.ldap_compatible_) {
719+
auth.allowed_sasl_mechanisms = { { "PLAIN" } };
720+
}
721+
722+
return impl_->set_authenticator(std::move(auth));
723+
}
724+
725+
auto
726+
cluster::set_authenticator(const certificate_authenticator& authenticator) -> couchbase::error
727+
{
728+
core::cluster_credentials auth;
729+
auth.certificate_path = authenticator.certificate_path_;
730+
auth.key_path = authenticator.key_path_;
731+
732+
return impl_->set_authenticator(std::move(auth));
733+
}
734+
703735
auto
704736
cluster::query_indexes() const -> query_index_manager
705737
{

core/origin.cxx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,11 @@ couchbase::core::origin::set_nodes_from_config(const topology::configuration& co
468468
}
469469
next_node_ = nodes_.begin();
470470
}
471+
void
472+
couchbase::core::origin::update_credentials(cluster_credentials auth)
473+
{
474+
credentials_ = std::move(auth);
475+
}
471476
auto
472477
couchbase::core::origin::next_address() -> std::pair<std::string, std::string>
473478
{

core/origin.hxx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ struct origin {
7171
void set_nodes(node_list nodes);
7272
void set_nodes_from_config(const topology::configuration& config);
7373

74+
void update_credentials(cluster_credentials auth);
75+
7476
[[nodiscard]] auto next_address() -> std::pair<std::string, std::string>;
7577

7678
[[nodiscard]] auto exhausted() const -> bool;

couchbase/certificate_authenticator.hxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,6 @@ private:
3535
std::string key_path_;
3636

3737
friend class cluster_options;
38+
friend class cluster;
3839
};
3940
} // namespace couchbase

couchbase/cluster.hxx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,38 @@ public:
102102
void close(std::function<void()>&& handler);
103103
[[nodiscard]] auto close() -> std::future<void>;
104104

105+
/**
106+
* Replaces the current authenticator used by this cluster.
107+
*
108+
* NOTE: Setting a new authenticator does not change the authentication status of existing
109+
* connections.
110+
*
111+
* @param authenticator the authenticator to replace
112+
*
113+
* @return error
114+
*
115+
* @since 1.3.0
116+
* @committed
117+
*/
118+
auto set_authenticator(const password_authenticator& authenticator) -> error;
119+
120+
/**
121+
* Replaces the current authenticator used by this cluster.
122+
*
123+
* NOTE: Setting a new authenticator does not change the authentication status of existing
124+
connections.
125+
*
126+
* @param authenticator the authenticator to replace
127+
128+
* @exception errc::common::invalid_argument if TLS is not enabled.
129+
*
130+
* @return error
131+
*
132+
* @since 1.3.0
133+
* @committed
134+
*/
135+
auto set_authenticator(const certificate_authenticator& authenticator) -> error;
136+
105137
/**
106138
* Opens a {@link bucket} with the given name.
107139
*

couchbase/password_authenticator.hxx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,6 @@ private:
4343
bool ldap_compatible_{ false };
4444

4545
friend class cluster_options;
46+
friend class cluster;
4647
};
4748
} // namespace couchbase

0 commit comments

Comments
 (0)