possible LDAP over SSl bug in OS 10, 10.4, 10.5, 10.6

S

Schley Andrew Kutz

This was submitted to Apple Bug Reporter on Oct. 23rd 2004.

---

23-Oct-2004 02:57 PM Schley Kutz:
Summary:
--------
As I have been reminded, for all intensive purposes I represent the
greater community of Mac users here at the University of Texas at
Austin who want to get Entourage to be as feature-full as it is
advertised to be. UT@Austin is the largest public university in the
nation, and at one time it was the largest concentration of Macs in the
nation as well. Hence, this is something that *really* needs to work.

Microsoft released Entourage 2004 into the ready hands of users
clamoring for a product that was the equivalent of Outlook 2003 and
would give Mac users a portal to access Exchange. Entourage 2004 had
some problems however. Particularly it did not let users securely
access the GAL (Directory Access in Entourage) or securely acknowledge
themselves as delegates. These were both LDAP over SSL issues. These
problems were thought to be on Entourage's part.

Then Service Pack 1 for Office 2004 came out. I applied it with great
hopes that it would fix the LDAP over SSL issue that plagued so many
users. It did not. I then composed a *very* long email to our
Microsoft Technical Account Manager (TAM). The email detailed all the
steps I had taken with Ethereal and ssltap to determine that Entourage
could decidedly still not properly talk to LDAP over SSL. Towards the
end of composing the email I decided to reconfirm that native OS X apps
would access a LDAP server over SSL. Much to my surprise (since this
had been tested before) Address Book could not talk to
austin.utexas.edu via SSL.

So the problem is deeper than Entourage 2004. The problem that I found
seems to be an issue with the way that OS X's Directory Services
framework interacts with OpenLDAP.


Steps to Reproduce:
-------------------
Thus began my journey on a different path. I compiled ssldump for OS X
and began examining different configurations of LDAP queries. I
realized that I had to test these configurations on more than just our
Active Directory so Eric Irrgang and Robert Kennedy of the ITS Unix
group graciously assisted me with this. Eric set me up with an account
on the Unix group's internal LDAP server, and Robert showed me some
basic openldap command line commands such as ldapsearch. In fact, I
used several programs to test LDAP over SSL functionality on OS X.
They are:

a) Address Book.app
b) JXplorer
c) ldapsearch
d) Entourage 2004 - Directory Service
e) Entourage 2004 - Delegates

d and e may seem surprising but it is the case while Directory Service
(the GAL) and Delegates in Entourage 2004 both issue the same type of
LDAP requests (I watch unencrypted traffic in Ethereal to prove this),
they produce different errors in ssldump when they do not work as
advertised.

There were three distinctly different results when trying to access
LDAP over SSL:

1) LDAP over SSL works successfully and much giddiness ensued

2) LDAP over SSL works and ssldump reports (in several fashions) an
Unknown Certificate Authority (ca|CA) error. This permutation will in
some cases report an error to the user but in fact all the traffic is
still encrypted and as far as Entourage's Directory Service is
concerned the data is still retrieved.

3) LDAP over SSL fails and ssldump reports that an Unknown CA was the cause.

4) LDAP over SSL fails completely. This is what sparked the OS X
investigation. What is odd about this error was the ssldump output.
It showed that although the commands were being issued over port 636
(ldaps port), the client was trying to initiate a NON SSL connection to
the server. At this point the server basically says "Um, yes, I am
terribly sorry sir but it would be entirely improper of me if I were to
allow you to continue this obvious assault on my person. Please make
haste in your efforts to retreat from my doorstep lest I be forced to
commit a barbaric act of v101ence."

