Missing channel binding prevents authentication to ActiveDirectory

Bug #1912256 reported by Robert Schneider
26
This bug affects 3 people
Affects Status Importance Assigned to Milestone
cyrus-sasl2 (Ubuntu)
Fix Released
Undecided
Andreas Hasenack
Jammy
Fix Released
Undecided
Lena Voytek
openldap (Ubuntu)
Fix Released
Undecided
Sergio Durigan Junior
Jammy
Fix Released
Undecided
Unassigned

Bug Description

[Impact]

When attempting to authenticate against a Windows Active Directory server configured to require SASL channel binding over SSL/TLS ldap connections (ldaps), authentication will fail stating invalid credentials as the cause.

This is due to cyrus-sasl2 missing the sasl channel binding feature of GSSAPI/GSS-SPNEGO.

Furthermore, for interoperability with Windows Active Directory Server, it's necessary to be able to set the SASL SSF (security strength factor) to 0 (zero) when it's used over an already encrypted connection like ldaps.

To fix these issues, these items are added as patches from a set of upstream commits.

[Test Plan]

To reproduce this issue, a machine running Windows with Active Directory must be available over the network. As an example, for Windows Server 2019 Evaluation:

The ISO can be downloaded from https://www.microsoft.com/en-us/evalcenter/download-windows-server-2019
Install Windows Server, Active Directory, and Certificate Services, then add the following registry changes from https://support.microsoft.com/en-us/topic/2020-ldap-channel-binding-and-ldap-signing-requirements-for-windows-kb4520412-ef185fb8-00f7-167d-744c-f299a66fc00a

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Parameters]
"ldapserverintegrity"=dword:00000002
"LdapEnforceChannelBinding"=dword:00000002

Also enable LDAP logging for Active Directory:

Reg Add HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\NTDS\Diagnostics /v "16 LDAP Interface Events" /t REG_DWORD /d 2

With the Windows machine available, set up an Ubuntu system on a network that can reach the Windows server. This works best and with less configuration needed if the Windows server is acting as DNS and DHCP server for that network.

Install packages with:
$ sudo apt install ldap-utils libsasl2-modules-gssapi-mit krb5-user
When the Configuring Kerberos Authentication prompt shows up, use the realm of the Windows Server. If prompted, use the windows server IP for the Kerberos KDC and admin servers.

Save the Windows Server AD CA certificate file as /usr/local/share/ca-certificates/ad-ca.crt then run
$ sudo update-ca-certificates

In /etc/ldap/ldap.conf set
BASE dc={REALM NAME} # split the domain components like dc=example,dc=com
URI ldaps://{WINDOWS SERVER MACHINE NAME}.{REALM NAME}

With Ubuntu set up, the actual test can be run:

$ kinit
Enter Password
$ ldapwhoami -Y GSSAPI -O maxssf=0 -o SASL_CBINDING=tls-endpoint

Prior to the fix, this would display the following:

SASL/GSSAPI authentication started
ldap_sasl_interactive_bind_s: Invalid credentials (49)
        additional info: 80090346: LdapErr: DSID-..., comment: AcceptSecurityContext error, data 80090346, v4563

With the fix, the authentication will display the user information.

The same happens with
$ ldapwhoami -Y GSS-SPNEGO -O maxssf=0 -o SASL_CBINDING=tls-endpoint

SASL/GSS-SPNEGO authentication started
ldap_sasl_interactive_bind_s: Invalid credentials (49)
        additional info: 80090346: LdapErr: DSID-..., comment: AcceptSecurityContext error, data 80090346, v4563

[Where problems could occur]

Based on the patches added, any problems that show up would likely occour either in the gssapi plugin or the SASL2 macros. The two files changed are plugins/gssapi.c and m4/sasl2.m4, along with some tests.

There are various situations apart from this one in which GSS-API can be used, and this change may affect the way some of these interactions over the network are handled.

In parallel with this SRU, we tested, in jammy, cyrus-imapd server and gssapi authentication over tls, with and without this updated sasl package. Using as a client thunderbird, imtest (from cyrus-imapd-clients), curl (it has imap support), mutt, evolution. All authenticated without issues. Also postfix with gssapi authentication was tested, and also worked.

[Other Info]

This issue was fixed in kinetic in version 2.1.28+dfsg-6ubuntu2

