Subject: Pluggable GSSAPI

From: "David Leonard" <[email-masked]>
Date: Fri, 13 Apr 2007 00:12:06 +1000

Hello, Kitten group.

I'd like to let you know about an experimental project we have, PGSSAPI, 
which is a dispatching library (a lot like mechglue) but operates 
primarily on shared libraries that expose a GSSAPI (really an ABI).

The problem this tries to solve is when you have applications pre-linked 
with existing GSS libraries and you want to make use of other security 
libraries that aren't mechglue compatible. It's intended for use either 
by operating system vendors who want their userland tools to be able to 
be reconfigured with different gss providers, and/or for application 
writers who want to configure the gss provider through their 
application's native config.

Some of the design goals were to support legacy use of the GSSAPI v1, 
map between v1 callers and v2 implementations, transparent memory 
management and spnego. I also added a ioctl-like call intended to be 
used for developing and experimenting with extensions to the GSSAPI.

Some of the problems I envisage are how to handle the bypassing of gss 
(especially as there is no krb5 C api standard), display_status state 
between threads.

This is a project in early stages, and I would be interested in comments 
on the idea. More information is at http://rc.vintela.com/topics/pgssapi/

David Leonard

_______________________________________________
Kitten mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/kitten

---

From: Michael B Allen <[email-masked]>
Date: Thu, 12 Apr 2007 13:29:27 -0400

On Fri, 13 Apr 2007 00:12:06 +1000

> on the idea. More information is at http://rc.vintela.com/topics/pgssapi/

Hi David,

Do you have any documentation that describes the technical aspects of
your approach (e.g. how symbols are loaded, specific linking requirements,
etc). From browsing the code and looking at the page you provided I could
not find anything technical. The design.xml file looks interesting but
apparently I do not have xml2html.

Mike

-- 
Michael B Allen
PHP Active Directory Kerberos SSO
http://www.ioplex.com/

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 12 Apr 2007 13:24:33 -0500

> apparently I do not have xml2html.

Maybe it's in the xml2rfc DTD?

http://xml.resource.org/

---

From: Nicolas Williams <[email-masked]>
Date: Thu, 12 Apr 2007 17:13:23 -0500

I recall someone from vintela wishing that the GSS functions took an
additional argument corresponding to, effectively, what krb5_context is
in the MIT and Heimdal krb5 APIs: an object representing application-
specific settings that don't relate directly to other GSS objects.

And we've all lamented C bindings issues like gss_buffer_desc (which, by
having its layout and size being part of the API, and thus the ABI,
makes it hard to track what allocator allocated what buffers).

Is that what PGSSAPI is about?

Nico
--

---

From: Michael B Allen <[email-masked]>
Date: Thu, 12 Apr 2007 21:35:54 -0400

On Thu, 12 Apr 2007 17:13:23 -0500

> makes it hard to track what allocator allocated what buffers).

An application context (as opposed to the existing authentication context)
would help in a number of ways. Making an implementation thread safe
would be more elegant because the lock could be associated with the
application context instead of being a global. Higher level code could
be more efficient because the application context could be embedded
in the higher level code's context. As you mention, allocation could
be abstracted.

My personal belief is that every major inteface should have an application
context. Think about the possibilites for a stdlib malloc interface that
accepted an application context. The fact that it doesn't have one is
a design flaw IMO.

Mike

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 13 Apr 2007 12:31:39 -0500

> in the higher level code's context. As you mention, allocation could

I'm not sure that an app context here is needed to simplify thread
safety because in general the GSS-API already has the right kind of
objects for fine-grained locking (i.e., you can associate locks with
NAME, CREDENTIAL HANDLE and SECURITY CONTEXT objects).  Never mind the
global locking that you see in our mech_krb5 implementation -- that's
not a result of the GSS-API's design.

> accepted an application context. The fact that it doesn't have one is

I agree that complex interfaces should have app contexts.

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 13 Apr 2007 12:35:42 -0500

OK, so I looked at the design.xml document.  I see that you have an
ioctl-like interface for specifying certain application preferences
(like which provider to use for a given mechanism, where there are
multiple options).

This is good, but I'm afraid that it's not good enough.