I exported two Certification Authority certificates to Base64 format.
They were the Secure Server Certification Authority certificate (SSCA)
(a standard Verisign CA), which is used by our Active Directory, and
the ITS Unix CA certificate, used by the Unix group's LDAP server. I
imported these into Keychain Access's X509Anchors keychain (I removed
the original SSCA CA from the keychain prior to adding mine) which
should be used by Address Book.app and Entourage 2004. Next, I
imported these into Jxplorer's Key Store. Finally, I used the
TLS_CACERT option in my .ldaprc file to specify the CA to use when
executing the OpenLDAP command ldapsearch. I then removed ALL of the
certificates and ran the tests again in order to get a full suite of
debugging information.

Here is a simple chart of the different configurations I tested. I
have attached text files of the logs for these configurations.
Although I tested this on 5 different systems (see Isolation for OS
versions), I only generated log files for my primary test system.

For interpreting the chart please refer to the alpha and numeric scheme
I used for lableling the applications I tested and the results I found.

yca = with Certificate Authority certificate installed for the ldap
server I was accessing

nca = without Certificate Authority certificate installed for the ldap
server I was accessing


a | b | c | d | e |
|----------|----------|----------|----------|----------|
yca | 4 | 1 | 1 | 2 | 4 |
|----------|----------|----------|----------|----------|
nca | 4 | 3 | 3 | 2 | 4 |
|----------|----------|----------|----------|----------|


yca/a - Address Book.app fails completely nca/a - Address Book.app
fails completely

yca/b - JXplorer works
nca/b - Jxplorer fails because of unknown CA

yca/c - ldapsearch works
nca/c - ldapsearch fails because of unknown CA

yca/d - Entourage Directory Service throws an error but continues to
return good data that IS encrypted nca/d - Entourage Directory Service
throws an error but continues to return good data that IS encrypted

yca/e - Entourage Delegates fails completely nca/e - Entourage
Delegates fails completely

So what do these results tell me? Well, what is MOST interesting is
that 2 different parts of the application that started this all,
Entourage, must use ENTIRELY DIFFERENT methods of doing a directory
lookup. I know this because they throw completely different errors.

What is telling about the Delegates error is that it is exactly the
same as the Address Book.app's error. This got me thinking. How can I
duplicate all of Entourage's errors (Address Book.app's error is the
same as Entourage's Delegates error so if I can dupe the Delegates
error I will have duped the Address Book.app error) errors with
OpenLDAP's command line tool, ldapsearch?

First, the not so shocking discovery. The error that the Entourage
Directory Service gives is that it cannot find the CA. Well that is
easy enough to reproduce. I just removed the TLS_CACERT definition
that pointed to the SSCA cert that our AD uses from my .ldaprc file. I
then defined TLS_CERT as 'request' and did an ldapsearch against our
AD. This produced the exact same error that Entourage gives when using
its Directory Service. Essentially, when Entourage issues a directory
request from its Directory Service it gets to OpenLDAP as a call that
does not use a CA but requests one. This causes the client to say
"Hey, I know you have a CA to give me, but I don't have one to give
you. Eh, don't worry about it. I'll take a warning sure, but we can
still talk in that crazy encrypted lingo that those cats like to call
SSL." The logs show a warning but all traffic still occurs and is
still encrypted.

When I removed the TLS_CACERT definition and executed the same command:

ldapsearch -H "ldaps://server.name.utexas.edu:636" -W -D "CN=not
real,OU=yeah right,OU=not on your
life,DC=server,DC=name,DC=utexas,DC=edu"

I received this error:

TLS certificate verification: Error, unable to get local issuer certificate

This just proves that it is at a different location than OpenLDAP that
the request of the CA from KeyChain happens. I could not find a
reference to X509 or Keychain (grep -ri) in any of the DirectoryAccess
sources either. I could not find a header for OpenSSL on a clean 10.3
install either. Hmmm. Duh! I finally found ssl.h in the DevSDK and
openssl header includes in the DirectoryAccess headers. OpenSSL
sources do not exist, that I found, in a clean install of OS X, but
rather are compiled into /usr/bin/openssl and the OS X Directory
Service.