This SRU is also pulling in the new DEP8 tests in the kinetic package for cyrus-sasl2. The only changes made to those tests are the list of mechanisms to test, which is slightly smaller in jammy, and an extra package to install for one of the tests due to packaging differences in jammy wrt kinetic.

[Original Description]

> Are you uncertain if your issue is really a bug?
Effect is an authentication error. Root case is a "missing feature" (see below) and requires updating dependencies, downporting.

> If you are certain this is a bug please include the source package the bug is in.
It's in the interaction between three libraries: openldap, cyrus-sasl, krb5

> 1) The release of Ubuntu you are using, via 'lsb_release -rd' or System -> About Ubuntu
Broken in 18.04 and also in 20.10 (I guess it's also broken in anything inbetween)

> 2) The version of the package you are using, via 'apt-cache policy pkgname' or by checking in Software Center

libsasl2-modules-gssapi-mit: 2.1.27+dfsg-2ubuntu1
ldap-utils: 2.4.53+dfsg-1ubuntu1.2
libgssapi-krb5-2: 1.17-10ubuntu0.1

> 3) What you expected to happen
# kinit
$ export LDAPSASL_CBINDING=tls-endpoint
$ ldapwhoami -O minssf=0,maxssf=0 -N -Y GSSAPI -H ldaps://<DC-fqdn>
SASL/GSSAPI authentication started
SASL username: <some-username>
SASL SSF: 0
u:<some-username>

> 4) What happened instead
SASL/GSSAPI authentication started
ldap_sasl_interactive_bind_s: Invalid credentials (49)
        additional info: 80090346: LdapErr: DSID-0C090597, comment: AcceptSecurityContext error, data 80090346, v4563

---------------

Microsoft ActiveDirectory has "LDAP Channel Binding" and recommends activating this as a required feature. See https://access.redhat.com/articles/4661861
Authentication to any AD DC which has mandatory channel binding fails.

Channel binding requires at least an update to cyrus-sasl, which is not in any release as far as I can see:

https://github.com/cyrusimap/cyrus-sasl/commit/975edbb69070eba6b035f08776de771a129cfb57

It also needs this commit in openldap:

https://git.openldap.org/openldap/openldap/-/commit/3cd50fa8b32a21040a9892e2a8a7a9dfc7541ce6

Which as far as I can tell is v2.5 (branch OPENLDAP_REL_ENG_2_5).

RH also mentions it needs up-to-date krb5 libraries, but I can't tell what minimum version this needs.

I can build all libraries from source, current master (except for krb5 where I've used 1.18.3) and can confirm that channel binding works when using those libraries.

I'm not sure if Samba is affected, but at least adcli, ldap-utils, and I would guess by extension also SSSD and realmd.

Related branches

Revision history for this message
Robert Schneider (sap-robot) wrote :

Might have been confusing to write

# kinit
$ export LDAPSASL_CBINDING=tls-endpoint

Both are supposed to be called from the same user. I meant to imply that an existing, valid ticket in the current user's credential cache is required for krb5 authentication via SASL in the ldapwhoami step.

Revision history for this message
Lucas Kanashiro (lucaskanashiro) wrote :

Thanks for taking the time to file this bug and try to make Ubuntu better.

I subscribed ubuntu-server and Sergio who has been working on this stack recently to investigate what you described.

Revision history for this message
Robert Schneider (sap-robot) wrote :

I should maybe add the following detail:

Channel binding, from all I can tell, is only available via TLS (even conceptually). That is, the issue mentioned in the bug report only happens when using ldaps.

In certain cases, it is therefore possible to work around the lack of channel binding by _not using TLS_. Typically, you'll have to set minssf to >=1 if TLS is not used, due to security settings of the LDAP server (AD DC).

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Hi,
I'm revisiting bugs that have been dormant for too long trying to retriage them.

In this case the current situation to me looks like:
- openldap change 3cd50fa having landed in v2.5.8 and later
- cyrus-sasl change 975edbb6 still isn't in any release AFAICS
  - that is odd as https://github.com/cyrusimap/cyrus-sasl/pull/601 which it is part of landed
  - it is in the master branch as expected
  - but cyrus-sasl-2.1.28 which was tagged much later does not contain it

There must be something to understand between cyrus-sasl and cyrus-impad releases that I not know yet :-)
$ git range-diff cyrus-sasl-2.1.27..cyrus-sasl-2.1.28 cyrus-sasl-2.1.27..upstream/master
...
 -: -------- > 51: 975edbb6 Add Channel Binding support for GSSAPI/GSS-SPNEGO

