Skip to content

Backport of: 2132 Fix support for enhanced authentication #2171

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

Open
wants to merge 1 commit into
base: release/4.x.x
Choose a base branch
from

Conversation

BillArmstrong
Copy link

@BillArmstrong BillArmstrong commented Apr 7, 2025

This PR is a backport of #2132 for the version 4 library.

This PR has a number of changes as compared to the PR on which it is based. Since this PR is a fix for the v4 library I stuck with the original "ExtendedAuthenticationExchange" naming convention that was used in the v4 library instead of the more correct "EnhancedAuthentication" naming convention used in the v5 library.

Additionally I tried to avoid any changes to existing interfaces/method signatures that would cause breaking changes. The PR on which these changes are based has many breaking changes as compared to the v4 library.

Another significant difference between this PR and the original is in the client handler. The original PR allowed you to both send and receive packets from inside the client handler until the exchange is complete. This PR uses the pre-existing handler context that only supports sending a response. As a result, a multi-step authentication exchange will result in the handler being called multiple times. This works fine, but it is a key difference between this PR and the v5 PR. I made this choice in an effort to avoid any breaking changes.

My company is unable to use the v5 library because we are constrained by having to support the .Net Framework, but we need to be able to authenticate clients using Enhanced Authentication.

This PR addresses the following issues:

@BillArmstrong
Copy link
Author

@dotnet-policy-service agree company="Quest Software"

var receivedPacket = await Receive(cancellationToken).ConfigureAwait(false);

switch (receivedPacket)
for (; ; )
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is the purpose of this loop? In v5 is also no loop required.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for the review.

The loop is needed because when when the client sends the initial connection request, depending on what type of authentication is requested the server response will be either a MqttConnAckPacket or a MqttAuthPacket. The server will send a MqttAuthPacket if it needs to request additional authentication token data. Depending on the authentication mechanism, the server may send several MqttAuthPacket responses that the client will need to handle.

The client must respond to the MqttAuthPacket server requests until it receives a MqttConnAckPacket response.

In the Kerberos authentication sample in the MQTT v5 specification, the server sends two AUTH responses back to the client before finally sending a CONNACK response.

Copy link
Author

Choose a reason for hiding this comment

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

From the MQTT specification under Enhanced Authentication:

The Client and Server exchange AUTH packets as needed until the Server accepts the authentication by sending a CONNACK with a Reason Code of 0.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry I was confused because the original code is 4.x. In 5.x we have a while(true) at the same place. But I am sure we should also check the cancellation token instead of building an endless loop.

Copy link
Author

Choose a reason for hiding this comment

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

cancellationToken.ThrowIfCancellationRequested();

is the first line within the loop.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants