Subject: Thoughts on the sasl plain authzid

From: Sam Hartman <[email-masked]>
Date: Sun, 27 Feb 2005 19:19:25 -0500

I find it helpful to think of things from a type matching standpoint.

The authcid is a mechanism-specific type and the authzid is an
application specific type.

If you have a mechanism mucking with authzid or an application mucknig
with authcid, then you are building the non-general knowledge into
either your mechanism or your application.  For a particular
implmentation that's OK, but we've decided in 2222bis that we will not
require that generally.  So if you are doing something that would
require all applications to know about an authcid or all
implementations of a mechanism to know about an authzid for a
particular application then you are going against 2222bis.  I think
the current text in plain probably crosses this line.

But somewhere you need a mapping from authcid_t to authzid_t to do the
default authzid logic.  How is that possible in a general framework?

I think that a general framework will need to have a
mechanism-independent form of authcids completely internal to the
framework.  So, the mechanism maps from authcid to frameworkid and
exports the frameworkid.  Then the application maps from frameworkid
to authzid.

In practice you'll probably do authorizations in terms of frameworkids
(particularly if they happen to be Windows sids or some general
concept like that) and so you'll only map authzids to frameworkids
when an explicit authzid is carried from the user to the server.

These are my thoughts at least for now.

--Sam

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Sun, 27 Feb 2005 20:26:26 -0800

>I find it helpful to think of things from a type matching standpoint.

Okay...

In the PLAIN mechanism, the authentication identities are of the
plain_authcid_t abstract type.  Values of plain_authcid_t may have
multiple possible Unicode string representations, each a value of
plain_authcid_representation_t (a UTF-8 encoded Unicode string).
While values of plain_authcid_representation_t are transferred by
the mechanism, these values are not used in the verification process
directly.  Instead the plain_authcid_representation_t value is to
be converted to a value of plain_authcid_t type.  SASLprep is the
recommended conversion function.

Likewise, in the LDAP application protocol, the authorization
identities are the ldap_authzid_t abstract type, a choice of the
ldap_dn_t and ldap_userid_t (and possibly other) abstract types.
Values of ldap_authzid_t may have multiple possible Unicode
string representations, each a value of the
ldap_authzid_representation_t (a UTF-8 encoded Unicode string).
While values of ldap_authzid_representation_t are transferred
by the mechanism, these values are not used in the verification
process directly.  Instead the ldap_authzid_representation value
is to be converted to a value of ldap_authzid_t type.

>either your mechanism or your application.

I assume s/application/application protocol/ here.

>For a particular
>particular application then you are going against 2222bis.

I assume s/application/application protocol/ here.
And, I think you are referring to specification of these.

For clarity, an implementation a SASL-enabled application protocol
must implement the application protocol specification, the
base SASL specification, and one or more mechanism specifications.

While an implementation might share code with other implementations,
how do share code between implementations is beyond the scope
of current SASL WG I-Ds.

>I think the current text in plain probably crosses this line.

I disagree.  The PLAIN I-D does not muck with the authzid.
It only is detailing how the mechanism specific wire representations
are to mapped to values of the mechanism's abstract authentication
identity type.

>default authzid logic.

Presently, all identity mapping is implementation specific.

>How is that possible in a general framework?

Not sure how you are using the term "general framework" here?
I assume you mean "SASL library", some code intended to be shared
between different implementations of the various SASL-enabled
application protocols.

>framework.

Or just pass a mechanism-dependent authcid form (not necessary
what used on the wire) through the SASL library.   I note this
as it may not be desirable to utilize shared mappings. 

>So, the mechanism maps from authcid to frameworkid and

Well, if I was designing the SASL library, I would require
each mechanism implementation to produce a canonical UTF-8
string representation of its authentication identity and
pass that, along with the name of the mechanism, to the
application protocol implementation for mapping to an
appropriate authzid.  (I'd pass the mechanism name as
PLAIN "joe" may not be same as say CRAM-MD5 "joe", or
in mechanism like DIGEST-MD5, may include realm information.)

>when an explicit authzid is carried from the user to the server.

In practice, I think its generally done in terms of non-canonical
mechanism-specific Unicode string representations, sometimes
mucked (*) by the framework (ugh).

---

From: Sam Hartman <[email-masked]>
Date: Mon, 28 Feb 2005 09:48:11 -0500

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

    Kurt> possibly other) abstract types.  Values of ldap_authzid_t
    Kurt> may have multiple possible Unicode string representations,
    Kurt> each a value of the ldap_authzid_representation_t (a UTF-8
    Kurt> encoded Unicode string).  

Agree up to here.

    Kurt> While values of
    Kurt> ldap_authzid_representation_t are transferred by the
    Kurt> mechanism, these values are not used in the verification
    Kurt> process directly.  

No, the mechanism may not actually transport unicode, although it
needs to be able to map to and from unicode.

I'm not sure this distiction matters for this discussion but it does
exist.

    >> If you have a mechanism mucking with authzid or an application
    >> mucknig with authcid, then you are building the non-general

No, I actually meant either application protocol or application here
and was focusing on application.

However my definition of application seems to be different than yours.
My basic argument is that the way we've constructed the plain document
is undesirable because it makes building SASL frameworks difficult.

So, by application I mean the part of the application that implements
the application protocol.  By framework I mean the part of the
implementation of SASL independent of mechanisms and applications--a
part of SASL mostly but not completely out of scope for this working
group.  I believe the only way in which this part of the
implementation is in scope for this working group is that we've
decided that such parts of an implementation need to be possible to
construct.  A mechanism is an implementation of a mechanism
specification.
    >> knowledge into either your mechanism or your application.

    Kurt> I assume s/application/application protocol/ here.

    >> For a particular implmentation that's OK, but we've decided in
    >> 2222bis that we will not require that generally.  So if you are
    >> doing something that would require all applications to know
    >> about an authcid or all implementations of a mechanism to know
    >> about an authzid for a particular application then you are
    >> going against 2222bis.

Again, not really.

    Kurt> I assume s/application/application protocol/ here.  And, I
    Kurt> think you are referring to specification of these.

    Kurt> For clarity, an implementation a SASL-enabled application
    Kurt> protocol must implement the application protocol
    Kurt> specification, the base SASL specification, and one or more
    Kurt> mechanism specifications.

I have provided alternate definitions because the definitions you
provide are not expressive enough for me to say what I wanted to say.
IN particular you did not distinguish the parts of an implementation.

    Kurt> While an implementation might share code with other
    Kurt> implementations, how do share code between implementations
    Kurt> is beyond the scope of current SASL WG I-Ds.

But the requirement that it be possible to do so is not.

    >> I think the current text in plain probably crosses this line.

    Kurt> I disagree.  The PLAIN I-D does not muck with the authzid.
    Kurt> It only is detailing how the mechanism specific wire
    Kurt> representations are to mapped to values of the mechanism's
    Kurt> abstract authentication identity type.

The concern I have is that the plain mechanism assumes there is some
single function that takes plain_authcid_t in and returns in the case
of LDAP ldap_authzid_t or ldap_authzid_rep_t depending on what level
you believe this function works at.  That is to say, an implementation
of plain is implied to have an application specific mapping.

I think that by this point our thinking has diverged enough that we
I'll let you respond to my clarifications of my very muddled original
thoughts before trying to finish responding to your original message.

--Sam

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Mon, 28 Feb 2005 08:34:51 -0800

>needs to be able to map to and from unicode.

The mechanism has to transfer the abstract value of the type.
It can encode that value as it pleases, as long as the encoding
preserves the abstract value.

>I'm not sure this distiction matters for this discussion but it does

The distinction I am trying to draw is between values of abstract
types and their representations.

However, as that doesn't seem to be working, let me try another
approach.

Consider a SASL mechanism PLAINprep which was much like PLAIN
except the client was required to prepare strings before
transfer.  Would have concerns than that the PLAINprep I-D was
passing this prepared string to the derive function and other
functions?  If its okay for PLAINprep I-D to provide a prepared authentication to these functions, why isn't it okay for PLAIN
to do the same?  Why does the difference in wire format between
PLAIN and PLAINprep matter?

>and was focusing on application.

I now think I understand how you are using the words "application"
and "framework".

But do actually think the boundaries between "application", "framework",
and "mechanism" implementations are going to aligned with the
specification boundaries?

Most current SASL frameworks do not hide details of mechanisms
from application implementations.   They could, but that would
likely require the SASL framework to under not only details of
the mechanisms, but details of application level protocols and
their implementations.

>is undesirable because it makes building SASL frameworks difficult.

I don't see how.  The work a mechanism implementation must do is
harder than before, it must prepare strings.  But all of this is
(properly) hidden from the framework and application implementations.
They only deal with prepared authentication identities.  Now if
we were to pass the unprepared authcid value in, the framework or
the application implementation would need to deal them (e.g.,
prepare this value before using it in comparison).

>the application protocol.

But, as previously discussed, this part will likely have knowledge
of the mechanism used and its particulars.

> By framework I mean the part of the
>group.

Well, what about a framework that provided a general identity mapping
facility.  That framework would need to know forms of authentication
and authorization identities used.

>I believe the only way in which this part of the
>construct.

There are many ways to divide implementations so that they can
share code.  Some are more feasible than others.

Personally, I think it infeasible for a framework to provide a
general identity facility.  I think it far more likely, as with
current SASL libraries I am familiar with, to push these issues
onto the "application" developer.