I have no experience/insight in their release process.
But @Sergio - maybe it is time to revisit that why it has been left out and trying to at least add it to Kinetic if it makes sense.

Changed in openldap (Ubuntu):
assignee: nobody → Sergio Durigan Junior (sergiodj)
tags: added: server-todo
Changed in cyrus-sasl2 (Ubuntu):
assignee: nobody → Sergio Durigan Junior (sergiodj)
assignee: Sergio Durigan Junior (sergiodj) → Andreas Hasenack (ahasenack)
Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in cyrus-sasl2 (Ubuntu):
status: New → Confirmed
Changed in openldap (Ubuntu):
status: New → Confirmed
Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :

Thank you, Christian.

As discussed with Andreas, I've added a cyrus-sasl2 task to this bug and assigned him to it. This bug is probably going to involve modifications on cyrus-sasl2 only; after channel binding has been implemented there, we should be able to enable it in openldap by just rebuilding the package. Either way, I'm leaving the openldap task open and assigned to myself just in case.

Thanks.

Changed in cyrus-sasl2 (Ubuntu):
status: Confirmed → In Progress
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

I have a build for kinetic which has two changes:
- enable channel binding
- allow setting maxssf=0 when using GSS-SPNEGO

The later might not be needed, as GSSAPI already supports maxssf=0, and adcli will forcibly select GSSAPI instead of GSS-SPNEGO if ldaps (ssl) is being used, exactly because not everybody might have that patch:

https://git.launchpad.net/ubuntu/+source/adcli/tree/library/adconn.c?h=ubuntu/kinetic-devel#n1090

    const char *mech = "GSSAPI";
    (...)
    /* There are issues with cryrus-sasl and GSS-SPNEGO with TLS even if
  * ssf_max is set to 0. To be on the safe side GSS-SPNEGO is only used
  * without LDAPS. */
 if (adcli_conn_server_has_sasl_mech (conn, "GSS-SPNEGO")
                      && !adcli_conn_get_use_ldaps (conn)) {
  mech = "GSS-SPNEGO";
 }

But without the second patch, using GSS-SPNEGO over ldaps:// against windows won't work (because -O maxssf=0 is ignored), so it's good to have I think.

I tested this against windows 2016 with LdapEnforceChannelBinding=2 and LDAPServerIntegrity=2 in the registry, and could verify that without the sasl changes, joining the domain with adcli/realmd run with --use-ldaps would not work. On kinetic so far.

I'm now trying to determine if I also need to pull in https://github.com/cyrusimap/cyrus-sasl/commit/8735185e9d5550e0f11e1ce4b77e391a16e4145b. There was a very technical discussion in the related issue at https://github.com/cyrusimap/cyrus-sasl/issues/637 involving RFCs and in the end the above commit landed, but only in master/main. I'm still unsure why that was needed if SASL_CBINDING defaults to "none":

  SASL_CBINDING <none/tls-unique/tls-endpoint>
  The channel-binding type to use, see also LDAP_OPT_X_SASL_CBINDING. The default is none.

I'm currently testing the patched library with other sasl-enabled services via gssapi and gss-spnego, to see if any of them complain about the channel binding patch.

The openldap test suite has a nice test for this at https://git.launchpad.net/ubuntu/+source/openldap/tree/tests/scripts/test077-sasl-gssapi?h=ubuntu/kinetic-devel#n175

I was expecting to be able to get ldap to fail if I enable it on the server, and not on the client, i.e.:

dn: cn=config
changetype: modify
replace: olcSaslCBinding
olcSaslCBinding: tls-unique

But whatever SASL_CBINDING setting I used on the client, the bind always worked (gssapi/gss-spnego + ldaps), so I'm still unsure if it's working as expected.

This on kinetic with openldap 2.5.12.

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Ok, the -o SASL_CBINDING command-line parameter seems to work. Against that window 2016 server the ldapwhoami command only works when I set the channel binding mode to tls-unique:

ubuntu@k1:~$ ldapwhoami -H ldaps://WIN-KRIET1E5ELO.internal.example.fake -Y GSSAPI -O maxssf=0 -o SASL_CBINDING=none
SASL/GSSAPI authentication started
ldap_sasl_interactive_bind: Invalid credentials (49)
        additional info: 80090346: LdapErr: DSID-0C09059A, comment: AcceptSecurityContext error, data 80090346, v3839

