14-Sep-2004: Release 1.0.8 ========================== * Support for Win64 on AMD Athlon64/Opteron. The resulting files are called gx64ntlm.dll and gx64krb5.dll. Win64/Itanic files have been renamed: gi64ntlm.dll gi64krb5.dll * Workaround for Memory leak in Microsoft's SSPI function QueryCredentialsAttributesA(NAMES) on all Win2K/WinXP releases (up to and including Win2Ksp4 and WinXPsp2), but not W2K3. This leak is critical to long-running Servers using gsskrb5.dll. SSPI leaks 4 KBytes virtual and 40 Bytes non-paged pool memory per API-call. The workaround is to call the WideChar version QueryCredentialsAttributesW(NAMES) and manually convert the return value to ANSI. After around 32500 API-calls the per-process quota limit on non-paged pool memory is reached and further SSPI calls fail with SEC_E_INSUFFICIENT_MEMORY. (Rational Purify 6 for Windows NT doesn't see this leak--AWWW!!) * Workaround to avoid (Event ID 673) with AD in W2K3 native mode. By requesting the ISC_REQ_USE_SESSION_KEY context attribute when trying to verify validity of **initiating** Kerberos credentials user2user authentication will be requested instead of the regular rfc-1964 authentication exchange. An Active Directory in Windows2003 native mode will log Event (ID 673) each time a NON user-2-user authentication is requested for an account that does not have a service principal name assigned, by default all accounts of regular (human) users. * Removed calls to GetUserNameEx() when trying to derive one's own Kerberos principal name; it seems to be causing problems for some of our customers and has never really worked anyway. SSPI in W2K+ contains the API calls GetUserNameEx() and TranslateName(), unfortunately these calls can not reliably be used to determine the *default* Kerberos Principal name of an account in the Microsoft AD. GetUserNameEx(NameUserPrincipal) does return the *default* Kerberos Principal name on WinXP and above, but fails always on a W2K machine with a W2K AD. TranslateName() always queries the Active Directory, and fails with ERROR_NONE_MAPPED when the Active Directory is W2K (not W2K3), when no *explicit* mapping exist in the AD on all NT 5.x platforms (W2K, WinXP, W2K3). With a W2K AD, TranslateName() will *NEVER* return the default mapping, whereas a W2K3 AD seems to return it (although it shouldn't according to MS). * Incompatible change of Kerberos accepting (inbound) credentials in WindowsXPsp2 (which will likely be reverted in a future hotfix/service pack). The Kerberos password is no longer being cached, however the the resulting behaviour is inconsistent and non-intuitive. Background: In Kerberos for the normal AP_REQ/AP_REP authentication exchange the acceptor needs his longterm secret (password) to open incoming service tickets. In traditional MIT Kerberos 5 an accepting credential is the longterm secret stored in a file called keytab. Regular users don't normally have keytabs and therefore no accepting credentials. The only possibility for (human) users to become targets/acceptors in an authentication is "user2user" authentication, but this protocol exchange is not part of the rfc1964 Kerberos gssapi mechanism spec. Microsoft did implement user2user authentication for their Kerberos SSP (which other implementations of vanilla rfc1964 will not understand). The default inbound credentials can use the existing TGT for accepting user2user authentication. In addition, as the LSA of NT has traditionally been caching the users password, Microsoft W2K Kerberos SSP did offer regular accepting credentials based on the cached password from the start. And LSA will automatically refresh Kerberos TGTs even if one manually purges them from the ticket cache (e.g. using the tool "KLIST.EXE" from the W2K ResKit). WinXPsp2 changes that, which does break some existing code. Strangely, the password-based accepting credentials are still available and accessible directly after logon, even on WinXPsp2 (so somewhere the password is still being cached...). But once a screen lock/unlock operation is performed, all further SSPI operations that require password-based accepting credentials will suddenly fail with SEC_E_NO_CREDENTIALS, and all requests for initiating credentials with an explicit name will start failing without the password. The default initiating credentials still work, but the Microsoft Kerberos SSP fails to match an explicitly supplied name to these credentials. Manual deletion of the TGTs from the ticket cache will prevent all further Kerberos authentications on WinXPsp2 until a screen lock/unlock or logout/login is used to request the password from the user in order to acquire new TGTs. (W2K, WinXPsp1 and W2K3 automatically reacquire manually deleted TGTs.) Similar to the problem with the SmartCard credentials, Microsoft Kerberos SSP is unable to match explicitly named credentials to existing TGTs when no (cached) password is available, so the fallback to request default credentials and matching them to an explicit name above SSPI is even more important in gsskrb5.dll with WinXPsp2. 05-Nov-2003: Release 1.0.7 ========================== * preliminary addition of acceptor side support for credential delegation. Unfortunately my "generic" code isn't generic enough to wrap a mechanism credential, therefore I slightly bent the internal layering and now call "gn_new_cred()" and "gn_release_cred()" from within krb5_accept_sec_context() * new Workaround for Microsoft Kerberos problem with SmartCard preauthentication: If SmartCards are used for preauthentication with Microsoft's Kerberos SSP then AcquireCredentialsHandle() is unable to match a explicitly supplied user name with the name from the TGT, ONLY request for default (unnamed) credentials works. So the workaround is to retry the unnamed credentials and match them manually (=above SSPI) with the supplied explicit kerberos principal name. According to Microsoft (and in contradiction to their own SSPI spec) the pszPrincipal parameter has always been and still is completely ignored by both NTLM and Kerberos SSP, and the support for the AUTH_IDENTITY structure is painfully insufficient. * partial Workaround for Microsoft Windows 2003 Kerberos incompatibility with rfc-1964 for Domains in Windows 2003 native mode (this problem doesn't show with Windows 2003 Domains in mixed mode). The source of the incompatibility is the addition of a protocol extension for Kerberos user2user authentication which was done in a fashion that clearly and seriously violates the GSS-API architecture, the rfc-1964 Kerberos 5 gssapi mechanism and also Microsoft's SSPI specification and architecture prior to Windows 2003 (see also Microsoft Knowledgebase Article Q266080). When a user account of in a Windows 2003 Domain in native mode is used as a target, the W2K3 Kerberos SSP will use Microsoft's new proprietary user2user token exchange (3-way or 4-way) for authentication instead of the regular rfc-1964 token exchange (1-way or 2-way). When there is a "service principal name (SPN)" defined in the Active Directory for the target account, then the standardized rfc-1964 conformant token exchange is used. The validation of initiating credentials built into gsskrb5.dll will recognize and permit a user2user token exchange now. (It would be so much easier if SSPI's AcquireCredentialsHandle() would do its job correctly and perform this verification...) The validation of accepting credentials built into gsskrb5.dll will recognize the rfc-1964-incompatible token exchange and fail with an error message indicating that there needs to be a service principal name defined for the account. user2user tokens showing up from InitializeSecurityContext() will result in the error message that a service principal name needs to be defined for the target's account. To define a service principal name for a service user account you can use the SETSPN.EXE command line tool from the SUPPORT/TOOLS/SUPPORT.CAB archive on the Windows 2003 CD. SETSPN -a /spn \ will do the trick. Traditionally servers would be using "hostbased service names" in Kerberos 5 containing the fully qualified hostname (f.q.d.n) like this: SETSPN -a /f.q.d.n \ however the only hostbased service name that Microsoft's Kerberos supports in some way is the host/f.q.d.n principal which is assigned to the PCs machine account in the Domain. All other SPNs are fakes in that they seem to provide the functionality but not the necessary protection against session replay for seperate instances of the same distributed service on different machines -- and this is one of the vulnerabilities which their user2user extension tries to work around (the other vulnerability is the lack of strong random keys for service accounts). Microsoft added user2user authentication with a seperate mechanism OID on the context level tokens, however this can NEITHER be selected NOR detected at the SSPI level. Determining the behaviour a-priori would require heavy and dead-slow Active Directory wizardry, and the dirty workaround to prevent it would require domain admin rights to set the SPN on the acceptors account... gsskrb5.dll is strictly tied to the Kerberos SSP and provides full rfc-2743 GSS-API compliance and rfc-1964 interoperability, so it has always been peeking into the parts of the context level tokens that are clearly standardized by rfc-1964... which is why the incompatible change of Windows 2003 Kerberos broke gsskrb5.dll... 09-Jul-2002: Release 1.0.6 ========================== Workarounds in gsskrb5.dll for new Microsoft Bugs: * Undocumented and unexpected alignment requirement for the ContextToken input parameter to the SSPI function ImportSecurityContext(). When the supplied token is only 4-byte aligned DrWatson will be called with an Alignment Exception (SIGBUS). * Re-appearance of a W2K-beta Kerberos SSP bug of incomplete initialization when a new process calls ImportSecurityContext() without having ever called AcquireCredentialsHandle(). In this situation AcquireCredentialsHandle() fails with SEC_E_INVALID_HANDLE which is a bug. I reported a bug with the exact same effect during W2K-beta and it is definitely fixed in W2K final. However W2Ksp2 is broken again, as is Win64/Itanium. The workaround is that krb5_import_sec_context() requests and releases an initiating credentials handle the first time it is called. * several small changes to accomodate Win64 builds: - target "clean" will no longer remove "today.exe" because a cross-compiled today.exe cannot be directly executed... - dependencies for the accompanying (old) SSPI-related windows header files removed from ntlm/Makefile and krb5/Makefile so that on Win64 the official Platform SDK Header files can be used - makekrb5.bat and makentlm.bat try to determine whether doing a Win32 native compile or a Win64 (cross-)compile and choose appropriate compiler flags accordingly - added "debug" pseudo-target to makekrb5/makentlm for building with debug compiler/linker options Still unresolved is a new Kerberos SSP bug that shows in the Win32 Emulation on Win64. There the first call to AcceptSecurityContextA() results in SEC_E_INSUFFICIENT_MEMORY when a NULL OutSecToken is supplied accompanied with the ASC_REQ-Flag ASC_REQ_ALLOCATE_MEMORY. However gsskrb5.dll works just fine on W2K-Win32 and Win64-native... * I fixed some very nasty bugs in MIT's gss-sample where locally malloc()ed memory from recv_token() was illegally passed to gss_release_buffer(). gss-sample was enhanced to allow passing a nametype-hint as a prefix to the service name command line argument for gss-server and gss-client: u:service-name -- import with GSS_C_NT_USER_NAME s:service-name -- import with GSS_C_NT_HOSTBASED_SERVICE p:service-name -- import with GSS_C_NO_OID finally, it is now possible to start gss-server without specifying a service-name (just a -port ), in which case it will request default accepting credentials and inquire and print the name of these credentials. Btw. use "makekrb5 sample" to build gss-sample and "makekrb5 debug sample" to build a debug-version and "makekrb5 clean-sample" to clean only gss-sample 25-Oct-2001: Release 1.0.5 ========================== * Fix in gssntlm.dll: Release Process and Thread Tokens acquired through OpenProcessToken() and OpenThreadToken() via CloseHandle(). Windows NT was first shipped in 1993 and the Visual 98 compiler documentation still doesn't document that a CloseHandle() is possible and even necessary on the HTOKEN returned from OpenThreadToken() and OpenProcessToken(). Finally the most recent MSDN documentation and new Code Samples correct this old and really longstanding documentation bug which resulted in about 10% of the bugfixes in WinNT4 service packs (Handle leaks in almost every server/service of NT4)... 24-Jan-2001: * Fix in gssntlm.dll: The workaround (from 1.0beta3) for the bug in AcquireCredentialsHandle() breaks on the original Releases of Windows 95 (Aug'95-release, OSR 2.0 and OSR 2.1). The Unicode structure results in SEC_E_INVALID_TOKEN. I have added a fallback to using an ANSI version of the auth identity structure (OEM character corrected). 31-Aug-2000: Release of Version 1.0beta4 ======================================== * Fix: W2K Kerberos doesn't implement gssapi channel bindings, however the wrapper only silently ignored them instead of returning GSS_S_FAILURE and indicating the lack of this feature when channel bindings were supplied by an application. The README was updated to mention this missing feature. * A syntax error was fixed in a DEBUG_* statement, and some DEBUG_ACTION() statments were added to the HostToRealm mapping function. GSSAPI-level tracing can be activated by *removing* "-DNDEBUG" from the following line in makekrb5.bat: set DEFINES="-DWIN32 -DNDEBUG" * the OpenVision gss-sample was adopted from the MIT Kerberos v1.0.5 distribution. I needed a few changes and additions to become usable on Win32 and with this GSSAPI wrapper for W2K Kerberos. 19-Jul-2000: Release of Version 1.0beta3 ======================================== * There is now a Makefile and makeboth.bat to build the multimechanism DLL "gssboth.DLL" * I have rearraged the Makefiles and bat-files so that all three DLLs can be built without the need to "clean" between the builds. The generic and the mechanism specific parts are now glued together by the new source files "gsskrb5.c", "gssntlm.c", "gssboth.c" * Fix: Account names with Umlauts didn't work with gssntlm.DLL because of a BUG in Microsoft's NTLM SSP. The names are now converted to and passed as UNICODE via the AuthIdentity structure to AcquireCredentialsHandle(). I haven't yet checked whether the Kerberos SSP has the same bug. 08-May-2000: Release of Version 1.0beta2 ======================================== * The Kerberos initiating credentials will be queried for the owner name when GetUserNameEx(NameUserPrincipal) fails. * Hostbased service names have been implemented, however they will probably need extra configuration to determine the realm mapping of native Kerberos realms. See the discussion of hostbased service names in the README. 01-Apr-2000: Release of Version 1.0beta1 ======================================== the current codebase provides enough of the look-and-feel of a Kerberos gssapi mechanism that our application will not see a difference from other Kerberos 5 implementations. HISTORY of gsskrb5 ================== In 1995/96 we added protection to the network communication of our legacy application and used the GSS-API to link with third-party software dynamically at runtime. This requires a common binary interface for DLLs/shared libraries on all our supported platforms. MIT Kerberos 5 was the first GSS-API mechanism that was addressed, and a public key based mechanism using X.509 certificates was 2nd. However, the intention was to remain generic at the API level and to be able to operate the application on top of many different GSS-API mechanisms yet to be developped. To be able to verify correct application behaviour with arbitrary GSS-API mechanisms, I started writing a "generic" gssapi mechanism as a low-priority project. Before I was able to complete it, we got a request from customers that wanted to use the single sign-on of their Microsoft platforms (NT Lan Manager) to log into our application as well. That's when I started writing an adapter to NTLM of Win95/NT4 instead of a generic test mechanism. Later on during the Beta-stages of Windows2000, I converted the NTLM SSP wrapper into a wrapper for the Kerberos SSP providing conformance to rfc1964 and interoperability with MIT Kerberos 5, so that it can be used to access applications on non-Microsoft platforms as well.