When getpass.getpass() function is interrupted via CTRL+D, EOFError
exception is thrown. Most of the install tools are not prepared for
this event and crash with this exception. Make sure that it is
handled properly and nice error message is printed.

https://fedorahosted.org/freeipa/ticket/1916

>From 5818782a4c7b5fda146c4b3f9e67ea850ba27b07 Mon Sep 17 00:00:00 2001
From: Martin Kosek <mko...@redhat.com>
Date: Tue, 4 Oct 2011 10:42:59 +0200
Subject: [PATCH] Install tools crash when password prompt is interrupted

When getpass.getpass() function is interrupted via CTRL+D, EOFError
exception is thrown. Most of the install tools are not prepared for
this event and crash with this exception. Make sure that it is
handled properly and nice error message is printed.

https://fedorahosted.org/freeipa/ticket/1916
---
 install/tools/ipa-ca-install              |    2 +
 install/tools/ipa-compat-manage           |    2 +
 install/tools/ipa-csreplica-manage        |    7 +++-
 install/tools/ipa-dns-install             |    2 +
 install/tools/ipa-ldap-updater            |    2 +
 install/tools/ipa-managed-entries         |    2 +
 install/tools/ipa-nis-manage              |    2 +
 install/tools/ipa-replica-conncheck       |    8 ++++-
 install/tools/ipa-replica-install         |    2 +
 install/tools/ipa-replica-manage          |    7 +++-
 install/tools/ipa-replica-prepare         |    2 +
 install/tools/ipa-server-certinstall      |    8 +++--
 install/tools/ipa-server-install          |    7 ++++
 ipa-client/ipa-install/ipa-client-install |   13 +++++++-
 ipaserver/install/installutils.py         |   45 +++++++++++++++-------------
 15 files changed, 79 insertions(+), 32 deletions(-)

diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install
index 37fa6269b91dcd1174225a93ac5974ddc04e5d3a..bfb947bcd7428f81ce43eb396f95ab0d04c9499f 100755
--- a/install/tools/ipa-ca-install
+++ b/install/tools/ipa-ca-install
@@ -98,6 +98,8 @@ def main():
             dirman_password = get_dirman_password()
         except KeyboardInterrupt:
             sys.exit(0)
+        if dirman_password is None:
+            sys.exit("\nDirectory Manager password required")
 
     if not options.admin_password and not options.skip_conncheck and \
         options.unattended:
diff --git a/install/tools/ipa-compat-manage b/install/tools/ipa-compat-manage
index 07531fddcdb3d211abb2360482551073fcbc3c00..898a797cf0fa10be288522a224a5ef7befaaf59b 100755
--- a/install/tools/ipa-compat-manage
+++ b/install/tools/ipa-compat-manage
@@ -100,6 +100,8 @@ def main():
         dirman_password = pw.strip()
     else:
         dirman_password = get_dirman_password()
+        if dirman_password is None:
+            sys.exit("\nDirectory Manager password required")
 
     api.bootstrap(context='cli', debug=options.debug)
     api.finalize()
diff --git a/install/tools/ipa-csreplica-manage b/install/tools/ipa-csreplica-manage
index 39d5056544966cd8a4077076a9f00b63dcc2119a..abfc117bae8491dcc04e93d5207faf20421a33c1 100755
--- a/install/tools/ipa-csreplica-manage
+++ b/install/tools/ipa-csreplica-manage
@@ -22,7 +22,7 @@
 import sys
 import os
 
-import getpass, ldap, krbV
+import ldap, krbV
 import logging
 
 from ipapython import ipautil
@@ -400,7 +400,10 @@ def main():
     if options.dirman_passwd:
         dirman_passwd = options.dirman_passwd
     else:
-        dirman_passwd = getpass.getpass("Directory Manager password: ")
+        dirman_passwd = installutils.read_password("Directory Manager", confirm=False,
+            validate=False, retry=False)
+        if dirman_passwd is None:
+            sys.exit("\nDirectory Manager password required")
 
     options.dirman_passwd = dirman_passwd
 
diff --git a/install/tools/ipa-dns-install b/install/tools/ipa-dns-install
index 9869eae8b143ee10e15fc811f9c1ab25aee77544..d81b6a2e804a815d5bece8426a286e3190f6dee3 100755
--- a/install/tools/ipa-dns-install
+++ b/install/tools/ipa-dns-install
@@ -128,6 +128,8 @@ def main():
 
     dm_password = options.dm_password or read_password("Directory Manager",
                                              confirm=False, validate=False)
+    if dm_password is None:
+        sys.exit("\nDirectory Manager password required")
     bind = bindinstance.BindInstance(fstore, dm_password)
 
     # try the connection
diff --git a/install/tools/ipa-ldap-updater b/install/tools/ipa-ldap-updater
index 5b63c120ec83a03fa0cc7ba9aab1cb60bda23e31..6ecb8c155d723f5e0c9c234c0e1ddb1f3150ca4a 100755
--- a/install/tools/ipa-ldap-updater
+++ b/install/tools/ipa-ldap-updater
@@ -96,6 +96,8 @@ def main():
     else:
         if (options.ask_password or not options.ldapi) and not options.upgrade:
             dirman_password = get_dirman_password()
