Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HBASE-28970 Get asyncfs working with custom SASL mechanisms #6507

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
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 @@ -112,7 +112,8 @@ private FanOutOneBlockAsyncDFSOutputSaslHelper() {

private static final String SERVER_NAME = "0";
private static final String PROTOCOL = "hdfs";
private static final String MECHANISM = "DIGEST-MD5";
private static final String MECHANISM =
org.apache.hadoop.security.SaslRpcServer.AuthMethod.TOKEN.getMechanismName();
private static final int SASL_TRANSFER_MAGIC_NUMBER = 0xDEADBEEF;
private static final String NAME_DELIMITER = " ";

Expand Down Expand Up @@ -461,7 +462,11 @@ private void sendSaslMessage(ChannelHandlerContext ctx, byte[] payload,
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
safeWrite(ctx, ctx.alloc().buffer(4).writeInt(SASL_TRANSFER_MAGIC_NUMBER));
sendSaslMessage(ctx, new byte[0]);
byte[] firstMessage = new byte[0];
if (saslClient.hasInitialResponse()) {
firstMessage = saslClient.evaluateChallenge(firstMessage);
}
sendSaslMessage(ctx, firstMessage);
ctx.flush();
step++;
}
Expand Down Expand Up @@ -502,12 +507,17 @@ private void checkSaslComplete() throws IOException {
Set<String> requestedQop =
ImmutableSet.copyOf(Arrays.asList(saslProps.get(Sasl.QOP).split(",")));
String negotiatedQop = getNegotiatedQop();
// Treat null negotiated QOP as "auth" for the purpose of verification
// Code elsewhere does the same implicitly
if (negotiatedQop == null) {
negotiatedQop = "auth";
}
Comment on lines +510 to +514
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why is this necessary here. It's only effective within this private method and doesn't make any difference in the verification at line 517, while it hides that there was no negotiated QoP with the client.

Since rest of the code handles "auth" and null equally, it'd make sense to return "auth" by the getNegotiatedQop() if null was negotiated effectively making sure that negotiatedQop will never be null. That would probably make some of the code in this class simpler, but still not strictly required for this patch.

Copy link
Contributor Author

@stoty stoty Dec 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's not true.

The Hadoop code always requests some kind of QOP, at least "auth".

SASL mechanisms that don't support QOP at all, like SCRAM, will ignore the requested QOP and always return null negotiated qop.

Without this if, we could not use SCRAM at all, as ["auth"] does not contain null.

The rest of the code does not check the negotiated QOP against the requested one, so a null check is fine there.

This is the simplest way I can think of to handle non-QOP capable SASL mechanisms.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, basically in case of SCRAM requestedQop is ["auth"], but negotiatedQop is NULL?
Do you put this hack here to pretend "auth" was negotiated?

LOG.debug(
"Verifying QOP, requested QOP = " + requestedQop + ", negotiated QOP = " + negotiatedQop);
if (!requestedQop.contains(negotiatedQop)) {
throw new IOException(String.format("SASL handshake completed, but "
+ "channel does not have acceptable quality of protection, "
+ "requested = %s, negotiated = %s", requestedQop, negotiatedQop));
+ "requested = %s, negotiated(effective) = %s", requestedQop, negotiatedQop));
}
}

Expand Down