Merge pull request #1214 from tmolitor-stud-tu/ibr2

XEP-0388: Rework whole spec, namespace bump
This commit is contained in:
Kevin Smith 2023-03-31 11:08:13 +01:00 committed by GitHub
commit b5c14fb170
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 353 additions and 170 deletions

View File

@ -10,16 +10,37 @@
<abstract>This document describes a replacement for the SASL profile documented in RFC 6120 which allows for greater extensibility.</abstract>
&LEGALNOTICE;
<number>0388</number>
<status>Deferred</status>
<status>Experimental</status>
<type>Standards Track</type>
<sig>Standards</sig>
<approver>Council</approver>
<dependencies>
<spec>XMPP Core</spec>
<spec>rfc5802</spec>
<spec>XEP-0440</spec>
</dependencies>
<supersedes/>
<supersededby/>
<shortname>sasl2</shortname>
&dcridland;
&tmolitor;
&mwild;
<revision>
<version>0.4.0</version>
<date>2022-11-16</date>
<initials>tm</initials>
<remark>
<ul>
<li>Bump namespace</li>
<li>Add reference to &xep0440; and &rfc5802;</li>
<li>Update security considerations and business rules</li>
<li>Clarify &lt;continue/> and tasks</li>
<li>Add expansion point to inline stream resumption and BIND2 (and possibly others)</li>
<li>Add optional &lt;user-agent/> element</li>
<li>Move from Deferred to Experimental</li>
</ul>
</remark>
</revision>
<revision>
<version>0.3.0</version>
<date>2018-10-01</date>
@ -94,81 +115,161 @@
</section1>
<section1 topic='Overview' anchor="overview">
<section2 topic="Discovering Support" anchor="feature">
<p>Servers capable of SASL2 offer a stream feature of &lt;mechanisms/>, qualified by the "urn:xmpp:sasl:1" namespace. This in turn contains one or more &lt;mechanism/> elements in the same namespace, and potentially other elements (for example, the &lt;hostname/> element defined within XEP-0233).</p>
<p>Note that SASL2 is impossible for clients to initiate without at least one mechanism being available, and therefore MUST NOT be offered.</p>
<section2 topic="SASL mechanism negotiation" anchor="feature">
<p>Servers capable of SASL2 offer a stream feature of &lt;authentication/>, qualified by the "urn:xmpp:sasl:2" namespace. This in turn contains one or more &lt;mechanism/> elements in the same namespace, and potentially other elements (for example, the &lt;hostname/> element defined within &xep0233;). The mechanism elements MUST only offer mechanisms the server can offer for the JID provided by the client in the "from" attribute of the stream-header. If that atrribute is omitted or does not contain a recognised bare JID, the server SHOULD only offer mechanisms it can provide independently of the JID. Note that varying responses based on whether an account exists or not may leak the existence of accounts to unauthorized parties. See the security considerations section for more information. If the "from" attribute is not empty and the domain used in this attribute does not match the domain used in the "to" attribute the server SHOULD respond with an invalid-from error as defined in §4.9.3.9 of &rfc6120;.</p>
<p>The feature so advertised, and its child content, SHOULD be stable for the given stream to and from attributes and encryption state, and therefore MAY be cached by clients for later connections.</p>
<p>The Service Name used by XMPP is unchanged from RFC 6120.</p>
<p>Note that SASL2 is impossible for clients to initiate without at least one mechanism being available, and therefore MUST NOT be offered if not at least one mechanism can be provided.</p>
<p>The Service Name used by XMPP is unchanged from &rfc6120;.</p>
<p>All servers and clients supporting channel-binding MUST implement &xep0440;.</p>
<p>Additional stream features that can be negotiated as part of a successful SASL authentication can be included in the &lt;inline/> element which is an immediate child of &lt;authentication/>.</p>
<example caption="Client sending stream header"><![CDATA[
<?xml version='1.0'?>
<stream:stream
from='user@example.org'
to='example.org'
version='1.0'
xml:lang='en'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'>
]]></example>
<example caption="Server responding with stream header and features"><![CDATA[
<?xml version='1.0'?>
<stream:stream
from='example.org'
id='++TR84Sm6A3hnt3Q065SnAbbk3Y='
to='user@example.org'
version='1.0'
xml:lang='en'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'>
<stream:features>
<authentication xmlns='urn:xmpp:sasl:2'>
<mechanism>SCRAM-SHA-1</mechanism>
<mechanism>SCRAM-SHA-1-PLUS</mechanism>
<inline>
<!-- Server indicates that XEP-0198 stream resumption can be done "inline" -->
<resume xmlns='urn:xmpp:sm:3'/>
<!-- Server indicates support for XEP-0386 Bind 2 -->
<bind xmlns='urn:xmpp:bind2:1'/>
</inline>
</authentication>
<!-- Channel-binding information provided by XEP-0440 -->
<sasl-channel-binding xmlns='urn:xmpp:sasl-cb:0'>
<channel-binding type='tls-server-end-point'/>
<channel-binding type='tls-exporter'/>
</sasl-channel-binding>
</stream:features>
]]></example>
</section2>
<section2 topic="SASL Data Encoding">
<p>In all cases, both Clients and Servers encode SASL exchanges using Base 64 encoding. This SHOULD NOT include any line wrapping or other whitespace. As the form &lt;element/> is equivalent to &lt;element>&lt;/element>, these both indicate an empty string. Challenges and responses with no data do not occur in SASL, and so require no special handling. To indicate the absence of an initial response, or the absence of success data, the element is simply not included.</p>
</section2>
<section2 topic="Initiation">
<p>Clients, upon observing this stream feature, initiate the authentication by the use of the &lt;authenticate/> top-level element, within the same namespace. The nature of this element is to inform the server about properties of the final stream state, as well as initiate authentication itself. To achieve the latter, it has a single mandatory attribute of "mechanism", with a string value of a mechanism name offered by the Server in the stream feature, and an optional child element of &lt;initial-response/>, containing a base64-encoded SASL Initial Response.</p>
<p>On subsequent connections, if a Client has previously cache the stream feature, the Client MAY choose to send it before seeing the stream features - sending it "pipelined" with the Stream Open tag for example.</p>
<section2 topic="Initiation" anchor="initiation">
<p>Clients, upon observing this stream feature, initiate the authentication by the use of the &lt;authenticate/> top-level element within the same namespace. The nature of this element is to inform the server about properties of the final stream state, as well as initiate authentication itself. To achieve this, it has a single mandatory attribute of "mechanism", with a string value of a mechanism name offered by the Server in the stream feature and an optional child element of &lt;initial-response/>, containing a base64-encoded SASL Initial Response. If the "mechanism" attribute contains a string not previously announced by the server in in the stream feature, the server MUST fail the authentication.</p>
<p>If the stream's from attribute (if present) does not match the non-empty authorization string, the server MUST fail the authentication as defined in <link url="#failure">Failure</link>.</p>
<p>Clients SHOULD also include a &lt;user-agent/> element, informing the server about the connecting client. The 'id' attribute is RECOMMENDED, and if present contains a unique stable identifier for the client installation. The contents of the 'id' attribute MUST be a UUID v4. This allows the server to provide functionality such as deriving stable resource identifiers (see &xep0386;). The child elements &lt;software/> and &lt;device/> MAY be supplied by clients and contain text descriptions of the client software and the device it is installed on. These allow the server to keep the user informed about what devices are connected to their account. Servers MUST NOT expose this information to other entities (such functionality is available in &xep0092; if required).</p>
<example caption="An authentication request"><![CDATA[
<authenticate xmlns='urn:xmpp:sasl:1' mechanism="BLURDLYBLOOP">
<initial-response>Tm9ib2R5IGV2ZXIgZGVjb2RlcyB0aGUgZXhhbXBsZXMu</initial-response>
<authenticate xmlns='urn:xmpp:sasl:2' mechanism='SCRAM-SHA-1-PLUS'>
<!-- Base64 of: 'p=tls-exporter,,n=user,r=12C4CD5C-E38E-4A98-8F6D-15C38F51CCC6' -->
<initial-response>cD10bHMtZXhwb3J0ZXIsLG49dXNlcixyPTEyQzRDRDVDLUUzOEUtNEE5OC04RjZELTE1QzM4RjUxQ0NDNg==</initial-response>
<user-agent id='d4565fa7-4d72-4749-b3d3-740edbf87770'>
<software>AwesomeXMPP</software>
<device>Kiva's Phone</device>
</user-agent>
</authenticate>
]]></example>
<p>In order to provide support for other desired stream states beyond authentication, additional child elements are used. For example, a hypothetical XEP-0198 session resumption element might be included, and/or Resource Binding requests.</p>
<example caption="An authentication request with a (hypothetical) bind request"><![CDATA[
<authenticate xmlns='urn:xmpp:sasl:1' mechanism='BLURDYBLOOP'>
<authenticate xmlns='urn:xmpp:sasl:2' mechanism='BLURDYBLOOP'>
<initial-response>
SSBzaG91bGQgbWFrZSB0aGlzIGEgY29tcGV0aXRpb24=
</initial-response>
<user-agent id='d4565fa7-4d72-4749-b3d3-740edbf87770'>
<software>AwesomeXMPP</software>
<device>Kiva's Phone</device>
</user-agent>
<bind xmlns='urn:xmpp:bind:example'/>
</authenticate>
]]></example>
</section2>
<section2 topic="Challenges and Responses" anchor="challenge">
<p>Server Challenges MAY then be sent. Each Challenge MUST be responded to by a Client in a Client Response. These are not extensible, and contain the corresponding base64 encoded SASL data:</p>
<example caption="A challenge and response exchange"><![CDATA[
<!-- A server might send: -->
<challenge xmlns='urn:xmpp:sasl:1'>
U28sIG5leHQgRk9TREVNIC0gMjAxOCwgdGhhdCBpcy4uLg==
</challenge>
<!-- A client might respond: -->
<response xmlns='urn:xmpp:sasl:1'>
Li4uSSdsbCBidXkgYSBiZWVyIGZvciB0aGUgZmlyc3QgcGVyc29uIHdoby4uLg==
</response>
]]></example>
</section2>
<section2 topic="During Authentication">
<p>At any time while authentication is in progress, neither Client nor Server sends any element (including stanzas) or other data except the top-level elements defined herein. Clients MUST NOT send whitespace, and MUST send only &lt;response/> elements as appropriate or an &lt;abort/> element to immediately cause an error. Servers MUST disconnect Clients immediately if any other traffic is received. Servers are similarly REQUIRED to send no whitespace, and only the &lt;response/> and completion elements from the section below.</p>
</section2>
<section2 topic="Completing Authentication">
<section2 topic="Challenges and Responses" anchor="challenge">
<p>Server Challenges MAY then be sent. Each Challenge MUST be responded to by a Client in a Client Response. These are not extensible, and contain the corresponding base64 encoded SASL data:</p>
<example caption="A challenge and response exchange (SCRAM-SHA-1-PLUS)"><![CDATA[
<!--
SCRAM-SHA-1-PLUS challenge issued by the server as defined in RFC 5802.
Base64 of: 'r=12C4CD5C-E38E-4A98-8F6D-15C38F51CCC6a09117a6-ac50-4f2f-93f1-93799c2bddf6,s=QSXCR+Q6sek8bf92,i=4096'
-->
<challenge xmlns='urn:xmpp:sasl:2'>
cj0xMkM0Q0Q1Qy1FMzhFLTRBOTgtOEY2RC0xNUMzOEY1MUNDQzZhMDkxMTdhNi1hYzUwLTRmMmYtOTNmMS05Mzc5OWMyYmRkZjYscz1RU1hDUitRNnNlazhiZjkyLGk9NDA5Ng==
</challenge>
<!--
The client responds with the base64 encoded SCRAM-SHA-1-PLUS client-final-message (password: 'pencil').
Base64 of: 'c=cD10bHMtZXhwb3J0ZXIsLMcoQvOdBDePd4OswlmAWV3dg1a1Wh1tYPTBwVid10VU,r=12C4CD5C-E38E-4A98-8F6D-15C38F51CCC6a09117a6-ac50-4f2f-93f1-93799c2bddf6,p=UApo7xo6Pa9J+Vaejfz/dG7BomU='
The c-attribute contains the GS2-header and channel-binding data blob (32 bytes) as defined in RFC 5802.
-->
<response xmlns='urn:xmpp:sasl:2'>
Yz1jRDEwYkhNdFpYaHdiM0owWlhJc0xNY29Rdk9kQkRlUGQ0T3N3bG1BV1YzZGcxYTFXaDF0WVBUQndWaWQxMFZVLHI9MTJDNENENUMtRTM4RS00QTk4LThGNkQtMTVDMzhGNTFDQ0M2YTA5MTE3YTYtYWM1MC00ZjJmLTkzZjEtOTM3OTljMmJkZGY2LHA9VUFwbzd4bzZQYTlKK1ZhZWpmei9kRzdCb21VPQ==
</response>]]></example>
<example caption="A challenge and response exchange (hypothetical)"><![CDATA[
<!-- A server might send: -->
<challenge xmlns='urn:xmpp:sasl:2'>
U28sIG5leHQgRk9TREVNIC0gMjAxOCwgdGhhdCBpcy4uLg==
</challenge>
<!-- A client might respond: -->
<response xmlns='urn:xmpp:sasl:2'>
Li4uSSdsbCBidXkgYSBiZWVyIGZvciB0aGUgZmlyc3QgcGVyc29uIHdoby4uLg==
</response>
]]></example>
</section2>
<section2 topic="Completing Authentication" anchor="outcome">
<p>Authentication may complete in one of three ways. It may complete successfully, in which case the client is authenticated. It may also fail, in which case the client is not authenticated and the stream and session state remain entirely unchanged.</p>
<p>Finally, it may have completed successfully, but further interaction is required - for example, a password change or second-factor authentication.</p>
<section3 topic="Success">
<p>If the Client is now authenticated, the Server sends a &lt;success/> element, which contains contains an &lt;authorization-identity/> element containing the negotiated identity - this is a bare JID, unless resource binding has occurred, in which case it is a full JID.</p>
<p>It MAY contain an &lt;additional-data> element, containing additional data from the exchange (task or SASL mechanism) that has just completed.</p>
<example caption="Successful authentication"><![CDATA[
<success xmlns='urn:xmpp:sasl:1'>
<section3 topic="Success" anchor="success">
<p>If the Client is now authenticated, the Server sends a &lt;success/> element, which contains an &lt;authorization-identity/> element containing the negotiated identity - this is a bare JID, unless resource binding has occurred, in which case it is a full JID.</p>
<p>If the &lt;success/> element it the response to a SASL mechanism exchange, it MAY contain an &lt;additional-data> element, containing additional data from the SASL mechanism that has just completed.</p>
<p>If the &lt;success/> element is the response to a task exchange <link url="#continue">initiated by a &lt;continue/> element</link>, it MAY contain any other element defined in a future protocol containing additional data from the task that has just completed</p>
<p>If the client requested any stream features inline as part of the SASL negotiation, they are processed by the server at this point.</p>
<example caption="Successful authentication with SCRAM-SHA-1-PLUS"><![CDATA[
<success xmlns='urn:xmpp:sasl:2'>
<!-- Base64 of: 'v=msVHs/BzIOHDqXeVH7EmmDu9id8=' -->
<additional-data>
dj1tc1ZIcy9CeklPSERxWGVWSDdFbW1EdTlpZDg9
</additional-data>
<authorization-identifier>user@example.org</authorization-identifier>
</success>
]]></example>
<example caption="Successful authentication with BLURDYBLOOP"><![CDATA[
<success xmlns='urn:xmpp:sasl:2'>
<additional-data>
ip/AeIOfZXKBV+fW2smE0GUB3I//nnrrLCYkt0Vj
</additional-data>
<authorization-identifier>juliet@montague.example/Balcony/a987dsh9a87sdh</authorization-identifier>
</success>
]]></example>
<p>Other extension elements MAY also be contained by the &lt;success/> element.</p>
<example caption="Successful re-authentication and resumption"><![CDATA[
<success xmlns='urn:xmpp:sasl:1'>
<p>The results of activating any requested inline stream features are included in the server's &lt;success/> response.</p>
<example caption="Successful re-authentication and resumption using BLURDYBLOOP"><![CDATA[
<success xmlns='urn:xmpp:sasl:2'>
<additional-data>
SGFkIHlvdSBnb2luZywgdGhlcmUsIGRpZG4ndCBJPw==
</additional-data>
<authorization-identifier>juliet@montague.example/Balcony/a987dsh9a87sdh</authorization-identifier>
<sm:resumed xmlns='urn:xmpp:sm:3:example' h='345' previd='124'/>
<authorization-identifier>juliet@montague.example</authorization-identifier>
<resumed xmlns='urn:xmpp:sm:3' h='345' previd='124'/>
</success>
]]></example>
<p>Any security layer negotiated SHALL take effect after the ">" octet of the closing tag (ie, immediately after "&lt;/success>"), if it has not already taken effect at a &lt;continue> - see <link url='#continue'>Continue</link> below.</p>
<p>The &lt;success> element is immediately followed by a &lt;features> element containing the applicable stream features of the newly authenticated stream. Note that no stream restart occurs.</p>
<p>The &lt;success> element is immediately followed by a &lt;features> element in the "http://etherx.jabber.org/streams" namespace containing the applicable stream features of the newly authenticated stream. Note that no stream restart occurs.</p>
</section3>
<section3 topic="Failure">
<section3 topic="Failure" anchor="failure">
<p>A &lt;failure/> element is used by the server to terminate the authentication attempt. It MAY contain application-specific error codes, and MAY contain a textual error. It MUST contain one of the SASL error codes from RFC 6120 Section 6.5.</p>
<p>The server MUST NOT process any inline features requested by the client in a failed authentication request, if any.</p>
<example caption="Failure"><![CDATA[
<failure xmlns='urn:xmpp:sasl:1'>
<failure xmlns='urn:xmpp:sasl:2'>
<aborted xmlns='urn:ietf:params:xml:ns:xmpp-sasl'/>
<optional-application-specific xmlns='urn:something:else'/>
<text>This is a terrible example.</text>
@ -176,16 +277,16 @@
]]></example>
</section3>
<section3 topic="Continue" anchor="continue">
<p>A &lt;continue/> element is used to indicate that while the SASL exchange was successful, it is insufficient to allow authentication at this time.</p>
<p>This can be used to indicate that the Client needs to perform a Second Factor Authentication ("2FA"), or is required to change password.</p>
<p>A &lt;continue/> element is used to indicate that while the SASL exchange was successful, it is insufficient to allow authentication at this time. This can be used to indicate, for example, that the Client needs to perform a Second Factor Authentication ("2FA"), or is required to change password (this list is not meant to be exhaustive in any way).</p>
<p>Such tasks are presented within a &lt;tasks> element, which contains a sequence of &lt;task> elements, each containing a name. These tasks are analogous to a SASL mechanism, but have a number of differences - they may never attempt to negotiate a new authorization identifier, nor a new security layer.</p>
<p>Like the &lt;success/> element, the &lt;continue/> element MAY contain an &lt;additional-data/> element containing additional data from the SASL mechanism that has completed.</p>
<p>A client MAY choose any one of the offered tasks; if multiple are required a sequence of &lt;continue> exchanges will occur until all mandatory tasks are complete.</p>
<p>The &lt;continue element therefore always contains a &lt;tasks/> element, as defined above. It MAY contain an &lt;additional-data/> element, as the &lt;success/> element does.</p>
<p>Finally, it MAY contain a &lt;text/> element, which can contain human-readable data explaining the nature of the step required.</p>
<example caption="Continue Required"><![CDATA[
<continue xmlns='urn:xmpp:sasl:1'>
<continue xmlns='urn:xmpp:sasl:2'>
<additional-data>
SSdtIGJvcmVkIG5vdy4=
SSdtIGJvcmVkIG5vdy4=
</additional-data>
<tasks>
<task>HOTP-EXAMPLE</task>
@ -195,71 +296,113 @@
</continue>
]]></example>
<p>After the final octet of the first &lt;continue> element, any SASL security layer negotiated in the preceding exchange SHALL be immediately in effect.</p>
<p>Clients respond with a &lt;next/> element, which has a single mandatory attribute of "task", containing the selected task name, and contains an OPTIONAL base64 encoded initial response contained in an &lt;initial-response> element.</p>
<example caption="Client Continues"><![CDATA[
<next xmlns='urn:xmpp:sasl:1' task='TOTP-EXAMPLE'>
<initial-response>
<p>Clients respond with a &lt;next/> element, which has a single mandatory attribute of "task", containing the selected task name, and MAY contain any other element as defined in a future protocol defining this task.</p>
<p>The concrete elements exchanged for each task after the &lt;next/> reside inside a &lt;task-data/> wrapper element in the namespace "urn:xmpp:sasl:2". Each wrapper element can contain any other element as defined in a future protocol defining this concrete task. Each task MUST end either by the server sending a &lt;failure/> element, if the task failed, a &lt;continue/> element, if the task was completed successfully and the server requests the client to perform a new task, or a &lt;success/> element, indicating that the task was completed successfully and no further tasks are needed.</p>
<example caption="Fictional TOTP task"><![CDATA[
<!-- Client starts TOTP-EXAMPLE task -->
<next xmlns='urn:xmpp:sasl:2' task='TOTP-EXAMPLE'>
<totp xmlns="urn:totp:example">
SSd2ZSBydW4gb3V0IG9mIGlkZWFzIGhlcmUu
</initial-response>
</next-authenticate>
]]></example>
</totp>
</next>
<!-- Server provides needed data to Client -->
<task-data xmlns='urn:xmpp:sasl:2'>
<totp xmlns="urn:totp:example">
94d27acffa2e99a42ba7786162a9e73e7ab17b9d
</totp>
</task-data>
<!-- Client responds with requested TOP data -->
<task-data xmlns='urn:xmpp:sasl:2'>
<totp xmlns="urn:totp:example">
OTRkMjdhY2ZmYTJlOTlhNDJiYTc3ODYxNjJhOWU3M2U3YWIxN2I5ZAo=
</totp>
</task-data>
<!-- Server indicates successful completion of TOTP-EXAMPLE task -->
<success xmlns='urn:xmpp:sasl:2'>
<totp xmlns="urn:totp:example">
SGFkIHlvdSBnb2luZywgdGhlcmUsIGRpZG4ndCBJPw==
</totp>
<authorization-identifier>juliet@montague.example</authorization-identifier>
</success>]]></example>
</section3>
</section2>
</section1>
<section1 topic="SASL Profile Definition">
<p>This provides pointers and/or clarifications to the <link url="#overview">Overview</link> in the order and manner defined in RFC 4422, section 4.</p>
<section2 topic="Service Name">
<p>The service name SHALL be "xmpp", as defined by RFC 6120.</p>
</section2>
<section2 topic="Mechanism negotiation">
<p>Servers list mechanisms during stream features (See <link url="#features">Discovering Support</link>).</p>
</section2>
<section2 topic="Message Definitions">
<section3 topic="Initiation">
<p>Clients initiate using the &lt;authenticate/> top level element (See <link url="#auth">Initiation</link>.</p>
</section3>
<section3 topic="Server Challenges and Client Responses">
<p>See <link url="#challenge">Challenges and Responses</link>.</p>
</section3>
<section3 topic="Outcome">
<p>See <link url="#outcome">Completing Authentication</link>.</p>
</section3>
</section2>
<section2 topic="Non-Empty Authorization Strings">
<p>If a Client specifies an authorization string which is non-empty, the identifier is normalized by treating it as a JID, and performing normalization as described in RFC 7622.</p>
<p>In general, implementors are advised that a non-empty authorization string MAY be considered an error if the stream's from attribute (if present) does not match.</p>
</section2>
<section2 topic="Aborting">
<p>Clients MAY abort unilaterally by sending &lt;abort/> as specified in <link url="#abort">Client Aborts</link>.</p>
<p>Servers MAY abort unliterally by sending &lt;failure/> with the &lt;aborted/> error code as defined in <link url="#failure">Failure</link>.</p>
</section2>
<section2 topic="Security Layer Effect">
<p>Security Layers take effect after the SASL mechanism itself (ie, the first negotiation) has completed successfully, after the final octet of the server's &lt;success> or &lt;continue>. See <link url="#success">Success</link> and <link url="#continue">Continue</link>.</p>
</section2>
<section2 topic="Security Layer Order">
<p>Option (a) is used - any SASL Security Layer is applied first to data being sent, and TLS applied last.</p>
</section2>
<section2 topic="Multiple Authentication">
<p>Although the &lt;continue/> concept does use tasks analogous to multiple SASL sequences, only the first SASL mechanism used is considered an authentication, and only the first can negotiate a security layer.</p>
<p>In particular, once &lt;success/> has been sent by the server, any further &lt;authenticate/> element MUST result in a stream error.</p>
</section2>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>Relative to the SASL profile documented in RFC 6120, this introduces more data unprotected by any security layer negotiated by SASL itself. While no actual exchanges are introduced that are unprotected, the nature of this exchange might allow for (for example) a resource binding extension to be introduced. SASL security layers are sparingly used in the field, however, so this is thought to be a theoretical, rather than practical, concern. TLS, if negotiated before authentication, could mitigate these risks further.</p>
<p>As explained in § 13.8.3 of &rfc6120;, servers and clients SHOULD NOT support SASL PLAIN. Usage of PLAIN allows for trivial downgrade atacks by Man-In-The-Middle attackers circumventing any possible channel-binding or mutual authentication and even allowing the attacker to gain access to the cleartext password. If possible, PLAIN should be disabled by default on servers and clients and only be enabled when configured by the admin respective client user (if at all).</p>
<p>This protocol makes use of the hint of its identity contained in the stream "from" attribute as defined in &rfc6120; prior to authentication. This value MUST NOT be trusted to contain the real identity of the connecting client. Varying pre-authentication responses (such as supported SASL mechanisms) based on this value may allow unauthorized parties to discover whether an account exists, and even guess at what software might be used with that account (e.g. by observing which SASL mechanisms can be used on this account). Minimizing differences between the default response for unregistered JIDs and registered JIDs, as well as rate-limiting (to prevent enumeration attempts), are possible countermeasures. If the server does not know the client-identity it is RECOMMENDED to randomize the list of provided SASL mechanisms to reduce these risks even further.</p>
<p>SASL2 MUST only be used by Clients or offered by Servers after TLS negotiation, see § 5.2 and § 5.3.4 of &rfc6120;.</p>
<p>Clients MUST NOT send, and servers MUST NOT process, authentication requests included in the TLS 0-RTT ("early data") extension. Such data is vulnerable to replay attacks, and without adequate protection this could allow an attacker to disrupt established sessions or cause other side-effects depending on the inline features negotiated. This rule may be overridden by later specifications, provided they define appropriate protocols to mitigate these issues. Examples of these attacks and mitigations are discussed in Section 8 of &rfc8446;.</p>
</section1>
<section1 topic="SASL Profile Definition">
<p>This provides pointers and/or clarifications to the <link url="#overview">Overview</link> in the order and manner defined in RFC 4422, section 4.</p>
<section2 topic="Service Name">
<p>The service name SHALL be "xmpp", as defined by RFC 6120.</p>
</section2>
<section2 topic="Mechanism negotiation">
<p>Servers list mechanisms in the &lt;mechanisms/> list in response to a &lt;request/> by the client. (See <link url="#initiation">Initiation</link>).</p>
</section2>
<section2 topic="Message Definitions">
<section3 topic="Initiation">
<p>Clients initiate using the &lt;authenticate/> top level element (See <link url="#initiation">Initiation</link>.</p>
</section3>
<section3 topic="Server Challenges and Client Responses">
<p>See <link url="#challenge">Challenges and Responses</link>.</p>
</section3>
<section3 topic="Outcome">
<p>See <link url="#outcome">Completing Authentication</link>.</p>
</section3>
</section2>
<section2 topic="Non-Empty Authorization Strings">
<p>If a Client specifies an authorization string which is non-empty, the identifier is normalized by treating it as a JID, and performing normalization as described in RFC 7622.</p>
<p>Any non-empty authorization string MUST be considered an error if the stream's from attribute (if present) does not match.</p>
</section2>
<section2 topic="Aborting">
<p>Clients MAY abort unilaterally at any time before the authentication completed by sending an &lt;abort/> element. This element MAY contain a &lt;text/> element containing a textual representation of the reason as well as any other element defined in some future protocol.</p>
<p>Servers MAY abort unliterally by sending &lt;failure/> with the &lt;aborted/> error code as defined in <link url="#failure">Failure</link>.</p>
</section2>
<section2 topic="Security Layer Effect">
<p>Security Layers take effect after the SASL mechanism itself (ie, the first negotiation) has completed successfully, after the final octet of the server's &lt;success> or &lt;continue>. See <link url="#success">Success</link> and <link url="#continue">Continue</link>.</p>
</section2>
<section2 topic="Security Layer Order">
<p>Option (a) is used - any SASL Security Layer is applied first to data being sent, and TLS applied last.</p>
</section2>
<section2 topic="Multiple Authentication">
<p>Although the &lt;continue/> concept does use tasks analogous to multiple SASL sequences, only the first SASL mechanism used is considered an authentication, and only the first can negotiate a security layer.</p>
<p>In particular, once &lt;success/> or &lt;continue/> has been sent by the server, any further &lt;authenticate/> element MUST result in a stream error.</p>
</section2>
</section1>
<section1 topic="Example Flows">
<p>This section provides some example flows. It aims to demonstrate the structure of SASL2 negotiation, but it does not definitively describe any of the additional extensions shown here.</p>
<section2 topic="Syntactic Equivalence">
<p>Where no additional features that SASL2 makes available are used, the flow of information is identical to the original SASL profile. This example shows the new syntax and draws the reader's attention to the differences.</p>
<example caption="PLAIN Authentication"><![CDATA[
<!--
Client sends stream header
-->
<stream:stream
from='alice@example.org'
to='example.org'
version='1.0'
xml:lang='en'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'>
<section1 topic="Example Flows">
<p>This section provides a fictional example. It is important to note that many of the extensions used wihtin this section do not, in fact, exist and therefore are to be avoided.</p>
<section2 topic="Syntactic Equivalence">
<p>Where no additional features that SASL2 makes available are used, the flow of information is identical to the original SASL profile. This example shows the new syntax and draws the reader's attention to the differences.</p>
<example caption="PLAIN Authentication"><![CDATA[
<!--
Server sends stream features.
These are identical to SASL1, but within a different namespace.
-->
<stream:features>
<mechanisms xmlns='urn:xmpp:sasl:1'>
<authentication xmlns='urn:xmpp:sasl:2'>
<mechanism>PLAIN</mechanism>
<mechanism>SCRAM-SHA-1</mechanism>
</mechanisms>
</authentication>
</stream:features>
<!--
@ -268,17 +411,22 @@
the main distinction is that initial-response data is held within an element,
so the "=" special case no longer applies.
-->
<authenticate xmlns='urn:xmpp:sasl:1' mechanism='PLAIN'>
<authenticate xmlns='urn:xmpp:sasl:2' mechanism='PLAIN'>
<initial-response>AGFsaWNlQGV4YW1wbGUub3JnCjM0NQ==</initial-response>
<user-agent id='d4565fa7-4d72-4749-b3d3-740edbf87770'>
<software>AwesomeXMPP</software>
<device>Kiva's Phone</device>
</user-agent>
</authenticate>
<!--
This completes in one step, so the Server sends a success.
A SASL2 success always includes the authorization identifier:
-->
<success xmlns='urn:xmpp:sasl:1'>
<success xmlns='urn:xmpp:sasl:2'>
<authorization-identifier>alice@example.org</authorization-identifier>
</success>
<!--
The server immediately sends a new set of stream features at this point.
There is no stream restart.
@ -293,16 +441,27 @@
The client now continues with resource binding.
-->
]]></example>
<p>Use of SASL2 in this simple scenario saves one round-trip (due to the lack of stream restart).</p>
</section2>
<section2 topic="Once More, This Time With CRAM">
<p>Again, this is an equivalent flow to a common SASL1 flow, although using the CRAM-MD5 mechanism which is (thankfully) rarely used in practise.</p>
<example caption="CRAM-MD5 Authentication"><![CDATA[
<p>Use of SASL2 in this simple scenario saves one round-trip (due to the lack of stream restart).</p>
</section2>
<section2 topic="Once More, This Time With CRAM">
<p>In this example, multiple potential round-trips are saved by negotiating resource binding and stream management inline.</p>
<example caption="CRAM-MD5 Authentication"><![CDATA[
<!--
Client sends stream header
-->
<stream:stream
from='tim@example.org'
to='example.org'
version='1.0'
xml:lang='en'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'>
<!--
Server sends stream features.
-->
<stream:features>
<mechanisms xmlns='urn:xmpp:sasl:1'>
<mechanisms xmlns='urn:xmpp:sasl:2'>
<mechanism>PLAIN</mechanism>
<mechanism>CRAM-MD5</mechanism>
</mechanisms>
@ -312,28 +471,34 @@
Client intiates authentication.
Here, no initial response is needed, so none is sent.
-->
<authenticate xmlns='urn:xmpp:sasl:1' mechanism='CRAM-MD5'/>
<authenticate xmlns='urn:xmpp:sasl:2' mechanism='CRAM-MD5'>
<user-agent id='d4565fa7-4d72-4749-b3d3-740edbf87770'>
<software>AwesomeXMPP</software>
<device>Kiva's Phone</device>
</user-agent>
</authenticate>
<!--
CRAM-MD5 starts with a server challenge:
-->
<challenge xmlns='urn:xmpp:sasl:1'>
<challenge xmlns='urn:xmpp:sasl:2'>
PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1jaS5uZXQ+
</challenge>
<!--
And the client responds:
-->
<response xmlns='urn:xmpp:sasl:1>
<response xmlns='urn:xmpp:sasl:2>
dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw
</response>
<!--
This completes, so the Server sends a success.
-->
<success xmlns='urn:xmpp:sasl:1'>
<success xmlns='urn:xmpp:sasl:2'>
<authorization-identifier>tim@example.org</authorization-identifier>
</success>
<!--
The server immediately sends a new set of stream features at this point.
There is no stream restart.
@ -348,29 +513,45 @@
The client now continues with resource binding.
-->
]]></example>
<p>Use of SASL2 in this simple scenario again simply saves one round-trip.</p>
</section2>
<section2 topic="Advanced Usage">
<p>This moves into the deeply hypothetical. A binding extension is posited, alongside an unrealistic 2FA mechanism which somehow mutually authenticates because why not.</p>
<example caption="CRAM-MD5 Authentication"><![CDATA[
</section2>
<section2 topic="Advanced Usage">
<p>This moves into the deeply hypothetical. A binding extension is posited, alongside an unrealistic 2FA mechanism which somehow mutually authenticates because why not.</p>
<example caption="BLURDYBLOOP and UNREALISTIC-2FA"><![CDATA[
<!--
Client sends stream header
-->
<stream:stream
from='alice@example.org'
to='example.org'
version='1.0'
xml:lang='en'
xmlns='jabber:client'
xmlns:stream='http://etherx.jabber.org/streams'>
<!--
Server sends stream features.
Note that whilst megabind is advertised, the unrealistic 2FA mechanism is not.
-->
<stream:features>
<mechanisms xmlns='urn:xmpp:sasl:1'>
<authentication xmlns='urn:xmpp:sasl:2'>
<mechanism>BLURDYBLOOP</mechanism>
</mechanisms>
<megabind xmlns='urn:example:megabind'/>
<inline>
<megabind xmlns='urn:example:megabind'/>
</inline>
</authentication>
</stream:features>
<!--
Client intiates authentication.
-->
<authenticate xmlns='urn:xmpp:sasl:1' mechanism='BLURDYBLOOP'>
<authenticate xmlns='urn:xmpp:sasl:2' mechanism='BLURDYBLOOP'>
<initial-response>
SW5pdGlhbCBSZXNwb25zZQ==
</initial-response>
<user-agent id='d4565fa7-4d72-4749-b3d3-740edbf87770'>
<software>AwesomeXMPP</software>
<device>Kiva's Phone</device>
</user-agent>
<megabind xmlns='urn:example:megabind'>
<resource>this-one-please</resource>
</megabind>
@ -379,26 +560,26 @@
<!--
Maybe BLURDYBLOOP does this:
-->
<challenge xmlns='urn:xmpp:sasl:1'>
<challenge xmlns='urn:xmpp:sasl:2'>
PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1jaS5uZXQ+
</challenge>
<!--
And the client responds:
-->
<response xmlns='urn:xmpp:sasl:1>
<response xmlns='urn:xmpp:sasl:2>
dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw
</response>
<!--
This completes, so the Server sends a continue, with the
success data (probably mutual auth) from BLURDYBLOOP.
The next task required is the unrealistic 2FA.
The next task required is the unrealistic-2FA.
Note that the session is - probably - bound at this point, but
the authorization-identifier is not passed to the client until
the full authentication sequence is completed.
-->
<continue xmlns='urn:xmpp:sasl:1'>
<continue xmlns='urn:xmpp:sasl:2'>
<additional-data>
QWRkaXRpb25hbCBEYXRh
</additional-data>
@ -408,60 +589,49 @@
</continue>
<!--
The client supports the unrealistic 2FA, so can move onto the next task:
The client supports the unrealistic-2FA, so can move onto the next task:
-->
<next xmlns='urn:xmpp:sasl:1' task='UNREALISTIC-2FA'>
<initial-response>
<next xmlns='urn:xmpp:sasl:2' task='UNREALISTIC-2FA'>
<parameters xmlns='urn:example:unrealistic2fa'>
VW5yZWFsaXN0aWMgMkZBIElS
</initial-response>
<!--
In principle, another option could be negotiated here, but this seems
unlikely to be useful in practise.
-->
</parameters>
</next>
<!--
This 2FA process is both unrealistic and also uses multiple round-trips.
-->
<challenge xmlns='urn:xmpp:sasl:1'>
PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1jaS5uZXQ+
</challenge>
<task-data xmlns='urn:xmpp:sasl:2'>
<question xmlns='urn:example:unrealistic2fa'>
PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1jaS5uZXQ+
</question>
</task>
<!--
The client responds here.
-->
<response xmlns='urn:xmpp:sasl:1>
dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw
</response>
<task-data xmlns='urn:xmpp:sasl:2'>
<response xmlns='urn:example:unrealistic2fa'>
dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw
</respons>
</task>
<!--
Finally, the server sends a success.
Here, we have an authzid which is a full jid, since the session is now bound.
The additional-data element here contains the mutual authentication data for the
The result element here contains the mutual authentication data for the
unrealistic 2FA, and doesn't refer back to the BLURDYBLOOP exchange.
-->
<success xmlns='urn:xmpp:sasl:1'>
<additional-data>
<success xmlns='urn:xmpp:sasl:2'>
<result xmlns='urn:example:unrealistic2fa'>
VW5yZWFsaXN0aWMgMkZBIG11dHVhbCBhdXRoIGRhdGE=
</additional-data>
</result>
<authorization-identifier>
alice@example.org/this-one-please
</authorization-identifier>
</success>
<!--
The Server also sends an (empty) features element.
The client can simply continue and send stanzas.
-->
<stream:features/>
]]></example>
<p>Although the unrealistic 2FA here uses 2 round-trips (real ones will probably use one), the embedding of resource binding as shown here means that a second RTT is saved by SASL2, and there's no net change. A more realistic example would see RTTs saved, and additional negotiations could be added to further reduce RTTs.</p>
</section2>
</section1>
<section1 topic='Security Considerations' anchor='security'>
<p>Relative to the SASL profile documented in RFC 6120, this introduces more data unprotected by any security layer negotiated by SASL itself.</p>
<p>While no actual exchanges are introduced that are unprotected, the nature of this exchange might allow for (for example) a resource binding extension to be introduced.</p>
<p>SASL security layers are sparingly used in the field, however, so this is thought to be a theoretical, rather than practical, concern.</p>
<p>Although the unrealistic 2FA here uses 2 round-trips (real ones will probably use one), the embedding of resource binding as shown here means that a second RTT is saved by SASL2, and there's no net change. A more realistic example would see RTTs saved, and additional negotiations could be added to further reduce RTTs.</p>
</section2>
</section1>
<section1 topic='IANA Considerations' anchor='iana'>
@ -476,14 +646,29 @@
<code><![CDATA[
<?xml version='1.0' encoding='utf-8'?>
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema'
targetNamespace="urn:xmpp:sasl:1"
xmlns="urn:xmpp:sasl:1"
targetNamespace="urn:xmpp:sasl:2"
xmlns="urn:xmpp:sasl:2"
elementFormDefault="qualified">
<xs:element name="mechanisms">
<xs:element name="authentication">
<xs:complexType>
<xs:sequence>
<xs:element name="mechanism" type="SaslMechName" minOccurs="1" maxOccurs="unbounded"/>
<xs:element name="inline" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:sequence>
<xs:any/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="abort">
<xs:complexType>
<xs:sequence>
<xs:element name="text" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:any/>
</xs:sequence>
</xs:complexType>
@ -493,17 +678,7 @@
<xs:complexType>
<xs:attribute name="mechanism" type="SaslMechName"/>
<xs:sequence>
<xs:element name="initial-response"/>
<xs:any/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="next">
<xs:complexType>
<xs:attribute name="task" type="SaslMechName"/>
<xs:sequence>
<xs:element name="initial-response"/>
<xs:element name="initial-response" type="SaslData" minOccurs="0" maxOccurs="1"/>
<xs:any/>
</xs:sequence>
</xs:complexType>
@ -513,13 +688,12 @@
<xs:element name="response" type="SaslData"/>
<xs:element name="initial-response" type="SaslData"/>
<xs:element name="success">
<xs:complexType>
<xs:sequence>
<xs:element name="additional-data" type="SaslData"/>
<xs:element name="authorization-identifier" type="Jid"/>
<xs:element name="additional-data" type="SaslData" minOccurs="0" maxOccurs="1"/>
<xs:element name="authorization-identifier" type="Jid" minOccurs="1" maxOccurs="1"/>
<xs:any/>
</xs:sequence>
</xs:complexType>
</xs:element>
@ -539,6 +713,15 @@
</xs:complexType>
</xs:element>
<xs:element name="next">
<xs:complexType>
<xs:attribute name="task" type="SaslMechName"/>
<xs:sequence>
<xs:any/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:simpleType name="Jid">
<xs:restriction base="xs:string">
<xs:maxLength value="3071"/>
@ -560,7 +743,7 @@
</section1>
<section1 topic='Acknowledgements' anchor='ack'>
<p>The author wishes to share any credit with many members of the community, including Lance Stout, Ralph Meijer, Phil Roberts and Florian Schmaus.</p>
<p>The authors wish to share any credit with many members of the community, including Lance Stout, Ralph Meijer, Phil Roberts and Florian Schmaus.</p>
</section1>
</xep>