Subject: [kitten] Simplified and async API

From: Nico Williams <[email-masked]>
Date: Fri, 22 Feb 2013 16:31:14 -0600

Too late for submitting -00s.  So here:

https://raw.github.com/nicowilliams/kitten/master/gss-step-ctx.txt

(also .unpg, .html, and .lyx)

Enjoy.  Yes, I'm trying to get the WG participants attention for the
other I-Ds I've submitted recently, particularly the one about channel
binding.  Perhaps submitting something mildly controversial will help?

Nico
--

---

From: "Jim Schaad" <[email-masked]>
Date: Fri, 22 Feb 2013 20:01:46 -0800

Nico,

Without appropriate methods for doing queries and potentially clearing
things I would consider the API set to be incomplete.

Jim

> -----Original Message-----
> From: [email-masked] [mailto:[email-masked]] On Behalf
> Of Nico Williams
> Sent: Friday, February 22, 2013 2:31 PM
> To: [email-masked]
> Subject: [kitten] Simplified and async API
> 
> Enjoy.  Yes, I'm trying to get the WG participants attention for the other
I-Ds
> I've submitted recently, particularly the one about channel binding.
Perhaps
> submitting something mildly controversial will help?
> 
> Nico
> --
> _______________________________________________
> Kitten mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/kitten

---

From: Nico Williams <[email-masked]>
Date: Fri, 22 Feb 2013 22:42:48 -0600

> things I would consider the API set to be incomplete.

Jim, I'm quite glad you looked at this so soon after I posted (and the
CB I-D, particularly the CB I-D; I'll respond to that review shortly)

I'm a fan of reflection interfaces.  I don't think we *need* them
here, and since the GSS-API has a nasty reputation of having too many
functions with too many arguments, I hesitate to add functions we
don't clearly need.  The only way we'd need reflection functions is if
an app built a partial context and passed it to some library to finish
-- and that clearly doesn't happen today, so we clearly don't need
reflection interfaces.  As for functions to unset things, there's no
reason I can see why we'd ever need those.

Nico
--

---

From: Nico Williams <[email-masked]>
Date: Fri, 22 Feb 2013 22:54:52 -0600

Although I should have tackled your response to the CB I-D first.

I see now what you probably had in mind w.r.t. querying context attributes.

Yes, we have GSS_Inquire_context(), and this I-D adds a function to
retrieve delegated credentials handles as well.  And we should have
additional such inquiry functions for any context attributes that can
come from the other peer.

So if an initiator sets some option that communicates some
authorization data to the acceptor, the acceptor has to be able to
extract that data from the context.

What I think we don't need is inquiry functions for discovering what
the local application has requested -- the app should already know.

Nico
--

---

From: "Stefan (metze) Metzmacher" <[email-masked]>
Date: Sat, 23 Feb 2013 07:32:15 +0100

Hi Nico,

> https://raw.github.com/nicowilliams/kitten/master/gss-step-ctx.txt

   Note that if GSS_S_CONTINUE_NEEDED is returned but no security
   context is output, then the function must be called again upon async
   I/O completion notification.

    OM_uint32
    gss_step_context(OM_uint32 *minor_status,
                     gss_ctx_id_t context,
                     gss_const_buffer_t input_token,
                     gss_buffer_t output_token,
                     gss_const_OID *actual_mech);

When getting GSS_S_CONTINUE_NEEDED, how can the caller detect the difference
between an empty output_token and no output_token?

metze

---

From: "Stefan (metze) Metzmacher" <[email-masked]>
Date: Sat, 23 Feb 2013 07:53:36 +0100

> between an empty output_token and no output_token?

I think an explicit return value would be better to indicate the need of
an additional step. Something like GSS_S_INCOMPLETE_STEP,
GSS_S_STEP_REQUIRED
or GSS_S_STEP_NEEDED.

This would make the required logic in the caller
much easier as it only needs a simple
if (ret == GSS_S_INCOMPLETE_STEP) {

}
instead of a more complex statement that need to work out the
condition based on multiple variables.

metze

---

From: "Stefan (metze) Metzmacher" <[email-masked]>
Date: Sat, 23 Feb 2013 08:09:37 +0100

