ldap: fix setting client TLS certificate (fixes #28570)

New tests depends upon ldaptools 0.15.
This commit is contained in:
Benjamin Dauvergne 2018-12-04 15:08:32 +01:00
parent 977455a304
commit acb2822992
3 changed files with 72 additions and 7 deletions

View File

@ -1029,7 +1029,7 @@ class LDAPBackend(object):
if block['certfile']:
conn.set_option(ldap.OPT_X_TLS_CERTFILE, block['certfile'])
if block['keyfile']:
conn.set_option(ldap.OPT_X_TLS_CERTFILE, block['keyfile'])
conn.set_option(ldap.OPT_X_TLS_KEYFILE, block['keyfile'])
for key, value in block['ldap_options']:
conn.set_option(key, value)
conn.set_option(ldap.OPT_REFERRALS, 1 if block['referrals'] else 0)

View File

@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
import os
import pytest
import mock
@ -29,10 +31,25 @@ DN = 'cn=%s,o=ôrga' % escape_dn_chars(CN)
PASS = 'passé'
EMAIL = 'etienne.michu@example.net'
base_dir = os.path.dirname(__file__)
key_file = os.path.join(base_dir, 'key.pem')
cert_file = os.path.join(base_dir, 'cert.pem')
@pytest.fixture
def slapd(request):
slapd = Slapd()
def slapd():
with create_slapd() as s:
yield s
@pytest.fixture
def tls_slapd():
with Slapd(ldap_url='ldap://localhost:4389', tls=(key_file, cert_file)) as s:
yield create_slapd(s)
def create_slapd(slapd=None):
slapd = slapd or Slapd()
slapd.add_db('o=ôrga')
slapd.add_ldif('''dn: o=ôrga
objectClass: organization
@ -72,10 +89,6 @@ memberUid: {uid}
group_ldif += 'memberUid: michu{i}\n'.format(i=i)
group_ldif += '\n\n'
slapd.add_ldif(group_ldif)
def finalize():
slapd.clean()
request.addfinalizer(finalize)
return slapd
@ -588,3 +601,54 @@ def test_user_cannot_change_password(slapd, settings, app, db):
assert 'Password' not in response
response = app.get('/accounts/password/change/')
assert response['Location'].endswith('/accounts/')
def test_tls(db, tls_slapd, settings, client):
conn = tls_slapd.get_connection_admin()
conn.modify_s('cn=config', [
(ldap.MOD_ADD, 'olcTLSCACertificateFile', cert_file),
(ldap.MOD_ADD, 'olcTLSVerifyClient', 'demand'),
])
# without TLS it does not work
settings.LDAP_AUTH_SETTINGS = [{
'url': [tls_slapd.ldap_url],
'basedn': u'o=ôrga',
'use_tls': False,
}]
result = client.post('/login/', {'login-password-submit': '1',
'username': USERNAME,
'password': PASS}, follow=True)
assert result.status_code == 200
assert 'Étienne Michu' not in str(result)
assert 'name="username"' in str(result)
# without TLS client authentication it does not work
settings.LDAP_AUTH_SETTINGS = [{
'url': [tls_slapd.ldap_url],
'basedn': u'o=ôrga',
'use_tls': True,
'cacertfile': cert_file,
}]
result = client.post('/login/', {'login-password-submit': '1',
'username': USERNAME,
'password': PASS}, follow=True)
assert result.status_code == 200
assert 'Étienne Michu' not in str(result)
assert 'name="username"' in str(result)
# now it works !
settings.LDAP_AUTH_SETTINGS = [{
'url': [tls_slapd.ldap_url],
'basedn': u'o=ôrga',
'use_tls': True,
'cacertfile': cert_file,
'certfile': cert_file,
'keyfile': key_file,
}]
result = client.post('/login/', {'login-password-submit': '1',
'username': USERNAME,
'password': PASS}, follow=True)
assert result.status_code == 200
assert 'Étienne Michu' in str(result)
assert 'name="username"' not in str(result)

View File

@ -48,6 +48,7 @@ deps =
httmock
pytz
pytest-freezegun
ldaptools>=0.15
commands =
./getlasso.sh
authentic: py.test {env:FAST:} {env:REUSEDB:} {env:COVERAGE:} {posargs:tests/ --random}