Skip to content

Commit ec64999

Browse files
committed
WIP: bmqbrkrcfg.json and authn timeout
1 parent 993f4ba commit ec64999

File tree

7 files changed

+213
-23
lines changed

7 files changed

+213
-23
lines changed

src/applications/bmqbrkr/etc/bmqbrkrcfg.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,23 @@
9292
},
9393
"bmqconfConfig": {
9494
"cacheTTLSeconds": 30
95+
},
96+
"plugins": {
97+
"libraries": ["/Users/wlei29/Workspace/blazingmq/build/blazingmq/src/plugins/"],
98+
"enabled": ["PassAuthenticator"]
99+
},
100+
"authentication": {
101+
"plugins": [
102+
{
103+
"name": "FailAuthenticator",
104+
"configs": []
105+
},
106+
{
107+
"name": "PassAuthenticator",
108+
"configs": []
109+
}
110+
],
111+
"fallbackPrincipal": "defaultFallbackPrincipal"
95112
}
96113
}
97114
}

src/groups/mqb/mqba/mqba_authenticator.cpp

Lines changed: 103 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
// limitations under the License.
1515

1616
// mqba_authenticator.h -*-C++-*-
17+
#include <bdlmt_timereventscheduler.h>
1718
#include <mqba_authenticator.h>
1819

1920
#include <mqbscm_version.h>
@@ -55,9 +56,6 @@ namespace mqba {
5556

5657
namespace {
5758
BALL_LOG_SET_NAMESPACE_CATEGORY("MQBA.AUTHENTICATOR");
58-
59-
const int k_AUTHENTICATION_READTIMEOUT = 3 * 60; // 3 minutes
60-
6159
}
6260

6361
// -------------------
@@ -224,7 +222,6 @@ void Authenticator::authenticate(
224222
&result,
225223
authenticateRequest.mechanism(),
226224
authenticationData);
227-
228225
if (rc != 0) {
229226
BALL_LOG_ERROR << "Authentication failed for connection '"
230227
<< channel->peerUri() << "' with mechanism '"
@@ -282,7 +279,10 @@ void Authenticator::authenticate(
282279
rc,
283280
sendResponseErrorStream.str(),
284281
bsl::shared_ptr<mqbnet::Session>());
282+
return; // RETURN
285283
}
284+
285+
setTimer(context, result, channel);
286286
}
287287
}
288288

@@ -338,7 +338,7 @@ void Authenticator::reAuthenticate(
338338
authenticateRequest.mechanism(),
339339
authenticationData);
340340
if (rc != 0) {
341-
BALL_LOG_ERROR << "Authentication failed for connection '"
341+
BALL_LOG_ERROR << "Reauthentication failed for connection '"
342342
<< channel->peerUri() << "' with mechanism '"
343343
<< authenticateRequest.mechanism() << "' [rc: " << rc
344344
<< ", error: " << authenticationErrorStream.str()
@@ -356,13 +356,14 @@ void Authenticator::reAuthenticate(
356356
channel,
357357
context->authenticationEncodingType());
358358

359-
bmqio::Status status(bmqio::StatusCategory::e_GENERIC_ERROR,
360-
"reAuthenticationError",
361-
rc,
362-
d_allocator_p);
363-
channel->close(status);
359+
cleanupOnError(rc, "reauthenticationError", context, channel);
364360
}
365361
else {
362+
// Authentication succeeded
363+
BALL_LOG_INFO << "Reauthentication succeeded for connection '"
364+
<< channel->peerUri() << "' with mechanism '"
365+
<< authenticateRequest.mechanism() << "'";
366+
366367
response.status().code() = 0;
367368
response.status().category() = bmqp_ctrlmsg::StatusCategory::E_SUCCESS;
368369
response.lifetimeMs() = result->lifetimeMs();
@@ -375,11 +376,7 @@ void Authenticator::reAuthenticate(
375376
BALL_LOG_ERROR << "Failed to set (re)authentication state for '"
376377
<< channel->peerUri()
377378
<< "' to 'e_AUTHENTICATED' from 'e_AUTHENTICATING'";
378-
bmqio::Status status(bmqio::StatusCategory::e_GENERIC_ERROR,
379-
"reAuthenticationError",
380-
rc,
381-
d_allocator_p);
382-
channel->close(status);
379+
cleanupOnError(rc, "reauthenticationError", context, channel);
383380
return; // RETURN
384381
}
385382

@@ -391,12 +388,11 @@ void Authenticator::reAuthenticate(
391388
context->authenticationEncodingType());
392389

393390
if (rc != 0) {
394-
bmqio::Status status(bmqio::StatusCategory::e_GENERIC_ERROR,
395-
"reAuthenticationError",
396-
rc,
397-
d_allocator_p);
398-
channel->close(status);
391+
cleanupOnError(rc, "reauthenticationError", context, channel);
392+
return; // RETURN
399393
}
394+
395+
setTimer(context, result, channel);
400396
}
401397
}
402398

