Package: libsasl2-modules-gssapi-mit Version: 2.1.25.dfsg1-6+deb7u1 Tags: patch upstream
(Apparently still unfixed on upstream git master branch. Copying cyrus-bugs.) After upgrading an LDAP server from squeeze to wheezy I started seeing bind failures from one client application. This application uses SASL GSSAPI binding after STARTTLS. On investigation it turned out that in the final handshake the server was returning both a security layer bitmask of 7 and a zero maximum token size. The issue went away after I applied the attached patch. My impression from reading the original code is that the problem can manifest itself when the SSF provided by the external layer is sufficient to satisfy the application's policy. I don't think it would be appropriate for the server not to offer security layers that the security context can support just because the external SSF exceeds some threshold; the client may have reasons of its own to insist on using those layers.
--- a/plugins/gssapi.c +++ b/plugins/gssapi.c @@ -990,21 +990,14 @@ } /* build up our security properties token */ - if (text->requiressf != 0 && - (text->qop & (LAYER_INTEGRITY|LAYER_CONFIDENTIALITY))) { - if (params->props.maxbufsize > 0xFFFFFF) { - /* make sure maxbufsize isn't too large */ - /* maxbufsize = 0xFFFFFF */ - sasldata[1] = sasldata[2] = sasldata[3] = 0xFF; - } else { - sasldata[1] = (params->props.maxbufsize >> 16) & 0xFF; - sasldata[2] = (params->props.maxbufsize >> 8) & 0xFF; - sasldata[3] = (params->props.maxbufsize >> 0) & 0xFF; - } + if (params->props.maxbufsize > 0xFFFFFF) { + /* make sure maxbufsize isn't too large */ + /* maxbufsize = 0xFFFFFF */ + sasldata[1] = sasldata[2] = sasldata[3] = 0xFF; } else { - /* From RFC 4752: "The client verifies that the server maximum buffer is 0 - if the server does not advertise support for any security layer." */ - sasldata[1] = sasldata[2] = sasldata[3] = 0; + sasldata[1] = (params->props.maxbufsize >> 16) & 0xFF; + sasldata[2] = (params->props.maxbufsize >> 8) & 0xFF; + sasldata[3] = (params->props.maxbufsize >> 0) & 0xFF; } sasldata[0] = 0; @@ -1029,6 +1022,12 @@ params->props.maxbufsize) { sasldata[0] |= LAYER_CONFIDENTIALITY; } + + if ((sasldata[0] & ~LAYER_NONE) == 0) { + /* From RFC 4752: "The client verifies that the server maximum buffer is 0 + if the server does not advertise support for any security layer." */ + sasldata[1] = sasldata[2] = sasldata[3] = 0; + } real_input_token.value = (void *)sasldata; real_input_token.length = 4;