RFC 4643

Network News Transfer Protocol (NNTP) Extension for Authentication

๐Ÿ“… published October 2006, from ietf

RFC 4643: Network News Transfer Protocol (NNTP) Extension for Authentication ๐ŸŽ€

Okay bestie, this is RFC 4643, and it's giving NNTP glow-up ๐Ÿ’–. It's a Standards Track doc from the Network Working Group, dated October 2006. The authors are J. Vinocur (Cornell University) and K. Murchison (Carnegie Mellon University). It updates RFC 2980, which is the only thing it updates. It's an Internet standards track protocol, so it's official ๐Ÿ’….


Status of This Memo

This one is an Internet standards track protocol for the whole Internet community, and they're literally asking for discussion and suggestions for improvements ๐Ÿ™. For the current standardization state and status, check the current edition of the "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited ๐ŸŒˆ.

Copyright (C) The Internet Society (2006) ๐Ÿ“œ.

Abstract

So this doc adds an extension to NNTP that lets a client tell the server which authentication mechanism it wants ๐Ÿ”‘. Then the client can run an authentication protocol exchange with the server, and it can optionally negotiate a security layer for the rest of the NNTP session ๐Ÿ”.

It also updates and formalizes the AUTHINFO USER/PASS method from RFC 2980 ๐Ÿ’–. Meanwhile, AUTHINFO SIMPLE and AUTHINFO GENERIC get deprecated ๐Ÿ’€. And the doc defines a profile of the Simple Authentication and Security Layer (SASL) for NNTP โœจ.

Table of Contents

   1. Introduction .............................................  3
      1.1. Conventions Used in This Document ...................  3
   2. The AUTHINFO Extension ...................................  4
      2.1. Advertising the AUTHINFO Extension ..................  4
      2.2. Authenticating with the AUTHINFO Extension ..........  5
      2.3. AUTHINFO USER/PASS Command ..........................  6
           2.3.1. Usage ........................................  7
           2.3.2. Description ..................................  7
           2.3.3. Examples .....................................  9
      2.4. AUTHINFO SASL Command ...............................  9
           2.4.1. Usage ........................................ 10
           2.4.2. Description .................................. 11
           2.4.3. Examples ..................................... 14
   3. Augmented BNF Syntax for the AUTHINFO Extension .......... 16
      3.1. Commands ............................................ 16
      3.2. Command Continuation ................................ 17
      3.3. Responses ........................................... 17
      3.4. Capability Entries .................................. 17
      3.5. General Non-terminals ............................... 18
   4. Summary of Response Codes ................................ 18
   5. Authentication Tracking/Logging .......................... 18
   6. Security Considerations .................................. 19
   7. IANA Considerations ...................................... 20
      7.1. IANA Considerations for SASL/GSSAPI Services ........ 20
      7.2. IANA Considerations for NNTP Extensions ............. 20
   8. Acknowledgements ......................................... 21
   9. References ............................................... 22
      9.1. Normative References ................................ 22
      9.2. Informative References .............................. 22

1. Introduction โœจ

NNTP [NNTP] has traditionally been all about public access to newsgroups ๐Ÿ“ฐ, but authentication is honestly useful for a bunch of reasons ๐Ÿงš. For example, it helps control resource consumption, lets you identify people who abuse the POST command, and restricts access to "local" newsgroups ๐Ÿ”’.

The ad-hoc AUTHINFO USER and AUTHINFO PASS commands, documented in [NNTP-COMMON], are a very weak authentication mechanism, but the installed base uses them everywhere ๐Ÿ˜ญ. Because they're so ubiquitous, this spec formalizes them. But because they're so insecure, they're only meant to be used together with appropriate security layers ๐Ÿซถ.

The ad hoc AUTHINFO GENERIC command is also documented in [NNTP-COMMON], though it's way less common ๐ŸŒธ. It was NNTP's own version of the generic SASL [SASL] facility. This document deprecates AUTHINFO GENERIC in favor of an AUTHINFO SASL replacement. That way NNTP can use authentication mechanisms built for other SASL-enabled application protocols, like Simple Mail Transfer Protocol (SMTP) [SMTP-AUTH], Post Office Protocol (POP) [POP-AUTH], Internet Message Access Protocol (IMAP) [IMAP], Lightweight Directory Access Protocol (LDAP) [LDAP-AUTH], and Blocks Extensive Exchange Protocol (BEEP) [BEEP] ๐Ÿฆ‹.

This spec is meant to be read alongside the NNTP base specification [NNTP] ๐Ÿ“–. Unless it says otherwise, if these two documents ever conflict, [NNTP] takes precedence over this one ๐Ÿ‘‘. It's also recommended that you read this alongside the SASL base specification [SASL] ๐Ÿ’œ.

1.1. Conventions Used in This Document

The notational conventions here are the same as the ones in [NNTP], and any term this document doesn't define has the same meaning it has there ๐Ÿ“.

The key words "REQUIRED", "MUST", "MUST NOT", "SHOULD", "SHOULD NOT", "MAY", and "OPTIONAL" in this document are to be interpreted as described in "Key words for use in RFCs to Indicate Requirement Levels" [KEYWORDS]. These are the official words that set how strict each rule is, so pay attention to them ๐Ÿ”ฅ.

Terms related to authentication are defined in "On Internet Authentication" [AUTH] ๐Ÿ”‘.

In the examples, commands from the client are marked with [C], and responses from the server are marked with [S] ๐Ÿ’….

2. The AUTHINFO Extension

The AUTHINFO extension is how you authenticate a user ๐ŸŽ€. Here's the tea: authorization is a matter of site policy, not network protocol, so this document doesn't cover it ๐Ÿ™ˆ. The server works out authorization however its implementation is configured by the site administrator.

This extension gives you three new commands: AUTHINFO USER, AUTHINFO PASS, and AUTHINFO SASL. The capability label for this extension is AUTHINFO โœจ.