@@ -411,6 +407,8 @@ Authenticator::Authenticator(
411407
100, // max threads
412408
bsls::TimeInterval(120).totalMilliseconds(), // idle time
413409
allocator)
410+
, d_scheduler(bdlmt::TimerEventScheduler(bsls::SystemClockType::e_MONOTONIC,
411+
allocator))
414412
, d_blobSpPool_p(blobSpPool)
415413
, d_allocator_p(allocator)
416414
{
@@ -432,6 +430,15 @@ int Authenticator::start(bsl::ostream& errorDescription)
432430
return rc; // RETURN
433431
}
434432

433+
rc = d_scheduler.start();
434+
if (rc != 0) {
435+
errorDescription << "Failed to start TimerEventScheduler for "
436+
"Authenticator [rc: "
437+
<< rc << "]";
438+
d_threadPool.stop();
439+
return rc; // RETURN
440+
}
441+
435442
return 0;
436443
}
437444

@@ -514,6 +521,82 @@ int Authenticator::handleReauthentication(
514521
return rc;
515522
}
516523

524+
void Authenticator::timeout(const ChannelSp& channel)
525+
{
526+
BALL_LOG_DEBUG << "Authentication timeout for channel: "
527+
<< channel->peerUri();
528+
529+
bmqio::Status status(bmqio::StatusCategory::e_TIMEOUT,
530+
"authenticationTimeout",
531+
-1,
532+
d_allocator_p);
533+
channel->close(status);
534+
}
535+
536+
void Authenticator::setTimer(const AuthenticationContextSp& context,
537+
const AuthenticationResultSp& result,
538+
const ChannelSp& channel)
539+
{
540+
if (!result->lifetimeMs().has_value()) {
541+
BALL_LOG_INFO
542+
<< "Lifetime not set for authentication timer for channel: "
543+
<< channel->peerUri() << ", this indicates an infinite lifetime.";
544+
return; // RETURN
545+
}
546+
547+
bslmt::LockGuard<bslmt::Mutex> guard(
548+
&context->authenticationTimerHandleMutex()); // MUTEX LOCKED
549+
550+
bdlmt::TimerEventScheduler::Handle handle =
551+
context->authenticationTimerHandle();
552+
553+
// If the timer handle is invalid, it means that this is the initial
554+
// authentication and the timer has not been set yet.
555+
if (handle == bdlmt::TimerEventScheduler::INVALID_HANDLE) {
556+
handle = d_scheduler.scheduleEvent(
557+
bsls::TimeInterval(result->lifetimeMs().value()),
558+
bdlf::BindUtil::bind(&Authenticator::timeout, this, channel));
559+
context->setAuthenticationTimerHandle(handle);
560+
}
561+
else {
562+
d_scheduler.cancelEvent(handle);
563+
564+
int rc = d_scheduler.rescheduleEvent(
565+
handle,
566+
bsls::TimeInterval(result->lifetimeMs().value()));
567+
568+
if (rc != 0) {
569+
BALL_LOG_ERROR << "Failed to reschedule authentication timer for '"
570+
<< channel->peerUri() << "' [rc: " << rc
571+
<< ", lifetime: " << result->lifetimeMs().value()
572+
<< "]";
573+
bmqio::Status status(bmqio::StatusCategory::e_GENERIC_ERROR,
574+
"reAuthenticationError",
575+
rc,
576+
d_allocator_p);
577+
channel->close(status);
578+
}
579+
}
580+
}
581+
582+
void Authenticator::cleanupOnError(int errorCode,
583+
const bsl::string& errorDescription,
584+
const AuthenticationContextSp& context,
585+
const ChannelSp& channel)
586+
{
587+
{
588+
bslmt::LockGuard<bslmt::Mutex> guard(
589+
&context->authenticationTimerHandleMutex()); // MUTEX LOCKED
590+
d_scheduler.cancelEvent(context->authenticationTimerHandle());
591+
}
592+
593+
bmqio::Status status(bmqio::StatusCategory::e_GENERIC_ERROR,
594+
errorDescription,
595+
errorCode,
596+
d_allocator_p);
597+
channel->close(status);
598+
}
599+
517600
int Authenticator::authenticationOutboundOrReverse(
518601
const AuthenticationContextSp& context)
519602
{

src/groups/mqb/mqba/mqba_authenticator.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
/// are called only from there. It is not thread safe.
3333

3434
// MQB
35+
#include "mqbplug_authenticator.h"
3536
#include <mqbauthn_authenticationcontroller.h>
3637
#include <mqbconfm_messages.h>
3738
#include <mqbnet_authenticationcontext.h>
@@ -47,6 +48,7 @@
4748
#include <bdlbb_blob.h>
4849
#include <bdlcc_sharedobjectpool.h>
4950
#include <bdlmt_threadpool.h>
51+
#include <bdlmt_timereventscheduler.h>
5052
#include <bsl_memory.h>
5153
#include <bsl_ostream.h>
5254
#include <bslma_allocator.h>
@@ -90,6 +92,11 @@ class Authenticator : public mqbnet::Authenticator {
9092
typedef bsl::shared_ptr<mqbnet::InitialConnectionContext>
9193
InitialConnectionContextSp;
9294

95+
typedef bsl::shared_ptr<mqbplug::AuthenticationResult>
96+
AuthenticationResultSp;
97+
98+
typedef bsl::shared_ptr<bmqio::Channel> ChannelSp;
99+
93100
private:
94101
// DATA
95102

@@ -98,6 +105,8 @@ class Authenticator : public mqbnet::Authenticator {
98105

99106
bdlmt::ThreadPool d_threadPool;
100107

108+
bdlmt::TimerEventScheduler d_scheduler;
109+
101110
BlobSpPool* d_blobSpPool_p;
102111

103112
/// Allocator to use.
@@ -193,6 +202,17 @@ class Authenticator : public mqbnet::Authenticator {
193202
const AuthenticationContextSp& context,
194203
const bsl::shared_ptr<bmqio::Channel>& channel);
195204

205+
void timeout(const bsl::shared_ptr<bmqio::Channel>& channel);
206+
207+
void setTimer(const AuthenticationContextSp& context,
208+
const AuthenticationResultSp& result,
209+
const ChannelSp& channel);
210+
211+
void cleanupOnError(int errorCode,
212+
const bsl::string& errorDescription,
213+
const AuthenticationContextSp& context,
214+
const ChannelSp& channel);
215+
196216
public:
197217
// TRAITS
198218
BSLMF_NESTED_TRAIT_DECLARATION(Authenticator, bslma::UsesBslmaAllocator)

src/groups/mqb/mqbnet/mqbnet_authenticationcontext.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,11 @@ AuthenticationContext::AuthenticationContext(
3939
bool isReversed,
4040
State state,
4141
ConnectionType::Enum connectionType)
42-
: d_initialConnectionContext_p(initialConnectionContext)
42+
: d_authenticationResultSp()
43+
, d_authenticationTimerHandle(bdlmt::TimerEventScheduler::INVALID_HANDLE)
44+
, d_timerHandleMutex()
45+
, d_mutex()
46+
, d_initialConnectionContext_p(initialConnectionContext)
4347
, d_authenticationMessage(authenticationMessage)
4448
, d_authenticationEncodingType(authenticationEncodingType)
4549
, d_reAuthenticateCb(reAuthenticateCb)
@@ -59,6 +63,13 @@ AuthenticationContext& AuthenticationContext::setAuthenticationResult(
5963
return *this;
6064
}
6165

66+
AuthenticationContext& AuthenticationContext::setAuthenticationTimerHandle(
67+
bdlmt::TimerEventScheduler::Handle value)
68+
{
69+
d_authenticationTimerHandle = value;
70+
return *this;
71+
}
72+
6273
AuthenticationContext& AuthenticationContext::setInitialConnectionContext(
6374
InitialConnectionContext* value)
6475
{
@@ -113,6 +124,17 @@ AuthenticationContext::authenticationResult() const
113124
return d_authenticationResultSp;
114125
}
115126

127+
bdlmt::TimerEventScheduler::Handle
128+
AuthenticationContext::authenticationTimerHandle() const
129+
{
130+
return d_authenticationTimerHandle;
131+
}
132+
133+
bslmt::Mutex& AuthenticationContext::authenticationTimerHandleMutex()
134+
{
135+
return d_timerHandleMutex;
136+
}
137+
116138
InitialConnectionContext*
117139
AuthenticationContext::initialConnectionContext() const
118140
{

src/groups/mqb/mqbnet/mqbnet_authenticationcontext.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@
2323
///
2424

2525
// MQB
26-
#include "bmqp_protocol.h"
2726
#include <mqbnet_initialconnectioncontext.h>
2827

2928
// BMQ
3029
#include <bmqp_ctrlmsg_messages.h>
30+
#include <bmqp_protocol.h>
3131

3232
// BDE
33+
#include <bdlmt_timereventscheduler.h>
3334
#include <bslmt_mutex.h>
3435
#include <bsls_atomic.h>
3536

@@ -63,6 +64,12 @@ class AuthenticationContext {
6364
/// during re-authentication.
6465
bsl::shared_ptr<mqbplug::AuthenticationResult> d_authenticationResultSp;
6566

67+
/// The timer handle for the authentication timeout.
68+
bdlmt::TimerEventScheduler::Handle d_authenticationTimerHandle;
69+
70+
/// The mutex to protect the AuthenticationTimerHandle and
71+
bslmt::Mutex d_timerHandleMutex;
72+
6673
/// The mutex to protect the AuthenticationResult.
6774
mutable bslmt::Mutex d_mutex;
6875

@@ -105,6 +112,8 @@ class AuthenticationContext {
105112
AuthenticationContext& setAuthenticationResult(
106113
const bsl::shared_ptr<mqbplug::AuthenticationResult>& value);
107114
AuthenticationContext&
115+
setAuthenticationTimerHandle(bdlmt::TimerEventScheduler::Handle value);
116+
AuthenticationContext&
108117
setInitialConnectionContext(InitialConnectionContext* value);
109118
AuthenticationContext&
110119
setAuthenticationMessage(const bmqp_ctrlmsg::AuthenticationMessage& value);
@@ -124,6 +133,12 @@ class AuthenticationContext {
124133
const bsl::shared_ptr<mqbplug::AuthenticationResult>&
125134
authenticationResult() const;
126135

136+
/// This function holds a mutex lock while accessing the
137+
/// `d_authenticationTimerHandle` to ensure thread safety.
138+
bdlmt::TimerEventScheduler::Handle authenticationTimerHandle() const;
139+
140+
bslmt::Mutex& authenticationTimerHandleMutex();
141+
127142
InitialConnectionContext* initialConnectionContext() const;
128143
const bmqp_ctrlmsg::AuthenticationMessage& authenticationMessage() const;
129144
bmqp::EncodingType::Enum authenticationEncodingType() const;

0 commit comments

Comments
 (0)