Skip to content

Commit 5185512

Browse files
committed
ARTEMIS-6037 refactor handling of cluster credentials
1 parent ed1b48e commit 5185512

19 files changed

Lines changed: 478 additions & 544 deletions

File tree

artemis-server/src/main/java/org/apache/activemq/artemis/core/security/impl/SecurityStoreImpl.java

Lines changed: 44 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
import com.github.benmanes.caffeine.cache.Cache;
3131
import com.github.benmanes.caffeine.cache.Caffeine;
32+
import org.apache.activemq.artemis.api.core.ActiveMQSecurityException;
3233
import org.apache.activemq.artemis.api.core.Pair;
3334
import org.apache.activemq.artemis.api.core.SimpleString;
3435
import org.apache.activemq.artemis.api.core.management.CoreNotificationType;
@@ -63,6 +64,8 @@
6364
import org.slf4j.Logger;
6465
import org.slf4j.LoggerFactory;
6566

67+
import static org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration.getDefaultClusterPassword;
68+
import static org.apache.activemq.artemis.api.config.ActiveMQDefaultConfiguration.getDefaultClusterUser;
6669
import static org.apache.activemq.artemis.utils.CertificateUtil.CERT_SUBJECT_DN_UNAVAILABLE;
6770

6871
/**
@@ -113,7 +116,7 @@ public SecurityStoreImpl(final HierarchicalRepository<Set<Role>> securityReposit
113116
final String managementClusterPassword,
114117
final NotificationService notificationService,
115118
final long authenticationCacheSize,
116-
final long authorizationCacheSize) throws NoSuchAlgorithmException {
119+
final long authorizationCacheSize) {
117120
this.securityRepository = securityRepository;
118121
this.securityManager = securityManager;
119122
this.securityEnabled = securityEnabled;
@@ -178,24 +181,10 @@ public String authenticate(final String user,
178181
RemotingConnection connection,
179182
String securityDomain) throws Exception {
180183
if (securityEnabled) {
181-
182-
if (managementClusterUser.equals(user)) {
183-
logger.trace("Authenticating cluster admin user");
184-
185-
/*
186-
* The special user cluster user is used for creating sessions that replicate management
187-
* operation between nodes
188-
*/
189-
if (!managementClusterPassword.equals(password)) {
190-
AUTHENTICATION_FAILURE_COUNT_UPDATER.incrementAndGet(this);
191-
throw ActiveMQMessageBundle.BUNDLE.unableToValidateClusterUser(user);
192-
} else {
193-
AUTHENTICATION_SUCCESS_COUNT_UPDATER.incrementAndGet(this);
194-
return managementClusterUser;
195-
}
184+
String validatedUser = handleClusterAuthentication(user, password, connection);
185+
if (validatedUser != null) {
186+
return validatedUser;
196187
}
197-
198-
String validatedUser = null;
199188
boolean userIsValid = false;
200189
boolean check = true;
201190

@@ -305,10 +294,12 @@ public boolean hasPermission(final SimpleString address,
305294
return true;
306295
}
307296

308-
// bypass permission checks for management cluster user
309297
String user = session.getUsername();
310-
if (managementClusterUser.equals(user) && session.getPassword().equals(managementClusterPassword)) {
298+
ClusterCredentialsCheckResult checkResult = checkClusterCredentials(user, session.getPassword());
299+
if (checkResult == ClusterCredentialsCheckResult.VALID) {
311300
return true;
301+
} else if (checkResult == ClusterCredentialsCheckResult.INVALID) {
302+
return false;
312303
}
313304

314305
// Special case: detect authentication failure for ActiveMQSecurityManager5
@@ -384,6 +375,39 @@ public boolean hasPermission(final SimpleString address,
384375
}
385376
}
386377