2.1. Advertising the AUTHINFO Extension

Okay, so this part is about how the server announces what it can do ๐Ÿ“ฃ. A server MUST implement at least one of the AUTHINFO USER or AUTHINFO SASL commands in order to advertise the "AUTHINFO" capability label in response to the CAPABILITIES command ([NNTP] Section 5.2). But the vibe check is this: this capability MUST NOT be advertised after successful authentication (see Section 2.2). It MAY be advertised both before and after any use of the MODE READER command ([NNTP] Section 5.3), and the semantics stay the same either way ๐Ÿฆ‹.

The AUTHINFO capability label carries an argument list that spells out which authentication commands are available ๐Ÿ“‹.

The "USER" argument says AUTHINFO USER/PASS is supported, as defined in Section 2.3 of this document. The "USER" argument MUST NOT be advertised, and the AUTHINFO USER/PASS commands SHOULD NOT be provided, unless a strong encryption layer (e.g., Transport Layer Security (TLS) [NNTP-TLS]) is in use or backward compatibility dictates otherwise ๐Ÿ”. Honestly, that's a big ick if it's sent in the clear ๐Ÿ’€.

The "SASL" argument says AUTHINFO SASL is supported, as defined in Section 2.4 of this document. If the server advertises the "SASL" argument, then it MUST also advertise the "SASL" capability in response to the CAPABILITIES command. The SASL capability is followed by a whitespace-separated list of the available SASL mechanism names ๐ŸŒˆ.

The server MAY list the AUTHINFO capability with no arguments. That means it follows this spec but doesn't allow any authentication commands in its current state ๐Ÿ™…โ€โ™€๏ธ. In that case, the client MUST NOT attempt to use any AUTHINFO commands, even if its logic would normally make it try (for example, for backward compatibility with servers that don't follow this spec) ๐Ÿšซ.

Future extensions may add more arguments to this capability โœจ. Unrecognized arguments MUST be ignored by the client, no exceptions ๐Ÿซถ.

Since AUTHINFO is security-related, cached CAPABILITIES results from a previous session MUST NOT be relied on, as per Section 12.6 of [NNTP] ๐Ÿ”’. However, a client MAY use those cached results to detect active down-negotiation attacks ๐Ÿ‘€.

Here's an example of the AUTHINFO capabilities before and after using the STARTTLS [NNTP-TLS] extension ๐Ÿ’–:

   [C] CAPABILITIES
   [S] 101 Capability list:
   [S] VERSION 2
   [S] READER
   [S] IHAVE
   [S] STARTTLS
   [S] AUTHINFO SASL
   [S] SASL CRAM-MD5 DIGEST-MD5 GSSAPI
   [S] LIST ACTIVE NEWSGROUPS
   [S] .
   [C] STARTTLS
   [S] 382 Continue with TLS negotiation
   [TLS negotiation proceeds, further commands protected by TLS]
   [C] CAPABILITIES
   [S] 101 Capability list:
   [S] VERSION 2
   [S] READER
   [S] IHAVE
   [S] AUTHINFO USER SASL
   [S] SASL CRAM-MD5 DIGEST-MD5 GSSAPI PLAIN EXTERNAL
   [S] LIST ACTIVE NEWSGROUPS
   [S] .

Part 2 is coming up next, bestie ๐Ÿ‘€๐ŸŒธ

2.2. Authenticating with the AUTHINFO Extension ๐Ÿ”

okay bestie, so here's the deal with when a server says "nope, log in first." ๐Ÿ’… An NNTP server answers a command with a 480 response to say the client MUST authenticate and/or authorize before it can use that command or get at that resource. AUTHINFO is one of the ways a client can do that authenticating/authorizing thing โœจ. So a client MAY send an AUTHINFO command after it gets a 480 response. And if you're planning to use AUTHINFO, you SHOULD send CAPABILITIES first so you can see which auth commands and mechanisms the server actually offers before you try logging in ๐Ÿงš

If a server advertises the AUTHINFO capability, a client MAY start the first step of authentication at any point in a session to unlock extra privileges, even without a 480 response first ๐Ÿฆ‹ Servers SHOULD accept those unsolicited auth requests too. But here's the big no-no ๐Ÿ™ˆ: a server MUST NOT, under any circumstances, reply to an AUTHINFO command with a 480 response.

Okay, this next bit is super important ๐Ÿ˜ญ A client MUST NOT, under any circumstances, keep going with any step of authentication past the first one, unless the server's response code says the auth exchange is welcome. Basically, anything other than a 38x response code means the client MUST NOT continue the exchange. Stop right there, babe ๐Ÿ›‘

Once authentication has worked, the client MUST NOT send another AUTHINFO command in that same session ๐Ÿ’œ A server MUST NOT return the AUTHINFO capability in response to a CAPABILITIES command, and a server MUST reject any later AUTHINFO commands with a 502 response. On top of that, the client MUST NOT issue a MODE READER command after authenticating, and a server MUST NOT advertise the MODE-READER capability. It's giving very strict, and I love it ๐ŸŽ€

Here's a fun one ๐ŸŒˆ In agreement with [SASL], the server MUST keep advertising the SASL capability in response to a CAPABILITIES command, with the same list of SASL mechanisms it showed before authentication. Why? So the client can notice if somebody tried to sneak in a downgrade attack ๐Ÿ‘€ (an active down-negotiation attack, if we're being formal). Other capabilities that show up after authentication MAY look different from the ones before. For example, an NNTP server may not want to advertise support for a certain extension unless the client has been authenticated, and that's totally fine ๐ŸŒธ

Also, a server can finish a successful authentication and still say no to some or all resources. That's where the permanent 502 response comes in: it means the resource is unavailable even though auth already happened ๐Ÿ’€ This is different from the temporary 480 error, which means a resource is unavailable right now but might open up after authentication. Two different vibes, both valid โœจ


