Details

    • Type: Improvement
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 5
    • Fix Version/s: 5, wd08
    • Component/s: core
    • Labels:
      None
    • Proposal:
      Hide

      Add an Identifier/Value pair of 15 (0xF) Auth Method. The data is a UTF-8 string which is the name of the authentication method. This is commonly a registered SASL mechanism, but it can be any string which is understood by both the Client and Server.

      Add an identifier/Value pair of 47 (0x2F) Auth Data. This is added to the CONNECT, CONNACK, and AUTH packets. The type is BinaryData.

      Add a new Control Packet: AUTH: Command=0xF, Flags=0x1 The variable header for AUTH consists of a Return code, and an Identifier/Value length, followed by 0 or more Identifier/Value pairs. There is no payload.

      On CONNECT, the Client MAY include an AuthMethod Idendifier/Value pair with the name of an authentication method. If this is not specified, the Server does the authentication based only on information in the CONNECT packet (as it does in MQTTv3.1.1).

      If the CONNECT packet has enough information for the Server to authenticate the Client, it sends a CONNACK with an Return code of 0. The Server MAY send an AuthMethod field in the CONNACK to indicate the authentication method is used. The Server MUST NOT send an AUTH token if it has not received an AuthMethod from the Client on the CONNECT packet.

      If the AuthMethod specified on the CONNECT has the value "LIST", the Server MUST either return a comma separated list of authentication methods it supports in the AuthMethod field of a AUTH packet or close the connection. If the server returns the list it MUST offer at least one authentication method in this list. If it does not support any form of extended authentication, it should close the connection (it MAY send a CONNACK return and MUST close the connection).

      If the Server does not support the authentication method selected by the client, it MAY send a Not authorized return code on CONNACK and MUST close the connection. If the Client does not accept any of the authentication methods returned by the server, it MAY send a DISCONNECT packet and MUST close the connection.

      If the Server needs additional information to complete the Authorization, it sends a AUTH packet with a Return code of More Auth Needed and the AuthMethod selected by the client. The Sever MAY send the first piece of server authentication data as the AuthData field in the AUTH packet.

      The Server and Client can continue to send AUTH packets to one another until the Server accepts the authentication by sending a CONNACK with a Return code of 0, or rejects the connection by sending a CONNACK with a non-zero return code. The Client MAY close the connection at any time and MAY send a DISCONNECT to the server informing it of the reason. These intermediate AUTH packets sent from the Server have a Return code of "More auth needed", and all AUTH packets sent by the Client have a Return code of 0.

      If the Server receives an AUTH packet after it has sent a CONNACK, it MUST have a Return code of "Revalidate" set to indicate that this is a revalidate. The revalidate acts just like the CONNECT and starts an authentication. This ends with a AUTH sent from Server to Client with a Return code of other than "More auth needed". A zero Return code indicates that the revalidation is successful. The Server MAY close the connection if the revalidate fails.

      The Client MUST NOT send an AUTH packet if it did not receive an AuthMethod id/value pair on the CONNACK.

      The spec update consists of two parts, the mechanism which is the addition of the AuthMethod and AuthData id/value pairs and the new AUTH control packet. In addition there is a chapter 4 section describing the use and showing the sequence for a common challenge / response auth method such as SCRAM.

      For instance, the exchange for SCRAM as an example of a simple challenge response is:

      client to server: CONNECT AuthMethod="SCRAM-SHA-256" AuthData=client-first-data
      server to client: AUTH rc="More auth" AuthMethod="SCRAM-SHA-256" AuthData=server-first-data
      client to server AUTH rc=0 AuthMethod="SCRAM-SHA-256" AuthData=client-final-data
      server to client CONNACK rc=0 AuthMethod="SCRAM-SHA-256" AuthData=server-final-data

      An example of an Kerberos challenge:

      client to server CONNECT AuthMethod="GS2-KRB5"
      server to client AUTH rc="More auth" AuthMethod="GS2-KRB5"
      client to server AUTH rc=0 AuthMethod="GS2-KRB5" AuthData=inital context token
      server to client AUTH rc="More auth" AuthMethod="GS2-KRB5" AuthData=reply context token
      client to server AUTH rc=0 AuthMethod="GS2-KRB5"
      server to client CONNACK rc=0 AuthMethod="GS2-KRB5" AuthData=outcome of authentication

      Show
      Add an Identifier/Value pair of 15 (0xF) Auth Method. The data is a UTF-8 string which is the name of the authentication method. This is commonly a registered SASL mechanism, but it can be any string which is understood by both the Client and Server. Add an identifier/Value pair of 47 (0x2F) Auth Data. This is added to the CONNECT, CONNACK, and AUTH packets. The type is BinaryData. Add a new Control Packet: AUTH: Command=0xF, Flags=0x1 The variable header for AUTH consists of a Return code, and an Identifier/Value length, followed by 0 or more Identifier/Value pairs. There is no payload. On CONNECT, the Client MAY include an AuthMethod Idendifier/Value pair with the name of an authentication method. If this is not specified, the Server does the authentication based only on information in the CONNECT packet (as it does in MQTTv3.1.1). If the CONNECT packet has enough information for the Server to authenticate the Client, it sends a CONNACK with an Return code of 0. The Server MAY send an AuthMethod field in the CONNACK to indicate the authentication method is used. The Server MUST NOT send an AUTH token if it has not received an AuthMethod from the Client on the CONNECT packet. If the AuthMethod specified on the CONNECT has the value "LIST", the Server MUST either return a comma separated list of authentication methods it supports in the AuthMethod field of a AUTH packet or close the connection. If the server returns the list it MUST offer at least one authentication method in this list. If it does not support any form of extended authentication, it should close the connection (it MAY send a CONNACK return and MUST close the connection). If the Server does not support the authentication method selected by the client, it MAY send a Not authorized return code on CONNACK and MUST close the connection. If the Client does not accept any of the authentication methods returned by the server, it MAY send a DISCONNECT packet and MUST close the connection. If the Server needs additional information to complete the Authorization, it sends a AUTH packet with a Return code of More Auth Needed and the AuthMethod selected by the client. The Sever MAY send the first piece of server authentication data as the AuthData field in the AUTH packet. The Server and Client can continue to send AUTH packets to one another until the Server accepts the authentication by sending a CONNACK with a Return code of 0, or rejects the connection by sending a CONNACK with a non-zero return code. The Client MAY close the connection at any time and MAY send a DISCONNECT to the server informing it of the reason. These intermediate AUTH packets sent from the Server have a Return code of "More auth needed", and all AUTH packets sent by the Client have a Return code of 0. If the Server receives an AUTH packet after it has sent a CONNACK, it MUST have a Return code of "Revalidate" set to indicate that this is a revalidate. The revalidate acts just like the CONNECT and starts an authentication. This ends with a AUTH sent from Server to Client with a Return code of other than "More auth needed". A zero Return code indicates that the revalidation is successful. The Server MAY close the connection if the revalidate fails. The Client MUST NOT send an AUTH packet if it did not receive an AuthMethod id/value pair on the CONNACK. The spec update consists of two parts, the mechanism which is the addition of the AuthMethod and AuthData id/value pairs and the new AUTH control packet. In addition there is a chapter 4 section describing the use and showing the sequence for a common challenge / response auth method such as SCRAM. For instance, the exchange for SCRAM as an example of a simple challenge response is: client to server: CONNECT AuthMethod="SCRAM-SHA-256" AuthData=client-first-data server to client: AUTH rc="More auth" AuthMethod="SCRAM-SHA-256" AuthData=server-first-data client to server AUTH rc=0 AuthMethod="SCRAM-SHA-256" AuthData=client-final-data server to client CONNACK rc=0 AuthMethod="SCRAM-SHA-256" AuthData=server-final-data An example of an Kerberos challenge: client to server CONNECT AuthMethod="GS2-KRB5" server to client AUTH rc="More auth" AuthMethod="GS2-KRB5" client to server AUTH rc=0 AuthMethod="GS2-KRB5" AuthData=inital context token server to client AUTH rc="More auth" AuthMethod="GS2-KRB5" AuthData=reply context token client to server AUTH rc=0 AuthMethod="GS2-KRB5" server to client CONNACK rc=0 AuthMethod="GS2-KRB5" AuthData=outcome of authentication

      Description

      MQTT 3.1.1 permits two client authentication mechanisms:
      1. Authentication by TLS (using a certificate/private key) prior to the CONNECT packet being sent
      2. Authentication via a username and password (or similar token) provided by a client in the CONNECT packet.

      The second mechanism also requires the use of TLS encryption in order for it to be secure.

      There are three reasons why we might consider adding alternative mechanisms, for example one involving server-directed challenge response during the MQTT CONNECT exchange:
      i) TLS might be considered too heavyweight for some particularly constrained devices.
      ii) There are many deployments where people are ok with TLS, but don't want to provision devices with bespoke Certificates. Some of these might not have a need to encrypt the MQTT protocol, but with approach 2 you end up having to encrypt all MQTT packets just in order to protect the password field in the CONNECT
      iii) The organization (or standard building on top of MQTT) might already have an alternative authentication protocol.

      Notes:
      1. The emphasis in this requirement is on composing with existing security mechanisms, rather than inventing new ones

      2. Some of this could be achieved by publishing Committee Notes (e.g. OAuth 2.0) rather than changing the CONNECT protocol packet exchange

        Attachments

          Activity

          Hide
          raphcohn Raphael Cohen (Inactive) added a comment -

          I like this proposal. It seems to cover all scenarios I think we should care about, and all the modern authentication mechanisms. Sending CONNACK as the final packet, whilst a 'breaking' change, ensures that a server only reveals details to an authenticated client. The only thing I'm not so sure about is "LIST". I worry that this could get us into some of the same problems as TLS ClientHello / ServerHello ciphersuite agreement over the years. I also think there might be a security issue of a downgrade attack if the LIST is offered to a client over a plaintext connection OR to an unauthenticated client. Of course, one can argue it is a broker's responsibility to only offer secure mechanisms, but the reality's no different to the TLS 1.0 / 1.1 / 1.2 issue on the internet today - if you want to support an older client, even during migration...

          Also, just as a client can either use TLS or not, and won't swap to the other, I think the same is true for a connection mechanism. Either it has the credentials (and the user's / system administrator's approval) for SCAM-SHA-256, or it doesn't. So I think LIST in practice is probably unnecessary. It might be useful to supply it on CONNACK, though.

          With this mechanism now in place, the opportunity exists to deprecate the user of username / password and call password 'initial client auth data' or the like. That might be a step too far, but an auth identifier can be:-

          • <nothing> => no username, no password
          • ANONYMOUS => username only
          • LOGIN => username, password
          • PLAIN => username, password, role
            etc
          Show
          raphcohn Raphael Cohen (Inactive) added a comment - I like this proposal. It seems to cover all scenarios I think we should care about, and all the modern authentication mechanisms. Sending CONNACK as the final packet, whilst a 'breaking' change, ensures that a server only reveals details to an authenticated client. The only thing I'm not so sure about is "LIST". I worry that this could get us into some of the same problems as TLS ClientHello / ServerHello ciphersuite agreement over the years. I also think there might be a security issue of a downgrade attack if the LIST is offered to a client over a plaintext connection OR to an unauthenticated client. Of course, one can argue it is a broker's responsibility to only offer secure mechanisms, but the reality's no different to the TLS 1.0 / 1.1 / 1.2 issue on the internet today - if you want to support an older client, even during migration... Also, just as a client can either use TLS or not, and won't swap to the other, I think the same is true for a connection mechanism. Either it has the credentials (and the user's / system administrator's approval) for SCAM-SHA-256, or it doesn't. So I think LIST in practice is probably unnecessary. It might be useful to supply it on CONNACK, though. With this mechanism now in place, the opportunity exists to deprecate the user of username / password and call password 'initial client auth data' or the like. That might be a step too far, but an auth identifier can be:- <nothing> => no username, no password ANONYMOUS => username only LOGIN => username, password PLAIN => username, password, role etc
          Hide
          knolleary Nick O'Leary (Inactive) added a comment -

          For the initial connect exchange, only AUTH packets are exchanged between the CONNECT and CONNACK.

          What is the behaviour after a client sends a Revalidate AUTH packet regarding other packet types? Can either the client or server continue to send other commands packets whilst the Revalidate AUTH flow is in progress or must all other packet flows be suspended until the AUTH flow has completed?

          Show
          knolleary Nick O'Leary (Inactive) added a comment - For the initial connect exchange, only AUTH packets are exchanged between the CONNECT and CONNACK. What is the behaviour after a client sends a Revalidate AUTH packet regarding other packet types? Can either the client or server continue to send other commands packets whilst the Revalidate AUTH flow is in progress or must all other packet flows be suspended until the AUTH flow has completed?
          Hide
          ken.borgendale Ken Borgendale (Inactive) added a comment -

          I put in the LIST function as it is a part of SASL, but I agree that it is not of very high value and I would prefer to drop it. We also need to decide if we want to do revalidation.

          The assumption on revalidation is that the client starts this at a point before the credentials expire. There should not be a issue with other packets flowing at the same time. The proposal is that the Server can decide what to do if the revalidation fails.

          Another thing to discuss is that sending an AuthMethod on CONNECT (at least with some methods) assumes that the client is willing to accept a challenge and therefore must not send any packets othere than AUTH before getting the CONNACK.

          Show
          ken.borgendale Ken Borgendale (Inactive) added a comment - I put in the LIST function as it is a part of SASL, but I agree that it is not of very high value and I would prefer to drop it. We also need to decide if we want to do revalidation. The assumption on revalidation is that the client starts this at a point before the credentials expire. There should not be a issue with other packets flowing at the same time. The proposal is that the Server can decide what to do if the revalidation fails. Another thing to discuss is that sending an AuthMethod on CONNECT (at least with some methods) assumes that the client is willing to accept a challenge and therefore must not send any packets othere than AUTH before getting the CONNACK.
          Hide
          ken.borgendale Ken Borgendale (Inactive) added a comment -

          This was resolved at the 2016-10-13 NQTT TC with the direction to remove the LIST function, and to move re-authorize to a separate issue. This is being put into WD08.

          Show
          ken.borgendale Ken Borgendale (Inactive) added a comment - This was resolved at the 2016-10-13 NQTT TC with the direction to remove the LIST function, and to move re-authorize to a separate issue. This is being put into WD08.
          Hide
          ken.borgendale Ken Borgendale (Inactive) added a comment -

          Issue included in MQTTv5.0 CS01 December 25, 2017

          Show
          ken.borgendale Ken Borgendale (Inactive) added a comment - Issue included in MQTTv5.0 CS01 December 25, 2017

            People

            • Assignee:
              ken.borgendale Ken Borgendale (Inactive)
              Reporter:
              peterniblett Peter Niblett (Inactive)
            • Watchers:
              5 Start watching this issue

              Dates

              • Due:
                Created:
                Updated:
                Resolved: