This is an automated email from the ASF dual-hosted git repository.

wangdan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-pegasus.git


The following commit(s) were added to refs/heads/master by this push:
     new dea36b1d4 refactor: optimize zookeeper client init for sasl (#1914)
dea36b1d4 is described below

commit dea36b1d4e9948368fd0c99f62b3f99f5ce5bb17
Author: Guohao Li <[email protected]>
AuthorDate: Tue Feb 27 17:53:25 2024 +0800

    refactor: optimize zookeeper client init for sasl (#1914)
    
    Reference:
    zookeeper 3.7 client
    
https://github.com/apache/zookeeper/blob/branch-3.7/zookeeper-client/zookeeper-client-c/src/cli.c
    
    Notes:
    If you want to use kerberos zookeeper before, you just need to set 
[security]
    enable_zookeeper_kerberos to "true" and do some kerberos configurations.
    After this commit, you also need to set [zookeeper] sasl_mechanisms_type
    to "GSSAPI". Otherwise, you'll get an error log prompting you to make 
changes.
    
    Some configurations are added:
    ```diff
    [zookeeper]
    sasl_service_name = zookeeper
    sasl_service_fqdn =
    sasl_mechanisms_type =
    sasl_user_name =
    sasl_realm =
    sasl_password_file =
    ```
---
 src/zookeeper/zookeeper_session.cpp | 118 +++++++++++++++++++++++++++++-------
 1 file changed, 95 insertions(+), 23 deletions(-)

diff --git a/src/zookeeper/zookeeper_session.cpp 
b/src/zookeeper/zookeeper_session.cpp
index ae3618795..ed4d6b9d2 100644
--- a/src/zookeeper/zookeeper_session.cpp
+++ b/src/zookeeper/zookeeper_session.cpp
@@ -24,6 +24,7 @@
  * THE SOFTWARE.
  */
 
+#include <sasl/sasl.h>
 #include <stdlib.h>
 #include <zookeeper/zookeeper.h>
 #include <algorithm>
@@ -31,8 +32,10 @@
 
 #include "runtime/app_model.h"
 #include "runtime/rpc/rpc_address.h"
+#include "utils/filesystem.h"
 #include "utils/flags.h"
 #include "utils/fmt_logging.h"
+#include "utils/strings.h"
 #include "zookeeper/proto.h"
 #include "zookeeper/zookeeper.jute.h"
 #include "zookeeper_session.h"
@@ -40,12 +43,12 @@
 DSN_DECLARE_bool(enable_zookeeper_kerberos);
 DSN_DEFINE_string(security,
                   zookeeper_kerberos_service_name,
-                  "zookeeper",
-                  "zookeeper kerberos service name");
+                  "",
+                  "[Deprecated] zookeeper kerberos service name");
 DSN_DEFINE_string(security,
                   zookeeper_sasl_service_fqdn,
                   "",
-                  "The FQDN of a Zookeeper server, used in Kerberos 
Principal");
+                  "[Deprecated] The FQDN of a Zookeeper server, used in 
Kerberos Principal");
 // TODO(yingchun): to keep compatibility, the global name is FLAGS_timeout_ms. 
The name is not very
 //  suitable, maybe improve the macro to us another global name.
 DSN_DEFINE_int32(zookeeper,
@@ -53,6 +56,47 @@ DSN_DEFINE_int32(zookeeper,
                  30000,
                  "The timeout of accessing ZooKeeper, in milliseconds");
 DSN_DEFINE_string(zookeeper, hosts_list, "", "Zookeeper hosts list");
+DSN_DEFINE_string(zookeeper, sasl_service_name, "zookeeper", "");
+DSN_DEFINE_string(zookeeper,
+                  sasl_service_fqdn,
+                  "",
+                  "SASL server name ('zk-sasl-md5' for DIGEST-MD5; default: 
reverse DNS lookup)");
+DSN_DEFINE_string(zookeeper,
+                  sasl_mechanisms_type,
+                  "",
+                  "SASL mechanisms (GSSAPI and/or DIGEST-MD5)");
+DSN_DEFINE_string(zookeeper, sasl_user_name, "", "");
+DSN_DEFINE_string(zookeeper, sasl_realm, "", "Realm (for SASL/GSSAPI)");
+DSN_DEFINE_string(zookeeper,
+                  sasl_password_file,
+                  "",
+                  "File containing the password (recommended for 
SASL/DIGEST-MD5)");
+DSN_DEFINE_group_validator(enable_zookeeper_kerberos, [](std::string &message) 
-> bool {
+    if (FLAGS_enable_zookeeper_kerberos &&
+        !dsn::utils::equals(FLAGS_sasl_mechanisms_type, "GSSAPI")) {
+        message = "Please set [zookeeper] sasl_mechanisms_type to GSSAPI if 
[security] "
+                  "enable_zookeeper_kerberos is true.";
+        return false;
+    }
+
+    return true;
+});
+DSN_DEFINE_group_validator(consistency_between_configurations, [](std::string 
&message) -> bool {
+    if (!dsn::utils::is_empty(FLAGS_zookeeper_kerberos_service_name) &&
+        !dsn::utils::equals(FLAGS_zookeeper_kerberos_service_name, 
FLAGS_sasl_service_name)) {
+        message = "zookeeper_kerberos_service_name deprecated, if set should 
be same as "
+                  "sasl_service_name.";
+        return false;
+    }
+    if (!dsn::utils::is_empty(FLAGS_zookeeper_sasl_service_fqdn) &&
+        !dsn::utils::equals(FLAGS_zookeeper_sasl_service_fqdn, 
FLAGS_sasl_service_fqdn)) {
+        message =
+            "zookeeper_sasl_service_fqdn deprecated, if set should be same as 
sasl_service_fqdn.";
+        return false;
+    }
+
+    return true;
+});
 
 namespace dsn {
 namespace dist {
@@ -157,29 +201,57 @@ zookeeper_session::zookeeper_session(const 
service_app_info &node) : _handle(nul
 int zookeeper_session::attach(void *callback_owner, const state_callback &cb)
 {
     utils::auto_write_lock l(_watcher_lock);
-    if (nullptr == _handle) {
-        if (FLAGS_enable_zookeeper_kerberos) {
-            zoo_sasl_params_t sasl_params = {0};
-            sasl_params.service = FLAGS_zookeeper_kerberos_service_name;
-            sasl_params.mechlist = "GSSAPI";
-            
CHECK(dsn::rpc_address::from_host_port(FLAGS_zookeeper_sasl_service_fqdn),
-                  "zookeeper_sasl_service_fqdn {} is invalid",
-                  FLAGS_zookeeper_sasl_service_fqdn);
-            sasl_params.host = FLAGS_zookeeper_sasl_service_fqdn;
-            _handle = zookeeper_init_sasl(FLAGS_hosts_list,
-                                          global_watcher,
-                                          FLAGS_timeout_ms,
-                                          nullptr,
-                                          this,
-                                          0,
-                                          NULL,
-                                          &sasl_params);
-        } else {
+    do {
+        if (nullptr != _handle) {
+            break;
+        }
+        if (utils::is_empty(FLAGS_sasl_mechanisms_type)) {
             _handle = zookeeper_init(
                 FLAGS_hosts_list, global_watcher, FLAGS_timeout_ms, nullptr, 
this, 0);
+            break;
         }
-        CHECK_NOTNULL(_handle, "zookeeper session init failed");
-    }
+        int err = sasl_client_init(nullptr);
+        CHECK_EQ_MSG(err,
+                     SASL_OK,
+                     "Unable to initialize SASL library {}",
+                     sasl_errstring(err, nullptr, nullptr));
+
+        if (!utils::is_empty(FLAGS_sasl_password_file)) {
+            CHECK(utils::filesystem::file_exists(FLAGS_sasl_password_file),
+                  "sasl_password_file {} not exist!",
+                  FLAGS_sasl_password_file);
+        }
+
+        auto param_host = "";
+        if (!utils::is_empty(FLAGS_sasl_service_fqdn)) {
+            CHECK(dsn::rpc_address::from_host_port(FLAGS_sasl_service_fqdn),
+                  "sasl_service_fqdn '{}' is invalid",
+                  FLAGS_sasl_service_fqdn);
+            param_host = FLAGS_sasl_service_fqdn;
+        }
+        // DIGEST-MD5 requires '--server-fqdn zk-sasl-md5' for historical 
reasons on zk c client
+        if (dsn::utils::equals(FLAGS_sasl_mechanisms_type, "DIGEST-MD5")) {
+            param_host = "zk-sasl-md5";
+        }
+
+        zoo_sasl_params_t sasl_params = {0};
+        sasl_params.service = FLAGS_sasl_service_name;
+        sasl_params.mechlist = FLAGS_sasl_mechanisms_type;
+        sasl_params.host = param_host;
+        sasl_params.callbacks = zoo_sasl_make_basic_callbacks(
+            FLAGS_sasl_user_name, FLAGS_sasl_realm, FLAGS_sasl_password_file);
+
+        _handle = zookeeper_init_sasl(FLAGS_hosts_list,
+                                      global_watcher,
+                                      FLAGS_timeout_ms,
+                                      nullptr,
+                                      this,
+                                      0,
+                                      nullptr,
+                                      &sasl_params);
+    } while (false);
+
+    CHECK_NOTNULL(_handle, "zookeeper session init failed");
 
     _watchers.push_back(watcher_object());
     _watchers.back().watcher_path = "";


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to