2.3. AUTHINFO USER/PASS Command ๐ŸŽ€

This section replaces the definition of the AUTHINFO USER and AUTHINFO PASS commands that was documented in Section 3.1.1 of [NNTP-COMMON]. Updated tea, bestie ๐Ÿ“

2.3.1. Usage ๐Ÿ’…

These commands MUST NOT be pipelined.

Syntax:

AUTHINFO USER username
AUTHINFO PASS password

Responses:

  281 Authentication accepted
  381 Password required [1]
  481 Authentication failed/rejected
  482 Authentication commands issued out of sequence
  502 Command unavailable [2]

  [1] Only valid for AUTHINFO USER.  Note that unlike traditional 3xx
      codes, which indicate that the client may continue the current
      command, the legacy 381 code means that the AUTHINFO PASS
      command must be used to complete the authentication exchange.

  [2] If authentication has already occurred, AUTHINFO USER/PASS are
      not valid commands (see Section 2.2).

      NOTE: Notwithstanding Section 3.2.1 of [NNTP], the server MUST
      NOT return 480 in response to AUTHINFO USER/PASS.

Parameters:

  username = string identifying the user/client
  password = string representing the user's password

2.3.2. Description ๐Ÿง 

The AUTHINFO USER and AUTHINFO PASS commands are how a client sends clear text credentials to the server โœจ Those credentials are either just a username, or a username plus a password. The difference is that a password is supposed to stay secret and a username isn't. Honestly this doesn't change how the protocol works, but it can matter for user interfaces ๐Ÿซถ The username goes in through AUTHINFO USER, and the password goes in through AUTHINFO PASS.

If the server only needs a username, it MUST NOT give a 381 response to AUTHINFO USER, and it MUST give a 482 response to AUTHINFO PASS ๐Ÿ™ˆ

If the server needs both a username and a password, the username MUST be sent before the password ๐ŸŒˆ The server has to hold onto the username until the password shows up, and it MAY insist that the password comes in the very next command (so it only keeps the username until the next command is sent). Here's what the server does in that case:

  • MUST return a 381 response to AUTHINFO USER;
  • MUST return a 482 response to AUTHINFO PASS if there is no cached username;
  • MUST use the argument of the most recent AUTHINFO USER for authentication; and
  • MUST NOT return a 381 response to AUTHINFO PASS.

The server MAY figure out whether a password is needed for a given username. So the same server can send back both 381 and other response codes to AUTHINFO USER, depending on the case ๐Ÿฆ‹

If the client shows up with proper credentials, the server replies with a 281 โœจ If the server can't authenticate the client, it MUST reject the AUTHINFO USER/PASS command with a 481 reply. If an AUTHINFO USER/PASS command fails, the client MAY carry on without authentication. Or, if it wants, the client MAY try a different authentication mechanism, or send different credentials by issuing another AUTHINFO command ๐Ÿ’–

Now for the spicy part ๐ŸŒถ๏ธ The AUTHINFO PASS command lets the client use a clear-text password to authenticate. A compliant implementation MUST NOT implement this command without also implementing support for TLS [NNTP-TLS]. Using this command without an active strong encryption layer is deprecated, because the user's password would be exposed to everyone on the network between the client and the server ๐Ÿ˜ญ Any implementation of this command SHOULD be configurable so it can be turned off whenever a strong encryption layer (like the one provided by [NNTP-TLS]) isn't active, and that configuration SHOULD be the default. The server uses the 483 response code to say the datastream isn't secure enough for the command being attempted (see Section 3.2.1 of [NNTP]) โญ

Also, a server MAY (but is not required to) allow white space characters in usernames and passwords. A server implementation MAY blindly split command arguments at white space, which means it might not keep the exact white space sequence in the username or password ๐Ÿ™ˆ So a client SHOULD scan the username and password for white space and, if it finds any, warn the user that problems are likely. The SASL PLAIN [PLAIN] mechanism is recommended as an alternative, because it doesn't have these issues ๐Ÿซถ

Last thing, and it's kind of a vibe: historically, the username is not canonicalized in any way. Servers MAY use the [SASLprep] profile of the [StringPrep] algorithm to prepare usernames for comparison, but doing that may cause interoperability problems with legacy implementations ๐Ÿ’€ If you want canonicalization, the SASL PLAIN [PLAIN] mechanism is recommended as an alternative.

2.3.3. Examples ๐Ÿ“

Example of successful AUTHINFO USER:

[C] AUTHINFO USER wilma
[S] 281 Authentication accepted

Example of successful AUTHINFO USER/PASS:

[C] AUTHINFO USER fred
[S] 381 Enter passphrase
[C] AUTHINFO PASS flintstone
[S] 281 Authentication accepted

Example of AUTHINFO USER/PASS requiring a security layer:

[C] AUTHINFO USER fred@stonecanyon.example.com
[S] 483 Encryption or stronger authentication required

Example of failed AUTHINFO USER/PASS:

[C] AUTHINFO USER barney
[S] 381 Enter passphrase
[C] AUTHINFO PASS flintstone
[S] 481 Authentication failed

Example of AUTHINFO PASS before AUTHINFO USER:

[C] AUTHINFO PASS flintstone
[S] 482 Authentication commands issued out of sequence

2.4. AUTHINFO SASL Command ๐Ÿฆ„

This section defines a formal profile of the Simple Authentication and Security Layer [SASL] ๐Ÿ‘‘ Using the AUTHINFO GENERIC command (documented in Section 3.1.3 of [NNTP-COMMON]) to do SASL authentication is deprecated, and the AUTHINFO SASL command is the new favorite ๐Ÿ’– A server SHOULD NOT advertise AUTHINFO GENERIC in the list of capabilities returned by CAPABILITIES.

2.4.1. Usage ๐Ÿ’œ

This command MUST NOT be pipelined.

Syntax:

AUTHINFO SASL mechanism [initial-response]

