#8970 Prevent double encryption of LDAP with TLS and SASL data security layer
Opened 2 years ago by cheimes. Modified 2 years ago

Issue

LDAP communication can be protected and encrypted in multiple ways:

  • LDAP + StartTLS
  • LDAPS
  • SASL data security layer with GSSAPI based data integrity and confidentiality protection
  • LDAPI (local Unix sockets are safe)

When using GSSAPI SASL bind with TLS or StartTLS, OpenLDAP encrypts all data twice by default. The outer layer is TLS and the inner layer is the SASL data security layer.

Steps to Reproduce

  1. Open an LDAPS connection
  2. Perform SASL with GSSAPI mech (with python-ldap use sasl_flags=0 to print more debug information)
  3. Check the value of OPT_X_SASL_SSF

Actual behavior

libldap and Cyrus SASL print:

SASL/GSSAPI authentication started
SASL username: admin@IPA.EXAMPLE
SASL SSF: 256
SASL data security layer installed.

SASL SSF: 256 means that server and client agree on security strength factor of 256. SASL data security layer installed. means that libldap detected that SASL encryption layer is required and installed the SASL encryption layer.

Expected behavior

For performance reasons LDAP connections should not double encrypt traffic.

Version/Release/Distribution

The issue affects RHEL 7, 8, and all latest Fedora versions

freeipa-server-4.9.3-2.4.fc33.x86_64
freeipa-client-4.9.3-2.4.fc33.x86_64
package ipa-server is not installed
package ipa-client is not installed
389-ds-base-2.0.4-1.3.fc33.x86_64
pki-ca-10.10.5-5.fc33.noarch
krb5-server-1.18.2-29.fc33.x86_64

Additional info:

Setting the minimum and maximum SSF value to 0 disables the data protection layer

conn.set_option(ldap.OPT_X_SASL_SSF_MIN, 0)
conn.set_option(ldap.OPT_X_SASL_SSF_MAX, 0)

However the options can also disable the protection layer for plain LDAP connections without TLS layer. The option also conflicts with 389-DS' nsslapd-minssf value. By default 389-DS has a minimum SSF of 0. It seems that 389-DS does not take TLS layer into account when it checks minimum SSF.


With nsslapd-minssf > 1 connections with smaller SSF_MAX fail either with {'result': -6, 'desc': 'Unknown authentication method', 'ctrls': [], 'info': 'SASL(-15): mechanism too weak for this user: Unable to find a callback: 32775'} in bind step or {'result': 53, 'desc': 'Server is unwilling to perform', 'ctrls': [], 'info': 'Minimum SSF not met.'} in subsequent LDAP operations. A higher SSF_MAX always establishes a data integration or confidentiality layer.

Test results with https://gist.github.com/tiran/d7622ee6bf899d4843841f5e674fba0b (Fedora 33)

nssldap-minssf = 0

$ python3 /tmp/ldap_sasl.py 
Vendor: 389-Directory/2.0.4 B2021.125.0000

URI: ldap://, StartTLS False, mech: GSSAPI, max SSF: 0
Actual SSF: None

URI: ldap://, StartTLS False, mech: GSSAPI, max SSF: 1
Actual SSF: 1

URI: ldap://, StartTLS False, mech: GSSAPI, max SSF: 256
Actual SSF: 256

URI: ldap://, StartTLS False, mech: GSS-SPNEGO, max SSF: 0
Actual SSF: None

URI: ldap://, StartTLS False, mech: GSS-SPNEGO, max SSF: 1
Actual SSF: 256

URI: ldap://, StartTLS False, mech: GSS-SPNEGO, max SSF: 256
Actual SSF: 256

URI: ldap://, StartTLS True, mech: GSSAPI, max SSF: 0
Actual SSF: None

URI: ldap://, StartTLS True, mech: GSSAPI, max SSF: 1
Actual SSF: None

URI: ldap://, StartTLS True, mech: GSSAPI, max SSF: 256
Actual SSF: 1

URI: ldap://, StartTLS True, mech: GSS-SPNEGO, max SSF: 0
Actual SSF: None

URI: ldap://, StartTLS True, mech: GSS-SPNEGO, max SSF: 1
Actual SSF: 256

URI: ldap://, StartTLS True, mech: GSS-SPNEGO, max SSF: 256
Actual SSF: 256

URI: ldaps://, StartTLS False, mech: GSSAPI, max SSF: 0
Actual SSF: None

URI: ldaps://, StartTLS False, mech: GSSAPI, max SSF: 1
Actual SSF: None

URI: ldaps://, StartTLS False, mech: GSSAPI, max SSF: 256
Actual SSF: 1

URI: ldaps://, StartTLS False, mech: GSS-SPNEGO, max SSF: 0
Actual SSF: None

URI: ldaps://, StartTLS False, mech: GSS-SPNEGO, max SSF: 1
Actual SSF: 256

URI: ldaps://, StartTLS False, mech: GSS-SPNEGO, max SSF: 256
Actual SSF: 256

nssldap-minssf = 256

$ python3 /tmp/ldap_sasl.py 
Vendor: 389-Directory/2.0.4 B2021.125.0000

URI: ldap://, StartTLS False, mech: GSSAPI, max SSF: 0
SASL bind failed: {'result': -6, 'desc': 'Unknown authentication method', 'ctrls': [], 'info': 'SASL(-15): mechanism too weak for this user: Unable to find a callback: 32775'}
LDAP whoami failed: {'result': 53, 'desc': 'Server is unwilling to perform', 'ctrls': [], 'info': 'Minimum SSF not met.'}
Actual SSF: None