Consider a situation where an application uses the GSS-API and some
library in the same application independently uses the GSS-API.  Without
an "application context"-like object as an argument to the GSS functions
the only way to resolve conflicts between these two consumers is to walk
the call stack to find out which consumer is making the calls.

This gets worse if the application and the library might share some GSS
objects.

IMO your approach is fine for many situations, but not general enough.

I wonder if for the GSS-APIv3 we should not just bite the bullet and add
arguments to existing GSSv2 functions, and rename them to gss3_*.

Nico
--

---

From: Michael B Allen <[email-masked]>
Date: Fri, 13 Apr 2007 14:49:33 -0400

On Fri, 13 Apr 2007 12:31:39 -0500

> not a result of the GSS-API's design.

I'd be willing to wager that having one lock on the app context for
protecting everything would not only be simpler but more efficient
because there are fewer locks and fewer locking calls which improves
cache locality and reduces syscalls. Of course you must make sure that you
unlock while blocking (e.g. to perform I/O with the filesystem or network)
[1].

Also, I think the global locking in mech_krb5 *is* the result of GSS-API's
design because mechglue's API is directly derived from GSS-API's. If
GSS-API had an app context, mechglue would have one and the lock would
not need to be global. Or did I not understand what you mean?

Mike

[1] I am not certain that this technique is more efficient on systems
with many CPUs and high numbers of GSS-API calls.

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 13 Apr 2007 14:06:45 -0500

> unlock while blocking (e.g. to perform I/O with the filesystem or network)

It's a trade-off in granularity.  A big lock per-app context pushes
responsibility for synchronization to the application (this is the model
in the MIT krb5 API since thread-safety was added).  A per-object lock
pushes responsibility for synchronization into the framework and the
providers, which makes it easier for the application developer.  Finer
grained locking gives the developer more freedom.

This has real world impact in protocols like NFSv4.  A busy multi-
threaded client that does not support fine-grained locking will either
serialize GSS per-message function calls and leave performance on the
table, or it will setup multiple GSS-API security contexts, one per-
thread, consuming more memory and reducing performance on the server (by
cooling L2 caches).

> not need to be global. Or did I not understand what you mean?

Absolutely not.

The global locking in mech_krb5 is the result of something else
entirely: the MIT source from which it was derived was not thread-safe
at the time (late 90s), so the simplest way to make it thread-safe (but
not thread-hot) was to throw in a big lock.

> with many CPUs and high numbers of GSS-API calls.

It really depends on the protocol.  In the case of NFSv4 what you
propose is less than optimal.

---

From: Michael B Allen <[email-masked]>
Date: Fri, 13 Apr 2007 16:06:05 -0400

On Fri, 13 Apr 2007 14:06:45 -0500

> thread, consuming more memory and reducing performance on the server (by

You don't have to serialize GSS calls. Just unlock "The Big Lock" while
you call anything that can block (e.g. krb5_cc_* functions). I don't
see why you can't reach full CPU utilization if you never hold the lock
while blocking.

But I think we're probably OT now so I'll give it a rest.

> not thread-hot) was to throw in a big lock.

Ok. Well I'm not terribly familiar with the MIT implementation. We use
Heimdal and it (at least 0.7) uses a number of globals for GSS-API objects
(although I guess I can't say the Heimdal authors wouldn't continue to
use globals if there were an app context).

Mike

---

From: Nicolas Williams <[email-masked]>
Date: Fri, 13 Apr 2007 15:10:09 -0500

> see why you can't reach full CPU utilization if you never hold the lock

Big lock -> serialize.  That's why we want to avoid big locks in
general.

> But I think we're probably OT now so I'll give it a rest.

Yes, we are way OT.

> use globals if there were an app context).

No, you can, but there is a good point here: thread-safety for the
GSS-APIv2uX couldn't rely on an app context, so implementors would
either have to use big locks or per-object locks.  But if we were to
pursue a GSS-APIv3 which has room for an app context argument then we'd
have to pick a model for thread-safety.

Nico
--

---

From: "David Leonard" <[email-masked]>
Date: Tue, 17 Apr 2007 15:56:18 +1000

Sorry for the delay. I'll reply to a couple of question below:

>apparently I do not have xml2html.
I have put up a text version of design.xml at 
http://rc.vintela.com/pub/rc/pgssapi/