This command MAY exceed 512 octets. Its maximum length gets bumped up to whatever can fit the largest encoded initial response possible for any SASL mechanism the implementation supports โœจ

Responses:

  281             Authentication accepted
  283 challenge   Authentication accepted (with success data) [1]
  383 challenge   Continue with SASL exchange [1]
  481             Authentication failed/rejected
  482             SASL protocol error
  502             Command unavailable [2]

  [1] These responses MAY exceed 512 octets.  The maximum length of
      these responses is increased to that which can accommodate the
      largest encoded challenge possible for any of the SASL
      mechanisms supported by the implementation.

  [2] If authentication has already occurred, AUTHINFO SASL is not a
      valid command (see Section 2.2).

      NOTE: Notwithstanding Section 3.2.1 of [NNTP], the server MUST
      NOT return 480 in response to AUTHINFO SASL.

Parameters:

  mechanism         = String identifying a [SASL] authentication
                      mechanism.
  initial-response  = Optional initial client response.
                      If present, the response MUST be encoded as
                      specified in Section 4 of [BASE64]. [3]
  challenge         = Server challenge.
                      The challenge MUST be encoded as specified
                      in Section 4 of [BASE64].

  [3] This argument MAY exceed 497 octets.  The maximum length of
      this argument is increased to that which can accommodate the
      largest encoded initial response possible for any of the SASL
      mechanisms supported by the implementation.

2.4.2. Description โœจ

okay so the AUTHINFO SASL command is how the client kicks off a [SASL] exchange with the server ๐Ÿ’– the client names the SASL mechanism it wants in the first parameter of the command. if the server supports that mechanism, it runs the SASL exchange to authenticate the user. optionally, it can also negotiate a security layer for the rest of the session ๐Ÿ”. if the requested mechanism is invalid (like, not supported), the server rejects the AUTHINFO SASL command with a 503 reply (see Section 3.2.1 of [NNTP]) ๐Ÿ™…. if the requested mechanism needs an encryption layer, the server rejects the command with a 483 reply (see Section 3.2.1 of [NNTP]).

the service name in this protocol's profile of SASL is "nntp" ๐Ÿงš

the whole SASL exchange is a back-and-forth of server challenges and client responses, and they're specific to whichever [SASL] mechanism was picked ๐Ÿฆ‹

a server challenge gets sent as a 383 reply with a single argument, which is the [BASE64]-encoded string the SASL mechanism handed over ๐Ÿ“จ. a server challenge with zero length MUST be sent as a single equals sign ("=") and MUST be included ๐ŸŒธ. why? bc [NNTP] says responses always have the same number of arguments, so this keeps the vibe consistent ๐Ÿ’…

a client response is a line holding a [BASE64]-encoded string ๐Ÿ’ฌ. a client response with zero length MUST be sent as a single equals sign ("=") and MUST be included, for consistency with the server challenge format ๐ŸŽ€. if the client wants to cancel the auth exchange, it sends a line with a single "*" ๐Ÿ›‘. if the server gets that, it MUST reject the AUTHINFO SASL command by sending a 481 reply. literally the server is not gonna let it slide ๐Ÿ’€

these [BASE64]-encoded strings can be WAY longer than normal NNTP responses ๐Ÿ˜ญ clients and servers MUST be able to handle the maximum encoded size of the challenges and responses their supported mechanisms generate. and this requirement is totally separate from any line length limits they might have in other parts of their protocol implementation ๐Ÿ™ˆ

the optional initial response argument is there to save a round trip when the mechanism supports an initial client response โœจ if you leave it out and the chosen mechanism needs an initial client response, the server MUST proceed as defined in section 5.1 of [SASL] ๐Ÿง . in NNTP, a server challenge with no data is the same as a zero-length challenge, and it's encoded as a single equals sign ("=") ๐Ÿ“

the [BASE64]-encoded initial response argument can go over 497 octets, which means the AUTHINFO SASL command can go over 512 octets too ๐Ÿ“ clients SHOULD and servers MUST be able to handle the maximum encoded size of initial responses their supported mechanisms can make. this requirement is also independent of any command or argument length limits in other parts of the protocol implementation ๐Ÿ‘‘

if using the initial response argument would push the AUTHINFO SASL command past 512 octets, the client MAY choose to omit the initial response parameter (and instead proceed as defined in Section 5.1 of [SASL]) ๐Ÿฆ‹

if the client is sending an initial response of zero length, it MUST instead send it as a single equals sign ("=") ๐Ÿซถ. that tells the server the response is there, it's just empty ๐ŸŒˆ

if the client uses an initial-response argument with a SASL mechanism that doesn't support an initial client response, the server MUST reject the AUTHINFO SASL command with a 482 reply ๐Ÿ™…โ€โ™€๏ธ

if the server can't [BASE64] decode a client response, it MUST reject the AUTHINFO SASL command with a 504 reply (see Section 3.2.1 of [NNTP]) ๐Ÿ’ฅ. and if the client can't BASE64 decode one of the server's challenges, it MUST cancel the auth using the "*" response ๐Ÿ›‘

ok this part is serious bestie: servers and clients MUST reject (and not ignore) any character that isn't explicitly allowed by the BASE64 alphabet ๐Ÿšซ. they also MUST reject any BASE64 sequence where the pad character ('=') shows up anywhere besides the end of the string. so "=AAA" and "AAA=BBB" are both a no-go ๐Ÿ’€

the authorization identity from this [SASL] exchange is a simple username, and both client and server MUST use the [SASLprep] profile of the [StringPrep] algorithm to prepare these names for transmission or comparison ๐Ÿช„. if preparing the authorization identity fails or ends up as an empty string (unless it was sent as the empty string to begin with), the server MUST fail the authentication with a 481 reply ๐Ÿ˜ค