> https://raw.github.com/nicowilliams/kitten/master/gss-step-ctx.txt

   The verto library has a lot of clever logic in it to find the
   event loop that the application might be using, as long as the
   application uses an event loop library known to verto,
   including: glib, libev, libevent, and tevent. Verto is portable to
   Unix and Unix-like systems (including Linux and BSDs)
   as well as to Windows.

Where is that "clever logic"?
This worries me a bit, the application should either explicitly
tell the gss library which verto_ctx context to use
or the gss library should create its own context.

If the clever detection only tries to find out which verto backend is
used, it's fine, but it should not try to find an explicit global
verto_ctx.

I'm not sure if the specification needs to include a
function to set a verto_ctx on the gss_ctx_id_t,
but it should at least mention that the specific implementation
should have a function like that.

metze

---

From: Nico Williams <[email-masked]>
Date: Sat, 23 Feb 2013 02:18:50 -0600

>    I/O completion notification.

oops, that should read "...but no security context _token_ is output, ...".

> between an empty output_token and no output_token?

The GSS-API does not allow empty tokens, thus making this a
distinction without a difference :)

Nico
--

---

From: Nico Williams <[email-masked]>
Date: Sat, 23 Feb 2013 02:22:10 -0600

> an additional step. Something like GSS_S_INCOMPLETE_STEP,

Maybe, but supplementary major status codes are in short supply (them
being a bitmask of 10 bits, IIRC), so I figured if I could avoid it...
 But I tend to agree that a GSS_S_WOULDBLOCK (or whatever appropriate
name) would be better, that perhaps I am being too cautious about
burning a supplementary code bit.  (Also, maybe this should not be
considered a supplementary code...)

Nico
--

---

From: Nico Williams <[email-masked]>
Date: Sat, 23 Feb 2013 02:30:03 -0600

> Where is that "clever logic"?

You'd have to look at the code.  Basically verto looks through the
process (using, e.g., dlinfo(), dladdr() and so on on Unix, and
similar on Windows) for a supported library that implements an event
loop and that has an event loop active.

> or the gss library should create its own context.

I think the mech should use the default loop.

The problem here really is that if we want to have the app tell the
mech what loop to use then we need to get extremely detailed, and
probably provide many options, to make the result portable.  It's not
really a business I want to be in unless we were to agree that neither
using something like verto nor starting a thread to run an event loop
are acceptable.  Since we have barely begun to discuss this (verto
and/or bg threads) I think it's too soon to tackle a third
alternative.

I am also of the opinion that a) app developers should not be in the
business of providing event loop wrappers or implementations, b) mech
implementors will find either verto or starting a thread to run an
event loop acceptable.

> used, it's fine, but it should not try to find an explicit global

Why not?  Assume you know more about verto than I do (a likely-correct
assumption).

> should have a function like that.

Possibly.  But then someone will say they don't want to use verto,
they want to use libevent.  And someone else will complain and say
they want libev, and so on.  Where do we stop then?  This is why I
find an implicit event loop, a la grand central, so appealing.

Nico
--

---

From: Volker Lendecke <[email-masked]>
Date: Sat, 23 Feb 2013 15:44:07 +0100

> loop and that has an event loop active.

Samba has multiple tevent context structs alive
simultaneously. Only one really active and used at a time,
but there are more than one allocated. Is that covered? Will
it find the right one?

With best regards,

Volker Lendecke

-- 
SerNet GmbH, Bahnhofsallee 1b, 37081 Göttingen
phone: +49-551-370000-0, fax: +49-551-370000-9
AG Göttingen, HRB 2816, GF: Dr. Johannes Loxen
http://www.sernet.de, mailto:[email-masked]

**********************************************************
visit us at CeBIT: March 5th - 9th 2013, hall 6, booth E15
all about SAMBA and verinice, firewalls, Linux and Windows
free tickets available via email here : [email-masked] !
**********************************************************

---

From: Greg Hudson <[email-masked]>
Date: Sat, 23 Feb 2013 10:52:57 -0500

On 02/23/2013 03:30 AM, Nico Williams wrote:
> they want to use libevent.

They could use libevent.  The application links against
libverto-libevent, calls verto_convert_libevent() to produce a verto_ctx
*, and passes that to GSSAPI.  When the GSSAPI implementation calls
verto_add_* functions on that context, events will be registered in the
application's libevent loop.

