>From c75b279e6bc61fe74d6663a2bb8e764b14805339 Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Sat, 25 Jun 2016 00:14:11 +0200
Subject: [PATCH] Fixed problem reading HSM password from password file.

A new method get_token_password() has been added into PKIInstance
Python class in order to read the token password correctly from
password.conf. If the token is an internal token, it will read the
'internal' password. If it is an HSM it will read the password for
'hardware-<token>'.

The codes that call the get_password() to get token password have
been modified to use get_token_password() instead.

https://fedorahosted.org/pki/ticket/2384
---
 base/server/python/pki/server/__init__.py      | 59 +++++++++++++++++++-------
 base/server/python/pki/server/cli/instance.py  |  4 +-
 base/server/python/pki/server/cli/subsystem.py | 11 ++---
 3 files changed, 50 insertions(+), 24 deletions(-)

diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py
index bf705fd358b00fb36fe9df25d7c6d74cff0d4154..454408f6ad54202a5a94809dede2a08e43078a3a 100644
--- a/base/server/python/pki/server/__init__.py
+++ b/base/server/python/pki/server/__init__.py
@@ -186,9 +186,11 @@ class PKISubsystem(object):
         cert = self.get_subsystem_cert(cert_id)
         nickname = cert['nickname']
         token = cert['token']
-        if token == 'Internal Key Storage Token':
-            token = 'internal'
-        nssdb_password = self.instance.get_password(token)
+
+        if token and token.lower() in ['internal', 'internal key storage token']:
+            token = None
+
+        nssdb_password = self.instance.get_token_password(token)
 
         tmpdir = tempfile.mkdtemp()
 
@@ -204,7 +206,7 @@ class PKISubsystem(object):
                 '-C', nssdb_password_file
             ]
 
-            if token and token != 'internal':
+            if token:
                 cmd.extend(['--token', token])
 
             cmd.extend([
@@ -234,9 +236,11 @@ class PKISubsystem(object):
         cert = self.get_subsystem_cert('subsystem')
         nickname = cert['nickname']
         token = cert['token']
-        if token == 'Internal Key Storage Token':
-            token = 'internal'
-        nssdb_password = self.instance.get_password(token)
+
+        if token and token.lower() in ['internal', 'internal key storage token']:
+            token = None
+
+        nssdb_password = self.instance.get_token_password(token)
 
         tmpdir = tempfile.mkdtemp()
 
@@ -252,7 +256,7 @@ class PKISubsystem(object):
                 '-C', nssdb_password_file
             ]
 
-            if token and token != 'internal':
+            if token:
                 cmd.extend(['--token', token])
 
             cmd.extend([
@@ -271,7 +275,7 @@ class PKISubsystem(object):
                 '-C', nssdb_password_file
             ]
 
-            if token and token != 'internal':
+            if token:
                 cmd.extend(['--token', token])
 
             cmd.extend([
@@ -359,7 +363,8 @@ class PKISubsystem(object):
             connection.set_credentials(
                 client_cert_nickname=self.config[
                     '%s.ldapauth.clientCertNickname' % name],
-                nssdb_password=self.instance.get_password('internal')
+                # TODO: remove hard-coded token name
+                nssdb_password=self.instance.get_token_password('internal')
             )
 
         else:
@@ -543,19 +548,41 @@ class PKIInstance(object):
         return external_certs
 
     def get_password(self, name):
+
+        # find password (e.g. internaldb, replicationdb) in password.conf
         if name in self.passwords:
             return self.passwords[name]
 
+        # prompt for password if not found
         password = getpass.getpass(prompt='Enter password for %s: ' % name)
         self.passwords[name] = password
 
         return password
 
+    def get_token_password(self, token='internal'):
+
+        # determine the password name for the token
+        if token.lower() in ['internal', 'internal key storage token']:
+            name = 'internal'
+
+        else:
+            name = 'hardware-%s' % token
+
+        # find password in password.conf
+        if name in self.passwords:
+            return self.passwords[name]
+
+        # prompt for password if not found
+        password = getpass.getpass(prompt='Enter password for %s: ' % token)
+        self.passwords[name] = password
+
+        return password
+
     def open_nssdb(self, token='internal'):
         return pki.nssdb.NSSDatabase(
             directory=self.nssdb_dir,
             token=token,
-            password=self.get_password(token))
+            password=self.get_token_password(token))
 
     def external_cert_exists(self, nickname, token):
         for cert in self.external_certs:
@@ -588,9 +615,11 @@ class PKIInstance(object):
         for cert in self.external_certs:
             nickname = cert.nickname
             token = cert.token
-            if token == 'Internal Key Storage Token':
-                token = 'internal'
-            nssdb_password = self.get_password(token)
+
+            if token and token.lower() in ['internal', 'internal key storage token']:
+                token = None
+
+            nssdb_password = self.get_token_password(token)
 
             tmpdir = tempfile.mkdtemp()
 
@@ -606,7 +635,7 @@ class PKIInstance(object):
                     '-C', nssdb_password_file
                 ]
 
-                if token and token != 'internal':
+                if token:
                     cmd.extend(['--token', token])
 
                 cmd.extend([
diff --git a/base/server/python/pki/server/cli/instance.py b/base/server/python/pki/server/cli/instance.py
index 6e336e11113cb8b9af7745143440ede95022cb7b..4a5a3b3e0e7d56356e571c8d25d8e19941a2ddb6 100644
--- a/base/server/python/pki/server/cli/instance.py
+++ b/base/server/python/pki/server/cli/instance.py
@@ -679,7 +679,7 @@ class InstanceExternalCertAddCLI(pki.cli.CLI):
                            instance_name)
 
     def import_certs(self, instance, cert_file, nickname, token, trust_args):
-        password = instance.get_password(token)
+        password = instance.get_token_password(token)
         certdb = pki.nssdb.NSSDatabase(
             directory=instance.nssdb_dir,
             password=password,
@@ -762,7 +762,7 @@ class InstanceExternalCertDeleteCLI(pki.cli.CLI):
                            instance_name)
 
     def remove_cert(self, instance, nickname, token):
-        password = instance.get_password(token)
+        password = instance.get_token_password(token)
         certdb = pki.nssdb.NSSDatabase(
             directory=instance.nssdb_dir,
             password=password,
diff --git a/base/server/python/pki/server/cli/subsystem.py b/base/server/python/pki/server/cli/subsystem.py
index c92ed16be251af87aa20ddada17da48de2ea4511..615b55e15be647e12d26ec4d04fa92084e9b82e3 100644
--- a/base/server/python/pki/server/cli/subsystem.py
+++ b/base/server/python/pki/server/cli/subsystem.py
@@ -843,14 +843,11 @@ class SubsystemCertValidateCLI(pki.cli.CLI):
 
         print('  Token: %s' % token)
 
-        if token == 'Internal Key Storage Token':
-            token = 'internal'
+        if token and token.lower() in ['internal', 'internal key storage token']:
+            token = None
 
         # get token password and store in temporary file
-        if token == 'internal':
-            passwd = instance.get_password('internal')
-        else:
-            passwd = instance.get_password("hardware-%s" % token)
+        passwd = instance.get_token_password(token)
 
         pwfile_handle, pwfile_path = mkstemp()
         os.write(pwfile_handle, passwd)
@@ -860,7 +857,7 @@ class SubsystemCertValidateCLI(pki.cli.CLI):
             cmd = ['pki', '-d', instance.nssdb_dir,
                    '-C', pwfile_path ]
 
-            if token != 'internal':
+            if token:
                 cmd.extend(['--token', token])
 
             cmd.extend(['client-cert-validate',
-- 
2.4.11