This still begs the question, why is the "Cannot find root certificate"
error occurring? 1 or 2 of 2 things is happening. Either something is
improperly using /usr/bin/openssl to generate a temporary root ca from
KeyChain or something is improperly hooking into the OpenSSL libraries.

Second, the discovery that left me saying, "Huh?" Error #4 was just
odd. All the other ssldumps showed the client's first contact with the
server as "C->S SSLv2 Compatible Hello (636)." Basically the client
was talking to the server over 636 in SSL lingo, as it should. But the
Address Book.app and Entourage's Delegates generated this log, "C->S
(636)." It was as if the client was trying to issue LDAP commands with
a normal ldap uri "ldap://" over 636. Well this won't fly cat. Nope
man, you've got to use "ldaps://" if you want to dig on 636. At least
with OpenLDAP you do. Anyway, so I imitated this with OpenLDAP. I
executed this command to both LDAP servers:

ldapsearch -H "ldap://server.name.utexas.edu:636" -W -D "CN=not
real,OU=yeah right,OU=not on your
life,DC=server,DC=name,DC=utexas,DC=edu"

Voilla! Same error as Address Book.app and Entourage's Delegates. I
know it sounds crazy, but it looks like those two programs are issuing
LDAP commands with a non secure form of the ldap uri over port 636.
This is just silly. Of course it won't work.

How, you might ask, could this have happened? Well, really, it is not
that hard to imagine. LDAP is a protocol that is used to access what
has been, until recently, philosophically something that is "public"
information. Directories, large ones especially, are by their nature
meant to be open and read by the public. If a directory is small and
needs to be secure there are better solutions than a LDAP enabled
directory.

Anyway.

So I was able to deduce quite a bit, but I was still kind of ticked
off. I may have possibly sort of perhaps figured out *what* was going
on, but *where* is the on going? That is the real zinger of the month
.... Well, as I mentioned, Entourage seems to hook into OS X's
networking API at different places, depending on where it is calling it
from. Also, I realized that if OpenLDAP is not grabbing goodies from
X509Anchors it must be Directory Access doing the dirty deed.

This is where my good friend and hated enemy Nicholas "St. Who?"
Lauland came in. I absolutely despise him (tongue in cheek there) for
informing me that "You can get the source code for Darwin Directory
Service off of ADC. Well crap. I already knew that I could get the
source for OpenLDAP (duh! ->OPEN<-LDAP), but this new revelation just
meant that I was going to be compelled to see this through much further
along than I was mentally capable of.

Do you know what happens after you press "Search" on the Address
Book.app and expect it to search a configured LDAP server?

Neither do I. But I do know where things go from when
CLDAPv3Plugin::processRequest invokes CLDAPv3Plugin::HandleRequest.
And that is really the point where the story can start anyway since
CLDAPv3Plugin inherits the CServerPlugin class. Any LDAP-centric
configuration is going to take place once a CLDAPv3Plugin object is
instantiated.

I have attached the OpenLDAP headers and sources that contain the
functions I am going to reference. I also attached the
DirectoryService sources and headers. The Adc membership it takes to
request them is free, so whomever could actually go online an get them.
Here is a full list of the headers and sources that contain the
functions that I am going to reference. In fact, they are listed in
the order in which they are invoked, so I will only list them here:

CServerPlugin::processRequest -
DirectoryService-257.1/Server/CServerPlugin.h .cpp

CServerPlugin::HandleRequest -
DirectoryService-257.1/Server/CServerPlugin.h .cpp

CLDAPv3Plugin::OpenDirNode -
DirectoryService-257.1/Plugins/LDAPv3/CLDAPv3Plugin.h .cpp

CLDAPNode::SafeOpen - DirectoryService-257.1/Plugins/LDAPv3/CLDAPNode.h .cpp

CLDAPNode::AuthOpen - DirectoryService-257.1/Plugins/LDAPv3/CLDAPNode.h .cpp

CLDAPNode::BindProc - DirectoryService-257.1/Plugins/LDAPv3/CLDAPNode.h .cpp