ubuntu@k1:~$ ldapwhoami -H ldaps://WIN-KRIET1E5ELO.internal.example.fake -Y GSSAPI -O maxssf=0 -o SASL_CBINDING=tls-unique
SASL/GSSAPI authentication started
ldap_sasl_interactive_bind: Invalid credentials (49)
        additional info: 80090346: LdapErr: DSID-0C09059A, comment: AcceptSecurityContext error, data 80090346, v3839

ubuntu@k1:~$ ldapwhoami -H ldaps://WIN-KRIET1E5ELO.internal.example.fake -Y GSSAPI -O maxssf=0 -o SASL_CBINDING=tls-endpoint
SASL/GSSAPI authentication started
SASL username: <email address hidden>
SASL SSF: 0
u:INTEXAMPLE\ubuntu

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

I'm concerned about interoperability issues...

https://github.com/cyrusimap/cyrus-imapd/issues/3317

Revision history for this message
Andreas Hasenack (ahasenack) wrote (last edit ):

I tried the same set of patches on jammy's cyrus-sasl (2.1.27). They applied, but I couldn't get gssapi + ldaps to work against AD 2016. It kept complaining that the channel binding token was not there. Weird. I then tried fedora 36, and centos 9, which I thought were the "benchmark" for this, but they also do not work against this AD 2016 server. Just kinetic with the patched 2.1.28 cyrus-sasl2. Maybe just proper RHEL works?

I'm confused.

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

Ok, got it working in jammy, it was a local problem. I had installed the heimdal sasl gssapi module, instead of MIT. Heimdal is another issue to fix later at some point, but now I'm concentrating on MIT.

Revision history for this message
Andreas Hasenack (ahasenack) wrote :

openldap in kinetic needs no further changes, marking that task as fix released.

Changed in openldap (Ubuntu):
status: Confirmed → Fix Released
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

openldap@jammy also needs no further changes

Changed in openldap (Ubuntu Jammy):
status: New → Fix Released
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package cyrus-sasl2 - 2.1.28+dfsg-6ubuntu2

---------------
cyrus-sasl2 (2.1.28+dfsg-6ubuntu2) kinetic; urgency=medium

  * Add SASL channel binding support for GSSAPI and GSS-SPNEGO
    (LP: #1912256):
    - d/p/0034-channel-binding-gssapi-gss-spnego.patch: add SASL channel
      binding support for GSSAPI and GSS-SPNEGO
    - d/p/0035-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO-1.patch:
      allow setting maxssf to 0 when using GSS-SPNEGO inside SSL/TLS
    - d/p/0035-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO-2.patch:
      be more conformant to RFC4752

 -- Andreas Hasenack <email address hidden> Tue, 16 Aug 2022 17:08:44 -0300

Changed in cyrus-sasl2 (Ubuntu):
status: In Progress → Fix Released
Changed in cyrus-sasl2 (Ubuntu Jammy):
assignee: nobody → Andreas Hasenack (ahasenack)
status: New → Triaged
Robie Basak (racb)
Changed in cyrus-sasl2 (Ubuntu Jammy):
assignee: Andreas Hasenack (ahasenack) → nobody
Lena Voytek (lvoytek)
Changed in cyrus-sasl2 (Ubuntu Jammy):
assignee: nobody → Lena Voytek (lvoytek)
status: Triaged → In Progress
Lena Voytek (lvoytek)
description: updated
description: updated
description: updated
description: updated
description: updated
tags: removed: server-todo
description: updated
Revision history for this message
Brian Murray (brian-murray) wrote : Please test proposed package

Hello Robert, or anyone else affected,

Accepted cyrus-sasl2 into jammy-proposed. The package will build now and be available at https://launchpad.net/ubuntu/+source/cyrus-sasl2/2.1.27+dfsg2-3ubuntu1.1 in a few hours, and then in the -proposed repository.

Please help us by testing this new package. See https://wiki.ubuntu.com/Testing/EnableProposed for documentation on how to enable and use -proposed. Your feedback will aid us getting this update out to other Ubuntu users.

If this package fixes the bug for you, please add a comment to this bug, mentioning the version of the package you tested, what testing has been performed on the package and change the tag from verification-needed-jammy to verification-done-jammy. If it does not fix the bug for you, please add a comment stating that, and change the tag to verification-failed-jammy. In either case, without details of your testing we will not be able to proceed.

Further information regarding the verification process can be found at https://wiki.ubuntu.com/QATeam/PerformingSRUVerification . Thank you in advance for helping!

N.B. The updated package will be released to -updates after the bug(s) fixed by this package have been verified and the package has been in -proposed for a minimum of 7 days.

Changed in cyrus-sasl2 (Ubuntu Jammy):
status: In Progress → Fix Committed
tags: added: verification-needed verification-needed-jammy
Revision history for this message
Robert Schneider (sap-robot) wrote :

This package fixes the bug for me, thank you very much :)

