Subject: Last Call: 'The Plain SASL Mechanism' to Proposed Standard

From: The IESG <[email-masked]>
Date: Fri, 11 Feb 2005 16:35:43 -0500

The IESG has received a request from the Simple Authentication and Security 
Layer WG to consider the following document:

- 'The Plain SASL Mechanism '
   <draft-ietf-sasl-plain-06.txt> as a Proposed Standard

The IESG plans to make a decision in the next few weeks, and solicits
final comments on this action.  Please send any comments to the
[email-masked] or [email-masked] mailing lists by 2005-02-25.

The file can be obtained via
http://www.ietf.org/internet-drafts/draft-ietf-sasl-plain-06.txt

---

From: "Jeffrey I. Schiller" <[email-masked]>
Date: Fri, 11 Feb 2005 17:49:40 -0500

I object to this document being made a proposed standard. It
effectively permits the use of plain text passwords over an insecure
mechanism. I thought we were trying to eliminate such things in IETF
protocols.

Although the document purports to be used only when an underlying
transport is providing security (aka TLS) it provides an escape
clause. Namely the phrase "or backwards compatibility dictates
otherwise." This phrase appears twice in the document. In section 1
and again in the Security Considerations Section. To wit:

From Section 1:

  The PLAIN SASL mechanism does not provide a security layer.  This
  mechanism MUST NOT be used without adequate security protection as the
  mechanism affords no integrity nor confidentiality protection itself.
  The PLAIN SASL mechanism MUST NOT be advertised unless a strong
  encryption layer, such as provided by Transport Layer Security
  ([TLS]), is active or backwards compatibility dictates otherwise.
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...

6. Security Considerations

  The PLAIN mechanism relies on the TLS encryption layer for security.
  When used without TLS, it is vulnerable to a common network
  eavesdropping attack.  Therefore PLAIN MUST NOT be advertised or used
  unless a suitable TLS encryption layer is active or backwards
                                                      ^^^^^^^^^
  compatibility dictates otherwise.
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