if the client successfully finishes the exchange, the server issues either a 281 or a 283 reply ๐ŸŽ‰. if the server can't authenticate the client, it MUST reject the AUTHINFO SASL command with a 481 reply ๐Ÿ’”. if an AUTHINFO SASL command fails, the client MAY go on without authenticating ๐Ÿคทโ€โ™€๏ธ. or, the client MAY try another authentication mechanism, or present different credentials by sending another AUTHINFO command ๐Ÿ”

if the SASL mechanism returns extra data on success (like server authentication), the NNTP server issues a 283 reply with a single argument containing the [BASE64]-encoded string the mechanism supplied ๐Ÿ“ฌ. if no extra data comes back on success, the server issues a 281 reply โœ…

if a security layer is negotiated during the SASL exchange, it takes effect for the client on the octet right after the CRLF that ends the last response the client generated ๐Ÿ”. for the server, it takes effect right after the CRLF of its success reply ๐Ÿ’œ

when a security layer takes effect, the NNTP protocol gets reset to the state it was in right after the initial greeting response was sent (see 5.1 of [NNTP]) ๐Ÿ”„. the one exception: if a MODE READER command was issued, its effects (if any) don't get reversed ๐Ÿ™ƒ. the server MUST discard any knowledge it got from the client, like the current newsgroup and article number, unless it came from the SASL negotiation itself ๐Ÿงน. the client SHOULD discard, and MUST NOT rely on, any knowledge it got from the server, like the capability list, unless that knowledge came from the SASL negotiation itself ๐Ÿšซ. (bonus: a client MAY compare the advertised SASL mechanisms before and after authentication to catch an active down-negotiation attack ๐Ÿ•ต๏ธโ€โ™€๏ธ)

when both TLS [NNTP-TLS] and SASL security layers are in effect, the TLS encoding MUST be applied after the SASL encoding ๐Ÿง. the cleartext data is always SASL encoded first, and then the result gets TLS encoded. the order matters, periodt ๐Ÿ’…

to make sure everything interoperates, client and server implementations of this extension MUST implement the [DIGEST-MD5] SASL mechanism ๐Ÿค

if AUTHINFO USER/PASS and AUTHINFO SASL are both implemented, the SASL [PLAIN] mechanism SHOULD also be implemented ๐ŸŒŸ. DIGEST-MD5 alone isn't enough for some environments, like when the server needs to hand the plaintext password off to an external authentication service ๐Ÿ˜ต. the SASL PLAIN mechanism is preferred over AUTHINFO USER, even when there's no strong encryption layer active ๐Ÿ’–. why? because it gets rid of the white space problems AUTHINFO USER/PASS has with usernames and passwords ๐Ÿซง

2.4.3. Examples โœจ

okay bestie, time for the examples ๐Ÿ’… first up is the [PLAIN] SASL mechanism under a TLS layer, using an initial client response:

[C] CAPABILITIES
[S] 101 Capability list:
[S] VERSION 2
[S] READER
[S] STARTTLS
[S] AUTHINFO SASL
[S] SASL CRAM-MD5 DIGEST-MD5 GSSAPI
[S] LIST ACTIVE NEWSGROUPS
[S] .
[C] STARTTLS
[S] 382 Continue with TLS negotiation
[TLS negotiation proceeds, further commands protected by TLS]
[C] CAPABILITIES
[S] 101 Capability list:
[S] VERSION 2
[S] READER
[S] AUTHINFO USER SASL
[S] SASL CRAM-MD5 DIGEST-MD5 GSSAPI PLAIN EXTERNAL
[S] LIST ACTIVE NEWSGROUPS
[S] .
[C] AUTHINFO SASL PLAIN AHRlc3QAMTIzNA==
[S] 281 Authentication accepted

next, the EXTERNAL SASL mechanism under a TLS layer ๐Ÿ” this one uses the authorization identity taken from the client TLS certificate, so the initial client response is zero-length. the commands before AUTHINFO SASL are the same as the last example, so they've been left out ๐Ÿซถ

[C] AUTHINFO SASL EXTERNAL =
[S] 281 Authentication accepted

now the [DIGEST-MD5] SASL mechanism ๐Ÿงš this one includes a server challenge and server success data. white space has been added so it's easier to read, but the base64 data is really sent as one single line with no white space in it

[C] AUTHINFO SASL DIGEST-MD5
[S] 383 bm9uY2U9InNheUFPaENFS0dJZFBNSEMwd3RsZUxxT0ljT0kyd1FZSWU0
    enplQXR1aVE9IixyZWFsbT0iZWFnbGUub2NlYW5hLmNvbSIscW9wPSJhdXRo
    LGF1dGgtaW50LGF1dGgtY29uZiIsY2lwaGVyPSJyYzQtNDAscmM0LTU2LHJj
    NCxkZXMsM2RlcyIsbWF4YnVmPTQwOTYsY2hhcnNldD11dGYtOCxhbGdvcml0
    aG09bWQ1LXNlc3M=

[C] dXNlcm5hbWU9InRlc3QiLHJlYWxtPSJlYWdsZS5vY2VhbmEuY29tIixub25j
    ZT0ic2F5QU9oQ0VLR0lkUE1IQzB3dGxlTHFPSWNPSTJ3UVlJZTR6emVBdHVp
    UT0iLGNub25jZT0iMFkzSlFWMlRnOVNjRGlwK08xU1ZDMHJoVmcvLytkbk9J
    aUd6LzdDZU5KOD0iLG5jPTAwMDAwMDAxLHFvcD1hdXRoLWNvbmYsY2lwaGVy
    PXJjNCxtYXhidWY9MTAyNCxkaWdlc3QtdXJpPSJubnRwL2xvY2FsaG9zdCIs
    cmVzcG9uc2U9ZDQzY2Y2NmNmZmE5MDNmOWViMDM1NmMwOGEzZGIwZjI=
[S] 283 cnNwYXV0aD1kZTJlMTI3ZTVhODFjZGE1M2Q5N2FjZGEzNWNkZTgzYQ==