Tested version:
libsasl2-modules:amd64 2.1.27+dfsg2-3ubuntu1.1
libsasl2-modules-db:amd64 2.1.27+dfsg2-3ubuntu1.1
libsasl2-2:amd64 2.1.27+dfsg2-3ubuntu1.1
libsasl2-modules-gssapi-mit:amd64 2.1.27+dfsg2-3ubuntu1.1

Test procedure:
- downloaded+upgraded Ubuntu 22.04 (minimal installation)
- installed ldap-utils libsasl2-modules-gssapi-mit krb5-user
- configured ldap.conf and krb5.conf for our AD
- ran kinit
- KRB5_TRACE=/dev/stderr ldapwhoami -Y GSSAPI -N -O maxssf=0 -o SASL_CBINDING=tls-endpoint -H ldaps://<ldap-server>

The test fails without the fix (AcceptSecurityContext error, data 80090346, v4563) and succeeds after upgrading the packages mentioned under "Tested versions" to the mentioned proposed versions.

Revision history for this message
Ubuntu SRU Bot (ubuntu-sru-bot) wrote : Autopkgtest regression report (cyrus-sasl2/2.1.27+dfsg2-3ubuntu1.1)

All autopkgtests for the newly accepted cyrus-sasl2 (2.1.27+dfsg2-3ubuntu1.1) for jammy have finished running.
The following regressions have been reported in tests triggered by the package:

python-bonsai/1.3.0+ds-3build1 (armhf)
librdkafka/1.8.0-1build1 (amd64)

Please visit the excuses page listed below and investigate the failures, proceeding afterwards as per the StableReleaseUpdates policy regarding autopkgtest regressions [1].

https://people.canonical.com/~ubuntu-archive/proposed-migration/jammy/update_excuses.html#cyrus-sasl2

[1] https://wiki.ubuntu.com/StableReleaseUpdates#Autopkgtest_Regressions

Thank you!

Revision history for this message
Lena Voytek (lvoytek) wrote :

Thanks for verifying Robert! Making sure the above tests pass then the package should migrate to jammy soon

tags: added: verification-done verification-done-jammy
removed: verification-needed verification-needed-jammy
Revision history for this message
Andreas Hasenack (ahasenack) wrote :

The tests are green now.

Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package cyrus-sasl2 - 2.1.27+dfsg2-3ubuntu1.1

---------------
cyrus-sasl2 (2.1.27+dfsg2-3ubuntu1.1) jammy; urgency=medium

  * Add SASL channel binding support for GSSAPI and GSS-SPNEGO
    (LP: #1912256):
    - d/p/0034-channel-binding-gssapi-gss-spnego.patch: add SASL channel
      binding support for GSSAPI and GSS-SPNEGO
    - d/p/0035-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO-1.patch:
      allow setting maxssf to 0 when using GSS-SPNEGO inside SSL/TLS
    - d/p/0035-Add-support-for-setting-max-ssf-0-to-GSS-SPNEGO-2.patch:
      be more conformant to RFC4752
  * Add some DEP8 tests (LP: #1677781):
    - d/t/{control,saslauthd}: saslauthd tests with multiple mechanisms
    - d/t/{control,gssapi}: test for SASL GSSAPI using OpenLDAP
    - d/t/{control,pluginviewer}: test available mechanisms
    - d/t/{control,shared-secret-mechs}: test shared secret mechanisms

 -- Lena Voytek <email address hidden> Wed, 19 Oct 2022 14:06:40 -0700

Changed in cyrus-sasl2 (Ubuntu Jammy):
status: Fix Committed → Fix Released
Revision history for this message
Robie Basak (racb) wrote : Update Released

The verification of the Stable Release Update for cyrus-sasl2 has completed successfully and the package is now being released to -updates. Subsequently, the Ubuntu Stable Release Updates Team is being unsubscribed and will not receive messages about this bug report. In the event that you encounter a regression using the package from -updates please report a new bug using ubuntu-bug and tag the bug report regression-update so we can easily find any regressions.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.