[Date Prev][Date Next] [Chronological] [Thread] [Top]

StartTLS issues (ITS#3037)



Hello,

We've spent some time digging into the issue. Here is the results; 

1. Request

The following table illustrates how parameters passed to the
ldap_extended_operation_s() influence upon the ANS.1 data being transferred
on wire.

Client API    |ldap_extended_operation_s()           | Sent Message
=======================================================================
OpenLDAP      | requestdata = NULL		           | w/o data octets
-----------------------------------------------------------------------
OpenLDAP      | requestdata = struct berval{0, NULL} | an empty berval
-----------------------------------------------------------------------
Netscape      | requestdata = NULL                   | N/A (crash)
-----------------------------------------------------------------------
Netscape      | requestdata = struct berval{0, NULL} | the empty berval
-----------------------------------------------------------------------
Microsoft     | requestdata = NULL                   | the empty berval
-----------------------------------------------------------------------
Microsoft     | requestdata = struct berval{0, NULL} | the empty berval
----------------------------------------------------------------------- 

Form this table you can see that Netscape and Microsoft API always send
empty an berval structure even if request data has to be absent (i.e. NULL).

Unfortunately, OpenLDAP server does not accept such requests for the
'StartTLS' extended operation because of the following code:

starttls.c (starttls_extop() function):

	if ( op->ore_reqdata != NULL ) {
		/* no request data should be provided */
		rs->sr_text = "no request data expected";
		return LDAP_PROTOCOL_ERROR;
	}

This code makes it impossible to execute 'StartTLS' operation if it is made
by clients who compiled against Netscape or Microsoft APIs. (The same is
true for the 'Who Am I' operation)

The fix for the problem is trivial: 

	if ( op->ore_reqdata != NULL && op->ore_reqdata->bv_len > 0) {
		/* no request data should be provided */
		rs->sr_text = "no request data expected";
		return LDAP_PROTOCOL_ERROR;
	}

We completely understand that this workaround contradicts RFC2830
(Lightweight Directory Access Protocol (v3): Extension for Transport Layer
Security)
saying:
...
   A Start TLS extended request is formed by setting the requestName
   field to the OID string given above.  The requestValue field is
   absent.
...
Still, we believe that the fix should be applied because of the huge amount
of mentioned clients installed worldwide.

2. Response

Having fixed described above we came across another issues which concerns
TLS extended operation response.

As RFC2830 states:

...
   A Start TLS extended response MUST contain a responseName field which
   MUST be set to the same string as that in the responseName field
   present in the Start TLS extended request.
...

Unfortunately OpenLDAP server doesn't return the 'responseName' field. This
defect may prevent other LDAP APIs from understanding the response of
OpenLDAP servers. For instance, Microsoft LDAP API doesn't accept the
response without this field. We suggest to add the responseName field to the
response. This is also a trivial one:

rs->sr_rspoid = SLAP_STRDUP(LDAP_EXOP_START_TLS);

before 'rc = LDAP_SUCCESS;' in starttls_extop() function (starttls.c).

3. Patch

Unfortunately didn't manage to get access to the /incoming FTP folder
despite the fact I used my email as password. So here is a patch for both
problems:

=============
--- orig/starttls.c	2004-01-01 21:15:32.000000000 +0200
+++ fixed/starttls.c	2004-05-27 14:14:54.000000000 +0300
@@ -94,6 +94,8 @@
     op->o_conn->c_is_tls = 1;
     op->o_conn->c_needs_tls_accept = 1;
 
+    rs->sr_rspoid = SLAP_STRDUP(LDAP_EXOP_START_TLS);
+
     rc = LDAP_SUCCESS;
 
 done:
=============

Looking forward for your comments...

Sincerely yours,

Kirill Kovalenko
Softerra LLC
http://www.softerra.com
mailto:kirill@softerra.com