next is a failed login because of bad [GSSAPI] credentials ๐Ÿ’€ the mechanism can use the initial response, but the client decides not to, because it's too long. that makes the server challenge zero-length. again, white space is added for clarity, and the base64 data is really one line with no white space

[C] AUTHINFO SASL GSSAPI
[S] 383 =
[C] YIICOAYJKoZIhvcSAQICAQBuggInMIICI6ADAgEFoQMCAQ6iBwMFACAAAACj
    ggE/YYIBOzCCATegAwIBBaEYGxZURVNULk5FVC5JU0MuVVBFTk4uRURVoiQw
    IqADAgEDoRswGRsEbmV3cxsRbmV0bmV3cy51cGVubi5lZHWjge8wgeygAwIB
    EKEDAgECooHfBIHcSQfLKC8vm2i17EXmomwk6hHvjBY/BnKnvvDTrbno3198
    vlX2RSUt+CjuAKhcDcj4DW0gvZEqH7t5v9yWedzztlpaThebBat6hQNr9NJP
    ozh1/+74HUwhGWb50KtjuftO/ftQ8q0nTuYKgIq6PM4tp2ddo1IfpjfdNR9E
    95GFi3y1uBT7lQOwtQbRJUjPSO3ijdue9V7cNNVmYsBsqNsaHhvlBJEXf4WJ
    djH8yG+Dw/gX8fUTtC5fDpB5zLt01mkSXh6Wc4UhqQtwZBI2t/+TpX1okbg6
    Hr1ZZupeH6SByjCBx6ADAgEQooG/BIG8GnCmcXWtqhXh48dGTLHQgJ04K5Fj
    RMMq2qPSbiha9lq0osqR2KAnQA6LioWYxU+6yPKpBDSC5WOT441fUfkM8iAL
    kW3uNc+luFCGcnDsacrmoVU7Y6Akcp9m7Fm7orRc+TWSWPpBg3OR2oG3ATW0
    0NAz8TT06VOLVxIMUTINKdYVI/Ja7f3sy+/N4LGkJqScCQOwlo5tfDWn/UQF
    iTWo5Zw435rH8pjy2smQCnqC14v3NMAWTu4j+dzHUNw=
[S] 481 Authentication error

next, a client that bails halfway through an exchange ๐Ÿ™ˆ

[C] AUTHINFO SASL GSSAPI
[S] 383 =
[C] *
[S] 481 Authentication aborted as requested

now the server doesn't support the mechanism the client asked for ๐Ÿฅฒ

[C] AUTHINFO SASL EXAMPLE
[S] 503 Mechanism not recognized

and here the client tries a mechanism that needs a security layer first ๐Ÿ”’

[C] AUTHINFO SASL PLAIN
[S] 483 Encryption or stronger authentication required

next is an initial response sent with a mechanism that doesn't support one. the server must start the exchange when using [CRAM-MD5] ๐Ÿง 

[C] AUTHINFO SASL CRAM-MD5 AHRlc3QAMTIzNA==
[S] 482 SASL protocol error

last one: an authentication that fails because the response was encoded wrong ๐Ÿ˜ญ

[C] AUTHINFO SASL CRAM-MD5
[S] 383 PDE1NDE2NzQ5My4zMjY4MzE3QHRlc3RAZXhhbXBsZS5jb20+
[C] abcd=efg
[S] 504 Base64 encoding error

3. Augmented BNF Syntax for the AUTHINFO Extension โœจ

okay so this section is the formal grammar for AUTHINFO ๐Ÿค“ it's written in ABNF [ABNF], and it extends the syntax in Section 9 of [NNTP]. any non-terminals that this document doesn't define are defined over there. the [NNTP] ABNF should be imported first before you try validating these rules ๐Ÿซถ

3.1. Commands

this bit extends the non-terminal "command", which stands for an NNTP command ๐Ÿ’–

command =/ authinfo-sasl-command /
     authinfo-user-command /
     authinfo-pass-command

authinfo-sasl-command = "AUTHINFO" WS "SASL" WS mechanism
     [WS initial-response]
authinfo-user-command = "AUTHINFO" WS "USER" WS username
authinfo-pass-command = "AUTHINFO" WS "PASS" WS password

initial-response = base64-opt
username = 1*user-pass-char
password = 1*user-pass-char
user-pass-char = B-CHAR

okay, now the NOTE ๐Ÿšจ a server implementation MAY parse AUTHINFO USER and AUTHINFO PASS specially, so that white space can be used inside the username or password. those implementations accept the extra syntax below, which makes these two items inconsistent with "token" in Section 9.8 of [NNTP]:

user-pass-char =/ SP / TAB

but here's the catch ๐Ÿ‘€ doing this means the grammar can get ambiguous if the username or password starts or ends with white space. to fix that, these implementations typically treat everything after the first white space character following "USER"/"PASS", up to but not including the CRLF, as the username/password ๐ŸŽ€

3.2. Command Continuation

this bit extends the non-terminal "command-continuation", which covers the extra material the client sends for multi-stage commands ๐Ÿฆ‹

command-continuation =/ authinfo-sasl-383-continuation

authinfo-sasl-383-continuation = ("*" / base64-opt) CRLF

3.3. Responses

this extends the non-terminal "initial-response-content", which is an initial response line sent by the server ๐ŸŒธ

initial-response-content =/ response-283-content /
     response-383-content

response-283-content = "283" SP base64
response-383-content = "383" SP base64-opt

3.4. Capability Entries

this extends "capability-entry", which is a capability the server might advertise ๐Ÿ“ฃ

capability-entry =/ authinfo-capability /
     sasl-capability

authinfo-capability = "AUTHINFO" *(WS authinfo-variant)
authinfo-variant = "USER" / "SASL"
sasl-capability = "SASL" 1*(WS mechanism)

3.5. General Non-terminals

