| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you 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. |
| #pragma once |
| |
| #include <cstddef> |
| #include <cstdint> |
| #include <functional> |
| #include <set> |
| #include <string> |
| |
| #include <sasl/sasl.h> |
| |
| #include "kudu/gutil/port.h" |
| #include "kudu/util/slice.h" |
| #include "kudu/util/status.h" |
| |
| #if defined(__APPLE__) |
| // Almost all functions in the SASL API are marked as deprecated |
| // since macOS 10.11. |
| #pragma GCC diagnostic push |
| #pragma GCC diagnostic ignored "-Wdeprecated-declarations" |
| #endif // #if defined(__APPLE__) |
| |
| namespace kudu { |
| |
| class Sockaddr; |
| |
| namespace rpc { |
| |
| // Constants |
| extern const char* const kSaslMechPlain; |
| extern const char* const kSaslMechGSSAPI; |
| extern const size_t kSaslMaxBufSize; |
| |
| struct SaslMechanism { |
| enum Type { |
| INVALID, |
| PLAIN, |
| GSSAPI |
| }; |
| static Type value_of(const std::string& mech); |
| static const char* name_of(Type val); |
| }; |
| |
| struct SaslProtection { |
| enum Type { |
| // SASL authentication without integrity or privacy. |
| kAuthentication = 0, |
| // Integrity protection, i.e. messages are HMAC'd. |
| kIntegrity = 1, |
| // Privacy protection, i.e. messages are encrypted. |
| kPrivacy = 2, |
| }; |
| static const char* name_of(Type val); |
| }; |
| |
| // Initialize the SASL library. |
| // appname: Name of the application for logging messages & sasl plugin configuration. |
| // Note that this string must remain allocated for the lifetime of the program. |
| // This function must be called before using SASL. |
| // If the library initializes without error, calling more than once has no effect. |
| // |
| // Some SASL plugins take time to initialize random number generators and other things, |
| // so the first time this function is invoked it may execute for several seconds. |
| // After that, it should be very fast. This function should be invoked as early as possible |
| // in the application lifetime to avoid SASL initialization taking place in a |
| // performance-critical section. |
| // |
| // This function is thread safe and uses a static lock. |
| // This function should NOT be called during static initialization. |
| Status SaslInit(bool kerberos_keytab_provided = false) WARN_UNUSED_RESULT; |
| |
| // Disable Kudu's initialization of SASL. See equivalent method in client.h. |
| Status DisableSaslInitialization() WARN_UNUSED_RESULT; |
| |
| // Wrap a call into the SASL library. 'call' should be a lambda which |
| // returns a SASL error code, 'conn' is the SASL connection to perform |
| // the operation with (might be null), and 'description' is be a description |
| // of the SASL call (e.g., the name of the SASL library function). |
| // |
| // The result is translated into a Status as follows: |
| // |
| // SASL_OK: Status::OK() |
| // SASL_CONTINUE: Status::Incomplete() |
| // otherwise: Status::NotAuthorized() |
| // |
| // The Status message is beautified to be more user-friendly compared |
| // to the underlying sasl_errdetails() call. |
| Status WrapSaslCall(sasl_conn_t* conn, |
| const std::function<int()>& call, |
| const char* description) WARN_UNUSED_RESULT; |
| |
| // Return <ip>;<port> string formatted for SASL library use. |
| std::string SaslIpPortString(const Sockaddr& addr); |
| |
| // Return available plugin mechanisms for the given connection. |
| std::set<SaslMechanism::Type> SaslListAvailableMechs(); |
| |
| // Initialize and return a libsasl2 callback data structure based on the passed args. |
| // id: A SASL callback identifier (e.g., SASL_CB_GETOPT). |
| // proc: A C-style callback with appropriate signature based on the callback id, or NULL. |
| // context: An object to pass to the callback as the context pointer, or NULL. |
| sasl_callback_t SaslBuildCallback(int id, int (*proc)(void), void* context); |
| |
| // Enable SASL integrity and privacy protection on the connection. Also allows |
| // setting the minimum required protection level, and the maximum receive buffer |
| // size. |
| Status EnableProtection(sasl_conn_t* sasl_conn, |
| SaslProtection::Type minimum_protection = SaslProtection::kAuthentication, |
| size_t max_recv_buf_size = kSaslMaxBufSize) WARN_UNUSED_RESULT; |
| |
| // Returns true if the SASL connection has been negotiated with auth-int or |
| // auth-conf. 'sasl_conn' must already be negotiated. |
| bool NeedsWrap(sasl_conn_t* sasl_conn); |
| |
| // Retrieves the negotiated maximum send buffer size for auth-int or auth-conf |
| // protected channels. |
| uint32_t GetMaxSendBufferSize(sasl_conn_t* sasl_conn) WARN_UNUSED_RESULT; |
| |
| // Encode the provided data. |
| // |
| // The plaintext data must not be longer than the negotiated maximum buffer size. |
| // |
| // The output 'ciphertext' slice is only valid until the next use of the SASL connection. |
| Status SaslEncode(sasl_conn_t* conn, |
| Slice plaintext, |
| Slice* ciphertext) WARN_UNUSED_RESULT; |
| |
| // Decode the provided SASL-encoded data. |
| // |
| // The decoded plaintext must not be longer than the negotiated maximum buffer size. |
| // |
| // The output 'plaintext' slice is only valid until the next use of the SASL connection. |
| Status SaslDecode(sasl_conn_t* conn, |
| Slice ciphertext, |
| Slice* plaintext) WARN_UNUSED_RESULT; |
| |
| // Deleter for sasl_conn_t instances, for use with unique_ptr after calling sasl_*_new(). |
| struct SaslDeleter { |
| inline void operator()(sasl_conn_t* conn) { |
| sasl_dispose(&conn); |
| } |
| }; |
| |
| // Internals exposed in the header for test purposes. |
| namespace internal { |
| void SaslSetMutex(); |
| } // namespace internal |
| |
| } // namespace rpc |
| } // namespace kudu |
| |
| #if defined(__APPLE__) |
| #pragma GCC diagnostic pop |
| #endif // #if defined(__APPLE__) |