Skip to content

Commit 262b3e9

Browse files
Refactor validateRepositoryPasswordHash
1 parent 8e036f0 commit 262b3e9

File tree

1 file changed

+26
-15
lines changed

1 file changed

+26
-15
lines changed

x-pack/plugin/repository-encrypted/src/main/java/org/elasticsearch/repositories/encrypted/EncryptedRepository.java

+26-15
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
import java.util.Set;
6868
import java.util.concurrent.Executor;
6969
import java.util.concurrent.atomic.AtomicReference;
70-
import java.util.function.Consumer;
7170
import java.util.function.Supplier;
7271

7372
public final class EncryptedRepository extends BlobStoreRepository {
@@ -271,11 +270,15 @@ public void finalizeSnapshot(SnapshotId snapshotId, ShardGenerations shardGenera
271270
int totalShards, List<SnapshotShardFailure> shardFailures, long repositoryStateId,
272271
boolean includeGlobalState, MetaData clusterMetaData, Map<String, Object> userMetadata,
273272
Version repositoryMetaVersion, ActionListener<SnapshotInfo> listener) {
274-
validateRepositoryPasswordHash(userMetadata, listener::onFailure);
275-
if (userMetadata != null && userMetadata.containsKey(PASSWORD_HASH_RESERVED_USER_METADATA_KEY)) {
273+
try {
274+
validateRepositoryPasswordHash(userMetadata);
276275
// remove the repository password hash from the snapshot metadata, after all repository password verifications
277276
// have completed, so that the hash is not displayed in the API response to the user
277+
userMetadata = new HashMap<>(userMetadata);
278278
userMetadata.remove(PASSWORD_HASH_RESERVED_USER_METADATA_KEY);
279+
} catch (Exception passValidationException) {
280+
listener.onFailure(passValidationException);
281+
return;
279282
}
280283
super.finalizeSnapshot(snapshotId, shardGenerations, startTime, failure, totalShards, shardFailures, repositoryStateId,
281284
includeGlobalState, clusterMetaData, userMetadata, repositoryMetaVersion, listener);
@@ -285,7 +288,12 @@ public void finalizeSnapshot(SnapshotId snapshotId, ShardGenerations shardGenera
285288
public void snapshotShard(Store store, MapperService mapperService, SnapshotId snapshotId, IndexId indexId,
286289
IndexCommit snapshotIndexCommit, IndexShardSnapshotStatus snapshotStatus, Version repositoryMetaVersion,
287290
Map<String, Object> userMetadata, ActionListener<String> listener) {
288-
validateRepositoryPasswordHash(userMetadata, listener::onFailure);
291+
try {
292+
validateRepositoryPasswordHash(userMetadata);
293+
} catch (Exception passValidationException) {
294+
listener.onFailure(passValidationException);
295+
return;
296+
}
289297
super.snapshotShard(store, mapperService, snapshotId, indexId, snapshotIndexCommit, snapshotStatus, repositoryMetaVersion,
290298
userMetadata, listener);
291299
}
@@ -771,25 +779,28 @@ private static String computeSaltedPBKDF2Hash(byte[] salt, char[] password) {
771779
}
772780

773781
/**
774-
* Called before every snapshot operation on every node to validate that the snapshot metadata contains a password hash
775-
* that matches up with the repository password on the local node.
782+
* Called before the shard snapshot and finalize operations, on the data and master nodes. This validates that the repository
783+
* password hash of the master node that started the snapshot operation matches with the repository password on the data nodes.
776784
*
777785
* @param snapshotUserMetadata the snapshot metadata to verify
778-
* @param exception the exception handler to call when the repository password check fails
786+
* @throws RepositoryException if the repository password on the local node mismatches or cannot be verified from the
787+
* master's password hash from {@code snapshotUserMetadata}
779788
*/
780-
private void validateRepositoryPasswordHash(Map<String, Object> snapshotUserMetadata, Consumer<Exception> exception) {
781-
Object repositoryPasswordHash = snapshotUserMetadata.get(PASSWORD_HASH_RESERVED_USER_METADATA_KEY);
789+
private void validateRepositoryPasswordHash(Map<String, Object> snapshotUserMetadata) throws RepositoryException {
790+
if (snapshotUserMetadata == null) {
791+
throw new RepositoryException(metadata.name(), "Unexpected fatal internal error",
792+
new IllegalStateException("Null snapshot metadata"));
793+
}
794+
final Object repositoryPasswordHash = snapshotUserMetadata.get(PASSWORD_HASH_RESERVED_USER_METADATA_KEY);
782795
if (repositoryPasswordHash == null || (false == repositoryPasswordHash instanceof String)) {
783-
exception.accept(new RepositoryException(metadata.name(), "Unexpected fatal internal error",
784-
new IllegalStateException("Snapshot metadata does not contain the repository password hash as a String")));
785-
return;
796+
throw new RepositoryException(metadata.name(), "Unexpected fatal internal error",
797+
new IllegalStateException("Snapshot metadata does not contain the repository password hash as a String"));
786798
}
787799
if (false == passwordHashVerifier.verify((String) repositoryPasswordHash)) {
788-
exception.accept(new RepositoryException(metadata.name(),
800+
throw new RepositoryException(metadata.name(),
789801
"Repository password mismatch. The local node's value of the keystore secure setting [" +
790802
EncryptedRepositoryPlugin.ENCRYPTION_PASSWORD_SETTING.getConcreteSettingForNamespace(metadata.name()).getKey() +
791-
"] is different from the elected master node, which started the snapshot operation"));
792-
return;
803+
"] is different from the elected master node, which started the snapshot operation");
793804
}
794805
}
795806

0 commit comments

Comments
 (0)