The specific symbols loaded are not documented (but see pgss-dlprov.c 
for the current list). The intent is to match what standard C 
development tools would do on each platform assuming a direct 
implementation of the GSSAPI and shared libraries. So far, dlsym() or an 
equivalent finds function pointers in shared libraries or equivalent, 
and PGSS casts them into function pointer types derived from the RFC(s). 
If the library relies on the caller using a special header file, then it 
probably won't work; so PGSS may have to be taught how to handle some cases.

>specific settings that don't relate directly to other GSS objects.

Yes, he also started this PGSSAPI project :)

>makes it hard to track what allocator allocated what buffers).

Just as painful is the hidden last-error context maintained for 
gss_display_status().

>Is that what PGSSAPI is about?
No.. PGSSAPI is mostly about allowing you to decouple your apps from 
particular GSS implementation libraries.
It has a secondary goal of multiplexing those security libraries, and it 
is there that an application context would make this a lot easier to manage.

>IMO your approach is fine for many situations, but not general enough.
You're absolutely right: like the rest of the GSSAPI, a single 
application is assumed. This matches the goal of this library is to fit 
existing GSS applications.
Even if it was changed to provide an application context, it couldn't be 
passed to nor made use of by gss_accept_sec_context(), for example.
pgss_ctl() talks to mechanisms, and mechanisms are currently ignorant of 
app contexts.

Aside from that, this kind of trapdoor for talking to mechanism 
implementation is missing from the GSSAPI. Instead what happens now is 
we use functions like gss_krb5_get_ccache(). If we're talking about 
future GSSv3 design, then I'd like to see this idea some way of sending 
messages from the application to the mechanism while not exceeding the 
API would be useful. It doesn't have to be ioctl-like.

>arguments to existing GSSv2 functions, and rename them to gss3_*.
I'd like to see a more object-oriented approach applied to any gssapiv3. 
By this, I mean ensure every function is thought of in terms of an 
operation on a context.
Not only would this lead to consistency between the OO language mappings 
(eg java, python) but then w wouldn't have the GSS_display_status() 
madness. Maybe security contexts could be created in an initial invalid 
state, rather than having invalidity managed as both null pointers and 
half-formed contexts. And throw out minor_status while you're there :)

Figuring out the mapping between a gssapiv3 application and a gssapiv2 
implementation (and vice versa) will be interesting, and could be part 
of pgss.

-- 
David Leonard
Resource Central software engineer
Quest Software; 303 Adelaide St, Brisbane, Australia; www.quest.com
Phone: (US) +1 801 655 2755  (AU) +61 7 3023 5133

---

From: Nicolas Williams <[email-masked]>
Date: Tue, 17 Apr 2007 09:41:55 -0500

> By this, I mean ensure every function is thought of in terms of an 

Actually, the abstract GSS-API is object-oriented enough as it is -- see
the Java bindings.  Adding an application context is not OO.

> (eg java, python) but then w wouldn't have the GSS_display_status() 

The GSS_Display_status() problem is not about application contexts,
though those would solv eit.  The problem with GSS_Display_status() is
that minor_status in all the function calls is a small integer output
parameter (OM_uint32 * in the C bindings) whereas it should instead be
an opaque object output parameter.

> half-formed contexts. And throw out minor_status while you're there :)

That's been one thought (and it would allow for setting flags on the
acceptor side while still re-using GSS_Accept_sec_context() as it is).
But it's not comprehensive.

> implementation (and vice versa) will be interesting, and could be part 

I think such a mapping should be quite feasible -- that is, a GSSv3
mechglue should be able to use mechanisms implemented with a GSSv2
interface without much trouble.

Is this worth doing?  Or is it better to patch up the GSSv2 APIs and
muddle throguh?

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 30 Apr 2007 00:02:32 -0500

Hmmm, it strikes me that we already have a pointer argument in every GSS
call in the C bindings.  It's the OM_uint32 *minor_status argument.

Suppose that we added functions for associating/dissassociating
application contexts with/from minor_status pointer values?

Compatibility would be preserved: minor_status would remain a pointer to
OM_uint32 that can be safely dereferenced only to access an OM_uint32
value.  And we'd no longer ened to entertain adding new versions of all
the GSSv2 C bindings functions just to add an application context
parameter -- we already have one we can use.

