h.b.furuseth(a)usit.uio.no wrote:
> Full_Name: Hallvard B Furuseth
> Version: HEAD, 2.3, 2.4
> OS: Linux
> URL: ftp://ftp.openldap.org/incoming/Hallvard-Furuseth-080627.diff
> Submission from: (NULL) (129.240.6.233)
> Submitted by: hallvard
>
>
> OpenLDAP only uses the default certificates installed with OpenSSL if
> TLS_CACERT or TLS_CACERTDIR is set. Or presumably
> TLSCACertificate<File/Dir> in servers, but the libldap/tls.c code for
> servers seem to require a certificate chain from that directory anyway.
>
Sounds like this works as designed. The docs tell you that either CACERT or
CACERTDIR must be explicitly configured.
--
-- Howard Chu
CTO, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/
Full_Name: Hallvard B Furuseth
Version: HEAD, 2.3, 2.4
OS: Linux
URL: ftp://ftp.openldap.org/incoming/Hallvard-Furuseth-080627.diff
Submission from: (NULL) (129.240.6.233)
Submitted by: hallvard
OpenLDAP only uses the default certificates installed with OpenSSL if
TLS_CACERT or TLS_CACERTDIR is set. Or presumably
TLSCACertificate<File/Dir> in servers, but the libldap/tls.c code for
servers seem to require a certificate chain from that directory anyway.
To reproduce:
$ export LDAPCONF=/dev/null
$ ldapwhoami -xZZh ldap.uio.no
certificate verify failed
$ export LDAPTLS_CACERT="*any* certificate.pem file"
$ ldapwhoami -xZZh ldap.uio.no
anonymous
Or if it still fails, find where OpenSSL wants its default certs:
strace ldapwhoami -xZZh ldap.uio.no 2>&1 | grep ssl
and temporarily append the root cert which signed our server cert from
https://secure.globalsign.net/cacert/CT_Root_CA.pem
Then try again. Something like /usr/local/ssl/cert.pem.
$ ldapwhoami -xZZh ldap.uio.no
anonymous
$ unset LDAPTLS_CACERT; ldapwhoami -xZZh ldap.uio.no
certificate verify failed
The relevant code is in libldap/tls.c:ldap_int_tls_init_ctx().
I enclose a tentative patch which fixes the above problem, but
I'm not sure it's the right one for servers and GnuTLS.
The GnuTLS branch does not require a server TLSCACertificateFile,
but the OpenSSL code does. I don't know if GnuTLS has a default
which is used instead, nor if OpenSSL can have that.
On Fri, Jun 27, 2008 at 03:17:10PM +0000, Andrew Findlay wrote:
> Hmm: I now have a crasher in attr_valadd when adding a member to a
> group that already contains two members. Not sure yet whether I caused it
> with the minus-one-line fix above, or whether I have uncovered a new
> problem.
> for ( j = a->a_numvals; j >= slot; j-- ) {
> a->a_vals[j+1] = a->a_vals[j]; <==================== Crash here
> if ( nvals )
> a->a_nvals[j+1] = a->a_nvals[j];
> }
... so I stepped through that in GDB. j did indeed start at 2 and
decrement to 0, but then it kept going!
407 for ( j = a->a_numvals; j >= slot; j-- ) {
(gdb)
408 a->a_vals[j+1] = a->a_vals[j];
(gdb) print j
$17 = 1
(gdb) print a->a_vals[j]
$18 = {bv_len = 97,
bv_val = 0x847b680 "uniqueIdentifier=a3,ou=accounts,uniqueIdentifier=to-a,dc=orgs,...."}
(gdb) n
409 if ( nvals )
(gdb)
410 a->a_nvals[j+1] = a->a_nvals[j];
(gdb)
407 for ( j = a->a_numvals; j >= slot; j-- ) {
(gdb)
408 a->a_vals[j+1] = a->a_vals[j];
(gdb) print print a->a_vals[j]
A syntax error in expression, near `a->a_vals[j]'.
(gdb) print a->a_vals[j]
$19 = {bv_len = 96,
bv_val = 0x847b618 "uniqueIdentifier=ag1,ou=groups,uniqueIdentifier=to-a,dc=orgs,..."}
(gdb) n
slap_client_connect: URI=ldap://localhost:2389/ DN="cn=replicator,dc=accounts,...." ldap_sasl_bind_s failed (-1)
do_syncrepl: rid=002 retrying (5 retries left)
409 if ( nvals )
(gdb)
410 a->a_nvals[j+1] = a->a_nvals[j];
(gdb)
407 for ( j = a->a_numvals; j >= slot; j-- ) {
(gdb)
408 a->a_vals[j+1] = a->a_vals[j];
(gdb) print j
$20 = -1
(gdb) n
409 if ( nvals )
(gdb) print slot
$21 = 0
(gdb) n
410 a->a_nvals[j+1] = a->a_nvals[j];
(gdb)
slap_client_connect: URI=ldap://localhost:2389/ DN="cn=replicator,dc=accounts,..." ldap_sasl_bind_s failed (-1)
do_syncrepl: rid=002 retrying (4 retries left)
407 for ( j = a->a_numvals; j >= slot; j-- ) {
(gdb)
408 a->a_vals[j+1] = a->a_vals[j];
(gdb) print j
$22 = -2
(gdb) print j >= slot
$23 = 1
(gdb) print slot
$24 = 0
Curiouser and curiouser cried Alice...
(gdb) whatis j
type = int
(gdb) whatis slot
type = unsigned int
Aha! Comparing signed and unsigned integers. Could be risky.
I don't do much C these days, and I don't see many explicit type-casts
in OpenLDAP code. What would be a good-practice solution here?
Casting slot to long int seems to work for me so I have updated the patch:
ftp://ftp.openldap.org/incoming/andrew.findlay-sortvals-20080627.patch
Andrew
--
-----------------------------------------------------------------------
| From Andrew Findlay, Skills 1st Ltd |
| Consultant in large-scale systems, networks, and directory services |
| http://www.skills-1st.co.uk/ +44 1628 782565 |
-----------------------------------------------------------------------
On Thu, Jun 26, 2008 at 10:00:00AM +0000, Andrew Findlay wrote:
> I have uploaded a proposed fix for this:
>
> ftp://ftp.openldap.org/incoming/andrew-findlay-sortvals-20080626.patch
>
> My reasoning is that the break statement terminates the loop before
> the last value in the list has been compared with the assertion value.
> Thus, even if the last value matches, the loop ends with -1 in 'match'.
Hmm: I now have a crasher in attr_valadd when adding a member to a
group that already contains two members. Not sure yet whether I caused it
with the minus-one-line fix above, or whether I have uncovered a new
problem.
I would expect the new value to sort at the front of the list.
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1518945392 (LWP 1431)]
0x0806e650 in attr_valadd (a=0xa6c71084, vals=0x847a148, nvals=0x847a190, nn=1) at attr.c:410
410 a->a_nvals[j+1] = a->a_nvals[j];
(gdb) where
#0 0x0806e650 in attr_valadd (a=0xa6c71084, vals=0x847a148, nvals=0x847a190, nn=1) at attr.c:410
#1 0x080b4db3 in modify_add_values (e=0xa5769cb0, mod=0x8479a98, permissive=0, text=0xa576b17c, textbuf=0xa5769bb0 "",
textlen=256) at mods.c:155
#2 0x080d0d4e in bdb_modify_internal (op=0x83964e0, tid=0x847b400, modlist=0x8479a98, e=0xa5769cb0, text=0xa576b17c,
textbuf=0xa5769bb0 "", textlen=256) at modify.c:101
#3 0x080d1926 in bdb_modify (op=0x83964e0, rs=0xa576b168) at modify.c:578
#4 0x080c6b21 in overlay_op_walk (op=0x83964e0, rs=0xa576b168, which=op_modify, oi=0x82f9a18, on=0x82fa0c8) at backover.c:646
#5 0x080c709d in over_op_func (op=0x83964e0, rs=0xa576b168, which=op_modify) at backover.c:698
#6 0x0807dd36 in fe_op_modify (op=0x83964e0, rs=0xa576b168) at modify.c:300
#7 0x0807e6a8 in do_modify (op=0x83964e0, rs=0xa576b168) at modify.c:175
#8 0x08065646 in connection_operation (ctx=0xa576b238, arg_v=0x83964e0) at connection.c:1084
#9 0x08065c42 in connection_read_thread (ctx=0xa576b238, argv=0x1f) at connection.c:1211
#10 0x0817e454 in ldap_int_thread_pool_wrapper (xpool=0x82b4310) at tpool.c:663
#11 0xb7c19112 in start_thread () from /lib/libpthread.so.0
#12 0xb7ba52ee in clone () from /lib/libc.so.6
(gdb) print j
$1 = -305887
(gdb) print a
$2 = (Attribute *) 0xa6c71084
(gdb) print *a
$3 = {a_desc = 0x82e12e8, a_vals = 0x847ba28, a_nvals = 0x847b6e8, a_numvals = 2, a_flags = 16, a_next = 0xa6c7bd34}
(gdb) print slot
$4 = 0
(gdb) print nvals
$5 = (BerVarray) 0x847a190
(gdb)
The relevant code block is this:
/* If sorted and old vals exist, must insert */
if (( a->a_flags & SLAP_ATTR_SORTED_VALS ) && a->a_numvals ) {
unsigned slot;
int j, rc;
v2 = nvals ? nvals : vals;
for ( i = 0; i < nn; i++ ) {
rc = attr_valfind( a, SLAP_MR_EQUALITY | SLAP_MR_VALUE_OF_ASSERTION_SYNTAX |
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH | SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH,
&v2[i], &slot, NULL );
if ( rc != LDAP_NO_SUCH_ATTRIBUTE ) {
/* should never happen */
if ( rc == LDAP_SUCCESS )
rc = LDAP_TYPE_OR_VALUE_EXISTS;
return rc;
}
for ( j = a->a_numvals; j >= slot; j-- ) {
a->a_vals[j+1] = a->a_vals[j]; <==================== Crash here
if ( nvals )
a->a_nvals[j+1] = a->a_nvals[j];
}
ber_dupbv( &a->a_nvals[slot], &v2[i] );
if ( nvals )
ber_dupbv( &a->a_vals[slot], &vals[i] );
a->a_numvals++;
}
BER_BVZERO( &a->a_vals[a->a_numvals] );
if ( a->a_vals != a->a_nvals )
BER_BVZERO( &a->a_nvals[a->a_numvals] );
} else {
I cannot see how j got that large negative value. It should have started the
loop at 2 (a->a_numvals) and decremented until it reached zero.
Must have been overwritten somewhere.
Andrew
--
-----------------------------------------------------------------------
| From Andrew Findlay, Skills 1st Ltd |
| Consultant in large-scale systems, networks, and directory services |
| http://www.skills-1st.co.uk/ +44 1628 782565 |
-----------------------------------------------------------------------
Howard Chu wrote:
> zdi-disclosures(a)tippingpoint.com wrote:
>> Full_Name: Cameron Hotchkies
>> Version: 2.3.41
>> OS: Gentoo Linux
>> URL: ftp://ftp.openldap.org/incoming/
>> Submission from: (NULL) (66.179.208.36)
>>
>>
>> This vulnerability allows remote attackers to deny services on vulnerable
>> installations of OpenLDAP. Authentication is not required to exploit this
>> vulnerability.
>
> Thanks for the report, a fix is now in HEAD. Please test.
For future reference, it looks like this may have crept in in 2001, rev
1.88/ITS#2465...
--
-- Howard Chu
CTO, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/
zdi-disclosures(a)tippingpoint.com wrote:
> Full_Name: Cameron Hotchkies
> Version: 2.3.41
> OS: Gentoo Linux
> URL: ftp://ftp.openldap.org/incoming/
> Submission from: (NULL) (66.179.208.36)
>
>
> This vulnerability allows remote attackers to deny services on vulnerable
> installations of OpenLDAP. Authentication is not required to exploit this
> vulnerability.
Thanks for the report, a fix is now in HEAD. Please test.
> The specific flaw exists in the decoding of ASN.1 BER network datagrams. When
> the size of a BerElement is specified incorrectly, the application will trigger
> an assert(), leading to abnormal program termination.
> Tech Details:
>
> The code exhibiting the problem is located in the function ber_get_next()
> function in "libraries/liblber/io.c" .
>
> The function fails to handle properly BER encoding of an element (tag + length +
> content) that contains:
>
> * exactly 4 bytes long "multi-byte tag"
> * exactly 4 bytes long "multi-byte size"
>
> The total size of the resulting encoding equals to the size of the BerElement
> structure buffer plus one byte. This causes the function returns indicating that
> more data are needed, but leaves the read-pointer pointing right at the end of
> the buffer, which is not permitted.
>
> Subsequent calls to the function result in an assertion failure:
>
> assert( 0 ); /* ber structure is messed up ?*/
>
> Example Exploitation:
>
> > slapd -h ldap:// -d511&
> ...
> > xxd packet
> 0000000: ffff ff00 8441 4243 44 .....ABCD
> > nc localhost 389< packet
>
>
>
--
-- Howard Chu
CTO, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/
Full_Name: Anderson M. Gomes
Version: 2.4.9 (but 2.4.10 has the bug)
OS: Ubuntu 8.04.1
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (189.58.241.178)
I submitted a bug report in Ubuntu's Launchpad. The address is:
https://bugs.launchpad.net/ubuntu/+source/openldap2.3/+bug/243337
The bug refers to 2.4.9, but it is reproducible in OpenLDAP 2.4.10 (I could
reproduce it, at least).
Full_Name: Cameron Hotchkies
Version: 2.3.41
OS: Gentoo Linux
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (66.179.208.36)
This vulnerability allows remote attackers to deny services on vulnerable
installations of OpenLDAP. Authentication is not required to exploit this
vulnerability.
The specific flaw exists in the decoding of ASN.1 BER network datagrams. When
the size of a BerElement is specified incorrectly, the application will trigger
an assert(), leading to abnormal program termination.
Tech Details:
The code exhibiting the problem is located in the function ber_get_next()
function in "libraries/liblber/io.c" .
The function fails to handle properly BER encoding of an element (tag + length +
content) that contains:
* exactly 4 bytes long "multi-byte tag"
* exactly 4 bytes long "multi-byte size"
The total size of the resulting encoding equals to the size of the BerElement
structure buffer plus one byte. This causes the function returns indicating that
more data are needed, but leaves the read-pointer pointing right at the end of
the buffer, which is not permitted.
Subsequent calls to the function result in an assertion failure:
assert( 0 ); /* ber structure is messed up ?*/
Example Exploitation:
> slapd -h ldap:// -d511 &
...
> xxd packet
0000000: ffff ff00 8441 4243 44 .....ABCD
> nc localhost 389 < packet
Full_Name: Andrew Findlay
Version: 2.4.10
OS: Linux
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (88.97.25.132)
If an account becomes locked due to excessive failed authentications, its entry
will contain the attributes pwdFailureTime and pwdAccountLockedTime. If the
account is subsequently unlocked by setting a new password, all values of those
attributes are automatically removed. However, if the password is left alone and
the account is unlocked by removing pwdAccountLockedTime, values remain in
pwdFailureTime. This means that a single authentication failure will immediately
lock the account again.
pwdFailureTime cannot be modified directly, so I think there is a case for
clearing it when pwdAccountLockedTime is cleared explicitly.
Andrew
I have uploaded a proposed fix for this:
ftp://ftp.openldap.org/incoming/andrew-findlay-sortvals-20080626.patch
My reasoning is that the break statement terminates the loop before
the last value in the list has been compared with the assertion value.
Thus, even if the last value matches, the loop ends with -1 in 'match'.
Andrew
--
-----------------------------------------------------------------------
| From Andrew Findlay, Skills 1st Ltd |
| Consultant in large-scale systems, networks, and directory services |
| http://www.skills-1st.co.uk/ +44 1628 782565 |
-----------------------------------------------------------------------