378+
private String handleClusterAuthentication(String user, String password, RemotingConnection connection) throws ActiveMQSecurityException {
379+
ClusterCredentialsCheckResult checkResult = checkClusterCredentials(user, password);
380+
381+
if (checkResult == ClusterCredentialsCheckResult.VALID) {
382+
AUTHENTICATION_SUCCESS_COUNT_UPDATER.incrementAndGet(this);
383+
return user;
384+
} else if (checkResult == ClusterCredentialsCheckResult.INVALID) {
385+
AUTHENTICATION_FAILURE_COUNT_UPDATER.incrementAndGet(this);
386+
throw ActiveMQMessageBundle.BUNDLE.unableToValidateUser(connection == null ? "null" : connection.getRemoteAddress(), user, null);
387+
} else {
388+
return null;
389+
}
390+
}
391+
392+
private ClusterCredentialsCheckResult checkClusterCredentials(String user, String password) {
393+
if ((getDefaultClusterUser().equals(user) && getDefaultClusterPassword().equals(password))) {
394+
// reject default cluster credentials
395+
return ClusterCredentialsCheckResult.INVALID;
396+
} else if (managementClusterUser.equals(user) && !managementClusterPassword.equals(password)) {
397+
// reject if username is right, but password is wrong
398+
return ClusterCredentialsCheckResult.INVALID;
399+
} else if (managementClusterUser.equals(user) && managementClusterPassword.equals(password)) {
400+
// accept if both user & password are right
401+
return ClusterCredentialsCheckResult.VALID;
402+
} else {
403+
return ClusterCredentialsCheckResult.IGNORE;
404+
}
405+
}
406+
407+
enum ClusterCredentialsCheckResult {
408+
VALID, INVALID, IGNORE
409+
}
410+
387411
@Override
388412
public void check(final SimpleString address,
389413
final SimpleString queue,

artemis-server/src/main/java/org/apache/activemq/artemis/core/server/ActiveMQServerLogger.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,8 @@ void slowConsumerDetected(String sessionID,
341341
@LogMessage(id = 222006, value = "Binding already exists with name {}, divert will not be deployed", level = LogMessage.Level.WARN)
342342
void divertBindingAlreadyExists(SimpleString bindingName);
343343

344-
@LogMessage(id = 222007, value = "Security risk! Apache Artemis is running with the default cluster admin user and default password. Please see the cluster chapter in the Artemis User Guide for instructions on how to change this.", level = LogMessage.Level.WARN)
345-
void clusterSecurityRisk();
344+
@LogMessage(id = 222007, value = "Apache Artemis is running with the default cluster user and password. Any connection using these credentials will be rejected. Please see the cluster chapter in the Artemis User Guide for instructions on how to change this.", level = LogMessage.Level.WARN)
345+
void defaultClusterCredentialsInUse();
346346

347347
@LogMessage(id = 222008, value = "unable to restart server, please kill and restart manually", level = LogMessage.Level.WARN)
348348
void serverRestartWarning(Exception e);

artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterConnection.java

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,6 @@ void nodeAnnounced(long eventUID,
7474

7575
boolean isNodeActive(String id);
7676

77-
/**
78-
* Verifies whether user and password match the ones configured for this ClusterConnection.
79-
*
80-
* @return {@code true} if username and password match, {@code false} otherwise
81-
*/
82-
boolean verify(String clusterUser, String clusterPassword);
83-
8477
void removeRecord(String targetNodeID);
8578

8679
void disconnectRecord(String targetNodeID);

artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterController.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -407,11 +407,19 @@ public void handlePacket(Packet packet) {
407407

408408
ClusterConnectMessage msg = (ClusterConnectMessage) packet;
409409

410-
if (server.getConfiguration().isSecurityEnabled() && !clusterConnection.verify(msg.getClusterUser(), msg.getClusterPassword())) {
411-
clusterChannel.send(new ClusterConnectReplyMessage(false));
412-
} else {
410+
boolean userIsValid = false;
411+
try {
412+
server.validateUser(msg.getClusterUser(), msg.getClusterPassword(), null, null);
413+
userIsValid = true;
414+
} catch (Exception e) {
415+
// cluster user isn't valid
416+
}
417+
418+
if (userIsValid) {
413419
authorized = true;
414420
clusterChannel.send(new ClusterConnectReplyMessage(true));
421+
} else {
422+
clusterChannel.send(new ClusterConnectReplyMessage(false));
415423
}
416424
}
417425
} else {

artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/ClusterManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -506,7 +506,7 @@ public boolean intercept(Packet packet, RemotingConnection connection) throws Ac
506506
if (packet.getType() == PacketImpl.EXCEPTION) {
507507
ActiveMQExceptionMessage msg = (ActiveMQExceptionMessage) packet;
508508
final ActiveMQException exception = msg.getException();
509-
if (exception.getType() == ActiveMQExceptionType.CLUSTER_SECURITY_EXCEPTION) {
509+
if (exception.getType() == ActiveMQExceptionType.CLUSTER_SECURITY_EXCEPTION || exception.getType() == ActiveMQExceptionType.SECURITY_EXCEPTION) {
510510
ActiveMQServerLogger.LOGGER.clusterManagerAuthenticationError(exception.getMessage());
511511
executor.execute(() -> {
512512
try {

artemis-server/src/main/java/org/apache/activemq/artemis/core/server/cluster/impl/ClusterConnectionImpl.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,11 +1769,6 @@ public ServerLocatorInternal createServerLocator() {
17691769
}
17701770
}
17711771

1772-
@Override
1773-
public boolean verify(String clusterUser0, String clusterPassword0) {
1774-
return clusterUser.equals(clusterUser0) && clusterPassword.equals(clusterPassword0);
1775-
}
1776-
17771772
@Override
17781773
public void removeRecord(String targetNodeID) {
17791774
logger.debug("Removing record for: {}", targetNodeID);

artemis-server/src/main/java/org/apache/activemq/artemis/core/server/impl/ActiveMQServerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3380,7 +3380,7 @@ synchronized boolean initialisePart1(boolean scalingDown) throws Exception {
33803380
storageManager = createStorageManager();
33813381

33823382
if (!configuration.getClusterConfigurations().isEmpty() && ActiveMQDefaultConfiguration.getDefaultClusterUser().equals(configuration.getClusterUser()) && ActiveMQDefaultConfiguration.getDefaultClusterPassword().equals(configuration.getClusterPassword())) {
3383-
ActiveMQServerLogger.LOGGER.clusterSecurityRisk();
3383+
ActiveMQServerLogger.LOGGER.defaultClusterCredentialsInUse();
33843384
}
33853385

33863386
securityStore = new SecurityStoreImpl(securityRepository, securityManager, configuration.getSecurityInvalidationInterval(), configuration.isSecurityEnabled(), configuration.getClusterUser(), configuration.getClusterPassword(), managementService, configuration.getAuthenticationCacheSize(), configuration.getAuthorizationCacheSize());

0 commit comments

Comments
 (0)