URI: ldap://, StartTLS False, mech: GSSAPI, max SSF: 1
SASL bind failed: {'result': -6, 'desc': 'Unknown authentication method', 'ctrls': [], 'info': 'SASL(-15): mechanism too weak for this user: Unable to find a callback: 32775'}
LDAP whoami failed: {'result': 53, 'desc': 'Server is unwilling to perform', 'ctrls': [], 'info': 'Minimum SSF not met.'}
Actual SSF: None

URI: ldap://, StartTLS False, mech: GSSAPI, max SSF: 256
Actual SSF: 256

URI: ldap://, StartTLS False, mech: GSS-SPNEGO, max SSF: 0
LDAP whoami failed: {'result': 53, 'desc': 'Server is unwilling to perform', 'ctrls': [], 'info': 'Minimum SSF not met.'}
Actual SSF: None

URI: ldap://, StartTLS False, mech: GSS-SPNEGO, max SSF: 1
Actual SSF: 256

URI: ldap://, StartTLS False, mech: GSS-SPNEGO, max SSF: 256
Actual SSF: 256

URI: ldap://, StartTLS True, mech: GSSAPI, max SSF: 0
SASL bind failed: {'result': -6, 'desc': 'Unknown authentication method', 'ctrls': [], 'info': 'SASL(-15): mechanism too weak for this user: Unable to find a callback: 32775'}
LDAP whoami failed: {'result': 53, 'desc': 'Server is unwilling to perform', 'ctrls': [], 'info': 'Minimum SSF not met.'}
Actual SSF: None

URI: ldap://, StartTLS True, mech: GSSAPI, max SSF: 1
SASL bind failed: {'result': -6, 'desc': 'Unknown authentication method', 'ctrls': [], 'info': 'SASL(-15): mechanism too weak for this user: Unable to find a callback: 32775'}
LDAP whoami failed: {'result': 53, 'desc': 'Server is unwilling to perform', 'ctrls': [], 'info': 'Minimum SSF not met.'}
Actual SSF: None

URI: ldap://, StartTLS True, mech: GSSAPI, max SSF: 256
SASL bind failed: {'result': -6, 'desc': 'Unknown authentication method', 'ctrls': [], 'info': 'SASL(-15): mechanism too weak for this user: Unable to find a callback: 32775'}
LDAP whoami failed: {'result': 53, 'desc': 'Server is unwilling to perform', 'ctrls': [], 'info': 'Minimum SSF not met.'}
Actual SSF: None

URI: ldap://, StartTLS True, mech: GSS-SPNEGO, max SSF: 0
LDAP whoami failed: {'result': 53, 'desc': 'Server is unwilling to perform', 'ctrls': [], 'info': 'Minimum SSF not met.'}
Actual SSF: None

URI: ldap://, StartTLS True, mech: GSS-SPNEGO, max SSF: 1
Actual SSF: 256

URI: ldap://, StartTLS True, mech: GSS-SPNEGO, max SSF: 256
Actual SSF: 256

URI: ldaps://, StartTLS False, mech: GSSAPI, max SSF: 0
SASL bind failed: {'result': -6, 'desc': 'Unknown authentication method', 'ctrls': [], 'info': 'SASL(-15): mechanism too weak for this user: Unable to find a callback: 32775'}
LDAP whoami failed: {'result': 53, 'desc': 'Server is unwilling to perform', 'ctrls': [], 'info': 'Minimum SSF not met.'}
Actual SSF: None

URI: ldaps://, StartTLS False, mech: GSSAPI, max SSF: 1
SASL bind failed: {'result': -6, 'desc': 'Unknown authentication method', 'ctrls': [], 'info': 'SASL(-15): mechanism too weak for this user: Unable to find a callback: 32775'}
LDAP whoami failed: {'result': 53, 'desc': 'Server is unwilling to perform', 'ctrls': [], 'info': 'Minimum SSF not met.'}
Actual SSF: None

URI: ldaps://, StartTLS False, mech: GSSAPI, max SSF: 256
SASL bind failed: {'result': -6, 'desc': 'Unknown authentication method', 'ctrls': [], 'info': 'SASL(-15): mechanism too weak for this user: Unable to find a callback: 32775'}
LDAP whoami failed: {'result': 53, 'desc': 'Server is unwilling to perform', 'ctrls': [], 'info': 'Minimum SSF not met.'}
Actual SSF: None

URI: ldaps://, StartTLS False, mech: GSS-SPNEGO, max SSF: 0
LDAP whoami failed: {'result': 53, 'desc': 'Server is unwilling to perform', 'ctrls': [], 'info': 'Minimum SSF not met.'}
Actual SSF: None

URI: ldaps://, StartTLS False, mech: GSS-SPNEGO, max SSF: 1
Actual SSF: 256

URI: ldaps://, StartTLS False, mech: GSS-SPNEGO, max SSF: 256
Actual SSF: 256

Metadata Update from @cheimes:
- Custom field on_review adjusted to https://github.com/freeipa/freeipa/pull/5993

2 years ago
  • Actual SSF: None means no SASL data security layer
  • Actual SSF: 1 means SASL data security layer with data integrity checks
  • Actual SSF: 256 means SASL data security layer with data integrity checks and encryption

Login to comment on this ticket.

Metadata