Also, this would solve the composite minor_status code problem for
pseudo-mechanisms like SPNEGO: if there's an app context associated with
the minor_status pointer parameter to a routine with comlex minor status
codes, then save the complex error information in the app context and
then retrieve it again in gss_display_status().

Something like:

OM_uint32 gss_make_app_context(OM_uint32 *minor_status);
OM_uint32 gss_release_app_context(OM_uint32 *minor_status);
OM_unit32 gss_set_app_context_attribute(OM_uint32 *minor_status,
		const char *attr, const gss_buffer_t value);
OM_unit32 gss_get_app_context_attribute(OM_uint32 *minor_status,
		const char *attr, gss_buffer_t value);

Comments?

Nico
--

---

From: Michael B Allen <[email-masked]>
Date: Mon, 30 Apr 2007 11:18:22 -0400

On Mon, 30 Apr 2007 00:02:32 -0500

> application contexts with/from minor_status pointer values?

Actually the more I think about this (you're going to hate this)
I think everything should be pushed into one context. Merge what
is now the authentication context and the new concept of an app
context into one context that is initialized up-front with a call to
"gss3_context_init". Then it can be used to set "params" before calling
the usual gss functions.

For example, a gss3_accept_sec_context call might look like the following:

  ret = gss3_context_init(&gssctx);
  if (ret == GSS3_S_COMPLETE) {
      ret = gss3_set_param(gssctx, GSS3_C_ACCEPTOR_CRED, verifier_cred_handle);
      if (ret) {
          ret = gss3_get_param(gssctx, GSS3_C_MINOR_STATUS, &minor);
      } else {
          do {
              read_token(input, input_token);
              ret = gss3_accept_sec_context(gssctx, input_token, output_token);
              write_token(output, output_token);
          } while (ret == GSS3_S_CONTINUE_NEEDED);

          if (ret == GSS3_S_COMPLETE) {
              ret = gss3_get_param(gssctx, GSS3_C_DELEGATED_CRED, &deleg);
              ...

Now the accept_sec_context has been reduced to only accepting and
producing buffers. User's only need to set or get the parameters that
they are concerned with. This is much cleaner and simpler IMO.

Mike

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 30 Apr 2007 11:26:59 -0500

> they are concerned with. This is much cleaner and simpler IMO.

But here's the thing: by stealing the OM_uint32 *minor_context parameter
we get what you want, what David wants and a fixed gss_display_status(),
ALL without changing function signatures and without having to change
any application code that doesn't need these features.

Yes, it's a bit of a hack to associate some contextual object with a
OM_uint32 * value, but it's not terrible, and the price (backwards
compat) is right: I'd rather avoid redoing the whole API if we can.

Nico
--

---

From: Michael B Allen <[email-masked]>
Date: Mon, 30 Apr 2007 13:56:58 -0400

On Mon, 30 Apr 2007 11:26:59 -0500

> compat) is right: I'd rather avoid redoing the whole API if we can.

Nico,

The API illustrated in the concept code above is clearly a "redo".

I told you you would hate it :->

Mike

---

From: Tom Yu <[email-masked]>
Date: Mon, 30 Apr 2007 14:37:58 -0400

>>>>> "Nico" == Nicolas Williams <[email-masked]> writes:

Nico> But here's the thing: by stealing the OM_uint32 *minor_context parameter
Nico> we get what you want, what David wants and a fixed gss_display_status(),
Nico> ALL without changing function signatures and without having to change
Nico> any application code that doesn't need these features.

I'm not sure you can guarantee that a caller will always pass the same
pointer in as a minor_context parameter, nor that the caller will
never alter the value pointed to.

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 30 Apr 2007 13:58:11 -0500

> never alter the value pointed to.

No, you can't -- but you can guarantee that the caller who would
associate an app context with minor_status values would.

---

From: Martin Rex <[email-masked]>
Date: Mon, 30 Apr 2007 22:12:32 +0200 (MEST)

YUCK, and I believe it will not work.

minor_status in the C-Bindings has always been a OM_uint32.
Since in C a function can only have a single return value and
that is used for the OM_uint32 major_status, therefore it is
necessary to use a function argument to supply the (OM_uint32)
buffer for returning the value.

> any application code that doesn't need these features.

That is obviously wrong.  the minor_status value that should be
translated into text in an input parameter to gss_display_status,
namely "status_value", and therefore it is passed as an OM_uint32 by value,
and *NOT* by reference.

The minor_status that is passed by reference into gss_display_status
is function return parameter of gss_display_status to report
translation errors from within gss_display_status, *NOT* the value
that is to be translated into text!

On Mon, Apr 30, 2007 at 11:18:22AM -0400, Michael B Allen wrote:
= > 
= > Suppose that we added functions for associating/dissassociating
= > application contexts with/from minor_status pointer values?
= 
= Actually the more I think about this (you're going to hate this)
= I think everything should be pushed into one context. Merge what
= is now the authentication context and the new concept of an app
= context into one context that is initialized up-front with a call to
= "gss3_context_init". Then it can be used to set "params" before calling
= the usual gss functions.
= 
= For example, a gss3_accept_sec_context call might look like the following:
= 
=   ret = gss3_context_init(&gssctx);
=   if (ret == GSS3_S_COMPLETE) {
=       ret = gss3_set_param(gssctx, GSS3_C_ACCEPTOR_CRED, verifier_cred_handle);
=       if (ret) {
=           ret = gss3_get_param(gssctx, GSS3_C_MINOR_STATUS, &minor);
=       } else {
=           do {
=               read_token(input, input_token);
=               ret = gss3_accept_sec_context(gssctx, input_token, output_token);
=               write_token(output, output_token);
=           } while (ret == GSS3_S_CONTINUE_NEEDED);
= 
=           if (ret == GSS3_S_COMPLETE) {
=               ret = gss3_get_param(gssctx, GSS3_C_DELEGATED_CRED, &deleg);
=               ...
= 
= Now the accept_sec_context has been reduced to only accepting and
= producing buffers. User's only need to set or get the parameters that
= they are concerned with. This is much cleaner and simpler IMO.

You're forgetting the context attributes retured from accept_sec_context
plus the name of the authenticated peer/initiator, and also the
input context attributes that are missing in GSS-API v2 and have been
asked for.

To me your approach looks like it suffers an "object orientation challenge",
results in more and less readable code and is usually the preferred approach
of those that don't want to spent time on thinking ahead.

I don't know what the real pupose of the gss_ctx here is.
It is certainly overkill like this if the only purpose is to
deal with minor_status values from different mechanisms.

What about gss_acquire_cred, gss_import_name, gss_export_name,
gss_canonicalize_name, gss_compare_name and the others, do they also
need a gss_ctx in your model?  Can credentials or names created
with gss_ctx a be used with gss_ctx b?  What about full duplex
operation for message protection on a security context?

-Martin

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 30 Apr 2007 15:12:15 -0500

> minor_status in the C-Bindings has always been a OM_uint32.

I did not propose changing it!

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 30 Apr 2007 15:16:27 -0500

> namely "status_value", and therefore it is passed as an OM_uint32 by value,

It's not obviously wrong.  Mechanisms like SPNEGO have error display
strings, and therefore minor status codes, that depend on other
mechanisms, and so these are dynamic -- SPNEGO implementations have to
allocate their minor_status values at runtime or lose information.

Once you start going down that route what I propose becomes obvious.

Note, once more, that I don't propose changing the type of minor_status,
or that GSS functions not put actual minor status codes in there, nor
that it be possible to case minor_status OM_uint32 * values to any other
type.

Nico
--

---

From: Martin Rex <[email-masked]>
Date: Mon, 30 Apr 2007 22:38:07 +0200 (MEST)

> that it be possible to case minor_status OM_uint32 * values to any other

Personally, I conider SPNEGO to be of _EXTREMELY_ limited use,
and sometimes just as a useless overhead (WWW-Autheticate: Negotiate).

A much more significant problem than the limited minor_status
numberspace is the namespace problem, because it directly and
significantly affects the entire security.

The error code numberspace issue is fairly common and can usually
be dealt with.  Microsoft Windows comes with a huge number of
independent APIs, but still Microsoft managed to fit most of them
into a single DWORD GetLastError() number space.
In my gsskrb5 wrapper for Microsoft's Kerberos SSP I have a number
of different sources from which I combine/fold error numbers
into a single OM_uint32.   Errors local to my code (e.g. parsing
tokens or object handle consistency), errors from ANSI-C functions,
error from "regular" Win32-API functions (e.g. LoadLibrary), errors
from WinSock functions (e.g. gethostbyname), errors from
SSPI functions.

The reason why SPNEGO does not break horribly in the Microsoft
environment in spite of the distinct name spaces between
NTLM and Kerberos SSPs is because with NTLM the target name
is completely ignored anyway and on the acceptor side Microsoft
doesn't use the name-based authentication provided by the
SSP, rather it uses the impersonation and delegation
through SSPI functions.

I it will much harder for Unix-based SPNEGO approaches to solve
the namespace issue than to find a workable approach to the 
error number space problem  (unless they also dump the
entire target-authentication and switch from name-based
authentication for the acceptor to something opaque as well).

-Martin

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 30 Apr 2007 15:59:06 -0500

On Mon, Apr 30, 2007 at 10:38:07PM +0200, Martin Rex wrote:
> [...]

But you didn't answer the [unstated, granted] question: is there a
fundamental problem with this approach?

I think the answer is obviously "no."  It doesn't break compatibility at
the binary nor source levels, but it does solve David's problem more
comprehensively than the previous proposal.

 - Backwards compatible with existing binaries?  Check.
 - Backwards compatible at the source level?  Check.
 - Does it allow for the things that David Leonard and Vintella want?
   Check (David agrees in private e-mail).
 - Does it solve the pseudo-mechanism composite/dynamic minor_status
   code issue?  Check.

Nico
--

---

From: Martin Rex <[email-masked]>
Date: Mon, 30 Apr 2007 23:51:41 +0200 (MEST)

>  - Does it solve the pseudo-mechanism composite/dynamic minor_status

Huh?

We are still talking about the minor_status, aren't we?

The OM_uint32 * minor_status values are pointers created and
supplied by the application caller, and they're likely to be
local and distinct for each call to gssapi.

Some application callers will visualize the numeric value directly,
so there is no point in the mechanism associating any information
with particular pointer values.

The rest will pass the minor_status to gss_display_status()
by value, so that the gssapi mechanism has no benefit whatsoever
from memorizing any previous random and unrelated pointer values
when trying to translate the OM_uint32 integer passed into
gss_display_status().

-Martin

---

From: Michael B Allen <[email-masked]>
Date: Mon, 30 Apr 2007 18:11:05 -0400

On Mon, 30 Apr 2007 22:12:32 +0200 (MEST)
> input context attributes that are missing in GSS-API v2 and have been

All of that would be handled through gss3_{set,get}_param. The api would
be like how the ldap_* api sets and gets options.

> need a gss_ctx in your model?

Yes. As a general rule everything but the most trivial functions should
have a context (e.g. like the krb5_* api).

> Can credentials or names created with gss_ctx a be used with gss_ctx b?

I can't think of a reason why not but the object would need to be freed
with the context from which it was allocated. Again krb5_* and ldap_*
apis illustrate that.

> What about full duplex operation for message protection on a security
> context?

Never heard of that but I'm not suggested that the procedures or semantics
of any functions or parameters be changed. I'm only suggesting that there
be a single context in place of the current authentication context and
proposed application context and that the API I propose take advantage
of that context by simplifying some parameter management.

Mike

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 30 Apr 2007 17:28:36 -0500

> We are still talking about the minor_status, aren't we?

Yes, and evidently you did not read what I wrote closely enough :)

> local and distinct for each call to gssapi.

Indeed.

In the new model an app that wants this new feature (but not other
apps) must have OM_uint32 * minor_status values that are malloc()ed, ...

...or, if the app wants to use a pointer to a OM_uint32 variable (which
would not be recommended) then it would have to remain in scope across
all uses of that variable with all GSS functions for whatever the app is
doing.

> with particular pointer values.

Minor status codes are NOT defined!  Applications cannot interpret them
deirectly -- they MUST call gss_display_status() in order to interpret
them.

But it wouldn't matter if they were defined.  Apps that want this new
feature would not interpret OM_uint32 minor_status values directly.

> when trying to translate the OM_uint32 integer passed into

Oh, but it does.  It can provide more context than simple integers can,
and when the app context object is destroyed the mechanism can also
release such additional context (whereas pseudo-mechs today cannot
because their minor status codes may be dynamically established and the
mechs have no idea when they will no longer be referenced).

And then there are David's uses for this scheme (see the post that
started this thread).

Nico
--

---

From: Tom Yu <[email-masked]>
Date: Mon, 30 Apr 2007 19:55:27 -0400

>>>>> "Nico" == Nicolas Williams <[email-masked]> writes:

Nico> Oh, but it does.  It can provide more context than simple integers can,
Nico> and when the app context object is destroyed the mechanism can also
Nico> release such additional context (whereas pseudo-mechs today cannot
Nico> because their minor status codes may be dynamically established and the
Nico> mechs have no idea when they will no longer be referenced).

That reminds me of a potentially very important question:

Do the GSS-API C Bindings require that a minor_status value be valid
for multiple invocation cycles of gss_display_status()?  "Invocation
cycle" means looping through gss_display_status() until the value
pointed to by message_context reaches zero.

The answer to this question determines whether a mechanism has a good
way to decide when to garbage-collect dynamic state associated with a
minor_status value.

---Tom

---

From: Martin Rex <[email-masked]>
Date: Tue, 1 May 2007 02:32:35 +0200 (MEST)

> feature would not interpret OM_uint32 minor_status values directly.

Applications hardly interpret them.  Portable apps certainly
will never try.  The will only visualize to a user.

Most apps will special case very few of the major_status values,
simply because there will not be programmatic recovery available
anyway--instead user intervention or even admin intervention required.

> mechs have no idea when they will no longer be referenced).

I'm sorry, but I completely fail to understand what you are
referring to.

If this is about GSS-API v3 with a backwards-incompatible change
to the function signature of gss_display_status, then we should
probably redesign it anyway.

If this is about a GSS-API v2 backwards compatible change, then
this possibility simply doesn't exist.  The input parameter
to gss_display_status is a 32-bit integer scalar type, there
simply is no pointer value.  The mechanism has no means to
recognize relation to previous failed GSS-API calls other
than by the numeric value of that 32-bit integer--you simply
cannot improve it beyond what is there today.

I have seen gssapi mechanism that keep additional state around
for failed gssapi calls in a pretty useful and fairly robust
fashion.

They keep a small ring buffer of dynamically allocated failure messages
for failed gssapi calls and they related by minor_status code only.
If one cares for thread-safety, using a small ring buffer per-thread
might do for that.  Cleaning up dynamic thread local storage
can be difficult at times.  With Microsoft's broken approach
it is impossible for statically linked libraries, and difficult
for DLLs that might get loaded&unloaded several times during
process lifetime and unsynchronized with thread creation/deletion.
With POSIX threads it works fine if you can use free() as the
destructor function (otherwise you get problems if a shared library
get dlclose()d before the thread terminates).

But compared to the authentication problem from incompatible
namespaces of arbitrary gssapi mechanism I consider the
minor_status issue almost a trivial issue.

-Martin

---

From: Martin Rex <[email-masked]>
Date: Tue, 1 May 2007 02:54:52 +0200 (MEST)

> pointed to by message_context reaches zero.

A very similar question was asked about all the various input
parameters to gss_accept_sec_context() and gss_init_sec_context()
which are iteration calls in *ALL* language bindings,
and the answer was:
  - all input parameters MUST be the same for all iteration calls,
  - all modify parameters MUST ONLY be modified by the gssapi mechanism
    on iteration calls
  - all opaque and static output parameters MUST be the same for all
    iteration calls, (i.e. mech_oid, deleg_cred and src_name)
  - no restriction for the token paramters, they're specific
    to each individual call

> way to decide when to garbage-collect dynamic state associated with a

While a minor_status text containing dynamic situation-specific information
might be helpful in a small number of situations, it is quite possible
for gssapi mechanisms to get along just fine with a 32-bit flat integer
and no dynamic resources whatsoever.
 
With GSS-API v2 I see no other possibility than to use a (ring) buffer
for a small number of past errors, potentially thread-local if that
is an issue.  I've seen implementations doing this and it worked well.
If the only thing that's being done is to echo back the entire
offending input parameter, then I don't really see the need.

An application does now which input parameters it supplied
to a gssapi call, and which of these input parametes can be
configured/changed by a user and how.

Dynamically generated error messages should primarily be used
to convey information that is local to the GSS-API mechanism.
i.e. GSS_S_FAILURE + minor_status = "File not found" is pretty dumb
for a mechanism since none of input parameters of any of the
gss_api v2 calls conveys a file name -- so the mechanism should
at least provide sufficient information on what kind of file it is
acutally looking for.  And when it is a configuration file,
then the name will often be static (i.e. can be recomputed with ease).

-Martin

---

From: Martin Rex <[email-masked]>
Date: Tue, 1 May 2007 03:24:19 +0200 (MEST)

> be like how the ldap_* api sets and gets options.

That is the awful response I expected.
As I said, this approach is extremely OO-impaired, i.e. broken.

GSS-API is an interface standard, more than it is an on-the-wire
standard.  An OO-approach for an API quickly results in myriads
of incompatible proprietary variants (of set/get params),
while the beauty of GSS-API (at least at the C-level) is that
you can easily get a large number of fully interoperable
implementations over many years.  We've been doing
binary plug'n'play with ~15 third-party gssapi mechanism
for the last 9 years.

In contrast to that, try to compile the most recent version of
a GNOME-based app on a original 4-year old Linux distro and
you hit a brick wall -- you will usually not be able to get
it compile without updating a large number of other apps
and libraries as well-- which shows how broken the approach is.

At times of Motif and X11R4/R5 the backwards compatibility of X11-apps
used to be MUCH MUCH MUCH better.

> with the context from which it was allocated. Again krb5_* and ldap_*

Luckily I never had to deal with either one, krb5_* and ldap_*.
I've been using GSS-API, SSPI and OpenSSL-like APIs to TLS and
neither of them uses it.

> of that context by simplifying some parameter management.

When communicating there are usually two independent streams on
the same connection, one from initiator to acceptor and one in the
opposite direction.  If you can communicate in both direction
simultaneously and indepently, it is called full-duplex,
i.e. you might be using two independent threads for reading
and writing on a network socket.

For GSS-API, the question would be whether parallel calls
(in seperate threads) to message protection (=write) and
message unprotection (=read) on the same gssapi security context handle
should be supported.

-Martin

---

From: Michael B Allen <[email-masked]>
Date: Mon, 30 Apr 2007 21:55:36 -0400

On Tue, 1 May 2007 03:24:19 +0200 (MEST)

> As I said, this approach is extremely OO-impaired, i.e. broken.

I have no idea what you're talking about.

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 30 Apr 2007 21:58:19 -0500

> way to decide when to garbage-collect dynamic state associated with a

Unsure.  I think I'd want mechanisms to be conservative about this.  Of
course, with an additional function to "register" and "unregister" minor
status pointers (which is another way to describe my proposal) the issue
goes away where apps use this extension.

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 30 Apr 2007 22:06:28 -0500

> will never try.  The will only visualize to a user.

No, users certainly don't ever look at minor status code values!  They
look at output from gss_display_status().

> anyway--instead user intervention or even admin intervention required.

Major status codes are defined, so apps can refer to them symbolically
(via C preprocessor defines in the C bindings).

> probably redesign it anyway.

I'd rather not.  I think you're too quick to say no.  I asked you what's

> cannot improve it beyond what is there today.

In the C bindings the minor_status parameter is always a OM_uint32 *, it
is always a pointer.  And my proposal doesn't change the type, it's
backwards compatible, both for binaries and source.

> for failed gssapi calls in a pretty useful and fairly robust

Only by making assumptions about the app's thread model.  Oh, I forget,
as far as you're concerned the GSS-API and multi-threading don't mix.
But to Sun, and, I believe, to MIT, thread-safe GSS matters.

> might do for that.  Cleaning up dynamic thread local storage

That won't suffice: it assumes threads don't do GSS work for multiple
different peers.  In today's world lots of multi-threaded apps don't
dedicate a thread to each peer, instead they are async apps that use
threads for concurrency.

Nico
--

---

From: Nicolas Williams <[email-masked]>
Date: Mon, 30 Apr 2007 22:20:07 -0500

> binary plug'n'play with ~15 third-party gssapi mechanism

You are reaching.  The standard is extensible, the protocol aspects of
it not nearly as complex as the API itself, and as for the bits on the
wire, the API itself defines very little.

Also, there is no ABI for the C bindings, and that truly sucks.

> message unprotection (=read) on the same gssapi security context handle

RPCSEC_GSS depends on it!

Nico
--