I will withdraw my objection if this "escape clause" is removed (and
an equivalent one isn't substituted...).

                        -Jeff

--
=============================================================================
Jeffrey I. Schiller
MIT Network Manager
Information Services and Technology
Massachusetts Institute of Technology
77 Massachusetts Avenue  Room W92-190
Cambridge, MA 02139-4307
617.253.0161 - Voice
[email-masked]
============================================================================

---

From: Sam Hartman <[email-masked]>
Date: Mon, 14 Feb 2005 17:04:48 -0500

At this time I'm not going to take a position on Jeff's objection;
I'll wait to hear what others say.

However his message did cause me to realize something that needs to be
fixed if the escape clause remains.  In one case the text says "strong
encryption layer, such as provided by Transport Layer Security," while
in other cases the text says that plain must not be advertized unless
TLS is active.

The draft must be consistent about the requirement it sets.  My
preference is that the first formulation be used: TLS should not be
considered special.

--Sam

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Tue, 15 Feb 2005 14:30:03 -0800

First, I think we need to separate use recommendations from
implementation requirements.  Second, we also need to consider
that PLAIN is a well entrenched authentication mechanism, used
in many existing protocols.  (If it wasn't for this, I might
agree with Jeffrey.)

As far as use recommendations, I think the specification
should be clear that this mechanism should be used in
conjunction with a service that provides adequate data
confidentiality protections.

As far as implementation requirements, I think we should
recommend that, by default, the mechanism should only be
advertised and/or made use of when adequate data
confidentiality protections are in place.

I do not think it appropriate for this specification to
state which particular data confidentiality protections
should be in place, nor even which should be implemented.
The latter, where appropriate, should be detailed in
application-level protocol TS and/or AS which states that
the PLAIN mechanism is applicable to that protocol, and
the former left to the user/administrator.

Hence, I suggest replacing the section 1 text:
  This mechanism MUST NOT be used without adequate security protection
  as the mechanism affords no integrity nor confidentiality protection
  itself.  The PLAIN SASL mechanism MUST NOT be advertised unless a
  strong encryption layer, such as provided by Transport Layer Security
  ([TLS]), is active or backwards compatibility dictates otherwise.

with:
  The PLAIN mechanism should not be used without adequate data
  security protection as this mechanism by affords no
  integrity nor confidentiality protections itself.  The
  mechanism is intended to be used with data security
  protections provided by application layer protocol,
  generally through its use of Transport Layer Security
  [TLS] services.

  By default, implementations SHOULD only advertise nor make
  use of the PLAIN mechanism when adequate data security
  services are in place.  Specifications for IETF protocols
  which indicate that PLAIN is an applicable authentication
  mechanism MUST mandate that implementations support an
  strong data security service, such as TLS.

And then update Security Considerations to discussion (and
to be consistent with) these statements.

-- Kurt

---

From: Rob Siemborski <[email-masked]>
Date: Thu, 17 Feb 2005 21:42:09 -0500 (EST)

>  By default, implementations SHOULD only advertise nor make
                                                      ^^^
You mean 'or', right?

>  strong data security service, such as TLS.

This seems fine to me.  (And to Sam's comment specifically...) TLS should 
not be special.

-Rob

-------------------------------------------------------------------------
Rob Siemborski        |     PGP:0x5CE32FCC     |      [email-masked] 
-----BEGIN GEEK CODE BLOCK----
Version: 3.12
GCS/IT/CM/PA d- s+: a-- C++++$ ULS++++$ P+++$ L+++ E W+ N(-) o? K- w-- O-
M-- V-- PS+ PE+ Y+ PGP+ t+@ 5+++ X- R@ tv-- b+ DI+++ D++ G e++ h+ r- y?
------END GEEK CODE BLOCK-----

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 22 Feb 2005 14:55:24 +0100

>    <draft-ietf-sasl-plain-06.txt> as a Proposed Standard

The following came up when implementing authzid derivation.  My
recommendations on solving this are given below, but first some
discussion on the problem.  In section 2:

  When an empty authorization identity is provided, the server SHALL
  derive the authorization identity from the prepared representation of
  the provided authentication identity string.  This ensures that the
  derivation of different representations of the authentication identity
  produce the same authorization identity.

Given that the strings are prepared as query strings, it is not
strictly true that, as the last sentence suggest, the step ensure that
different representations produce the same authorization identity.

Consider two authid strings with unassigned code points (e.g., with
some new Unicode 4.0 code points).  They could be two different
Unicode representations of essentially the same string.  I.e., had
Unicode 4.0 NFKC been used on the two strings, the output would have
been identical.

Further, the pseudo code description for this case appear
miss-leading, consider:

        string pAuthcid = SASLprep(authcid, true); # prepare authcid
...
        if (authzid == NULL) {
          authzid = DeriveAuthzid(pAuthcid);
          if (authzid == NULL || authzid == "") {
              return false; # could not derive authzid
          }
        }
        if (!Authorize(pAuthcid, authzid)) {
          return false;     # not authorized
        }
...
  The second parameter provided to the Authorize function is not
  prepared by this code.  The application-level SASL profile should be
  consulted to determine what, if any, preparation is necessary.

Now, if authzid is NULL in the first 'if' clause, 'authzid' will
actually be prepared by the code, which doesn't match the explanation.

RECOMMENDATIONS:

Don't derive authorization identities from the prepared representation
of authentication identities, when the presented authzid is empty.

Change the paragraph above into something like:

  When an empty authorization identity is provided, the server SHALL
  derive the authorization identity from the provided authentication
  identity string.  The application-level SASL profile should be
  consulted to determine what, if any, preparation is necessary.

In the pseudo-code, let the DeriveAuthzid function take 'authcid' as
parameter:

        if (authzid == NULL) {
          authzid = DeriveAuthzid(authcid);
          if (authzid == NULL || authzid == "") {
              return false; # could not derive authzid
          }
        }

Further, add an explanation of the DeriveAuthzid function, that
suggest the function prepare the string internally, if required by the
application profile:

  The DeriveAuthzid function is responsible for deriving an
  authorization identity string given the presented authentication
  identity string.  The application-level SASL profile should be
  consulted to determine what, if any, preparation is necessary.

Thanks,
Simon

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Tue, 22 Feb 2005 12:36:42 -0800

First, I note that the I-D uses the term "empty" in conjunction
with authorization identities to mean "absent".  The text would
likely be less confusing if the following patches were applied.

 As with other SASL mechanisms,
-the client leaves the authorization identity empty
+the client does not provide an authorization identity
 when it wishes the server to derive an identity from the
 credentials and use that as the authorization identity.

-When an empty authorization identity is provided,
+When no authorization identity is provided,
 the server SHALL derive the authorization identity from the
 prepared representation of the provided authentication
 identity string.

This makes the text consistent with the ABNF and pseudo-code
(which was written in terms of the ABNF), in particular:
        authzid = 1*SAFE

Secondly, the lead in to the pseudo-code likely should be:
  The verification function (using hashed password and the
  RECOMMENDED preparation algorithm, SASLprep) can be written
  (in pseudo\-code):

That said, I have to disagree with Simon here.  In particular,
I do not believe his recommendation should be adopted.

The requirement to use the prepared authcid in deriving of
authorization identity when the client provided none is
technical sound and quite appropriate.  Without this, a user
(not doing proxy authorization) using two different clients,
say one sending NFKC strings and one sending NFC, might end
up different authorization identities.  This would be a bad
thing.  The WG concluded that requiring the prepared form of
the authcid be used in determining the authorization identity
when no authzid field is absent is the best way to ensure
interoperability here.

Additional comments below...

At 05:55 AM 2/22/2005, Simon Josefsson wrote:
>some new Unicode 4.0 code points).

Provided by two different clients, or where one client has provided
one authcid and the server needs to compare it to a second (in
deriving the authzid)?

If the former, and SASLprep is used, then the server should have
failed the authentication (because the prepared representation of
the stored authcid cannot contain unassigned code points).  If
the former and SASLprep is not used, then details should be left
to the implementor.

If the latter, and SASLprep is used, that compare will fail.
If the latter, and SASLprep is not used, details should be left
to the implementor.

>They could be two different

Well, if the server is applying Unicode 4.0 NFKC, then the
server is obviously not using the RECOMMENDED preparation
algorithm, SASLprep.  In such cases, the server needs to consider
all the ramifications of not using the RECOMMENDED preparation
algorithm, including ironing out all such details.

>Further, the pseudo code description for this case appear

If you consider the code in light of:
        authzid = 1*SAFE

it should make more sense.

>actually be prepared by the code, which doesn't match the explanation.

See my comment regarding "empty" meaning "absent".

>of authentication identities, when the presented authzid is empty.

I think that this approach is unwise.  I do not support making
these changes.

---

From: Sam Hartman <[email-masked]>
Date: Tue, 22 Feb 2005 16:10:55 -0500

I agree with Kurt here.  I actually think Simon and perhaps the whole
discussion of this issue in the working group has missed a more
fundamental issue.  The authorization ID is not in the same namespace
or typespace as the authentication identity.  

I fele like Simon's arguing over details that miss this in an
important way.

Unfortunately I have failed to actually come up with a way of
articulating this issue.  

So I'll fall back to agreeing with Kurt and saying that I think that
there is a better reason Kurt is right than what he's managed to
actually write up.

Of course it is also quite possible that there is nothing here and I'm
just feeling something ought to exist even when it does not.

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 22 Feb 2005 22:12:36 +0100

"Kurt D. Zeilenga" <[email-masked]> writes:

> thing.

Indeed, but that wouldn't occur with my proposal.

I'm saying that it is the application profile that should define the
form of authzid, and in particular, the application profile should say
how to derive (prepare) an authzid from authcid, when the authzid is
absent.

Setting authzid=SASLPrep(authid) inside a SASL mechanism, like PLAIN,
assume too much about the structure of authorization identities.

One point is that deriving a default authzid is not something that has
to be described by each and every SASL mechanism, especially if it
must always be the same algorithm, i.e., authzid=SASLprep(authid).
The application profiles should describe it, or the core document
could do it.

> The WG concluded that requiring the prepared form of

That is not in conflict with my proposal.  (As an aside, as I
understood it, the WG concluded to strongly suggest, but not require,
the use of SASLprep.)

I want the invocation of 'authzid=SASLprep(authcid)' derivation moved
from the PLAIN mechanism into the application profiles or core
document.

For most applications, the end result will be the same.

With my approach, PLAIN can be used by application profiles that have
special authzid structures; structures that is otherwise permitted by
the core SASL specification.

It seems to me that if the current text stand, PLAIN may invalidate
assumptions for application profiles that follow from the core
document.

> algorithm, including ironing out all such details.

I was not talking about server using Unicode 4.0 NFKC.  I was talking
about two strings which would be identical after U4NFKC().

Thanks,
Simon

---

From: Sam Hartman <[email-masked]>
Date: Tue, 22 Feb 2005 16:45:49 -0500

>>>>> "Simon" == Simon Josefsson <[email-masked]> writes:

    Simon> I'm saying that it is the application profile that should
    Simon> define the form of authzid, 

I think the authorization ID tends to have more of an implementation
specific (instead of application specific) component than you seem to
be assuming.  The profile does need to describe the form in so far as
it needs to describe normalization and that sort of thing.  However I
am unclear on whether application profiles must assign semantics to
authorization identities.

Also, placing requirements on the profile document in this
specification is inappropriate.  That should go in rfc2222bis.

--Sam

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Tue, 22 Feb 2005 16:37:22 -0500

> how to derive (prepare) an authzid from authcid, when the authzid is
         ^^^^^^^^^^^^^^^^

And there is the fundamental confusion.
To "prepare" a string means to apply SASLPrep or some other string 
preparation procedure (or none); in the case of authzid this is indeed 
specified by the application profile.

To "derive" an authzid from an authcid does _not_ mean "take the authcid, 
apply SASLprep (or some other stringprep), and that is your authzid".  It 
means taking the (prepared) authcid and passing it through a fairly 
arbitrary mapping function which is defined by some combination of the 
application profile, the server implementation, and local policy, and which 
emits an authzid.

For example, I have used an IMAP server implementation which allowed the 
administrator to provide a file containing an arbitrary mapping from 
Kerberos principal names (authcids) to local IMAP users (authzids).

-- Jeffrey T. Hutzelman (N3NHS) <[email-masked]>
   Sr. Research Systems Programmer
   School of Computer Science - Research Computing Facility
   Carnegie Mellon University - Pittsburgh, PA

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 23 Feb 2005 01:09:36 +0100

>> how to derive (prepare) an authzid from authcid, when the authzid is

I agree with your descriptions, but I fail to see how it explain any
confusion.

I'm suggesting that the "prepare" step should be made part of the
"derive" step.  I don't see what is gained, for the PLAIN mechanism,
to enforce what input the "derive" step receive.  I agree "derive" is
typically a complex function.  To me that is another argument that it
should receive the raw input (authcid) as provided by the client,
rather than SASLprep(authcid).  The "derive" function can compute the
latter itself, but cannot go from SASLprep(authcid) to authcid.

Thanks,
Simon

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 23 Feb 2005 01:01:45 +0100

> authorization identities.

The problem here is that a mechanism (PLAIN) assume some semantics on
authzid's when it is using SASLprep to prepare input to the
DeriveAuthzid function.  I'm saying it is better to let DeriveAuthzid
call SASLprep internally, if appropriate.  Then we also do not need to
copy the same 'authzid=SASLprep(authcid)' text to all future SASL
mechanism documents.

> specification is inappropriate.  That should go in rfc2222bis.

Agreed.

Thanks,
Simon

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Tue, 22 Feb 2005 16:38:13 -0800

At 04:09 PM 2/22/2005, Simon Josefsson wrote:
>rather than SASLprep(authcid).

Actually, it receives the prepare(authcid) where prepare()
is recommended to be SASLprep().

Second, your suggestion would allow
        derive(X) != derive(Y)
even though prepare(X) == prepare(Y).

>The "derive" function can compute the

The point of using prepare here is to ensure that the
output of derive() is not dependent on possible representational
differences in the authentication identity.

That is, if one client happens to produce NFC representation
of the authentication identity, and another NKFC, the user
will have the same authorization identity regardless of
which of the two clients was used.

Your proposal, if adopted, would allow servers to make the
derivation dependent on allowed representational differences
which should not impact the behavior of the server.

Kurt

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Tue, 22 Feb 2005 19:57:35 -0500

> copy the same 'authzid=SASLprep(authcid)' text to all future SASL

The document does not say "authzid=SASLprep(authcid)".
It says "authzid=DeriveAuthzid(SASLprep(authcid))".

This does not say that the authzid is prepared by SASLprep.  It says that 
the authcid is prepared by SASLprep before being handed to DeriveAuthzid, 
which then returns authzid in whatever form is appropriate for the 
application.  We are not applying SASLprep to the _output_ of the mapping; 
we're applying it to the _input_ to the mapping, which is a 
mechanism-specific authcid.

> actually be prepared by the code, which doesn't match the explanation.

No.  Neither the pseudocode nor the explanation says anything about 
applying SASLprep to the authzid.  It says that the Derive function is 
applied to the prepared form of the authcid, not to the raw form.  That 
does not mean that the output will necessarily have been processed by 
SASLprep; that is up to the application.  If the application requires its 
authzid's to be prepared, it presumably do the appropriate preparation as 
part of the Authorize function, or else require that clients do it before 
sending an authzid and define the Derive function to produce prepared 
output.

The Derive function can do pretty much whatever it wants.  It cannot be 
constrained by mechanisms, and in most cases is not constrained by the 
application profile either (rather, it is usually 
implementation-dependent).  However, its input is a valid authcid for the 
mechanism in use, prepared according to the specification of that 
mechanism.  This _needs_ to be specified by each mechanism because it is a 
mechanism-specific behaviour.

It would be no more appropriate for an application profile to specify 
preparation for authcid's than it would be for a mechanism to specify 
preparation for authzid's.  The input to DeriveAuthzid is an authcid, and 
thus its form can be specified only by the mechanism.

-- Jeff

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 23 Feb 2005 10:51:39 +0100

> which of the two clients was used.

Not necessarily, since prepare() currently permit unassigned code
points in the output.  I.e., with the current text you can have
prepare(NFC(X)) != prepare(NFKC(X)) if X contain some code point new
in Unicode 4.0 that is normalized differently by NFC and NFKC.

> which should not impact the behavior of the server.

I think the current text permit this too, see above, since unassigned
code points are left untouched by prepare().

An alternative solution to this problem would be to disallow
unassigned code points when preparing the authcid that is used as
input to DeriveAuthzid.  That would be simpler, but I still prefer my
approach, although I can't pin-point exactly what the difference would
be.

Thanks,
Simon

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 23 Feb 2005 10:41:47 +0100

> mechanism-specific authcid.

Right, I agree, but I expressed myself poorly.

> thus its form can be specified only by the mechanism.

That view seem consistent, and now I understand it.  A further
question then: Why are unassigned code points allowed in the input to
DeriveAuthzid()?  Recall:

If the goal is to _ensure_ a good situation, it seems more appropriate
to disallow unassigned code points, or?

Thanks,
Simon

---

From: Sam Hartman <[email-masked]>
Date: Wed, 23 Feb 2005 09:41:38 -0500

[Tom, I'm asking for an explicit call from the chair for this document.]

    Simon> "Kurt D. Zeilenga" <[email-masked]> writes:

    >>> The "derive" function can compute the latter itself, but
    >>> cannot go from SASLprep(authcid) to authcid.
    >>  The point of using prepare here is to ensure that the output
    >> of derive() is not dependent on possible representational
    >> That is, if one client happens to produce NFC representation of
    >> the authentication identity, and another NKFC, the user will
    >> have the same authorization identity regardless of which of the
    >> two clients was used.

    Simon> Not necessarily, since prepare() currently permit
    Simon> unassigned code points in the output.  I.e., with the
    Simon> current text you can have prepare(NFC(X)) !=
    Simon> prepare(NFKC(X)) if X contain some code point new in
    Simon> Unicode 4.0 that is normalized differently by NFC and NFKC.

Simon, when you bring up an issue in IETF-wide last call that has been
extensively discussed in the working group, please note that fact.  In
this instance it's not the same field as was discussed before but it
is the same issue as with the password.  

It's my opinion that the consensus on the last go around was fairly
rough, so bringing it up again especially when you noticed a new
implication is a fine thing to do.

Currently we're under a bit of time pressure because the document is
on the IESG agenda.  This issue is complicated enough that if the WG
wants to revisit it, I will remove the document from the agenda and we
can hash things out on the working group list bringing it back when
we're done.  I don't think making a quick change to the handling of
this issue would give me the necessary confidence in the quality of
the change.

My personal opinion is that the text is fine as is and that the
current text creates greater interoperability than forbidding unassigned
codepoints.

Tom, please let me know by Friday whether there is a consensus in the
WG to pull the document back to discuss this issue.

--Sam

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Wed, 23 Feb 2005 07:01:45 -0800

>in Unicode 4.0 that is normalized differently by NFC and NFKC.

If X contains some new code points, e.g., unassigned in
Unicode as defined in SASLprep, then authentication will
fail (by design) if the server uses the RECOMMENDED
algorithm.  If the server doesn't use the RECOMMENDED
algorithm, behavior is implementation specific.

>code points are left untouched by prepare().

When SASLprep is not used, anything is possible.

>input to DeriveAuthzid.

When SASLprep is used, they are (since even if allowed in the
provided authcid, a provided authcid with unassigned code
points cannot possibly match a SASLprep-prepared stored authcid.

>That would be simpler, but I still prefer my

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 23 Feb 2005 16:24:45 +0100

> algorithm, behavior is implementation specific.

The document is not clear that deriving a "default" authzid using
DeriveAuthzid(SASLprep(authcid)) is part of the RECOMMENDED
verification algorithm.  The section reads:

If you are saying that this SHALL is not mandatory, or that it is
conditioned on some other decision, I believe it is misleading to use
the term SHALL.

Thanks,
Simon

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Wed, 23 Feb 2005 07:32:42 -0800

At 01:41 AM 2/23/2005, Simon Josefsson wrote:
>DeriveAuthzid()? 

If SASLprep is used, then unassigned code points won't appear
in the input to DerivedAuthzid as such an authcid value
cannot possibly match any stored authcid value.  In the
pseudo-code, this is the case of FetchPasswordHash(pAuthcid)
returning NULL (unknown authcid).

Of course, if using another prepare algorithm the behavior
is implementation specific.

Kurt

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Wed, 23 Feb 2005 08:14:12 -0800

At 07:24 AM 2/23/2005, Simon Josefsson wrote:

>verification algorithm.

First, there is no RECOMMENDED verification algorithm, there
is a verification process which includes preparation, an
a statement of which preparation algorithm is RECOMMENDED.

I think the document is quite clear as to what the
verification process is, what the RECOMMENDED preparation
algorithm is, and that the verification process includes
both verification that the passwd is suitable to authenticate
the user identified by the authcid AND verification of that
that this user can assume the identity represented by the
provided authzid or, if absent, associated with the authcid.

  Upon receipt of the message, the server will verify the presented
  (in the message) authentication identity (authcid) and password
  (passwd) with the system authentication database, and verify the
  authentication credentials permit the client to act as the (presented
  or derived) authorization identity.  If both steps succeed, the   
  user is authenticated.

  In this verification process, the presented authentication identity
  and password strings, as well as the database authentication identity
  and password strings, are to be prepared before being used in any
  comparison.  The server SHOULD prepare each string using the
  [SASLPrep] profile of the [StringPrep] algorithm.  The SASLprep
  preparation is recommended to improve the likelihood that comparisons
  behave in an expected manner.  It is not mandatory to allow the      
  server to employ other preparation algorithms (including none) as  
  necessary to interoperate with external systems.

We've also provided pseudo code to illustrate this.  Hence,
I disagree that the I-D is not clear as to what the verification
process is, where preparation should be used, and/or what
preparation algorithm should be used.

>The section reads:
>If you are saying that this SHALL is not mandatory,

This text says that server SHALL use the prepared form of the
authentication identity in deriving the authorization identity
when no authzid is provided.  The earlier text says:
  The server SHOULD prepare each string using the
  [SASLPrep] profile of the [StringPrep] algorithm. 

>or that it is

I don't think its misleading.

---

From: Simon Josefsson <[email-masked]>
Date: Thu, 24 Feb 2005 11:09:36 +0100

>   [SASLPrep] profile of the [StringPrep] algorithm.

What is unclear to me is whether following is permitted or not: Let's
say authcid is prepared using SASLprep (i.e., the SHOULD is followed).
The authzid is missing, so it is has to be derived from authcid.  In
this case, do the SHALL above require that the "default" authzid input
to DeriveAuthzid is SASLprep(authcid)?

As far as I can tell, the answer would be yes.  And I believe that is
unfortunate.

In my opinion, it should be permitted to let DeriveAuthzid receive
'authcid', so the function can prepare the string according to its own
application-specific preparation rules.

Another way to put it, is that the choice of preparation algorithm
used by a mechanism should not be forced upon all application
profiles.

Thanks,
Simon

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Thu, 24 Feb 2005 07:44:21 -0800

>say authcid is prepared using SASLprep (i.e., the SHOULD is followed).

So, the implementor has choose to use the SASLprep as the preparation
algorithm.

>The authzid is missing, so it is has to be derived from authcid.

It has to be derived from the prepared form of the authentication
identity, e.g., prepare(authcid) or, as SASLprep() was chosen as
the preparation algorithm, SASLprep(authcid).  (Note that this
is the same octet string as prepare(stored authentication identity,
hence the language "THE prepared representation" (in the I-D),
"THE prepared form" (in my comment).)

>In

As SASLprep was chosen as the preparation algorithm, yes.  But the implementor
could have chosen to use another preparation algorithm.  If it does so, then
it to consistently use that algorithm in the verification process.

>As far as I can tell, the answer would be yes.  And I believe that is

Aside from ranting further that it would be unfortunate if the authorization
identity given the user would depend on the details of the client implementation
the user choose, I ask you to provide an "for instance" which is not addressed
by selecting a different preparation algorithm for use in the verification
process.

>application-specific preparation rules.

The implementor is given plenty of rope (in the SHOULD use SASLprep).

>used by a mechanism should not be forced upon all application

Not sure what you mean by "profile".  I generally take that word
to refer to a particular kind of specification, you might be using to
refer to an implementation of a specification.

In the former case, see Jeffrey comments regarding the separation of
mechanisms and application protocols.  In the latter case, I again
note that implementors are free not to use SASLprep as PLAIN's
preparation algorithm.

Kurt

---

From: Sam Hartman <[email-masked]>
Date: Thu, 24 Feb 2005 13:52:06 -0500

Simon> "Kurt D. Zeilenga" <[email-masked]> writes:

    >>> The section reads:
    >>> 
    >>> When an empty authorization identity is provided, the server
    >>> SHALL derive the authorization identity from the prepared
    >>> representation of the provided authentication identity string.
    >>> This ensures that the derivation of different representations
    >>> of the authentication identity produce the same authorization
    >>> identity.
    >>> 
    >> when no authzid is provided.  The earlier text says: The server
    >> SHOULD prepare each string using the [SASLPrep] profile of the
    >> [StringPrep] algorithm.

    Simon> What is unclear to me is whether following is permitted or
    Simon> not: Let's say authcid is prepared using SASLprep (i.e.,
    Simon> the SHOULD is followed).  The authzid is missing, so it is
    Simon> has to be derived from authcid.  In this case, do the SHALL
    Simon> above require that the "default" authzid input to
    Simon> DeriveAuthzid is SASLprep(authcid)?

    Simon> As far as I can tell, the answer would be yes.  

I agree with Kurt and you that the answer is yes.

    Simon> And I
    Simon> believe that is unfortunate.

    Simon> In my opinion, it should be permitted to let DeriveAuthzid
    Simon> receive 'authcid', so the function can prepare the string
    Simon> according to its own application-specific preparation
    Simon> rules.
I think with moderate confidence that the working group explicitly
decided not to allow this.  I don't have a pointer to a discussion though.

I'm quite sure I don't want to allow this.  In particular it would
allow nonsensical behavior such as the following:

* the identity you authenticate as (or what password you need) is dependent on saslprep.
* The identity you act as is dependent on un-normalized Unicode.

In other words you're asking for rope that would allow the set of
privileges you end up having to depend on whether separate accent
characters are used in your login name, even though your password
cannot depend on this.

I see no advantage in offering such rope and significant
disadvantages.

    Simon> Another way to put it, is that the choice of preparation
    Simon> algorithm used by a mechanism should not be forced upon all
    Simon> application profiles.

Storngly disagree.  The authentication identity is in the namespace of
the mechanism; only the mechanism knows what type it is.  The
authorization identity is in the namespace of the application profile.
The application profile must not depend on the mechanism so it must
not say anything about the mapping from authentication identity to
authorization identity; that mapping is an implementation matter.  It
is not a matter for the mechanism spec or the application profile.
Doing anything else will violate typing rules.

--Sam

---

From: Tom Yu <[email-masked]>
Date: Fri, 25 Feb 2005 03:54:41 -0500

>>>>> "Sam" == Sam Hartman <[email-masked]> writes:

Sam> I agree with Kurt here.  I actually think Simon and perhaps the whole
Sam> discussion of this issue in the working group has missed a more
Sam> fundamental issue.  The authorization ID is not in the same namespace
Sam> or typespace as the authentication identity.  

I apologize for not replying to this discussion sooner.  It has taken
me some amount of time to unravel the issues in a satisfactory manner.
At this point I think that it is best to withdraw the document from
the IESG for further discussion in the working group.  There appear to
be some conceptual discrepancies between sasl-rfc2222bis and
sasl-plain.  Both documents could use some further discussion and
revision to remove conceptual ambiguity.  I make the following
observations:

* The pseudo-code in Section 4 of sasl-plain appears to me to be not
  normative; it probably should be clearly labeled as not normative.
  If it is intended to be normative, the use of SASLprep(...)
  conflicts with the "SHOULD" language in Section 2 regarding
  preparation of the presented strings.

* The pseudo-code in Section 4, in addition to the ensuing discussion,
  exhibits some confusion regarding the actions which belong in a SASL
  mechanism.  In particular, it is not clear whether the actions
  performed when receiving an empty authorization identity (authzid)
  are performed by the SASL mechanism or by the application server
  implementation.  Additionally, the mechanism description in Section
  2 exhibits similar confusion.

* Section 3.2 of sasl-rfc2222bis implies to me that the role of the
  SASL mechanism is to transmit the authorization identity from the
  client to the application server unchanged.  This suggests that the
  application server, not the SASL mechanism, is responsible for
  handling the empty authzid string, while sasl-plain can be
  interpreted as stating that the SASL PLAIN mechanism is responsible
  for producing a authzid string from the authentication identity when
  the authzid is an empty string.

Simon's points about authzid strings in sasl-plain leave me with the
impression that text in sasl-plain is sufficiently confusing to cause
implementation difficulties.  These difficulties arise from conceptual
ambiguity about the exact boundaries of the abstract interface to a
SASL mechanism.

I suggest that the working group discuss and arrive at a consensus
concerning the interface between a SASL mechanism and an application
protocol server implementation, and that sufficiently lucid text be
written to resolve the conceptual ambiguity.  For the time being,
sasl-plain should be withdrawn from the IESG, pending revision.

Are there any objections to this proposed course of action?

---Tom

---

From: Simon Josefsson <[email-masked]>
Date: Fri, 25 Feb 2005 10:56:52 +0100

> Are there any objections to this proposed course of action?

Not from me, although I sympathize with those who are concerned with
the time delay.  It is not entirely clear to me that my approach (move
all authzid handling to the application profile, including
preparation/derivation of a default authzid) is not conceptually
problematic in some other way.  The discussion has made me less sure
about my position.

One idea is to last call the core document at the same time as at
least one mechanism, since, if I recall correctly, the text regarding
authcid/authzid has been changed in the core document a few times.  It
may help to review the core document and one mechanism, for
consistency, at the same time.

Thanks,
Simon

---

From: Simon Josefsson <[email-masked]>
Date: Fri, 25 Feb 2005 11:07:16 +0100

Programmers may be helped in thinking about this issue by considering
an actual implementation.  There is one in:

http://josefsson.org/cgi-bin/viewcvs.cgi/gsasl/lib/plain/server.c?view=markup

I have applied a patch to make the implementation behave according to
the current document (i.e., the mechanism is responsible for
preparing/deriving the authzid).  The patch is straightforward, even
though the implications may not be:

http://josefsson.org/cgi-bin/viewcvs.cgi/gsasl/lib/plain/server.c?r1=1.22&r2=1.23&diff_format=l

I've done this to experiment with that approach.

(Naturally, I'm not saying there aren't other thinkos in that code.
Comments appreciated, of course.)

Thanks,
Simon

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Fri, 25 Feb 2005 08:29:26 -0800

>Are there any objections to this proposed course of action?

I do not object to this course of action.

I do have comment, intend to spark WG discussion.  I've trimmed
the Cc list so not to overload the IESG list with these discussions.

>I make the following observations:
>

I suggest replacing the statement to the top of the section with:
   This section provides pseudo-code illustrating the
   verification process (using hashed passwords and the SASLprep
   preparation function).  This section is not definitive.

>  2 exhibits similar confusion.

Note that the pseudo-code does not illustrate detail (nor does
Section 3 specify) the particulars of the derivation.  That is
purposely left to implementations.  What the pseudo-code does
illustrates (and the Section 3 specifies) is what representation
of the authentication identity the mechanism provides to the
derivation function.  Likewise, for the Authorize function.

One could simply add the following text to the end of the Section 4
to clarify this:
   Note that the details of the DeriveAuthzId and Authorize
   are not illustrated as they are not specified in the above
   specification.  The authentication identity provided to these
   functions by this mechanism is, as specified above, is a
   prepared representation.

>  application server, not the SASL mechanism,

The application server implements both the application protocol
and the SASL mechanism and hence is responsible for implementing
the application protocol specification, the SASL specification,
and the mechanism specification.  The question seems to be: which
specification is responsible for specify what.

>  is responsible for handling the empty authzid string,

The mechanism specification is responsible for specifying
the form of the authentication identity and how it is
verified.   The PLAIN specification does not detail how
the authorization identity is derived, it only prescribes
the form of the authentication identity it produces for
use in deriving the authorization identity.  It is quite
appropriate for mechanism to be clear in regards to
authentication identity forms.

I would argue that mechanism specifications SHOULD specify
how to produce a canonical representation of the authentication
identity or, at the very least, detail which representations are
to be considered equivalent.

>while sasl-plain can be

That's a stretch in my opinion.  PLAIN only states what it
produces for use in the derivation (and authorization)
and illustrates how these functions in the verification
process.

Note that the pseudo-code illustrates that no special action
(e.g., decoding) in regards to the authzid, as in some mechanisms.
For a mechanism transferred the authzid using base64, it would be
appropriate for the mechanism to illustrate that decoded authzid
is provided to the authorize function.  Hence, it is appropriate
for this pseudo-code to illustrate that no such decoding is done.

>ambiguity about the exact boundaries of the abstract interface to a

Which, I presume we agree, is largely a base specification issue.

>written to resolve the conceptual ambiguity.  

As noted above, a server implements multiple specifications.  While
I agree that we need to be more clear in our abstractions separating
mechanisms from application protocols (and whatever might be in between)
and responsibilities and restrictions placed upon specifications of
mechanisms and application protocols, we need to be careful to leave
actual interface boundaries within a implementation as implementation
details.

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Fri, 25 Feb 2005 08:45:47 -0800

At 01:56 AM 2/25/2005, Simon Josefsson wrote:
>the time delay.

This I-D has to wait for the base specification to catch up,
so pulling it back is likely not to cause any delay in its
publication.

>It is not entirely clear to me that my approach (move
>problematic in some other way.

Some handling of the authorization identity is mechanism specific.
For instance, a mechanism is free to encode the authorization
identity using base64.  It is appropriate for the mechanism
specification to be clear has to how its encoded for transfer.
The pseudo-code illustrates that no special decoding is needed.

The form of the authentication identity is mechanism specific,
as are details to which forms are to be considered equivalent.
It is appropriate for a mechanism specification to, as the
PLAIN I-D does, to specify and illustrate this.

It would be inappropriate for a mechanism specification to
otherwise detail how the authorization identity is derived,
or how authorization is done.  The PLAIN I-D does not otherwise
detail these functions.

Kurt

---

From: "Jeffrey I. Schiller" <[email-masked]>
Date: Fri, 11 Feb 2005 17:49:40 -0500

From Section 1:

                        -Jeff

---

From: Sam Hartman <[email-masked]>
Date: Mon, 14 Feb 2005 17:04:48 -0500

--Sam

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Tue, 15 Feb 2005 14:30:03 -0800

with:

-- Kurt

---

From: Rob Siemborski <[email-masked]>
Date: Thu, 17 Feb 2005 21:42:09 -0500 (EST)

^^^
You mean 'or', right?

-Rob

-----BEGIN GEEK CODE BLOCK----
Version: 3.12
------END GEEK CODE BLOCK-----

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 22 Feb 2005 14:55:24 +0100

RECOMMENDATIONS:

        if (authzid == NULL) {

Thanks,
Simon

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Tue, 22 Feb 2005 12:36:42 -0800

---

From: Sam Hartman <[email-masked]>
Date: Tue, 22 Feb 2005 16:10:55 -0500

---

From: Simon Josefsson <[email-masked]>
Date: Tue, 22 Feb 2005 22:12:36 +0100

Thanks,
Simon

---

From: Sam Hartman <[email-masked]>
Date: Tue, 22 Feb 2005 16:45:49 -0500

--Sam

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Tue, 22 Feb 2005 16:37:22 -0500

^^^^^^^^^^^^^^^^

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 23 Feb 2005 01:09:36 +0100

Thanks,
Simon

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 23 Feb 2005 01:01:45 +0100

Agreed.

Thanks,
Simon

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Tue, 22 Feb 2005 16:38:13 -0800

Kurt

---

From: Jeffrey Hutzelman <[email-masked]>
Date: Tue, 22 Feb 2005 19:57:35 -0500

-- Jeff

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 23 Feb 2005 10:51:39 +0100

Thanks,
Simon

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 23 Feb 2005 10:41:47 +0100

Thanks,
Simon

---

From: Sam Hartman <[email-masked]>
Date: Wed, 23 Feb 2005 09:41:38 -0500

--Sam

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Wed, 23 Feb 2005 07:01:45 -0800

---

From: Simon Josefsson <[email-masked]>
Date: Wed, 23 Feb 2005 16:24:45 +0100

Thanks,
Simon

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Wed, 23 Feb 2005 07:32:42 -0800

Kurt

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Wed, 23 Feb 2005 08:14:12 -0800

---

From: Simon Josefsson <[email-masked]>
Date: Thu, 24 Feb 2005 11:09:36 +0100

Thanks,
Simon

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Thu, 24 Feb 2005 07:44:21 -0800

Kurt

---

From: Sam Hartman <[email-masked]>
Date: Thu, 24 Feb 2005 13:52:06 -0500

Simon> And I

--Sam

---

From: Tom Yu <[email-masked]>
Date: Fri, 25 Feb 2005 03:54:41 -0500

---Tom

---

From: Simon Josefsson <[email-masked]>
Date: Fri, 25 Feb 2005 10:56:52 +0100

Thanks,
Simon

---

From: Simon Josefsson <[email-masked]>
Date: Fri, 25 Feb 2005 11:07:16 +0100

Thanks,
Simon

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Fri, 25 Feb 2005 08:29:26 -0800

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Fri, 25 Feb 2005 08:45:47 -0800

Kurt