+            if dirman_password is None:
+                sys.exit("\nDirectory Manager password required")
 
     files = []
     if len(args) > 0:
diff --git a/install/tools/ipa-managed-entries b/install/tools/ipa-managed-entries
index 9b3f54714c2809fffecc92d428328d110a9fdc64..16f0a956cd2b1398dc3385d3f2254cb56cf23c09 100755
--- a/install/tools/ipa-managed-entries
+++ b/install/tools/ipa-managed-entries
@@ -112,6 +112,8 @@ def main():
             dirman_password = options.dirman_password
         else:
             dirman_password = get_dirman_password()
+            if dirman_password is None:
+                sys.exit("\nDirectory Manager password required")
         conn.do_simple_bind(bindpw=dirman_password)
     except errors.ExecutionError, lde:
         sys.exit("An error occurred while connecting to the server.\n%s\n" %
diff --git a/install/tools/ipa-nis-manage b/install/tools/ipa-nis-manage
index 542736a8d973db051b920ee16acc2d8f493ec756..886f23ab8cf168857891d55d979f78c2a9f2042f 100755
--- a/install/tools/ipa-nis-manage
+++ b/install/tools/ipa-nis-manage
@@ -111,6 +111,8 @@ def main():
         dirman_password = pw.strip()
     else:
         dirman_password = get_dirman_password()
+        if dirman_password is None:
+            sys.exit("\nDirectory Manager password required")
 
     if not dirman_password:
         sys.exit("No password supplied")
diff --git a/install/tools/ipa-replica-conncheck b/install/tools/ipa-replica-conncheck
index ac1817e5d38e88566f2e8433b1c0c2da3f2a8449..d8098f6b01ae36bd827e98c9716b51992cc56a5f 100755
--- a/install/tools/ipa-replica-conncheck
+++ b/install/tools/ipa-replica-conncheck
@@ -22,6 +22,7 @@ from ipapython.config import IPAOptionParser
 from ipapython import version
 from ipapython import ipautil
 from ipapython.ipautil import CalledProcessError
+from ipaserver.install import installutils
 import ipaclient.ipachangeconf
 from optparse import OptionGroup
 import logging
@@ -29,7 +30,6 @@ import sys
 import os
 import signal
 import tempfile
-import getpass
 import socket
 import time
 import threading
@@ -314,7 +314,11 @@ def main():
             if options.password:
                 password=options.password
             else:
-                password = getpass.getpass("Password for %s: " % principal)
+                password = installutils.read_password(principal, confirm=False,
+                           validate=False, retry=False)
+                if password is None:
+                    sys.exit("\nPrincipal password required")
+
 
             stderr=''
             (stdout, stderr, returncode) = ipautil.run(['/usr/bin/kinit', principal],
diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index 62380443afa228315ebe7c598fe0e5427c7afb93..98e1054b24b204605eb94b744fe57ee882a8ac29 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -313,6 +313,8 @@ def main():
             dirman_password = get_dirman_password()
         except KeyboardInterrupt:
             sys.exit(0)
+        if dirman_password is None:
+            sys.exit("\nDirectory Manager password required")
 
     try:
         top_dir, dir = expand_replica_info(filename, dirman_password)
diff --git a/install/tools/ipa-replica-manage b/install/tools/ipa-replica-manage
index c3dd0b3fe9e2efcc32e20286ef42d798bf567e08..84cfd8f3e50fe78e576b75b41961eba33d27eaca 100755
--- a/install/tools/ipa-replica-manage
+++ b/install/tools/ipa-replica-manage
@@ -20,7 +20,7 @@
 import sys
 import os
 
-import getpass, ldap, re, krbV
+import ldap, re, krbV
 import traceback, logging
 
 from ipapython import ipautil
@@ -444,7 +444,10 @@ def main():
         dirman_passwd = options.dirman_passwd
     else:
         if not test_connection(realm, host):
-            dirman_passwd = getpass.getpass("Directory Manager password: ")
+            dirman_passwd = installutils.read_password("Directory Manager",
+                confirm=False, validate=False, retry=False)
+            if dirman_passwd is None:
+                sys.exit("\nDirectory Manager password required")
 
     options.dirman_passwd = dirman_passwd
 
diff --git a/install/tools/ipa-replica-prepare b/install/tools/ipa-replica-prepare
index 05115ac3ccdfdca87960025811dc992c5d6ab530..ae453d9986fa36c151a34309583a55e8e520e073 100755
--- a/install/tools/ipa-replica-prepare
+++ b/install/tools/ipa-replica-prepare
@@ -294,6 +294,8 @@ def main():
             dirman_password = get_dirman_password()
         except KeyboardInterrupt:
             sys.exit(0)
+        if dirman_password is None:
+            sys.exit("\nDirectory Manager password required")
 
     # Try out the password
     try:
diff --git a/install/tools/ipa-server-certinstall b/install/tools/ipa-server-certinstall
index 312d412024fb23a91eacd25f75a2e89bc25f5b1c..901678b2e8e250ed7d460df326ff965e74d6167e 100755
--- a/install/tools/ipa-server-certinstall
+++ b/install/tools/ipa-server-certinstall
@@ -25,14 +25,13 @@ import tempfile
 
 import traceback
 
-import krbV, getpass
+import krbV
 
 from ipapython.ipautil import user_input
 
 from ipaserver.install import certs, dsinstance, httpinstance, installutils
 from ipalib import api
 from ipaserver.plugins.ldap2 import ldap2
-from ipaserver.install import installutils
 
 def get_realm_name():
     c = krbV.default_context()
@@ -132,7 +131,10 @@ def main():
 
     try:
         if options.dirsrv:
-            dm_password = getpass.getpass("Directory Manager password: ")
+            dm_password = installutils.read_password("Directory Manager",
+                confirm=False, validate=False, retry=False)
+            if dm_password is None:
+                sys.exit("\nDirectory Manager password required")
             realm = get_realm_name()
             dirname = dsinstance.config_dirname(dsinstance.realm_to_serverid(realm))
             fd = open(dirname + "/pwdfile.txt")
diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index 504d6af50f70278864dacf44cac9e4bbc832e069..c39361bd8e5208c70a232463609d0c492def200e 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -622,6 +622,8 @@ def main():
     # This will override any settings passed in on the cmdline
     if ipautil.file_exists(ANSWER_CACHE):
         dm_password = read_password("Directory Manager", confirm=False)
+        if dm_password is None:
+            sys.exit("\nDirectory Manager password required")
         options._update_loose(read_cache(dm_password))
 
     if options.external_cert_file:
@@ -782,6 +784,9 @@ def main():
 
     if not options.dm_password:
         dm_password = read_dm_password()
+
+        if dm_password is None:
+            sys.exit("\nDirectory Manager password required")
     else:
         dm_password = options.dm_password
 
@@ -792,6 +797,8 @@ def main():
 
     if not options.admin_password:
         admin_password = read_admin_password()
+        if admin_password is None:
+            sys.exit("\nIPA admin password required")
     else:
         admin_password = options.admin_password
 
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index 76f7f1913c804053edb8b90979286a0592fa5737..9828e3a14fef70dfc764f9c95a0d979930bda950 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -917,7 +917,10 @@ def install(options, env, fstore, statestore):
                     stdin = options.password
                 else:
                     if not options.unattended:
-                        stdin = getpass.getpass("Password for %s: " % principal)
+                        try:
+                            stdin = getpass.getpass("Password for %s: " % principal)
+                        except EOFError:
+                            stdin = None
                         if not stdin:
                             print "Password must be provided for %s. " % \
                                 principal
@@ -942,7 +945,13 @@ def install(options, env, fstore, statestore):
                 if options.unattended:
                     print "Password must be provided in non-interactive mode"
                     return CLIENT_INSTALL_ERROR
-                password = getpass.getpass("Password: ")
+                try:
+                    password = getpass.getpass("Password: ")
+                except EOFError:
+                    password = None
+                if not password:
+                    print "Password must be provided."
+                    return CLIENT_INSTALL_ERROR
                 join_args.append("-w")
                 join_args.append(password)
                 nolog = (password,)
diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py
index 44292fd4c303c0caa5d77e525dd1041095543b51..b72a3bf9b0ee3108e61b57a9e91f4aa97d3d5425 100644
--- a/ipaserver/install/installutils.py
+++ b/ipaserver/install/installutils.py
@@ -315,27 +315,30 @@ def get_password(prompt):
 
 def read_password(user, confirm=True, validate=True, retry=True):
     correct = False
-    pwd = ""
-    while not correct:
-        if not retry:
-            correct = True
-        pwd = get_password(user + " password: ")
-        if not pwd:
-            continue
-        if validate and len(pwd) < 8:
-            print "Password must be at least 8 characters long"
-            pwd = ""
-            continue
-        if not confirm:
-            correct = True
-            continue
-        pwd_confirm = get_password("Password (confirm): ")
-        if pwd != pwd_confirm:
-            print "Password mismatch!"
-            print ""
-            pwd = ""
-        else:
-            correct = True
+    pwd = None
+    try:
+        while not correct:
+            if not retry:
+                correct = True
+            pwd = get_password(user + " password: ")
+            if not pwd:
+                continue
+            if validate and len(pwd) < 8:
+                print "Password must be at least 8 characters long"
+                pwd = None
+                continue
+            if not confirm:
+                correct = True
+                continue
+            pwd_confirm = get_password("Password (confirm): ")
+            if pwd != pwd_confirm:
+                print "Password mismatch!"
+                print ""
+                pwd = None
+            else:
+                correct = True
+    except EOFError:
+        return None
     print ""
     return pwd
 
-- 
1.7.6.2

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to