php / php/php-src

LDAPS client certificate authentication does not work

Offen
#12,081 6 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Dieses Issue hat noch niemand übernommen.

Bug Extension: ldap Status: Needs Triage
Vorherrschende Sprache
C
Sterne
40.4k
Forks
8.1k
Ø Merge
2 T. 13 Std.
Gemergte PRs (30 T.)
96

Beschreibung

Description

The following code:

<?php

// Test case for PHP bug: https://bugs.php.net/bug.php?id=73558
//
// The two commands below work totally fine:
//
// OpenSSL:
// $ openssl s_client -verifyCAfile ca.crt -cert ldap-client.crt -key ldap-client.key -connect ldap.home.arpa:636
//
// ldapsearch:
// $ LDAPTLS_CACERT=ca.crt LDAPTLS_CERT=ldap-client.crt LDAPTLS_KEY=ldap-client.key ldapwhoami -H ldaps://ldap.home.arpa -x
// anonymous

$ldapUri = 'ldaps://ldap.home.arpa';
$caFile = __DIR__.'/ca.crt';
$certFile = __DIR__.'/ldap-client.crt';
$keyFile = __DIR__.'/ldap-client.key';

//putenv(sprintf('LDAPTLS_CACERT=%s', $caFile));
//putenv(sprintf('LDAPTLS_CERT=%s', $certFile));
//putenv(sprintf('LDAPTLS_KEY=%s', $keyFile));

$ldapResource = ldap_connect($ldapUri);
$ldapOptions = [
    LDAP_OPT_PROTOCOL_VERSION => 3,
    LDAP_OPT_REFERRALS => 0,
    LDAP_OPT_X_TLS_CACERTFILE => $caFile,
    LDAP_OPT_X_TLS_CERTFILE => $certFile,
    LDAP_OPT_X_TLS_KEYFILE => $keyFile,
];

foreach($ldapOptions as $k => $v) {
    ldap_set_option($ldapResource, $k, $v);
}

if(false === ldap_bind($ldapResource)) {
    ldap_get_option($ldapResource, LDAP_OPT_DIAGNOSTIC_MESSAGE, $errMsg);
    echo sprintf(
        "%s (%d): %s\n",
        ldap_error($ldapResource),
        ldap_errno($ldapResource),
        $errMsg
    );
}

var_dump(
    ldap_exop_whoami($ldapResource)
);

Resulted in this output:

PHP Warning:  ldap_bind(): Unable to bind to server: Can't contact LDAP server in /home/fkooman/ldap.home.arpa/ldap_test.php on line 36
Can't contact LDAP server (-1): error:0A000086:SSL routines::certificate verify failed (self-signed certificate in certificate chain)
PHP Warning:  ldap_exop_whoami(): Whoami extended operation failed: Can't contact LDAP server (-1) in /home/fkooman/ldap.home.arpa/ldap_test.php on line 47
bool(false)

But I expected this output instead (anonymous bind):

string(0) ""

Workaround

When you enable the three putenv lines, things start working, but this probably not how it should be :)

Additional details

It seems the options LDAP_OPT_X_TLS_CACERTFILE, LDAP_OPT_X_TLS_CERTFILE and LDAP_OPT_X_TLS_KEYFILE are somehow ignored.

We tested this on Fedora 38 (PHP 8.2.9 (cli) (built: Aug 3 2023 11:39:08) (NTS gcc x86_64)):

LDAP Support => enabled
Total Links => 0/unlimited
API Version => 3001
Vendor Name => OpenLDAP
Vendor Version => 20604
SASL Support => Enabled

Directive => Local Value => Master Value
ldap.max_links => Unlimited => Unlimited

And on Debian 12 (PHP 8.2.7 (cli) (built: Jun 9 2023 19:37:27) (NTS)):

LDAP Support => enabled
Total Links => 0/unlimited
API Version => 3001
Vendor Name => OpenLDAP
Vendor Version => 20513
SASL Support => Enabled

Directive => Local Value => Master Value
ldap.max_links => Unlimited => Unlimited

See also: https://bugs.php.net/bug.php?id=73558

Test Setup without LDAP server

If you do not have an LDAP server, you can also use openssl to create a test server that results in the exact same error message in the PHP script as the problem is in the TLS setup, not the actual LDAP connection:

$ openssl s_server -CAfile ca.crt -cert ldap.home.arpa.crt -key ldap.home.arpa.key

All you need is the client cert/key, server cert/key and CA and connect to port 4433 (the default of s_server).

PHP Version

PHP 8.2.9 / 8.2.7

Operating System

Fedora 38 / Debian 12

Beitragsleitfaden

Beitragsleitfaden öffnen

Erste Schritte

  1. Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
  3. Forke das Repository und arbeite in einem Branch.
  4. Öffne einen Pull Request, der die Issue-Nummer nennt.

Rechercherichtung

Beginnen Sie mit dem bereitgestellten PHP-Skript, insbesondere mit ldap_set_option(), ldap_bind() und den Optionen LDAP_OPT_X_TLS_*, und reproduzieren Sie anschließend die TLS-Einrichtung mit dem gezeigten openssl s_server-Befehl. Vergleichen Sie diesen Weg mit der funktionierenden Konfiguration über Umgebungsvariablen. Als abgeschlossen gilt die Aufgabe, wenn die Zertifikatsoptionen berücksichtigt werden und sowohl der Bind als auch ldap_exop_whoami() ohne den Zertifikatsüberprüfungsfehler erfolgreich sind.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
php
Bereich
authentication, networking, security
Issue-Typ
Bug
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Veraltet
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
35/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.