>A mechanism is an implementation of a mechanism specification.

I don't see how the PLAIN I-D precludes sharing of code
between implementations.

>you believe this function works at.

Is this the general presumption?

Doesn't GSSAPI I-D presume there is some single function that
takes a GSSAPI identity information and produces an appropriate
authorization identity?

Doesn't DIGEST-MD5 I-D presume there is some single function that
takes a DIGEST-MD5 identity information and produces an appropriate
authorization identity?

Doesn't EXTERNAL I-D presume there is some single function that
takes a EXTERNAL identity information and produces an appropriate
authorization identity?

Now, I guess I could I could have written:
        authzid = DeriveAuthzid("PLAIN", pAuthcid);
and, likewise,
        Authorize("PLAIN", pAuthcid, authzid)

That, at least at this level, implies a shared derived function.

But we need to pass the prepared form of the authenticate identity
in so that these functions need not have to implement the preparation
function.

>That is to say, an implementation

SASL, as a whole, relies on there being a facility for mapping
mechanism-specific identity forms to application-protocol
specific identity forms (and to implementation-specific
identity forms).

---

From: Sam Hartman <[email-masked]>
Date: Mon, 28 Feb 2005 13:02:03 -0500

Kurt> At 06:48 AM 2/28/2005, Sam Hartman wrote:
    >> I'm not sure this distiction matters for this discussion but it
    >> does exist.

    Kurt> The distinction I am trying to draw is between values of
    Kurt> abstract types and their representations.

    Kurt> However, as that doesn't seem to be working, let me try
    Kurt> another approach.

    Kurt> Consider a SASL mechanism PLAINprep which was much like
    Kurt> PLAIN except the client was required to prepare strings
    Kurt> before transfer.  Would have concerns than that the
    Kurt> PLAINprep I-D was passing this prepared string to the derive
    Kurt> function and other functions?  If its okay for PLAINprep I-D
    Kurt> to provide a prepared authentication to these functions, why
    Kurt> isn't it okay for PLAIN to do the same?  Why does the
    Kurt> difference in wire format between PLAIN and PLAINprep
    Kurt> matter?

I agree that plain must only provide a prepared authcid as output.

I have not complained about the fact that when deriving a default
authorization ID only the prepared form of the authentication ID is
used.  I'm complaining that the handling of the default authorization
ID is discussed in the mechanism spec and that people think you might
want to do it in the mechanism implementation.

    >> >> If you have a mechanism mucking with authzid or an
    >> application >> mucknig with authcid, then you are building the
    >> non-general
    >> 
    >> 
    >> 
    >> No, I actually meant either application protocol or application
    >> here and was focusing on application.

    Kurt> I now think I understand how you are using the words
    Kurt> "application" and "framework".

    Kurt> But do actually think the boundaries between "application",
    Kurt> "framework", and "mechanism" implementations are going to
    Kurt> aligned with the specification boundaries?

Yes.

    Kurt> Most current SASL frameworks do not hide details of
    Kurt> mechanisms from application implementations.  They could,
    Kurt> but that would likely require the SASL framework to under
    Kurt> not only details of the mechanisms, but details of
    Kurt> application level protocols and their implementations.

I think I disagree with you here.  I'd say that most current SASL
implementations other than Microsoft's SSPI (which isn't quite a SASL
implementation but is close enough for this discussion) do a bad job
of hiding mechanism details from the application because they have a
simplistic concept of authentication identity.

I certainly consider it a requirement that I be able to use a SASL
mechanism I wrote with an application that has never heard about that
SASL mechanism.  I consider it a requirement for operating systems
that their native SASL support works well with this usage.

There is some implementation work needed to get to this point.

    >> However my definition of application seems to be different than
    >> yours.  My basic argument is that the way we've constructed the
    >> plain document is undesirable because it makes building SASL
    >> frameworks difficult.

    Kurt> I don't see how.  The work a mechanism implementation must
    Kurt> do is harder than before, it must prepare strings.  But all
    Kurt> of this is (properly) hidden from the framework and
    Kurt> application implementations.  They only deal with prepared
    Kurt> authentication identities.  Now if we were to pass the
    Kurt> unprepared authcid value in, the framework or the
    Kurt> application implementation would need to deal them (e.g.,
    Kurt> prepare this value before using it in comparison).

I agree passing back unprepared strings would be problematic.

    >> So, by application I mean the part of the application that
    >> implements the application protocol.

    Kurt> But, as previously discussed, this part will likely have
    Kurt> knowledge of the mechanism used and its particulars.

Disagree as previous.

    >> By framework I mean the part of the implementation of SASL
    >> independent of mechanisms and applications--a part of SASL
    >> mostly but not completely out of scope for this working group.

    Kurt> Well, what about a framework that provided a general
    Kurt> identity mapping facility.  That framework would need to
    Kurt> know forms of authentication and authorization identities
    Kurt> used.

