Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
501 changes: 501 additions & 0 deletions src/groups/mqb/mqba/mqba_authenticator.cpp

Large diffs are not rendered by default.

265 changes: 265 additions & 0 deletions src/groups/mqb/mqba/mqba_authenticator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
// Copyright 2025 Bloomberg Finance L.P.
// SPDX-License-Identifier: Apache-2.0
//
// 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.

// mqba_authenticator.h -*-C++-*-
#ifndef INCLUDED_MQBA_AUTHENTICATOR
#define INCLUDED_MQBA_AUTHENTICATOR

/// @file mqba_authenticator.h
///
/// @brief Provide an authenticator for authenticating a connection.
///
/// @bbref{mqba::Authenticator} implements the @bbref{mqbnet::Authenticator}
/// interface to authenticate a connection with a BlazingMQ client or another
/// bmqbrkr. From a @bbref{bmqio::Channel}, it will exchange authentication
/// message and authenticate depending on the authentication message received.
///
/// Thread Safety {#mqba_authenticator_thread}
/// =============
/// This component is *NOT* thread safe.

// MQB
#include <mqbauthn_authenticationcontroller.h>
#include <mqbconfm_messages.h>
#include <mqbnet_authenticationcontext.h>
#include <mqbnet_authenticator.h>
#include <mqbnet_initialconnectioncontext.h>

// BMQ
#include <bmqio_channel.h>
#include <bmqio_status.h>
#include <bmqp_ctrlmsg_messages.h>

// BDE
#include <ball_log.h>
#include <bdlbb_blob.h>
#include <bdlcc_sharedobjectpool.h>
#include <bdlmt_eventscheduler.h>
#include <bdlmt_threadpool.h>
#include <bsl_memory.h>
#include <bsl_ostream.h>
#include <bsl_string_view.h>
#include <bslma_allocator.h>
#include <bslma_usesbslmaallocator.h>
#include <bslmf_nestedtraitdeclaration.h>

