Skip to content

Commit 993f4ba

Browse files
committed
added reauthentication
Signed-off-by: Emelia Lei <[email protected]>
1 parent 6f2b35b commit 993f4ba

25 files changed

+763
-308
lines changed

src/groups/mqb/mqba/mqba_application.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,14 +360,15 @@ int Application::start(bsl::ostream& errorDescription)
360360
bslma::ManagedPtr<mqbnet::InitialConnectionHandler>
361361
initialConnectionHandlerMp(
362362
new (*d_allocator_p) InitialConnectionHandler(
363-
authenticatorMp,
364363
negotiatorMp,
364+
authenticatorMp.get(),
365365
d_allocators.get("InitialConnectionHandler")),
366366
d_allocator_p);
367367

368368
d_transportManager_mp.load(new (*d_allocator_p) mqbnet::TransportManager(
369369
d_scheduler_p,
370370
&d_bufferFactory,
371+
authenticatorMp,
371372
initialConnectionHandlerMp,
372373
d_statController_mp.get(),
373374
d_allocators.get("TransportManager")),

src/groups/mqb/mqba/mqba_authenticator.cpp

Lines changed: 245 additions & 60 deletions
Large diffs are not rendered by default.

src/groups/mqb/mqba/mqba_authenticator.h

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ class Authenticator : public mqbnet::Authenticator {
144144
int sendAuthenticationMessage(
145145
bsl::ostream& errorDescription,
146146
const bmqp_ctrlmsg::AuthenticationMessage& message,
147-
const InitialConnectionContextSp& context);
147+
const bsl::shared_ptr<bmqio::Channel>& channel,
148+
bmqp::EncodingType::Enum authenticationEncodingType);
148149

149150
/// Initiate an outbound authentication (i.e., send out some authentication
150151
/// message and schedule a read of the response) using the specified
@@ -153,12 +154,44 @@ class Authenticator : public mqbnet::Authenticator {
153154
void
154155
initiateOutboundAuthentication(const AuthenticationContextSp& context);
155156

156-
/// Authenticate using a plugin based on the mechanism specified in the
157-
/// `AuthenticateRequest` message. If the authentication fails, reset
158-
/// `AuthenticationContext` and close the channel. Send an
159-
/// `AuthenticationResponse` message back to the peer with the status of
160-
/// the authentication.
161-
void authenticate(const InitialConnectionContextSp& context);
157+
/// Schedule an authentication job in the thread pool using the
158+
/// specified `context` and `channel`. Return 0 on success, or a
159+
/// non-zero error code and populate the specified `errorDescription`
160+
/// with a description of the error otherwise.
161+
int authenticateAsync(bsl::ostream& errorDescription,
162+
const AuthenticationContextSp& context,
163+
const bsl::shared_ptr<bmqio::Channel>& channel);
164+
165+
/// Schedule a re-authentication job in the thread pool using the
166+
/// specified `context` and `channel`. Return 0 on success, or a
167+
/// non-zero error code and populate the specified `errorDescription`
168+
/// with a description of the error otherwise.
169+
int reAuthenticateAsync(bsl::ostream& errorDescription,
170+
const AuthenticationContextSp& context,
171+
const bsl::shared_ptr<bmqio::Channel>& channel);
172+
173+
/// Authenticate the connection using the `AuthenticationMessage` stored in
174+
/// `context`. If authentication fails, invoke
175+
/// `initialConnectionCompleteCb` to close the `channel`. Also, update the
176+
/// state of `context` as appropriate.
177+
void authenticate(const AuthenticationContextSp& context,
178+
const bsl::shared_ptr<bmqio::Channel>& channel);
179+
180+
/// Re-authenticate the connection using the `AuthenticationMessage`
181+
/// stored in `context`. If re-authentication fails, invoke
182+
/// `initialConnectionCompleteCb` to close the `channel`. Also, update the
183+
/// state of `context` as appropriate.
184+
void reAuthenticate(const AuthenticationContextSp& context,
185+
const bsl::shared_ptr<bmqio::Channel>& channel);
186+
187+
/// Handle re-authentication depending on the type of AuthenticationMessage
188+
/// stored in `context` for the specified `context` and `channel`. If the
189+
/// re-authentication is successful, return 0; otherwise, return a non-zero
190+
/// error code and populate the specified `errorDescription` with a
191+
/// description of the error.
192+
int handleReauthentication(bsl::ostream& errorDescription,
193+
const AuthenticationContextSp& context,
194+
const bsl::shared_ptr<bmqio::Channel>& channel);
162195

163196
public:
164197
// TRAITS
@@ -201,10 +234,10 @@ class Authenticator : public mqbnet::Authenticator {
201234
const bmqp_ctrlmsg::AuthenticationMessage&
202235
authenticationMsg) BSLS_KEYWORD_OVERRIDE;
203236

204-
/// Send out outbound authentication message or reverse connection request
205-
/// with the specified `context`.
206-
/// Return 0 on success, or a non-zero error code and populate the
207-
/// specified `errorDescription` with a description of the error otherwise.
237+
/// Send out outbound authentication message or reverse connection
238+
/// request with the specified `context`. Return 0 on success, or a
239+
/// non-zero error code and populate the specified `errorDescription`
240+
/// with a description of the error otherwise.
208241
int authenticationOutboundOrReverse(const AuthenticationContextSp& context)
209242
BSLS_KEYWORD_OVERRIDE;
210243
};

src/groups/mqb/mqba/mqba_clientsession.cpp

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@
153153
#include <mqbcfg_brokerconfig.h>
154154
#include <mqbi_cluster.h>
155155
#include <mqbi_queue.h>
156+
#include <mqbnet_authenticationcontext.h>
156157
#include <mqbnet_tcpsessionfactory.h>
157158
#include <mqbstat_brokerstats.h>
158159
#include <mqbu_messageguidutil.h>
@@ -2631,14 +2632,16 @@ ClientSession::ClientSession(
26312632
const bsl::shared_ptr<bmqio::Channel>& channel,
26322633
const bmqp_ctrlmsg::NegotiationMessage& negotiationMessage,
26332634
const bsl::string& sessionDescription,
2634-
mqbi::Dispatcher* dispatcher,
2635-
mqbblp::ClusterCatalog* clusterCatalog,
2636-
mqbi::DomainFactory* domainFactory,
2637-
bslma::ManagedPtr<bmqst::StatContext>& clientStatContext,
2638-
ClientSessionState::BlobSpPool* blobSpPool,
2639-
bdlbb::BlobBufferFactory* bufferFactory,
2640-
bdlmt::EventScheduler* scheduler,
2641-
bslma::Allocator* allocator)
2635+
const bsl::shared_ptr<mqbnet::AuthenticationContext>&
2636+
authenticationContext,
2637+
mqbi::Dispatcher* dispatcher,
2638+
mqbblp::ClusterCatalog* clusterCatalog,
2639+
mqbi::DomainFactory* domainFactory,
2640+
bslma::ManagedPtr<bmqst::StatContext>& clientStatContext,
2641+
ClientSessionState::BlobSpPool* blobSpPool,
2642+
bdlbb::BlobBufferFactory* bufferFactory,
2643+
bdlmt::EventScheduler* scheduler,
2644+
bslma::Allocator* allocator)
26422645
: d_self(this) // use default allocator
26432646
, d_operationState(e_RUNNING)
26442647
, d_isDisconnecting(false)
@@ -2650,6 +2653,7 @@ ClientSession::ClientSession(
26502653
bmqp::MessagePropertiesFeatures::k_MESSAGE_PROPERTIES_EX,
26512654
d_clientIdentity_p->features()))
26522655
, d_description(sessionDescription, allocator)
2656+
, d_authenticationContext(authenticationContext)
26532657
, d_channel_sp(channel)
26542658
, d_state(clientStatContext,
26552659
blobSpPool,
@@ -2716,7 +2720,54 @@ void ClientSession::processEvent(const bmqp::Event& event,
27162720
{
27172721
// executed by the *IO* thread
27182722

2719-
if (event.isControlEvent()) {
2723+
if (!event.isAuthenticationEvent() && !d_authenticationContext) {
2724+
BALL_LOG_ERROR << "The authentication lifetime has expired. Need to "
2725+
"re-authenticate.";
2726+
return; // RETURN
2727+
}
2728+
2729+
if (event.isAuthenticationEvent()) {
2730+
if (d_authenticationContext->state().testAndSwap(
2731+
AuthnState::e_AUTHENTICATED,
2732+
AuthnState::e_AUTHENTICATING) != AuthnState::e_AUTHENTICATED) {
2733+
BALL_LOG_ERROR << "#CLIENT_IMPROPER_BEHAVIOR " << description()
2734+
<< ": received Authentication event while "
2735+
"authentication is in progress";
2736+
return; // RETURN
2737+
}
2738+
2739+
bmqp_ctrlmsg::AuthenticationMessage authenticationMessage;
2740+
int rc = event.loadAuthenticationEvent(&authenticationMessage);
2741+
if (rc != 0) {
2742+
BALL_LOG_ERROR << "#CORRUPTED_EVENT " << description()
2743+
<< ": Received invalid authentication message "
2744+
"from client [reason: 'failed to decode', rc: "
2745+
<< rc << "]:\n"
2746+
<< bmqu::BlobStartHexDumper(event.blob());
2747+
return; // RETURN
2748+
}
2749+
2750+
BALL_LOG_INFO << description() << ": Received authentication message: "
2751+
<< authenticationMessage;
2752+
2753+
d_authenticationContext->setAuthenticationMessage(
2754+
authenticationMessage);
2755+
d_authenticationContext->setAuthenticationEncodingType(
2756+
event.authenticationEventEncodingType());
2757+
2758+
bmqu::MemOutStream errorStream;
2759+
rc = d_authenticationContext->reAuthenticateCb()(
2760+
errorStream,
2761+
d_authenticationContext,
2762+
d_channel_sp);
2763+
if (rc != 0) {
2764+
BALL_LOG_ERROR << "#AUTHENTICATION_FAILED " << description()
2765+
<< ": Authentication failed [reason: '"
2766+
<< errorStream.str() << "', rc: " << rc << "]";
2767+
return; // RETURN
2768+
}
2769+
}
2770+
else if (event.isControlEvent()) {
27202771
bdlma::LocalSequentialAllocator<2048> localAllocator(
27212772
d_state.d_allocator_p);
27222773
bmqp_ctrlmsg::ControlMessage controlMessage(&localAllocator);

src/groups/mqb/mqba/mqba_clientsession.h

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#include <mqbi_dispatcher.h>
3434
#include <mqbi_domain.h>
3535
#include <mqbi_queue.h>
36+
#include <mqbnet_authenticationcontext.h>
37+
#include <mqbnet_initialconnectioncontext.h>
3638
#include <mqbnet_session.h>
3739
#include <mqbstat_queuestats.h>
3840

@@ -255,6 +257,8 @@ class ClientSession : public mqbnet::Session,
255257

256258
typedef bsl::function<void(void)> VoidFunctor;
257259

260+
typedef mqbnet::AuthenticationContext::State AuthnState;
261+
258262
/// Enum to signify the session's operation state.
259263
enum OperationState {
260264
/// Running normally.
@@ -337,6 +341,11 @@ class ClientSession : public mqbnet::Session,
337341
/// Short identifier for this session.
338342
bsl::string d_description;
339343

344+
/// The authenticationContext first created during authentication in
345+
/// initial connection, and later on may get updated during
346+
/// re-authentication.
347+
bsl::shared_ptr<mqbnet::AuthenticationContext> d_authenticationContext;
348+
340349
/// Channel associated with this session.
341350
bsl::shared_ptr<bmqio::Channel> d_channel_sp;
342351

@@ -628,14 +637,16 @@ class ClientSession : public mqbnet::Session,
628637
ClientSession(const bsl::shared_ptr<bmqio::Channel>& channel,
629638
const bmqp_ctrlmsg::NegotiationMessage& negotiationMessage,
630639
const bsl::string& sessionDescription,
631-
mqbi::Dispatcher* dispatcher,
632-
mqbblp::ClusterCatalog* clusterCatalog,
633-
mqbi::DomainFactory* domainFactory,
634-
bslma::ManagedPtr<bmqst::StatContext>& clientStatContext,
635-
ClientSessionState::BlobSpPool* blobSpPool,
636-
bdlbb::BlobBufferFactory* bufferFactory,
637-
bdlmt::EventScheduler* scheduler,
638-
bslma::Allocator* allocator);
640+
const bsl::shared_ptr<mqbnet::AuthenticationContext>&
641+
authenticationContext,
642+
mqbi::Dispatcher* dispatcher,
643+
mqbblp::ClusterCatalog* clusterCatalog,
644+
mqbi::DomainFactory* domainFactory,
645+
bslma::ManagedPtr<bmqst::StatContext>& clientStatContext,
646+
ClientSessionState::BlobSpPool* blobSpPool,
647+
bdlbb::BlobBufferFactory* bufferFactory,
648+
bdlmt::EventScheduler* scheduler,
649+
bslma::Allocator* allocator);
639650

640651
/// Destructor
641652
~ClientSession() BSLS_KEYWORD_OVERRIDE;

src/groups/mqb/mqba/mqba_clientsession.t.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <mqbmock_queue.h>
2727
#include <mqbmock_queueengine.h>
2828
#include <mqbmock_queuehandle.h>
29+
#include <mqbnet_initialconnectioncontext.h>
2930
#include <mqbstat_brokerstats.h>
3031
#include <mqbstat_queuestats.h>
3132
#include <mqbu_messageguidutil.h>
@@ -689,6 +690,7 @@ class TestBench {
689690
, d_cs(d_channel,
690691
negotiationMessage,
691692
"sessionDescription",
693+
bsl::shared_ptr<mqbnet::AuthenticationContext>(),
692694
setInDispatcherThread(&d_mockDispatcher),
693695
0, // ClusterCatalog
694696
&d_mockDomainFactory,
@@ -2125,7 +2127,7 @@ static void test11_initiateShutdown()
21252127
100000000); // 100 ms
21262128
bslmt::TimedSemaphore semaphore;
21272129
bmqp::Protocol::MsgGroupId msgGroupId(bmqtst::TestHelperUtil::allocator());
2128-
const unsigned int subscriptionId =
2130+
const unsigned int subscriptionId =
21292131
bmqp::Protocol::k_DEFAULT_SUBSCRIPTION_ID;
21302132
const unsigned int subQueueId = bmqp::QueueId::k_DEFAULT_SUBQUEUE_ID;
21312133

@@ -2376,11 +2378,11 @@ static void test11_initiateShutdown()
23762378

23772379
PV("Confirm multiple messsages while shutting down");
23782380
{
2379-
const int NUM_MESSAGES = 5;
2381+
const int NUM_MESSAGES = 5;
23802382
TestBench tb(client(e_FirstHop),
23812383
isAtMostOnce,
23822384
bmqtst::TestHelperUtil::allocator());
2383-
bsls::AtomicInt callbackCounter(0);
2385+
bsls::AtomicInt callbackCounter(0);
23842386
bsl::vector<bmqt::MessageGUID> guids(
23852387
bmqtst::TestHelperUtil::allocator());
23862388
guids.reserve(NUM_MESSAGES);

src/groups/mqb/mqba/mqba_initialconnectionhandler.cpp

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -211,11 +211,10 @@ int InitialConnectionHandler::processBlob(
211211
context->negotiationContext()->d_negotiationMessage =
212212
bsl::get<bmqp_ctrlmsg::NegotiationMessage>(message.value());
213213

214-
rc = d_negotiator_mp->createSessionOnMsgType(
215-
errorDescription,
216-
session,
217-
isContinueRead,
218-
context->negotiationContext());
214+
rc = d_negotiator_mp->createSessionOnMsgType(errorDescription,
215+
session,
216+
isContinueRead,
217+
context);
219218
}
220219

221220
return rc;
@@ -334,9 +333,9 @@ void InitialConnectionHandler::complete(
334333
}
335334

336335
InitialConnectionHandler::InitialConnectionHandler(
337-
bslma::ManagedPtr<mqbnet::Authenticator>& authenticator,
338-
bslma::ManagedPtr<mqbnet::Negotiator>& negotiator,
339-
bslma::Allocator* allocator)
336+
bslma::ManagedPtr<mqbnet::Negotiator>& negotiator,
337+
mqbnet::Authenticator* authenticator,
338+
bslma::Allocator* allocator)
340339
: d_authenticator_mp(authenticator)
341340
, d_negotiator_mp(negotiator)
342341
, d_allocator_p(allocator)
@@ -389,9 +388,7 @@ void InitialConnectionHandler::handleConnectionFlow(
389388
// TODO: When we are ready to move on to the next step, we should
390389
// call `authenticationOutboundOrReverse` here instead before calling
391390
// `negotiateOutboundOrReverse`.
392-
rc = d_negotiator_mp->negotiateOutboundOrReverse(
393-
errStream,
394-
context->negotiationContext());
391+
rc = d_negotiator_mp->negotiateOutboundOrReverse(errStream, context);
395392

396393
// Send outbound request success, continue to read
397394
if (rc == 0) {
@@ -407,17 +404,6 @@ void InitialConnectionHandler::handleConnectionFlow(
407404
guard.release();
408405
}
409406

410-
int InitialConnectionHandler::start(bsl::ostream& errorDescription)
411-
{
412-
int rc = d_authenticator_mp->start(errorDescription);
413-
return rc;
414-
}
415-
416-
void InitialConnectionHandler::stop()
417-
{
418-
d_authenticator_mp->stop();
419-
}
420-
421407
void InitialConnectionHandler::handleInitialConnection(
422408
const InitialConnectionContextSp& context)
423409
{

src/groups/mqb/mqba/mqba_initialconnectionhandler.h

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ class InitialConnectionHandler : public mqbnet::InitialConnectionHandler {
7171
// DATA
7272

7373
/// Authenticator to use for authenticating a connection.
74-
bslma::ManagedPtr<mqbnet::Authenticator> d_authenticator_mp;
74+
mqbnet::Authenticator* d_authenticator_mp;
7575

7676
/// Negotiator to use for converting a Channel to a Session.
7777
bslma::ManagedPtr<mqbnet::Negotiator> d_negotiator_mp;
@@ -148,24 +148,15 @@ class InitialConnectionHandler : public mqbnet::InitialConnectionHandler {
148148
public:
149149
// CREATORS
150150

151-
InitialConnectionHandler(
152-
bslma::ManagedPtr<mqbnet::Authenticator>& authenticator,
153-
bslma::ManagedPtr<mqbnet::Negotiator>& negotiator,
154-
bslma::Allocator* allocator);
151+
InitialConnectionHandler(bslma::ManagedPtr<mqbnet::Negotiator>& negotiator,
152+
mqbnet::Authenticator* authenticator,
153+
bslma::Allocator* allocator);
155154

156155
/// Destructor
157156
~InitialConnectionHandler() BSLS_KEYWORD_OVERRIDE;
158157

159158
// MANIPULATORS
160159

161-
/// Start the InitialConnectionHandler. Return 0 on success, or a
162-
/// non-zero error code and populate the specified `errorDescription`
163-
/// with a description of the error otherwise.
164-
int start(bsl::ostream& errorDescription) BSLS_KEYWORD_OVERRIDE;
165-
166-
/// Stop the InitialConnectionHandler.
167-
void stop() BSLS_KEYWORD_OVERRIDE;
168-
169160
/// Method invoked by the client of this object to negotiate a session.
170161
/// The specified `context` is an in-out member holding the initial
171162
/// connection context to use, including an

0 commit comments

Comments
 (0)