last but not least, the general non-terminals ๐Ÿ’…

base64-opt = "=" / base64
mechanism = 1*20mech-char
mech-char = UPPER / DIGIT / "-" / "_"

4. Summary of Response Codes ๐Ÿ“‹

this section is the cheat sheet of every new response code defined in this document ๐Ÿ“ for each one it tells you whether it's multi-line, which commands can produce it, what arguments it takes, and what it means

Response code 281
   Generated by: AUTHINFO USER, AUTHINFO PASS, AUTHINFO SASL
   Meaning: authentication accepted

Response code 283
   Generated by: AUTHINFO SASL
   1 argument: challenge
   Meaning: authentication accepted (with success data)

Response code 381
   Generated by: AUTHINFO USER
   Meaning: password required via AUTHINFO PASS command.  Note
   that this code is used for backwards compatibility and does
   not conform to the traditional use of 3xx codes.

Response code 383
   Generated by: AUTHINFO SASL
   1 argument: challenge
   Meaning: continue with SASL exchange

Response code 481
   Generated by: AUTHINFO USER, AUTHINFO PASS, AUTHINFO SASL
   Meaning: authentication failed/rejected

Response code 482
   Generated by: AUTHINFO USER, AUTHINFO PASS, AUTHINFO SASL
   Meaning: authentication commands issued out of sequence or
   SASL protocol error

5. Authentication Tracking/Logging ๐Ÿ•ต๏ธโ€โ™€๏ธ

this section is full of implementation suggestions and best current practice notes ๐Ÿ’œ it doesn't set any extra network protocol requirements, so no pressure ๐Ÿซถ

