Re: KITTEN BOF at IETF 60?
Martin Rex <[email protected]> Mon, 22 Mar 2004 22:17:40 +0100 (MET)
| Newsgroups | gmane.ietf.cat |
|---|---|
| Message-ID | <[email protected]> |
Ken Raeburn wrote: > > Well, I haven't implemented a mechanism from scratch, mostly tweaked > MIT's krb5 mechanism, but I can toss out a few nits I have to pick > with RFC 2744: > > - No GSS_C_AF_INET6 definition. Some of the AF definitions that are > included are silly. Does anyone on the planet care about > GSS_C_AF_CHAOS? For me GSS_C_AF_CHAOS is just as useless ans GSS_C_AF_INET4. :) Seriously, the channel bindings are probably straight from GSS-API v1 which was published in 1993 (rfc-1508/1509) and someone was trying to create a complete list of known networking protocols at that time, I suppose. That there is no GSS_C_AF_INET6 seems to indicate that there weren't many implementors using channel bindings when GSS-API v2 was discussed... > > - No guidance concerning thread support. Multi-threading is an extremely platform specific mess and thread support will implementation specific anyway. GSS-API v2 does *NOT* cover threads at all, and it is quite good that it doesn't even try to (because it would almost certainly have failed). The discussion about multi-threading with GSS-API came up a few times on CAT before GSS-API v2 was completed, but most of the participants agreed that it would be a too radical change for a mature API and better be saved for a GSS-API v3 revision that could decide to break with interoperability. The apparently most often mentioned lack was an initialization and a final cleanup call. The problems that I have encountered with multithreading on various platforms are: - on most Unix/Posix platforms single-threaded objects/shared libs can *NOT* be used/linked with multi-threaded objects/shared libs - some Unix/Posix platforms offer two different incompatible threading models and code compiled for one cannot be used together with code compiled for the other (Reliant Unix 5.45 with DCE- vs Unix98-threads) - Win32 has a serious deficiency with cleaning up thread-local storage, since it lacks a destructor in TlsAlloc(). Hooking the THREAD_DETACH event in DllMain() might be a workaround, but you have to put your code into a DLL for this to work--but what about cleanup when UnloadLibrary() is used before the threads terminate ... - some platforms are still stuck on old draft4 Posix threads (IBM's OS/390 Open Edition alias z/OS, and OS/400) > > If a mechanism doesn't provide out-of-sequence detection, can I use > gss_get_mic in two threads with the same security context, without > ensuring that the calls aren't fully serialized? In the portable sense: NOPE, never. With most "multi-threading-capable" gssapi mechanism implementations you will have to serialize calls on the same "handle", since these handles have internal state which can be affected by gssapi calls and by external events. To offer such a functionality, an implementation would either use a global locking or a handle-specific locking itself, and it would have to always use it, even if the application did serialize or wasn't multithreaded at all. In the POSIX thread spec there is a rather low upper limit on the number of Mutexes that a threads implementation must be able to support. If a mechanism wanted to offer such functionality, then it would be appropriate if the mechanism offered special locking calls that would lock operations on the handle and can be used by the application. Similar to GetDC()/ReleaseDC() on Microsoft Windows platforms. The more common situation than two independent threads calling gss_get_mic() on the same context would be two independent threads for each direction of the communication (incoming/outgoing) so that one thread calls gss_get_mic() on the same context handle on which the second thread calls gss_verify_mic() (analogous with wrap/unwrap). Personally, even with a multi-thread-capable gssapi mechanism I would always serialize calls that used the same object handle (here context). Btw. have you checked the constraints of OpenSSL when calling SSL_Read and SSL_Write on the same SSL handle in two independent threads (I haven't)? > > How about gss_inquire_cred on the same credentials in multiple > threads? The description of that function suggests that cred_handle > is an input argument, but the description of gss_acquire_cred says > that gss_inquire_cred may implement delayed credential acquisition, > which suggests modification under the covers. Again, in the portable sense: never. With credentials it may be even worse. On Microsoft Windows NT platforms there usually are thread-local permissions (thread-local access tokens), so when the application plays funny "impersonation" games this may cause some gssapi mechanisms (not native to Windows NT) to run into problems accessing credentials. I haven't checked whether SSPI credentials (once the handle is acquired) remain fully accessible while the application caller plays around with context impersonation. > > How about general use of the GSS-API from multiple threads for > unrelated sessions? If a mechanism has static data that it > modifies, must it use a mutex (or semaphore, or atomic-access > instructions) internally in a threaded environment? Or is it up to > the application to avoid the simultaneous use of GSS-API functions > in different threads? As you found out, there is no GSS-API definition for a multi-threaded environment, so whatever you do it will be *specific* to the combination of both, your multi-threaded app and your multi-threaded gssapi mechanism. A portable application will assume a non-threadsafe gssapi mechanism and therefore have to serialize *all* gssapi calls. A gssapi mechanism implementation that wants to offer support for multiple threads must at least offer concurrent use of independent handles (correctly locking/serializing access to internally shared resources). > > I'm actually working on thread safety for the MIT code right now, > and I'm pretty much having to guess. Well, Good Luck! When we had a discussion on multi-threading on CAT (but I think it was rather a conversation > > - The handling of "const" is confused. > > Several "pointer or arithmetic type" parameters are declared > "const". This does *not* mean "any pointed-to data is not modified > by the function". It means "the function implementation cannot > modify its local copy of the argument passed in", which is just > silly, since doing so doesn't influence the caller at all. > > I'd have to check the C spec, but I'm not sure if it would be > compliant with ISO C to actually define the specified OIDs as > "const", given the header file we're supposed to provide. But > that's an "implementation detail", and implementations are on real > systems, not ISO C abstract machines. The application isn't allowed > to write to the OIDs, so as long as the behavior is correct for a > compliant application, stuffing them in read-only storage and not > declaring them "const" in the available header is probably fine. Bad luck. I hardly use const even today. I certainly didn't use it back then. The GSS-API header file which we use for our application doesn't have const anywhere, probably because it was nailed down early 1996 :) Comment from Ted Ts'o on the CAT list about the use of "const": : : From: "Theodore Y. Ts'o" <[email protected]> : To: Marc Horowitz <[email protected]> : Cc: [email protected], [email protected] : Subject: Re: GSS Storage Issues : Date: Fri, 30 Aug 1996 16:08:48 -0400 : : Cc: [email protected] : From: Marc Horowitz <[email protected]> : : >> Perhaps we should add the keyword "const" where : >> appropriate too. : : I'd be for that. : : So would I; right now, there are some people who are inserting "const" : into their GSSAPI function prototypes, which I claim is in violation of : the GSSV1 C Bindings specs --- it causes compilers to flame incessantly : about type warnings, and that masks the real bugs. :-) : : The people who put in the "const" keywords claims that it's better C : coding style. I don't disagree with that, but I'd much rather see it : into the C bindings specification first. : : - Ted > > Maybe that's not completely true. The spec says "should" in a lot > of places, including "GSS-API implementations *should* provide > constant gss_OID values" and "*should* treat...as read-only", but > not "must", and as far as I've found, it doesn't explicitly give the > implementation license to blow up if the application misbehaves in > this regard. rfc-2743/2744 is actually GSS-API v2 update 1. If you look at rfc-2078 there was the concept of dynamic OIDs over a few years in GSS-API v2, but was dropped when it was realized that there were several problems with dynamically allocated OIDs and that it was backward-incompatible with GSS-API v1. Rather than explicitly "outlawing" mechanism implementations that had implemented the gss-api-v2 draft it was considered more appropriate to list the requirements and constraints on OIDs once they're made visible to the application. One of the situations where OIDs might be initially dynamic is plug-n-play multimechanism schemes where the glue layer figures out OIDs and OID_sets at runtime. But as there is no (more) gss_release_oid() call, the OID needs to exhibit "const" behaviour once it has been returned to the application caller via any of the gssapi calls. > > - How is the header file used? <gssapi.h> or <foo/gssapi.h> or > something else? At least some applications are testing the > environment in order to pick between <gssapi.h> and > <gssapi/gssapi.h>. What's "portable" here? For our application we're using our own header file (one single header file for *ALL* of our platforms). Hardly any platform that we use for building our code comes with a gssapi mechanism on-board, and neither do we install one. > > - Tying anything to whether or not X/Open header files are available > is pretty clear, but unfortunate. (Especially where a lot of > systems have optional add-on packages these days.) Updating to C > '99 would be nice, if it can be done compatibly. Our application explicitly does NOT use the X/Open stuff, since that is a royal PITA, and unfortunately on 64-bit platforms tend to be incompatible the OID/OID_set "fallback definitions" in the gssapi v2 sample header file. > > - Is an implementation allowed to define any of these functions as > macros as well (a la C '89, which generally allows it but requires > that an addressable function be available as well). > > For example: > #define gss_wrap(a,b,c,d,e,f,g) \ > ({ /* statement expression - gcc extension */ \ > gss_ctx_id_t _ctx = (b); /* no multiple evaluation */ \ > (_ctx->ops->wrap(a,_ctx,c,d,e,f,g)); \ > }) YUCK! Besides that wouldn't work with binary plug'n'play mechanisms (using shared libraries) it is also distasteful. I consider every code seriously broken which reveals internal implementation detail in the API header file or which performs recursion through its external programming API so that inside the function you cannot immediately distinguish a genuine call from the application from an internal use or recursion. > > - Appendix A: "C-language GSS-API implementations should include a > copy of the following header-file." > > Ignoring the fact that platform-specific substitutions need to be > done first, and the preprocessor test using sizeof is completely > useless (the preprocessor doesn't evaluate sizeof), this also > suggests that no other changes (e.g., declaring extension functions > or additional name-type OIDs) are allowed. The definitions at the beginning of the gssapi_2.h Header file that I've been using since 1995 for *ALL* platforms looks like the following, and I do ignore <xom.h> which still isn't available on many of our build platforms. /* * Determine platform-dependent configuration. */ #include <limits.h> #if USHRT_MAX > 0x10000 # define GSS_SIZEOF_SHORT 4 #else # define GSS_SIZEOF_SHORT 2 #endif #if UINT_MAX > 0x10000 # define GSS_SIZEOF_INT 4 #else # define GSS_SIZEOF_INT 2 #endif #if ULONG_MAX > 0xffffffff # define GSS_SIZEOF_LONG 8 #else # define GSS_SIZEOF_LONG 4 #endif /* * Define APIENTRY, NEAR & FAR * plus LOCAL_APIENTRY (for WIN16 to avoid __loadds) */ #ifndef APIENTRY # if defined(_WINDOWS) # define APIENTRY __far __export __pascal # define LOCAL_APIENTRY __far __pascal # elif defined(WIN32) # define APIENTRY __stdcall # else # define APIENTRY # endif #endif #ifndef LOCAL_APIENTRY # define LOCAL_APIENTRY APIENTRY #endif #ifndef FAR # if defined(_WINDOWS) # define FAR __far # define NEAR __near # else # define FAR # define NEAR # endif #endif > > - The description of equality comparisons in section B.3 makes me > shudder. I'm not even sure what it means. As far as I can tell, if > your machine lets you have two objects (pointers, integers, floats) > that compare equal with "==" despite having some bits that are not > identical, then you have to fix up those bits to always be equal. B.3 says: For binary portability, additional constraints are required. The following is an attempt at defining platform-independent constraints. Why does this make you shudder? The decription that follows this is more-or-less the assumptions that must be met so that the *independent* header files of the application programmer and the gssapi mechanism programmer will smoothly interoperate when the two binaries (exe-application and shared lib-mechanism) meet in the wild. > > - If you want to make recommendations about ABI compatibility, how > about suggesting *either* pointer or arithmetic type for handles, > and not giving the implementation the choice. Not only is it valid > for pointers and arithmetic types to be passed and returned > differently, there is at least one platform where pointers and > numbers *are* returned differently. Also, floating-point values are > "arithmetic", and are often passed differently from both integers > and pointers. It really doesn't matter how it is passed. It is about interoperability when the two binaries (exe-app and shared lib-mechansim) have been *independently* built with differing definitions for e.g. gss_ctx_id_t. So even if the application treats it as a pointer and the gssapi mechanism actually uses an "int" they both should interoperate! However if the gssapi mechanism uses an integer (and a union to get size/alignment of void*), then the gssapi mechanism must clear bits in gss_ctx_id_t when setting the integer part of the union in case that sizeof(void*)>sizeof(int), e.g. on a 64-bit platform. > > (And I'd have to research it, but suggesting incomplete struct > pointer types might be a better option.) I agree. Instead of just discouraging (void*) the spec would have better suggested to use imcomplete struct pointers -- I didn't know how simple that is and how good it works for quite a while... > > - Should the ABI discussion touch on shared library names? I'm not > sure. Perhaps not. Nope. There are definitely going to be several independent gssapi mechanisms available. So either its fine when an application is directly linked with an implementation-specific library, or the application should be able to load one (or more) of arbitrarily named libaries dynamically at runtime. > > - No discussion of C namespace issues. > > Are names starting with "gss_" and "GSS_" reserved for > implementation internal use, future updates and extensions? Or > should applications feel free to use them? If they're reserved, > then under what conditions? (See the C library spec's description > of this sort of thing, IIRC there are at least two classes of > reserved names.) > > Inclusion of gssapi.h on an ANSI C system is required to define > ptrdiff_t and offsetof(), right? After all, Appendix A, which > apparently is normative, says it includes stddef.h, and C '89 says > stddef.h defines those. So using some system-specific header than > only provides a __size_t for the implemenation's use, and avoiding > stddef.h, is not allowed? > > What's added to the namespace on an X/Open system? > > Can I use gss_uint32 in my code? (True, there's no guarantee that > it's the same as OM_uint32.) Actually I'm using OM_uint32 everywhere in the header and my application code, but I do *NOT* use the X/Open definitions or header files anywhere -- actually the X/Open definitions would cause serious incompatibilities on some platforms... > > (Taking off my "amateur language lawyer" hat now....) > > > Channel bindings are actually non-portable anyway, many gss-api mechanisms > > don't implement them (even Microsoft's Kerberos doesn't) and portable > > applications don't use them anyway. Routing&multihoming issues, > > NATs and all that interfere in all sorts of ways. > > And the non-portability makes it okay for the specification to be > confusing? Does the GSS-API spec say that you shouldn't use channel > bindings? Should it? I think that a GSS-API v2 spec that wants to advance to draft standard (which may well be independent of KITTEN going for GSS-API v3), then the refined spec should clearly outline that channel bindings are optional for the gssapi mechanism to implement and optional for the application to use and it should give a warning what mechanisms should do if one peer supplied/supports channel bindings and the other doesn't... (in order to document existing practice). > > > So far I've primarily seen clear breaches of the abstraction when > > IPv4 channel bindings where used with Kerberos and the Kerberos > > gssapi mechanism did not only verify the channel bindings at both > > ends with the application provided values, but also peeked inside > > the channel bindings and matched them up against credentials. > > What abstraction? I thought RFC 2743 section 1.1.6 allowed for this > sort of use? I would consider that heavily underspecified. I think it is a flawed assumption that the network interface that the application is using is for communication will always be available/visible/accessible to the gssapi implementation when it acquires/creates credentials, even if both are using IPv4. This seems to be more obvious when the application is *NOT* using IPv4. I know little about IPv6, but the situation of adhoc-creation of network addresses unknown to the gssapi mechanism may be more common with IPv6. -Martin -++**==--++**==--++**==--++**==--++**==--++**==--++**== This message was posted through the Stanford campus mailing list server. If you wish to unsubscribe from this mailing list, send the message body of "unsubscribe ietf-cat-wg" to [email protected]