ldap_bind - OpenLDAP-37.2.1/include/ldap.h /libraries/libldap/bind.c

ldap_simple_bind - OpenLDAP-37.2.1/include/ldap.h /libraries/libldap/sbind.c

ldap_sasl_bind - OpenLDAP-37.2.1/include/ldap.h /libraries/libldap/sasl.c

ldap_send_initial_request - OpenLDAP-37.2.1/include/ldap.h
/libraries/libldap/request.c

ldap_send_server_request - OpenLDAP-37.2.1/include/ldap.h
/libraries/libldap/request.c

The error occurs in the last function. The code that throws the error
is as follows:

if ( srv == NULL ) {
if ( !use_ldsb ) {
ber_sockbuf_free( lc->lconn_sb );
}
LDAP_FREE( (char *)lc );
ld->ld_errno = LDAP_SERVER_DOWN;
return( NULL );
}

The text of the error reads, "Can't contact LDAP Server." The error is
defined in OpenLDAP-37.2.1/include/ldap.h and looks like this:

#define LDAP_SERVER_DOWN 0x51


For laughs I decided to set Address Book.app and Entourage Delegates to
use SSL over port 389. Guess what? Instead of acting in error like
they do when you specify port 636/3239 (Global Catalog SSL, GCS) and
trying to talk to the server without first initiating a compatible
SSLv2 Hello, they issue a compatible SSLv2 Hello! However, I used
ethereal and verified that the traffic is in fact traveling in the
clear when you do this. BUT, it does cause Address Book.app and
Entourage Delegates to issue the correct Hello.

It seems to me that the combination of specifying SSL and talking over
port 636 causes some type of confusion in the Directory Access API. I
do not know where since I do not have the sources or headers for
Address Book.app and/or Entourage.

I confirmed the errors by duplicating the theorized process with
ldapsearch. This was the command I used:

ldapsearch -H "ldaps://server.name.utexas.edu:389" -W -D "CN=not
real,OU=yeah right,OU=not on your
life,DC=server,DC=name,DC=utexas,DC=edu"

I also tested all of the above by adding a LDAPv3 entry into OS X's
Directory Access preferences for austin.utexas.edu. I checked it by
searching against OS X's Directory Services in Address Book.app and by
doing a "lookupd -d <return> userWithName: akutz." Both failed.


Expected Results:
-----------------

Well, that table I drew earlier should look like this:

a) Address Book.app
b) JXplorer
c) ldapsearch
d) Entourage 2004 - Directory Service
e) Entourage 2004 - Delegates

1) LDAP over SSL works successfully and much giddiness ensued

2) LDAP over SSL works and ssldump reports (in several fashions) an
Unknown Certificate Authority (ca|CA) error. This permutation will in
some cases report an error to the user but in fact all the traffic is
still encrypted and as far as Entourage's Directory Service is
concerned the data is still retrieved.

3) LDAP over SSL fails and ssldump reports that an Unknown CA was the cause.

4) LDAP over SSL fails completely. This is what sparked the OS X
investigation. What is odd about this error was the ssldump output.
It showed that although the commands were being issued over port 636
(ldaps port), the client was trying to initiate a NON SSL connection to
the server. At this point the server basically says "Um, yes, I am
terribly sorry sir but it would be entirely improper of me if I were to
allow you to continue this obvious assault on my person. Please make
haste in your efforts to retreat from my doorstep lest I be forced to
commit a barbaric act of v101ence."

yca = with Certificate Authority certificate installed for the ldap
server I was accessing

nca = without Certificate Authority certificate installed for the ldap
server I was accessing


a | b | c | d | e |
|----------|----------|----------|----------|----------|
yca | 1 | 1 | 1 | 1 | 1 |
|----------|----------|----------|----------|----------|
nca | 2/3 | 2/3 | 2/3 | 2/3 | 2/3 |
|----------|----------|----------|----------|----------|


yca/a - Address Book.app works
nca/a - Address Book.app throws an error but continues to return good
data that IS encrypted OR fails because of unknown CA