once someone has authenticated, the authorization identity from the AUTHINFO exchange (the username when you're using USER/PASS) SHOULD be included in an audit trail that links that identity to any articles posted during a POST operation. this SHOULD be the default setup too ๐Ÿ“ you could do this by adding headers to the posted articles, or with a server logging mechanism. the server MAY give you a way to turn this off, since some users or admins might see it as a privacy violation ๐Ÿ™ˆ

6. Security Considerations ๐Ÿ”

okay this one is serious bestie, so pay attention ๐Ÿ‘‘

security issues are talked about all throughout this memo ๐Ÿ’€

in general, the security considerations of [SASL] and any SASL mechanisms you implement apply here too. only the most important ones get called out below. also, this extension is NOT meant to fix the security considerations in section 12 of [NNTP], and those still matter for any NNTP implementation ๐Ÿ’…

before the [SASL] negotiation starts, any protocol interactions may have happened in the clear, and an active attacker may have changed them ๐Ÿ˜ฑ that's why clients and servers MUST discard any sensitive knowledge they got before the SASL negotiation started, once a security layer is set up. on top of that, the CAPABILITIES command SHOULD be issued again once a security layer is established, and other protocol state SHOULD be re-negotiated too ๐Ÿ”„

servers MAY use a policy where the connection gets dropped after a number of failed authentication attempts. if they do, they SHOULD NOT drop the connection until at least 3 authentication attempts have failed ๐Ÿ™…โ€โ™€๏ธ

implementations MUST support a configuration where authentication mechanisms that are vulnerable to passive eavesdropping attacks (such as AUTHINFO USER/PASS and SASL [PLAIN]) are not advertised or used without an external security layer such as TLS [NNTP-TLS] being present. this configuration SHOULD be the default ๐Ÿ”’

when a client and server both allow multiple authentication mechanisms, an active attacker can force a down-negotiation to the weakest one ๐Ÿ˜ญ for that reason, both clients and servers SHOULD be configurable to forbid weak mechanisms. what counts as an acceptable minimum strength is a policy decision that's outside the scope of this specification ๐Ÿซถ

7. IANA Considerations ๐Ÿ“š

7.1. IANA Considerations for SASL/GSSAPI Services

the IANA registered the SASL/GSSAPI service name "nntp" ๐ŸŽ€ this service name refers to authenticated use of Usenet news service when it's provided over the [NNTP] protocol.

  • Published Specification: This document.
  • Contact for Further Information: Authors of this document.
  • Change Controller: IESG <iesg@ietf.org>.

7.2. IANA Considerations for NNTP Extensions

Okay so this section is the formal definition of AUTHINFO for the IANA registry, which [NNTP] Section 3.3.3 requires. It's basically the extension's official profile card, so here's the whole vibe ๐Ÿ’…

  • This extension provides an extensible mechanism for NNTP authentication via a variety of methods. ๐Ÿ”
  • The capability label for this extension is AUTHINFO. ๐ŸŽ€
  • The AUTHINFO capability label has two possible optional arguments, USER and SASL (as defined in Section 2.1), indicating which variants of the AUTHINFO command are supported. ๐Ÿงš
  • This extension also provides the SASL capability label, whose arguments list the available SASL mechanisms. โœจ
  • This extension defines three new commands, AUTHINFO USER, AUTHINFO PASS, and AUTHINFO SASL, whose behavior, arguments, and responses are defined in Sections 2.3 and 2.4. ๐Ÿ’–
  • This extension does not associate any new responses with pre-existing NNTP commands. ๐Ÿ™…โ€โ™€๏ธ
  • This extension may affect the overall behavior of both server and client in that the AUTHINFO SASL command may require that subsequent communication be transmitted via an intermediary security layer. ๐Ÿ›ก๏ธ
  • The length of the AUTHINFO SASL command (as defined in this document) may exceed 512 octets. The maximum length of this command is increased to that which can accommodate the largest initial response possible for any of the SASL mechanisms supported by the implementation. ๐Ÿ“
  • This extension defines two new responses, 283 and 383, whose lengths may exceed 512 octets. The maximum length of these responses is increased to that which can accommodate the largest challenge possible for any of the SASL mechanisms supported by the implementation. ๐ŸŒˆ
  • This extension does not alter pipelining, but AUTHINFO commands cannot be pipelined. ๐Ÿšซ
  • Use of this extension may alter the capabilities list. Once the AUTHINFO command has been used successfully, the AUTHINFO capability can no longer be advertised by CAPABILITIES. Additionally, the MODE-READER capability MUST NOT be advertised after successful authentication. ๐Ÿ‘€
  • This extension does not cause any pre-existing command to produce a 401, 480, or 483 response. ๐ŸŒธ
  • This extension is unaffected by any use of the MODE READER command. However, the MODE READER command MUST NOT be used in the same session following successful authentication. ๐Ÿ™ˆ
  • Published Specification: This document. ๐Ÿ“–
  • Contact for Further Information: Authors of this document. ๐Ÿซถ
  • Change Controller: IESG <iesg@ietf.org>. ๐Ÿ‘‘

8. Acknowledgements

Big thank you to Chris Newman, who wrote the document this RFC started from. ๐Ÿฅฐ

A whole lot of the authentication text came from the NNTP revision or the common authentication specs, written by Stan Barber. A huge chunk of the SASL text was lifted from the revisions to RFC 1734 and RFC 2554, courtesy of Rob Siemborski. ๐Ÿ“

Special shoutout to Russ Allbery, Clive Feather, and everyone else who gave private comments on the earlier drafts, plus the IETF NNTP Working Group for their steady (if sporadic) insight in discussion. ๐Ÿ’œ


9. References

9.1. Normative References

[ABNF] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax Specifications: ABNF", RFC 4234, October 2005. ๐Ÿ“

[AUTH] Haller, N. and R. Atkinson, "On Internet Authentication", RFC 1704, October 1994. ๐Ÿ”‘

[BASE64] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings", RFC 4648, October 2006. ๐Ÿ”ค

[DIGEST-MD5] Leach, P. and C. Newman, "Using Digest Authentication as a SASL Mechanism", RFC 2831, May 2000. ๐Ÿงฉ

[KEYWORDS] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, March 1997. ๐Ÿท๏ธ

[NNTP] Feather, C., "Network News Transfer Protocol (NNTP)", RFC 3977, October 2006. ๐Ÿ“ฐ

[NNTP-TLS] Murchison, K., Vinocur, J., and C. Newman, "Using Transport Layer Security (TLS) with Network News Transfer Protocol (NNTP)", RFC 4642, October 2006. ๐Ÿ”’

[SASL] Melnikov, A. and K. Zeilenga, "Simple Authentication and Security Layer (SASL)", RFC 4422, June 2006. ๐Ÿง

[SASLprep] Zeilenga, K., "SASLprep: Stringprep Profile for User Names and Passwords", RFC 4013, February 2005. ๐Ÿช„

[StringPrep] Hoffman, P. and M. Blanchet, "Preparation of Internationalized Strings ("stringprep")", RFC 3454, December 2002. ๐ŸŒ

9.2. Informative References

[BEEP] Rose, M., "The Blocks Extensible Exchange Protocol Core", RFC 3080, March 2001. ๐Ÿงฑ

[CRAM-MD5] Nerenberg, L., "The CRAM-MD5 SASL Mechanism", Work in Progress. ๐Ÿšง

[GSSAPI] Melnikov, A., "SASL GSSAPI mechanisms", Work in Progress. ๐Ÿšง

[IMAP] Crispin, M., "INTERNET MESSAGE ACCESS PROTOCOL - VERSION 4rev1", RFC 3501, March 2003. ๐Ÿ“ฌ

[LDAP-AUTH] Harrison, R., "Lightweight Directory Access Protocol (LDAP): Authentication Methods and Security Mechanisms", RFC 4513, June 2006. ๐Ÿ“’

[NNTP-COMMON] Barber, S., "Common NNTP Extensions", RFC 2980, October 2000. ๐Ÿ—ž๏ธ

[PLAIN] Zeilenga, K., Ed., "The PLAIN Simple Authentication and Security Layer (SASL) Mechanism", RFC 4616, August 2006. ๐Ÿซง

[POP-AUTH] Myers, J., "POP3 AUTHentication command", RFC 1734, December 1994. ๐Ÿ“ฎ

[SMTP-AUTH] Myers, J., "SMTP Service Extension for Authentication", RFC 2554, March 1999. โœ‰๏ธ


Authors' Addresses

Jeffrey M. Vinocur
Department of Computer Science
Upson Hall
Cornell University
Ithaca, NY 14853 USA

EMail: vinocur@cs.cornell.edu


Kenneth Murchison
Carnegie Mellon University
5000 Forbes Avenue
Cyert Hall 285
Pittsburgh, PA  15213 USA

EMail: murch@andrew.cmu.edu

Here's the legal bit, and it's important, so read it properly ๐Ÿ“œ

Copyright (C) The Internet Society (2006).

This document is subject to the rights, licenses and restrictions contained in BCP 78, and except as set forth therein, the authors retain all their rights.

This document and the information contained herein are provided on an "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.


Intellectual Property

The IETF takes no position regarding the validity or scope of any Intellectual Property Rights or other rights that might be claimed to pertain to the implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; nor does it represent that it has made any independent effort to identify any such rights. Information on the procedures with respect to rights in RFC documents can be found in BCP 78 and BCP 79.

Copies of IPR disclosures made to the IETF Secretariat and any assurances of licenses to be made available, or the result of an attempt made to obtain a general license or permission for the use of such proprietary rights by implementers or users of this specification can be obtained from the IETF on-line IPR repository at http://www.ietf.org/ipr.

The IETF invites any interested party to bring to its attention any copyrights, patents or patent applications, or other proprietary rights that may cover technology that may be required to implement this standard. Please address the information to the IETF at ietf-ipr@ietf.org.


Acknowledgement

Funding for the RFC Editor function is provided by the IETF Administrative Support Activity (IASA). ๐Ÿ’–

๐Ÿ“ฆ where this page comes from