Re: Malformed Packet in SASL binding

Rich Megginson <[email protected]> Thu, 20 Aug 2009 21:16:21 -0600
Newsgroups gmane.comp.mozilla.devel.directory
Message-ID <[email protected]>
Xu, Qiang (FXSGSC) wrote:
> Hi, all: 
> 
> As you know, although my SASL binding is successful, it still has some defect.
> 
> As you can see, the Malformed Packet is in the 2nd round of binding interaction with the server: 
> ========================================
> 32	17.839052	13.198.98.107	13.198.98.35	LDAP	bindRequest(1) "<ROOT>" sasl 
> 33	17.917608	13.198.98.35	13.198.98.107	LDAP	bindResponse(1) saslBindInProgress 
> 35	17.919333	13.198.98.107	13.198.98.35	LDAP	bindRequest(2) "<ROOT>" [Malformed Packet]
>   Lightweight-Directory-Access-Protocol
>     LDAPMessage bindRequest(2) "<ROOT>"
>       messageID: 2
>       protocolOp: bindRequest (0)
>         bindRequest
>           version: 3
>           name: 
>           authentication: sasl (3)
>             sasl
>               mechanism: GSSAPI
>               credentials: <MISSING>
>     [Malformed Packet: LDAP]
> 36	17.919637	13.198.98.35	13.198.98.107	LDAP	bindResponse(2) saslBindInProgress 
> 37	17.920316	13.198.98.107	13.198.98.35	LDAP	bindRequest(3) "<ROOT>" sasl 
> 38	17.920691	13.198.98.35	13.198.98.107	LDAP	bindResponse(3) success 
> ========================================
> I am not sure if packet 35 is normal or not? After all, it says the packet is malformed. Luckily, it will not affect the result of SASL binding.
> 
> In contrast, a trace captured with OpenLDAP ldapsearch utility does not have this malformat packet: 
> ========================================
> 20	24.622555	13.198.98.190	13.198.98.35	LDAP	bindRequest(1) "<ROOT>" sasl 
> 22	24.805633	13.198.98.35	13.198.98.190	LDAP	bindResponse(1) saslBindInProgress 
> 28	26.616093	13.198.98.190	13.198.98.35	LDAP	bindRequest(2) "<ROOT>" sasl 
>   Lightweight-Directory-Access-Protocol
>     LDAPMessage bindRequest(2) "<ROOT>"
>       messageID: 2
>       protocolOp: bindRequest (0)
>         bindRequest
>           version: 3
>           name: 
>           authentication: sasl (3)
>             sasl
>               mechanism: GSSAPI
>         [Response In: 29]
> 29	26.616459	13.198.98.35	13.198.98.190	LDAP	bindResponse(2) saslBindInProgress 
> 31	26.616705	13.198.98.190	13.198.98.35	LDAP	bindRequest(3) "<ROOT>" sasl 
> 32	26.633134	13.198.98.35	13.198.98.190	LDAP	bindResponse(3) success 
> ========================================
> When I compare the content of packet 35 in MozLDAP trace and packet 28 in OpenLDAP trace, it is noted that the MozLDAP packet has extra bytes "04 00" after "mechanism: GSSAPI". These extra bytes are interpreted as "<MISSING> credentials" by WireShark. In contrast, although the OpenLDAP packet doesn't have any credential information as well, it doesn't have these extra bytes. That's why packet 35 in MozLDAP trace is marked as Malformed Packet, while packet 28 in OpenLDAP trace is not.
> 
> Looking into the code of MozLDAP, I found the following is suspicous: 
> ========================================
> int
> LDAP_CALL
> ldap_sasl_bind(
>     LDAP		*ld,
>     const char		*dn,
>     const char		*mechanism,
>     const struct berval	*cred,
>     LDAPControl		**serverctrls,
>     LDAPControl		**clientctrls,
>     int			*msgidp
> )
> {
>   ...
> 		if ( cred == NULL ) {
> 			rc = ber_printf( ber, "{it{ist{s}}", msgid,
> 			    LDAP_REQ_BIND, ldapversion, dn, LDAP_AUTH_SASL,
> 			    mechanism );
> 		} else {
> 			rc = ber_printf( ber, "{it{ist{so}}", msgid,
> 			    LDAP_REQ_BIND, ldapversion, dn, LDAP_AUTH_SASL,
> 			    mechanism, cred->bv_val,
> 			    cred->bv_len );
> 		}
>   ...
> }
> ========================================
> At the first look, it seem innocent. But...
> 
> Let's have a look at OpenLDAP's code as well: 
> ========================================
> int
> ldap_sasl_bind(
> 	LDAP			*ld,
> 	LDAP_CONST char	*dn,
> 	LDAP_CONST char	*mechanism,
> 	struct berval	*cred,
> 	LDAPControl		**sctrls,
> 	LDAPControl		**cctrls,
> 	int				*msgidp )
> {
>   ...
> 	if( mechanism == LDAP_SASL_SIMPLE ) {
> 		/* simple bind */
> 		rc = ber_printf( ber, "{it{istON}" /*}*/,
> 			id, LDAP_REQ_BIND,
> 			ld->ld_version, dn, LDAP_AUTH_SIMPLE,
> 			cred );
> 		
> 	} else if ( cred == NULL || cred->bv_val == NULL ) {
> 		/* SASL bind w/o credentials */
> 		rc = ber_printf( ber, "{it{ist{sN}N}" /*}*/,
> 			id, LDAP_REQ_BIND,
> 			ld->ld_version, dn, LDAP_AUTH_SASL,
> 			mechanism );
> 
> 	} else {
> 		/* SASL bind w/ credentials */
> 		rc = ber_printf( ber, "{it{ist{sON}N}" /*}*/,
> 			id, LDAP_REQ_BIND,
> 			ld->ld_version, dn, LDAP_AUTH_SASL,
> 			mechanism, cred );
> 	}
>   ...
> }
> ========================================
> Comparing both snippets of MozLDAP and OpenLDAP, I am wondering whether MozLDAP should add the condition "|| cred->bv_val == NULL" to the already existing one "if ( cred == NULL )" to decide whether to do SASL binding without explicit credential.

And || cred->bv_len == 0 too
> 
> I feel this is why there is Malformed Packet in MozLDAP SASL trace, but hope someone in the list more familiar with the code can confirm. 

Please file a bug in bugzilla.mozilla.org against the LDAP C SDK.

> 
> Thanks,
> Xu Qiang