yca/b - JXplorer works
nca/b - Jxplorer throws an error but continues to return good data that
IS encrypted OR fails because of unknown CA

yca/c - ldapsearch works
nca/c - ldapsearch throws an error but continues to return good data
that IS encrypted OR fails because of unknown CA

yca/d - Entourage Directory Service works nca/d - Entourage Directory
Service throws an error but continues to return good data that IS
encrypted OR fails because of unknown CA

yca/e - Entourage Delegates works
nca/e - Entourage Delegates throws an error but continues to return
good data that IS encrypted OR fails because of unknown CA

Why 2 OR 3 without the certificate authority? Because I OS X 's
Directory Service should, and from what I can tell from my testing it
apparently is not, respect any .ldaprc file in my homedir or any
ldap.conf file in /etc/openldap/ldap.conf. The ldap.conf can be in 1
or 2 more places, but the lid to my powerbook is closed, and I enjoy
watching the button light throb too much to open the lid back up to
bring up ldap.conf 's man page. Meaning Directory Service should
respect whether or not I tell OpenLDAP to ignore TLS_REQCERT and
TLS_CHECKPEER. The ldapsearch command does (of course) and anything
that implements OpenLDAP should too.

Actual Results:
---------------

a) Address Book.app
b) JXplorer
c) ldapsearch
d) Entourage 2004 - Directory Service
e) Entourage 2004 - Delegates

1) LDAP over SSL works successfully and much giddiness ensued

2) LDAP over SSL works and ssldump reports (in several fashions) an
Unknown Certificate Authority (ca|CA) error. This permutation will in
some cases report an error to the user but in fact all the traffic is
still encrypted and as far as Entourage's Directory Service is
concerned the data is still retrieved.

3) LDAP over SSL fails and ssldump reports that an Unknown CA was the cause.

4) LDAP over SSL fails completely. This is what sparked the OS X
investigation. What is odd about this error was the ssldump output.
It showed that although the commands were being issued over port 636
(ldaps port), the client was trying to initiate a NON SSL connection to
the server. At this point the server basically says "Um, yes, I am
terribly sorry sir but it would be entirely improper of me if I were to
allow you to continue this obvious assault on my person. Please make
haste in your efforts to retreat from my doorstep lest I be forced to
commit a barbaric act of v101ence."

yca = with Certificate Authority certificate installed for the ldap
server I was accessing

nca = without Certificate Authority certificate installed for the ldap
server I was accessing


a | b | c | d | e |
|----------|----------|----------|----------|----------|
yca | 4 | 1 | 1 | 2 | 4 |
|----------|----------|----------|----------|----------|
nca | 4 | 3 | 3 | 2 | 4 |
|----------|----------|----------|----------|----------|


yca/a - Address Book.app fails completely nca/a - Address Book.app
fails completely

yca/b - JXplorer works
nca/b - Jxplorer fails because of unknown CA

yca/c - ldapsearch works
nca/c - ldapsearch fails because of unknown CA

yca/d - Entourage Directory Service throws an error but continues to
return good data that IS encrypted nca/d - Entourage Directory Service
throws an error but continues to return good data that IS encrypted

yca/e - Entourage Delegates fails completely nca/e - Entourage
Delegates fails completely


Workaround:
-----------

I have not found one. Nick suggested that I recompile OpenLDAP and
throw in some extra debugging statements. I even thought of checking
for the presence of port 636 and forcing the uri to start with "ldaps."
Quite frankly, that's what the folks at Apple get paid to do : ) For
now I know the limitations of OS X and subsequently Entourage 2004 /
SP1.

All we Entourage users here at the University can do is wait.

Isolation:
----------

The same errors have occurred on 5 different Macs. Here are they
operating systems:

10.3.5
10.3.5
10.3.5
10.3.4
10.3



'one file to bind them.zip' and 'System Profile.spx'were successfully uploaded
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top