namespace BloombergLP {

// FORWARD DECLARATION
namespace mqbblp {
class ClusterCatalog;
}
namespace mqbi {
class Dispatcher;
}

namespace mqba {

// ===================
// class Authenticator
// ===================

/// Authenticator for a BlazingMQ session with client or broker
class Authenticator : public mqbnet::Authenticator {
private:
// CLASS-SCOPE CATEGORY
BALL_LOG_SET_CLASS_CATEGORY("MQBA.AUTHENTICATOR");

public:
// TYPES

/// Type of a pool of shared pointers to blob
typedef bdlcc::SharedObjectPool<
bdlbb::Blob,
bdlcc::ObjectPoolFunctors::DefaultCreator,
bdlcc::ObjectPoolFunctors::RemoveAll<bdlbb::Blob> >
BlobSpPool;

private:
typedef bsl::shared_ptr<mqbnet::AuthenticationContext>
AuthenticationContextSp;

typedef bsl::shared_ptr<mqbnet::InitialConnectionContext>
InitialConnectionContextSp;

typedef mqbnet::InitialConnectionEvent InitialConnectionEvent;
typedef mqbnet::InitialConnectionState InitialConnectionState;

private:
// DATA

/// Allocator to use.
bslma::Allocator* d_allocator_p;

/// Authentication Controller.
mqbauthn::AuthenticationController* d_authnController_p;

/// Thread pool to run authentication and reauthentication tasks.
bdlmt::ThreadPool d_threadPool;

/// Pool of shared pointers to blobs. Held, not owned.
BlobSpPool* d_blobSpPool_p;

/// Used to track the duration of a valid authenticated connection.
/// If reauthentication does not occur within the specified time,
/// an event is triggered to close the channel.
bdlmt::EventScheduler* d_scheduler_p;

/// True if this component is started.
bool d_isStarted;

private:
// NOT IMPLEMENTED

/// Copy constructor and assignment operator not implemented.
Authenticator(const Authenticator&); // = delete
Authenticator& operator=(const Authenticator&); // = delete

private:
// PRIVATE MANIPULATORS

/// Handle an incoming AuthenticationRequest message by authenticating
/// using the specified `authenticationMsg` and `context`. On success,
/// create an AuthenticationContext and stores it in `context`. The
/// behavior of this function is undefined unless `authenticationMsg` is an
/// `AuthenticationRequest` and this is an incoming connection.
/// Return 0 on success; otherwise, return a non-zero error code and
/// populate `errorDescription` with details of the failure.
int onAuthenticationRequest(
bsl::ostream& errorDescription,
const bmqp_ctrlmsg::AuthenticationMessage& authenticationMsg,
const InitialConnectionContextSp& context);

/// Handle an incoming AuthenticationResponse message by authenticating
/// using the specified `authenticationMsg` and `context`. On success,
/// create an AuthenticationContext and stores it in `context`. The
/// behavior of this function is undefined unless `authenticationMsg` is an
/// `AuthenticationResponse`. Return 0 on success; otherwise, return a
/// non-zero error code and populate `errorDescription` with details of the
/// failure.
int onAuthenticationResponse(
bsl::ostream& errorDescription,
const bmqp_ctrlmsg::AuthenticationMessage& authenticationMsg,
const InitialConnectionContextSp& context);

/// Send out outbound authentication message with the specified `message`
/// on the specified `channel` using the specified
/// `authenticationEncodingType`. Return 0 on success, or a non-zero error
/// code and populate the specified `errorDescription` with a description
/// of the error otherwise.
int sendAuthenticationMessage(
bsl::ostream& errorDescription,
const bmqp_ctrlmsg::AuthenticationMessage& message,
const bsl::shared_ptr<bmqio::Channel>& channel,
bmqp::EncodingType::Enum authenticationEncodingType);

// Authenticate the specified `context`. Send an authentication
// response back to the client via the specified `channel` if the specified
// `isDefaultAuthn` is false. If `isReauthn` is true, this is for
// reauthentication, otherwise this is for initial authentication. On
// completion, trigger the initial connection state machine with either
// success or error event.
void authenticate(const AuthenticationContextSp& context,
const bsl::shared_ptr<bmqio::Channel>& channel,
bool isDefaultAuthn,
bool isReauthn);

/// Perform the authentication based on the specified `request` and
/// build the corresponding `response`. Use the specified `channel` and
/// `authenticationContext` during the authentication process.
/// Return 0 if the response is built successfully, regardless of a
/// successful or failed authentication, or a non-zero code on error and
/// populate the specified `errorDescription` with a description of the
/// error.
int authenticateAndBuildResponse(
bsl::ostream& errorDescription,
bmqp_ctrlmsg::AuthenticationResponse* response,
const bmqp_ctrlmsg::AuthenticationRequest& request,
const bsl::shared_ptr<bmqio::Channel>& channel,
const AuthenticationContextSp& authenticationContext);

public:
// TRAITS
BSLMF_NESTED_TRAIT_DECLARATION(Authenticator, bslma::UsesBslmaAllocator)

public:
// CREATORS

/// Create a new `Authenticator` using the specified `authnController` and
/// `blobSpPool`. Use the specified `allocator` for all memory
/// allocations.
Authenticator(mqbauthn::AuthenticationController* authnController,
BlobSpPool* blobSpPool,
bdlmt::EventScheduler* scheduler,
bslma::Allocator* allocator);

/// Destructor
~Authenticator() BSLS_KEYWORD_OVERRIDE;

// MANIPULATORS
// (virtual: mqbnet::Authenticator)

/// Start the authenticator. Return 0 on success, or a non-zero error
/// code and populate the specified `errorDescription` with a description
/// of the error otherwise.
/// This method will block until the thread pool is started.
int start(bsl::ostream& errorDescription) BSLS_KEYWORD_OVERRIDE;

/// Stop the authenticator. This method will block until the thread pool
/// is stopped.
void stop() BSLS_KEYWORD_OVERRIDE;

/// Authenticate the connection based on the type of AuthenticationMessage
/// `authenticationMsg`. Create an AuthenticationContext and store into
/// `context`. Return 0 on success, or a non-zero error code and populate
/// the specified `errorDescription` with a description of the error
/// otherwise.
int handleAuthentication(bsl::ostream& errorDescription,
const InitialConnectionContextSp& context,
const bmqp_ctrlmsg::AuthenticationMessage&
authenticationMsg) BSLS_KEYWORD_OVERRIDE;

/// Send out an outbound authentication message with the specified
/// `context`. Return 0 on success, or a non-zero error code and populate
/// the specified `errorDescription` with a description of the error
/// otherwise.
int authenticationOutbound(bsl::ostream& errorDescription,
const AuthenticationContextSp& context)
BSLS_KEYWORD_OVERRIDE;

/// Schedule an authentication job in the thread pool using the
/// specified `context` and `channel`. The specified `isAnonAuthn` is set
/// to true when this is for anonymous authentication. The specified
/// `isReauthn` is set to true when this is for re-authentication. Return
/// 0 on success, or a non-zero error code and populate the specified
/// `errorDescription` with a description of the error otherwise.
int authenticateAsync(bsl::ostream& errorDescription,
const AuthenticationContextSp& context,
const bsl::shared_ptr<bmqio::Channel>& channel,
bool isAnonAuthn,
bool isReauthn) BSLS_KEYWORD_OVERRIDE;

/// ACCESSORS

/// Return the anonymous credential used for authentication.
/// If no anonymous credential is set, return an empty optional.
const bsl::optional<mqbcfg::Credential>&
anonymousCredential() const BSLS_KEYWORD_OVERRIDE;
};

} // close package namespace
} // close enterprise namespace

#endif
1 change: 1 addition & 0 deletions src/groups/mqb/mqba/package/mqba.dep
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
mqbauthn
mqbblp
mqbcmd
mqbnet
Expand Down
1 change: 1 addition & 0 deletions src/groups/mqb/mqba/package/mqba.mem
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mqba_adminsession
mqba_application
mqba_authenticator
mqba_clientsession
mqba_commandrouter
mqba_configprovider
Expand Down
Loading
Loading