From e9157ac6ce8d30a0d32177e35ac23fff89b03a03 Mon Sep 17 00:00:00 2001 From: Sankar Ramalingam Date: Tue, 26 Sep 2017 22:19:21 +0530 Subject: [PATCH] Ticket #48085 - CI tests - changelog encryption tests Description: Adding encryption changelog tests. Master1 with AES algorithm and Master2 with 3DES algorithm. unhashed#user#password attr is expected to be encrypted on the server where changelog encryption is configured. Cleartext password should be present if changelog encryption not configured. https://pagure.io/389-ds-base/issue/48085 Reviewed by: ? --- .../suites/replication/encryption_cl5_test.py | 289 +++++++++++++++++++++ 1 file changed, 289 insertions(+) create mode 100644 dirsrvtests/tests/suites/replication/encryption_cl5_test.py diff --git a/dirsrvtests/tests/suites/replication/encryption_cl5_test.py b/dirsrvtests/tests/suites/replication/encryption_cl5_test.py new file mode 100644 index 000000000..5c0b4dcbc --- /dev/null +++ b/dirsrvtests/tests/suites/replication/encryption_cl5_test.py @@ -0,0 +1,289 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2017 Red Hat, Inc. +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- +# +import os +import logging +import ldap +import pytest +from lib389.utils import generate_ds_params +from lib389.dseldif import DSEldif +from lib389.idm.user import UserAccounts +from lib389.properties import TASK_WAIT +from lib389.topologies import topology_m2 as topo +from lib389._constants import * + +ATTRIBUTE = 'unhashed#user#password' +USER_PROPERTIES = { + 'uid': 'encrypt1usr', + 'cn': 'encrypt1usr', + 'sn': 'encrypt1usr', + 'uidNumber': '1001', + 'gidNumber': '2001', + 'userpassword': PASSWORD, + 'description': 'userdesc', + 'homeDirectory': '/home/testuser' +} + +DEBUGGING = os.getenv("DEBUGGING", default=False) +if DEBUGGING: + logging.getLogger(__name__).setLevel(logging.DEBUG) +else: + logging.getLogger(__name__).setLevel(logging.INFO) +log = logging.getLogger(__name__) + + +@pytest.fixture(scope='module') +def enable_ssl_masters(topo, request): + """Configure SSL for all masters""" + + log.info('Enabling SSL for all masters') + for master in topo.ms.values(): + inst_num = int(master.serverid.split("master")[1]) + instance_data = generate_ds_params(inst_num, ReplicaRole.MASTER) + secure_port = instance_data[SER_SECURE_PORT] + + master.stop() + assert master.nss_ssl.reinit() is True + assert master.nss_ssl.create_rsa_ca() is True + assert master.nss_ssl.create_rsa_key_and_cert() is True + master.start() + + master.rsa.create() + master.config.set('nsslapd-secureport', str(secure_port)) + master.config.set('nsslapd-security', 'on') + master.sslport = secure_port + master.restart(post_open=False) + + def fin(): + log.info('Disabling SSL for all masters') + for master in topo.ms.values(): + master.config.set('nsslapd-security', 'off') + master.rsa.delete() + + request.addfinalizer(fin) + + +def _enable_changelog_encryption(topo, inst_name, encrypt_algorithm): + """Configure changelog encryption for master""" + + log.info('Configuring changelog encryption:{} for: {}'.format(inst_name, encrypt_algorithm)) + topo.ms[inst_name].stop() + dse_ldif = DSEldif(topo.ms[inst_name]) + try: + dse_ldif.replace(DN_CHANGELOG, 'nsslapd-encryptionalgorithm', encrypt_algorithm) + except: + log.error('Failed to add nsslapd-encryptionalgorithm value: {}'.format(encrypt_algorithm)) + raise + topo.ms[inst_name].start() + + +def _check_unhashed_userpw_encrypted(topo, change_type, inst_name, user_dn, user_pw, is_encrypted): + """Check if unhashed#user#password attribute value is encrypted or not""" + + master = topo.ms['{}'.format(inst_name)] + changelog_dbdir = os.path.join(os.path.dirname(master.dbdir), DEFAULT_CHANGELOG_DB) + for dbfile in os.listdir(changelog_dbdir): + if dbfile.endswith('.db'): + changelog_dbfile = os.path.join(changelog_dbdir, dbfile) + log.info('Changelog dbfile file exist: {}'.format(changelog_dbfile)) + log.info('Running dbscan -f to check {} attr'.format(ATTRIBUTE)) + dbscanOut = master.dbscan(DEFAULT_CHANGELOG_DB, changelog_dbfile) + count = 0 + for entry in dbscanOut.split('dbid: '): + if 'operation: ' + change_type in entry and ATTRIBUTE in entry and user_dn in entry: + count += 1 + if is_encrypted: + if ATTRIBUTE + ': ' + user_pw in entry: + log.fatal('Changelog entry contains clear text password') + assert False + else: + if not ATTRIBUTE + ': ' + user_pw in entry: + log.fatal('Changelog entry does not contain clear text password') + assert False + if not count: + log.fatal('Operation type and DN of the entry not matched in changelog') + assert False + + +def test_encrypt_m1_unhashed_user_passw_m1user(topo, enable_ssl_masters): + """Changelog encryption in m1, add/modfiy userPassword from m1/m2 and check if + unhashed#user#password attr is encrypted in m1 + + :id: b7a37bf8-4b2e-4dbd-9891-70117d67558c + :setup: Replication with two masters and SSL configured. + Changelog encryption in m1 + :steps: 1. Add user to master1 + 2. Run dbscan -f on m1 to check unhashed#user#password attribute is encrypted. + 3. Run dbscan -f on m2 to check unhashed#user#password attribute is in cleartext. + 4. Modify password in m2. + 5. Run dbscan -f on m1 to check unhashed#user#password attribute is encrypted. + 6. Run dbscan -f on m2 to check unhashed#user#password attribute is in cleartext. + :expectedresults: + 1. Add user to m1 should PASS. + 2. Unhashed#user#password attribute in m1 should be encrypted. + 3. Unhashed#user#password attribute in m2 should be in cleartext. + 4. Modify password in m2 should PASS. + 5. Unhashed#user#password attribute in m1 should be encrypted. + 6. Unhashed#user#password attribute in m2 should be in cleartext. + """ + + test_entry = 'test1encrypt' + test_passw = 'm2Test199' + log.info('Enable changelog encryption AES on master1') + _enable_changelog_encryption(topo, 'master1', 'AES') + + USER_PROPERTIES.update(dict.fromkeys(['uid', 'cn', 'sn'], test_entry)) + log.info('Adding user: {} to master1'.format(test_entry)) + users = UserAccounts(topo.ms['master1'], DEFAULT_SUFFIX) + tuser = users.create(properties=USER_PROPERTIES) + + _check_unhashed_userpw_encrypted(topo, 'add', 'master1', tuser.dn, PASSWORD, True) + _check_unhashed_userpw_encrypted(topo, 'add', 'master2', tuser.dn, PASSWORD, False) + + log.info('Reset password from m2 and check unhashed#user#password') + users = UserAccounts(topo.ms['master2'], DEFAULT_SUFFIX) + tuser = users.get(test_entry) + tuser.set('userPassword', test_passw) + _check_unhashed_userpw_encrypted(topo, 'modify', 'master1', tuser.dn, test_passw, True) + _check_unhashed_userpw_encrypted(topo, 'modify', 'master2', tuser.dn, test_passw, False) + tuser.delete() + + +def test_encrypt_m1_unhashed_user_passw_m2user(topo, enable_ssl_masters): + """Changelog encryption in m1, add/modfiy userPassword from m2/m1 and check if + unhashed#user#password attr is encrypted in m1 + + :id: 1355357a-9f30-4932-8129-f6f229cc2397 + :setup: Replication with two masters and SSL configured. + Changelog encryption in m1 + :steps: 1. Add user to master2 + 2. Run dbscan -f on m1 to check unhashed#user#password attribute is encrypted. + 3. Run dbscan -f on m2 to check unhashed#user#password attribute is in cleartext. + 4. Modify password in m1. + 5. Run dbscan -f on m1 to check unhashed#user#password attribute is encrypted. + 6. Run dbscan -f on m2 to check unhashed#user#password attribute is in cleartext. + :expectedresults: + 1. Add user to m2 should PASS. + 2. Unhashed#user#password attribute in m1 should be encrypted. + 3. Unhashed#user#password attribute in m2 should be in cleartext. + 4. Modify password in m1 should PASS. + 5. Unhashed#user#password attribute in m1 should be encrypted. + 6. Unhashed#user#password attribute in m2 should be in cleartext. + """ + + test_entry = 'test2encrypt' + test_passw = 'm1Test299' + + USER_PROPERTIES.update(dict.fromkeys(['uid', 'cn', 'sn'], test_entry)) + log.info('Adding user: {} to master2'.format(test_entry)) + users = UserAccounts(topo.ms['master2'], DEFAULT_SUFFIX) + tuser = users.create(properties=USER_PROPERTIES) + + _check_unhashed_userpw_encrypted(topo, 'add', 'master1', tuser.dn, PASSWORD, True) + _check_unhashed_userpw_encrypted(topo, 'add', 'master2', tuser.dn, PASSWORD, False) + + log.info('Reset password from m1 and check unhashed#user#password') + users = UserAccounts(topo.ms['master1'], DEFAULT_SUFFIX) + tuser = users.get(test_entry) + tuser.set('userPassword', test_passw) + _check_unhashed_userpw_encrypted(topo, 'modify', 'master1', tuser.dn, test_passw, True) + _check_unhashed_userpw_encrypted(topo, 'modify', 'master2', tuser.dn, test_passw, False) + tuser.delete() + + +def test_encrypt_m1_m2_unhashed_user_passw_m1user(topo, enable_ssl_masters): + """Changelog encryption on m1 and m2, add/modfiy userPassword from m1/m2 and check if + unhashed#user#password attr is encrypted in both m1 and m2 + + :id: 52be15d7-64d0-4527-aaa9-9d3b67cf0030 + :setup: Replication with two masters and SSL configured. + Changelog encryption in m1 and m2 + :steps: 1. Add user to master1 + 2. Run dbscan -f on m1 to check unhashed#user#password attribute is encrypted. + 3. Run dbscan -f on m2 to check unhashed#user#password attribute is encrypted. + 4. Modify password in m2. + 5. Run dbscan -f on m1 to check unhashed#user#password attribute is encrypted. + 6. Run dbscan -f on m2 to check unhashed#user#password attribute is encrypted. + :expectedresults: + 1. Add user to m1 should PASS. + 2. Unhashed#user#password attribute in m1 should be encrypted. + 3. Unhashed#user#password attribute in m2 should be encrypted. + 4. Modify password in m2 should PASS. + 5. Unhashed#user#password attribute in m1 should be encrypted. + 6. Unhashed#user#password attribute in m2 should be encrypted. + """ + + test_entry = 'test3encrypt' + test_passw = 'm2Test399' + log.info('Enable changelog encryption 3DES on master2') + _enable_changelog_encryption(topo, 'master2', '3DES') + + USER_PROPERTIES.update(dict.fromkeys(['uid', 'cn', 'sn'], test_entry)) + log.info('Adding user: {} to master1'.format(test_entry)) + users = UserAccounts(topo.ms['master1'], DEFAULT_SUFFIX) + tuser = users.create(properties=USER_PROPERTIES) + + _check_unhashed_userpw_encrypted(topo, 'add', 'master1', tuser.dn, PASSWORD, True) + _check_unhashed_userpw_encrypted(topo, 'add', 'master2', tuser.dn, PASSWORD, True) + + log.info('Reset password from m2 and check unhashed#user#password') + users = UserAccounts(topo.ms['master2'], DEFAULT_SUFFIX) + tuser = users.get(test_entry) + tuser.set('userPassword', test_passw) + _check_unhashed_userpw_encrypted(topo, 'modify', 'master1', tuser.dn, test_passw, True) + _check_unhashed_userpw_encrypted(topo, 'modify', 'master2', tuser.dn, test_passw, True) + tuser.delete() + + +def test_encrypt_m1_m2_unhashed_user_passw_m2user(topo, enable_ssl_masters): + """Changelog encryption on m1 and m2, add/modfiy userPassword from m1/m2 and check if + unhashed#user#password attr is encrypted in both m1 and m2 + + :id: 6f7ee1c1-e5eb-4339-809c-210743e9333e + :setup: Replication with two masters and SSL configured. + Changelog encryption in m1 and m2 + :steps: 1. Add user to master2 + 2. Run dbscan -f on m1 to check unhashed#user#password attribute is encrypted. + 3. Run dbscan -f on m2 to check unhashed#user#password attribute is encrypted. + 4. Modify password in m1. + 5. Run dbscan -f on m1 to check unhashed#user#password attribute is encrypted. + 6. Run dbscan -f on m2 to check unhashed#user#password attribute is encrypted. + :expectedresults: + 1. Add user to m2 should PASS. + 2. Unhashed#user#password attribute in m1 should be encrypted. + 3. Unhashed#user#password attribute in m2 should be encrypted. + 4. Modify password in m1 should PASS. + 5. Unhashed#user#password attribute in m1 should be encrypted. + 6. Unhashed#user#password attribute in m2 should be encrypted. + """ + + test_entry = 'test4encrypt' + test_passw = 'm1Test499' + + USER_PROPERTIES.update(dict.fromkeys(['uid', 'cn', 'sn'], test_entry)) + log.info('Adding user: {} to master2'.format(test_entry)) + users = UserAccounts(topo.ms['master2'], DEFAULT_SUFFIX) + tuser = users.create(properties=USER_PROPERTIES) + + _check_unhashed_userpw_encrypted(topo, 'add', 'master1', tuser.dn, PASSWORD, True) + _check_unhashed_userpw_encrypted(topo, 'add', 'master2', tuser.dn, PASSWORD, True) + + log.info('Reset password from m1 and check unhashed#user#password') + users = UserAccounts(topo.ms['master1'], DEFAULT_SUFFIX) + tuser = users.get(test_entry) + tuser.set('userPassword', test_passw) + _check_unhashed_userpw_encrypted(topo, 'modify', 'master1', tuser.dn, test_passw, True) + _check_unhashed_userpw_encrypted(topo, 'modify', 'master2', tuser.dn, test_passw, True) + tuser.delete() + + +if __name__ == '__main__': + # Run isolated + # -s for DEBUG mode + CURRENT_FILE = os.path.realpath(__file__) + pytest.main("-s {}".format(CURRENT_FILE)) -- 2.13.5