The application provides a mapping from authorization identities to
the generic form.  The mechanism provides mapping from authcids to the
generic form.

    >> I believe the only way in which this part of the implementation
    >> is in scope for this working group is that we've decided that
    >> such parts of an implementation need to be possible to
    >> construct.

    Kurt> There are many ways to divide implementations so that they
    Kurt> can share code.  Some are more feasible than others.

    Kurt> Personally, I think it infeasible for a framework to provide
    Kurt> a general identity facility.  I think it far more likely, as
    Kurt> with current SASL libraries I am familiar with, to push
    Kurt> these issues onto the "application" developer.

I consider this unacceptable.  I do not believe this is the goal of
general SASL implementations today although I agree that said
implementations have not done a great job of handling these
situations.

    Kurt> I don't see how the PLAIN I-D precludes sharing of code
    Kurt> between implementations.

It tends to require the application implementation to be aware of
mechanism details of the plain mechanism.

    >>  The concern I have is that the plain mechanism assumes there
    >> is some single function that takes plain_authcid_t in and
    >> returns in the case of LDAP ldap_authzid_t or
    >> ldap_authzid_rep_t depending on what level you believe this
    >> function works at.

    Kurt> Is this the general presumption?

Perhaps.  I'm arguing that this presumption is wrong.  Simon's
implementation difficulties started me thinking and then I started
looking at whether we had divided things reasonably.

I think that we have in fact divided things incorrectly.  I believe
that mechanisms specifications should output an abstract authcid and
an abstract authzid+.  The authzid+ is either an authzid as specified
by the client or and indication that a default authzid should be
derived from the authcid.  I.E. the mechanism and the mechanism spec
should not do the work of deriving the authzid; they should leave this
up to the application or framework as appropriate.

    Kurt> Doesn't GSSAPI I-D presume there is some single function
    Kurt> that takes a GSSAPI identity information and produces an
    Kurt> appropriate authorization identity?

This is an excellent example of why I don't think this belongs in a
mechanism implementation.  Thinking about all the work we're doing
with naming in kitten, this seems clearly the wrong place for that
step in GSSAPI.

--Sam

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Mon, 28 Feb 2005 10:41:29 -0800

>simplistic concept of authentication identity.

I argue its because the isn't a unified identity space for the
Internet, and frankly, I don't think there ever will be one.

>SASL mechanism.

I don't see SASL as being able to met that requirement
as the SASL framework doesn't provide a unified identity space
across all mechanisms and application-level protocols.

>I consider it a requirement for operating systems
>the generic form.  The mechanism provides mapping from authcids to the  generic form.

What form is that?

>mechanism details of the plain mechanism.

That's SASL.

>Perhaps.  I'm arguing that this presumption is wrong.

I argue that the presumption is what it is.

>Simon's
>derived from the authcid.

Er, which is what the current pseudo-code illustrates.
The DeriveAuthzid and Authorize functions are not provided by
the mechanism implementation, they are provided by the framework
or application.  Would use of function pointers in the pseudo-code make
this more clear?  Or maybe just comment to say that functions are
detailed here as they are provided by the application or framework
codes.  Of course, these codes are still dependent on the mechanism
specific authentication identity abstractions (and their
implementations dependent on representations used in the
mechanism implementation).

That is, none of this would change the fact that SASL-enabled
applications (or their frameworks they use) have to deal with
mechanism (and mechanism implementation) details.

>I.E. the mechanism and the mechanism spec

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Mon, 28 Feb 2005 11:03:43 -0800

At 10:02 AM 2/28/2005, Sam Hartman wrote:
> I'm complaining that the handling of the default authorization

Are you complaining about this text?
   "... and verify the authentication credentials permit the client
   to act as the (presented or derived) authorization identity."

or just the pseudo code?  If just the latter, I note that the
code is illustrating the above text.  That is, I would think
that if you have a problem with the pseudo code, you'd have
a problem with the text.

Kurt

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Sun, 27 Feb 2005 20:26:26 -0800

Okay...

---

From: Sam Hartman <[email-masked]>
Date: Mon, 28 Feb 2005 09:48:11 -0500

Agree up to here.

    Kurt> While values of

Again, not really.

--Sam

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Mon, 28 Feb 2005 08:34:51 -0800

---

From: Sam Hartman <[email-masked]>
Date: Mon, 28 Feb 2005 13:02:03 -0500

Yes.

Disagree as previous.

--Sam

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Mon, 28 Feb 2005 10:41:29 -0800

What form is that?

That's SASL.

---

From: "Kurt D. Zeilenga" <[email-masked]>
Date: Mon, 28 Feb 2005 11:03:43 -0800

Kurt