That's the whole point of libverto, and there's no linker magic required
for that.  Things get tougher if the application wants to use an event
loop which libverto doesn't have a wrapper for, but I think even then
it's possible for the application to provide a shim (which tends to be
about 200 lines of code).

libverto is not so magic that it can actually find the application's
event loop, if such a thing were even well-defined.  It used to have
code to try to use the same event loop *library* as the application,
just as a VM usage optimization, but I believe that's gone.  libverto
uses a small amount of linker magic to find its own module libraries at
runtime, but that's it.

---

From: Nico Williams <[email-masked]>
Date: Sat, 23 Feb 2013 15:41:35 -0600

OK, so we actually need to define C prototypes for event loop
functions to be passed to the GSS-API, or otherwise make a normative
reference to verto, libevent, or the like.  Bummer.

---

From: Nico Williams <[email-masked]>
Date: Sat, 23 Feb 2013 17:08:25 -0600

I will gladly take text (and co-authors) about how to pass an event
loop to the mech.  I will also gladly settle for having no standard
way to do that, leaving threads as the only standard solution, but
with actual implementations that support passing event loops to the
mech.

Nico
--

---

From: Nico Williams <[email-masked]>
Date: Sat, 23 Feb 2013 17:16:06 -0600

> condition based on multiple variables.

We already have this sort of situation in the GSS-API: when
GSS_S_COMPLETE is returned an output token can also be returned.  So I
don't feel too bad about adding another one of these :)

---

From: Sam Hartman <[email-masked]>
Date: Sat, 23 Feb 2013 21:31:36 -0500

>>>>> "Stefan" == Stefan (metze) Metzmacher <[email-masked]> writes:

    Stefan> I'm not sure if the specification needs to include a
    Stefan> function to set a verto_ctx on the gss_ctx_id_t, but it
    Stefan> should at least mention that the specific implementation
    Stefan> should have a function like that.

I'm not at all sure this is true.  I've been thinking about use cases.
I can think of a lot of use cases for applications wanting an async
interface to GSS.  

There are a lot of applications that call into GSS in a UI thread and
block the entire application on GSS.
That's undesirable.
In some of these applications, an asynchronous interface would help.
(Some of the applications just seem kind of hopeless)

However, in many cases I think it would be fine an
implementation handled this with threads and a blocking implementation
of the GSS mechanisms.

That is, I'd rather see this implemented in the mechglue calling into
mechanisms using the synchronous interface.  I'd like to get some
experience with that before we start unwinding GSS implementations and
turning them into async code.

So, I'm sure it is not necessary that an implementation have a function
to set an event loop context.  I'm also unconvinced it is desirable to
have such a function. I'd prefer to get experience with simpler
implementations that do not involve event loops first.

---

From: Nico Williams <[email-masked]>
Date: Sun, 24 Feb 2013 00:02:34 -0600

I agree with Sam.  I've been playing with how to pass an event loop without
getting in the business of either defining an event loop API in an RFC or
needing a normative reference to such a thing in an RFC.  I've yet to find
a suitable solution.

My proposal is that we only standardize an async interface that implies
threading or implied event loops.  We should still have C bindings
extensions with explicit event loops if that's useful, but we should not
standirdize them until we've gathered some experience with them.

Nico
--

---

From: "Stefan (metze) Metzmacher" <[email-masked]>
Date: Mon, 25 Feb 2013 15:58:21 +0100

> distinction without a difference :)

Where is that defined? At least over SMB spnego tokens can be fragmented,
and the GSS_S_CONTINUE_NEEDED may take or produce emtpy tokens.

metze

---

From: Nico Williams <[email-masked]>
Date: Mon, 25 Feb 2013 10:34:28 -0600

> and the GSS_S_CONTINUE_NEEDED may take or produce emtpy tokens.

RFC2743, section 1.1.2, fourth paragraph, third sentence:

"Zero-length tokens are never returned by GSS routines for transfer to a peer."

Can you tell me more about the SMB issue?  Does SMB make the length of
fragments and/or the reassembled tokens definite, or does it depend on
GSS_Init/Accept_sec_context to somehow tell it where the end of a
token is?  If the former then there's no problem: just reassemble the
tokens first, then pass them to the GSS-API.  If the latter... how
would the GSS-API indicate the end of the token?!

Nico
--