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
Original file line number Diff line number Diff line change
Expand Up @@ -5535,9 +5535,21 @@ public void startQuotaRepair(List<String> buckets) throws IOException {
new QuotaRepairTask(this).repair(buckets);
}

public byte[] getS3DerivedKey(String accessId, String signingKey) throws IOException {
String awsSecretKey = s3SecretManager.getSecretString(accessId);
return AWSV4AuthValidator.getSigningKey(awsSecretKey, signingKey);
/** Derives the signing key on the RPC thread after S3 authentication has succeeded. */
public byte[] getS3DerivedKey(S3Authentication s3Auth) throws IOException {
final String awsSecretKey;
if (StringUtils.isNotEmpty(s3Auth.getSessionToken())) {
STSTokenIdentifier stsToken = getStsTokenIdentifier();
if (stsToken == null || !s3Auth.getAccessId().equals(stsToken.getTempAccessKeyId())
|| StringUtils.isEmpty(stsToken.getSecretAccessKey())) {
throw new OMException("Missing authenticated STS credentials for signing key derivation",
OMException.ResultCodes.INVALID_TOKEN);
}
awsSecretKey = stsToken.getSecretAccessKey();
} else {
awsSecretKey = getS3SecretManager().getSecretString(s3Auth.getAccessId());
}
return AWSV4AuthValidator.getSigningKey(awsSecretKey, s3Auth.getStringToSign());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import static org.apache.hadoop.ozone.om.request.file.OMFileRequest.OMDirectoryResult.FILE_EXISTS_IN_GIVENPATH;
import static org.apache.hadoop.ozone.util.MetricUtil.captureLatencyNs;

import com.google.protobuf.ByteString;
import java.io.IOException;
import java.nio.file.InvalidPathException;
import java.nio.file.Paths;
Expand Down Expand Up @@ -65,12 +64,9 @@
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.KeyArgs;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMRequest;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.OMTokenProto;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.Type;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos.UserInfo;
import org.apache.hadoop.ozone.request.validation.RequestProcessingPhase;
import org.apache.hadoop.ozone.security.OzoneTokenIdentifier;
import org.apache.hadoop.ozone.security.S3SecurityUtil;
import org.apache.hadoop.ozone.security.acl.IAccessAuthorizer;
import org.apache.hadoop.util.Time;
import org.slf4j.Logger;
Expand Down Expand Up @@ -322,8 +318,7 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, Execut
checkBucketQuotaInBytes(omMetadataManager, bucketInfo,
preAllocatedSpace);
checkBucketQuotaInNamespace(bucketInfo, numMissingParents + 1L);
CreateKeyResponse.Builder builder =
getResponseBuilderWithDerivedKey(getOmRequest(), ozoneManager, createKeyRequest);
CreateKeyResponse.Builder builder = CreateKeyResponse.newBuilder();
perfMetrics.addCreateKeyQuotaCheckLatencyNs(Time.monotonicNowNanos() - quotaCheckStartTime);
bucketInfo.incrUsedNamespace(numMissingParents);

Expand Down Expand Up @@ -465,27 +460,4 @@ public static OMRequest blockCreateKeyWithBucketLayoutFromOldClient(
}
return req;
}

protected CreateKeyResponse.Builder getResponseBuilderWithDerivedKey(
OMRequest omRequest, OzoneManager ozoneManager,
CreateKeyRequest createKeyRequest) throws IOException {
CreateKeyResponse.Builder builder = CreateKeyResponse.newBuilder();
if (omRequest.hasS3Authentication() && ozoneManager.isSecurityEnabled()
&& createKeyRequest.hasDerivedKeyPiggyBacking()
&& createKeyRequest.getDerivedKeyPiggyBacking()
) {
OzoneTokenIdentifier s3Token = S3SecurityUtil.constructS3Token(omRequest);
if (!s3Token.getTokenType().equals(OMTokenProto.Type.S3AUTHINFO)) {
// Piggyback was requested but this token type cannot produce a derived key.
// S3 Gateway should only set this flag for S3AUTHINFO tokens.
LOG.warn("Derived key piggyback requested but token type is {}, " +
"not S3AUTHINFO. Derived key will not be returned.",
s3Token.getTokenType());
return builder;
}
byte[] derivedKey = ozoneManager.getS3DerivedKey(s3Token.getAwsAccessId(), s3Token.getStrToSign());
builder.setDerivedKey(ByteString.copyFrom(derivedKey));
}
return builder;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,7 @@ public OMClientResponse validateAndUpdateCache(OzoneManager ozoneManager, Execut
checkBucketQuotaInBytes(omMetadataManager, omBucketInfo,
preAllocatedSpace);
checkBucketQuotaInNamespace(omBucketInfo, numKeysCreated + 1L);
CreateKeyResponse.Builder createKeyResponseBuilder =
getResponseBuilderWithDerivedKey(getOmRequest(), ozoneManager, createKeyRequest);
CreateKeyResponse.Builder createKeyResponseBuilder = CreateKeyResponse.newBuilder();
perfMetrics.addCreateKeyQuotaCheckLatencyNs(Time.monotonicNowNanos() - quotaCheckStartTime);
omBucketInfo.incrUsedNamespace(numKeysCreated);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import static org.apache.hadoop.ozone.util.MetricUtil.captureLatencyNs;

import com.google.common.annotations.VisibleForTesting;
import com.google.protobuf.ByteString;
import com.google.protobuf.RpcController;
import com.google.protobuf.ServiceException;
import java.io.IOException;
Expand Down Expand Up @@ -176,6 +177,7 @@ public void logLargeResponseIfNeeded(OMResponse response) {

private OMResponse internalProcessRequest(OMRequest request) throws ServiceException {
boolean s3Auth = false;
ByteString derivedKey = null;

try {
if (request.hasS3Authentication()) {
Expand All @@ -185,6 +187,13 @@ private OMResponse internalProcessRequest(OMRequest request) throws ServiceExcep
// If request has S3Authentication, validate S3 credentials.
// If current OM is leader and then proceed with the request.
S3SecurityUtil.validateS3Credential(request, ozoneManager);
if (ozoneManager.isSecurityEnabled() && request.getCmdType() == OzoneManagerProtocolProtos.Type.CreateKey
&& request.getCreateKeyRequest().getDerivedKeyPiggyBacking()) {
derivedKey = ByteString.copyFrom(ozoneManager.getS3DerivedKey(request.getS3Authentication()));
// Only the RPC response needs this key. Older followers must not derive it during apply either.
request = request.toBuilder().setCreateKeyRequest(request.getCreateKeyRequest().toBuilder()
.clearDerivedKeyPiggyBacking()).build();
}
} catch (IOException ex) {
return createErrorResponse(request, ex);
}
Expand All @@ -201,13 +210,16 @@ private OMResponse internalProcessRequest(OMRequest request) throws ServiceExcep
}

// check retry cache
final OMResponse cached = omRatisServer.checkRetryCache();
if (cached != null) {
return cached;
OMResponse response = omRatisServer.checkRetryCache();
if (response == null) {
this.lastRequestToSubmit = request;
response = ozoneManager.getOmExecutionFlow().submit(request, true);
}

this.lastRequestToSubmit = request;
return ozoneManager.getOmExecutionFlow().submit(request, true);
if (derivedKey != null && response.getSuccess() && response.hasCreateKeyResponse()) {
return response.toBuilder().setCreateKeyResponse(response.getCreateKeyResponse().toBuilder()
.setDerivedKey(derivedKey)).build();
}
return response;
} finally {
OzoneManager.setS3Auth(null);
OzoneManager.setStsTokenIdentifier(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1519,12 +1519,11 @@ protected OmKeyInfo checkCreatedPaths(
}

@Test
public void testCreateKeyWithS3DerivedKey() throws Exception {
public void testCreateKeyDoesNotDeriveSigningKeyDuringApply() throws Exception {
when(ozoneManager.getOzoneLockProvider()).thenReturn(
new OzoneLockProvider(true, true));
when(ozoneManager.isSecurityEnabled()).thenReturn(true);
byte[] expectedDerivedKey = new byte[] {9, 8, 7, 6};
when(ozoneManager.getS3DerivedKey(anyString(), anyString())).thenReturn(expectedDerivedKey);
when(ozoneManager.getS3DerivedKey(any())).thenThrow(new IOException("Credentials unavailable during apply"));

KeyArgs.Builder keyArgs = KeyArgs.newBuilder()
.setVolumeName(volumeName)
Expand Down Expand Up @@ -1568,8 +1567,8 @@ public void testCreateKeyWithS3DerivedKey() throws Exception {
OzoneManagerProtocolProtos.CreateKeyResponse createKeyResponse =
response.getOMResponse().getCreateKeyResponse();
assertNotNull(createKeyResponse);
assertTrue(createKeyResponse.hasDerivedKey());
assertEquals(com.google.protobuf.ByteString.copyFrom(expectedDerivedKey), createKeyResponse.getDerivedKey());
assertThat(createKeyResponse.hasDerivedKey()).isFalse();
verify(ozoneManager, never()).getS3DerivedKey(any());
}

@Test
Expand Down
Loading
Loading