URL: https://github.com/freeipa/freeipa/pull/757
Author: tomaskrizek
 Title: #757: ca, kra install: validate DM password
Action: synchronized

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/757/head:pr757
git checkout pr757
From 2cce2304491ce575b6803ca4dd7d8f6630c57a35 Mon Sep 17 00:00:00 2001
From: Tomas Krizek <tkri...@redhat.com>
Date: Wed, 3 May 2017 10:05:25 +0200
Subject: [PATCH 1/3] ca install: merge duplicated code for DM password

Extract copy-pasted code to a single function.

Related https://pagure.io/freeipa/issue/6892

Signed-off-by: Tomas Krizek <tkri...@redhat.com>
---
 install/tools/ipa-ca-install | 40 +++++++++++++++++-----------------------
 1 file changed, 17 insertions(+), 23 deletions(-)

diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
index 60261aa..da6e5c3 100755
--- a/install/tools/ipa-ca-install
+++ b/install/tools/ipa-ca-install
@@ -116,9 +116,19 @@ def parse_options():
     return safe_options, options, filename
 
 
-def get_dirman_password():
-    return installutils.read_password(
-        "Directory Manager (existing master)", confirm=False, validate=False)
+def _get_dirman_password(password=None, unattended=False):
+    if not password:
+        if unattended:
+            sys.exit('Directory Manager password required')
+        try:
+            password = installutils.read_password(
+                "Directory Manager (existing master)", confirm=False,
+                validate=False)
+        except KeyboardInterrupt:
+            sys.exit(0)
+        if password is None:
+            sys.exit("Directory Manager password required")
+    return password
 
 
 def install_replica(safe_options, options, filename):
@@ -142,16 +152,8 @@ def install_replica(safe_options, options, filename):
         check_creds(options, api.env.realm)
 
     # get the directory manager password
-    dirman_password = options.password
-    if not dirman_password:
-        if options.unattended:
-            sys.exit('Directory Manager password required')
-        try:
-            dirman_password = get_dirman_password()
-        except KeyboardInterrupt:
-            sys.exit(0)
-        if dirman_password is None:
-            sys.exit("Directory Manager password required")
+    dirman_password = _get_dirman_password(
+        options.password, options.unattended)
 
     if (not options.promote and not options.admin_password and
             not options.skip_conncheck and options.unattended):
@@ -199,16 +201,8 @@ def install_replica(safe_options, options, filename):
 
 
 def install_master(safe_options, options):
-    dm_password = options.password
-    if not dm_password:
-        if options.unattended:
-            sys.exit('Directory Manager password required')
-        try:
-            dm_password = get_dirman_password()
-        except KeyboardInterrupt:
-            sys.exit(0)
-        if dm_password is None:
-            sys.exit("Directory Manager password required")
+    dm_password = _get_dirman_password(
+        options.password, options.unattended)
 
     options.realm_name = api.env.realm
     options.domain_name = api.env.domain

From e3e8f051220970f10a34c8297b1a381d1721b663 Mon Sep 17 00:00:00 2001
From: Tomas Krizek <tkri...@redhat.com>
Date: Wed, 3 May 2017 10:01:09 +0200
Subject: [PATCH 2/3] installutils: add DM password validator

Add a validator that checks whether provided Directory Manager
is valid by attempting to connect to LDAP.

Related https://pagure.io/freeipa/issue/6892

Signed-off-by: Tomas Krizek <tkri...@redhat.com>
---
 ipaserver/install/installutils.py | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 9230e70..b6f0148 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -50,6 +50,7 @@
 from ipapython import ipautil, admintool, version
 from ipapython.admintool import ScriptError
 from ipapython.ipa_log_manager import root_logger
+from ipapython.ipaldap import DIRMAN_DN, LDAPClient
 from ipalib.util import validate_hostname
 from ipalib import api, errors, x509
 from ipapython.dn import DN
@@ -329,6 +330,21 @@ def _read_password_default_validator(password):
     if len(password) < 8:
         raise ValueError("Password must be at least 8 characters long")
 
+
+def validate_dm_password_ldap(password):
+    """
+    Validate DM password by attempting to connect to LDAP. api.env has to
+    contain valid ldap_uri.
+    """
+    client = LDAPClient(api.env.ldap_uri, cacert=paths.IPA_CA_CRT)
+    try:
+        client.simple_bind(DIRMAN_DN, password)
+    except errors.ACIError:
+        raise ValueError("Invalid Directory Manager password")
+    else:
+        client.unbind()
+
+
 def read_password(user, confirm=True, validate=True, retry=True, validator=_read_password_default_validator):
     correct = False
     pwd = None

From 630829ea87e602ece3a4fc60279d68760c4c3677 Mon Sep 17 00:00:00 2001
From: Tomas Krizek <tkri...@redhat.com>
Date: Wed, 3 May 2017 10:16:13 +0200
Subject: [PATCH 3/3] ca, kra install: validate DM password

Before proceeding with installation, validate DM password. If the
provided DM password is invalid, abort the installation.

Fixes https://pagure.io/freeipa/issue/6892

Signed-off-by: Tomas Krizek <tkri...@redhat.com>
---
 install/tools/ipa-ca-install         | 18 ++++++++++--------
 ipaserver/install/ipa_kra_install.py |  8 ++++++++
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
index da6e5c3..36ae7d2 100755
--- a/install/tools/ipa-ca-install
+++ b/install/tools/ipa-ca-install
@@ -117,17 +117,19 @@ def parse_options():
 
 
 def _get_dirman_password(password=None, unattended=False):
+    # sys.exit() is used on purpose, because otherwise user is advised to
+    # uninstall the component, even though it is not needed
     if not password:
         if unattended:
             sys.exit('Directory Manager password required')
-        try:
-            password = installutils.read_password(
-                "Directory Manager (existing master)", confirm=False,
-                validate=False)
-        except KeyboardInterrupt:
-            sys.exit(0)
-        if password is None:
-            sys.exit("Directory Manager password required")
+        password = installutils.read_password(
+            "Directory Manager (existing master)", confirm=False,
+            validate=False)
+    try:
+        installutils.validate_dm_password_ldap(password)
+    except ValueError:
+        sys.exit("Directory Manager password is invalid")
+
     return password
 
 
diff --git a/ipaserver/install/ipa_kra_install.py b/ipaserver/install/ipa_kra_install.py
index 8b1cb63..41729c3 100644
--- a/ipaserver/install/ipa_kra_install.py
+++ b/ipaserver/install/ipa_kra_install.py
@@ -137,6 +137,14 @@ def ask_for_options(self):
     def run(self):
         super(KRAInstaller, self).run()
 
+        # Verify DM password. This has to be called after ask_for_options(),
+        # so it can't be placed in validate_options().
+        try:
+            installutils.validate_dm_password_ldap(self.options.password)
+        except ValueError:
+            raise admintool.ScriptError(
+                "Directory Manager password is invalid")
+
         if not cainstance.is_ca_installed_locally():
             raise RuntimeError("Dogtag CA is not installed. "
                                "Please install the CA first")
-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to