>From 112343469949a3a5389d2747411ee6343bd20acb Mon Sep 17 00:00:00 2001
From: "Endi S. Dewata" <edewata@redhat.com>
Date: Wed, 29 Jun 2016 17:13:20 +0200
Subject: [PATCH] Fixed pki-server subsystem-cert-update.

The pki-server subsystem-cert-update is supposed to restore the
system certificate data and requests into CS.cfg. The command was
broken since the CASubsystem class that contains the code to find
the certificate requests from database was not loaded correctly.
To fix the problem the CASubsystem class has been moved into the
pki/server/__init__.py.

All pki-server subsystem-* commands have been modified to check
the validity of the instance.

An option has been added to the pki-server subsystem-cert-show
command to display the data and request of a particular system
certificate.

The redundant output of the pki-server subsystem-cert-update has
been removed. The updated certificate data and request can be
obtained using the pki-server subsystem-cert-show command.

https://fedorahosted.org/pki/ticket/2385
---
 base/server/python/pki/server/__init__.py      | 67 +++++++++++++++++++
 base/server/python/pki/server/ca.py            | 91 --------------------------
 base/server/python/pki/server/cli/subsystem.py | 58 ++++++++++++++--
 3 files changed, 120 insertions(+), 96 deletions(-)
 delete mode 100644 base/server/python/pki/server/ca.py

diff --git a/base/server/python/pki/server/__init__.py b/base/server/python/pki/server/__init__.py
index 454408f6ad54202a5a94809dede2a08e43078a3a..355b8b0ca5a9ead610fe102d18031c97d06df156 100644
--- a/base/server/python/pki/server/__init__.py
+++ b/base/server/python/pki/server/__init__.py
@@ -25,6 +25,7 @@ import getpass
 import grp
 import io
 import ldap
+import ldap.filter
 import operator
 import os
 import pwd
@@ -389,6 +390,72 @@ class PKISubsystem(object):
         return str(self.instance) + '/' + self.name
 
 
+class CASubsystem(PKISubsystem):
+
+    def __init__(self, instance):
+        super(CASubsystem, self).__init__(instance, 'ca')
+
+    def find_cert_requests(self, cert=None):
+
+        base_dn = self.config['internaldb.basedn']
+
+        if cert:
+            escaped_value = ldap.filter.escape_filter_chars(cert)
+            search_filter = '(extdata-req--005fissued--005fcert=%s)' % escaped_value
+
+        else:
+            search_filter = '(objectClass=*)'
+
+        con = self.open_database()
+
+        entries = con.ldap.search_s(
+            'ou=ca,ou=requests,%s' % base_dn,
+            ldap.SCOPE_ONELEVEL,
+            search_filter,
+            None)
+
+        con.close()
+
+        requests = []
+        for entry in entries:
+            requests.append(self.create_request_object(entry))
+
+        return requests
+
+    def get_cert_requests(self, request_id):
+
+        base_dn = self.config['internaldb.basedn']
+
+        con = self.open_database()
+
+        entries = con.ldap.search_s(
+            'cn=%s,ou=ca,ou=requests,%s' % (request_id, base_dn),
+            ldap.SCOPE_BASE,
+            '(objectClass=*)',
+            None)
+
+        con.close()
+
+        entry = entries[0]
+        return self.create_request_object(entry)
+
+    def create_request_object(self, entry):
+
+        attrs = entry[1]
+
+        request = {}
+        request['id'] = attrs['cn'][0]
+        request['type'] = attrs['requestType'][0]
+        request['status'] = attrs['requestState'][0]
+        request['request'] = attrs['extdata-cert--005frequest'][0]
+
+        return request
+
+
+# register CASubsystem
+SUBSYSTEM_CLASSES['ca'] = CASubsystem
+
+
 class ExternalCert(object):
 
     def __init__(self, nickname=None, token=None):
diff --git a/base/server/python/pki/server/ca.py b/base/server/python/pki/server/ca.py
deleted file mode 100644
index afb281cc1b6fdb6fb983a105a8d8fba8fa9b429b..0000000000000000000000000000000000000000
--- a/base/server/python/pki/server/ca.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Authors:
-#     Endi S. Dewata <edewata@redhat.com>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Copyright (C) 2015 Red Hat, Inc.
-# All rights reserved.
-#
-
-from __future__ import absolute_import
-import ldap
-import ldap.filter
-
-import pki
-import pki.server
-
-
-class CASubsystem(pki.server.PKISubsystem):
-
-    def __init__(self, instance):
-        super(CASubsystem, self).__init__(instance, 'ca')
-
-    def find_cert_requests(self, cert=None):
-
-        base_dn = self.config['internaldb.basedn']
-
-        if cert:
-            escaped_value = ldap.filter.escape_filter_chars(cert)
-            search_filter = '(extdata-req--005fissued--005fcert=%s)' % escaped_value
-
-        else:
-            search_filter = '(objectClass=*)'
-
-        con = self.open_database()
-
-        entries = con.ldap.search_s(
-            'ou=ca,ou=requests,%s' % base_dn,
-            ldap.SCOPE_ONELEVEL,
-            search_filter,
-            None)
-
-        con.close()
-
-        requests = []
-        for entry in entries:
-            requests.append(self.create_request_object(entry))
-
-        return requests
-
-    def get_cert_requests(self, request_id):
-
-        base_dn = self.config['internaldb.basedn']
-
-        con = self.open_database()
-
-        entries = con.ldap.search_s(
-            'cn=%s,ou=ca,ou=requests,%s' % (request_id, base_dn),
-            ldap.SCOPE_BASE,
-            '(objectClass=*)',
-            None)
-
-        con.close()
-
-        entry = entries[0]
-        return self.create_request_object(entry)
-
-    def create_request_object(self, entry):
-
-        attrs = entry[1]
-
-        request = {}
-        request['id'] = attrs['cn'][0]
-        request['type'] = attrs['requestType'][0]
-        request['status'] = attrs['requestState'][0]
-        request['request'] = attrs['extdata-cert--005frequest'][0]
-
-        return request
-
-
-pki.server.SUBSYSTEM_CLASSES['ca'] = CASubsystem
diff --git a/base/server/python/pki/server/cli/subsystem.py b/base/server/python/pki/server/cli/subsystem.py
index 45f5be9b4fa92b3c087f71a87dcbb45a06260550..49215cf46a56ac984bdd5b8ad54e618a7b04393e 100644
--- a/base/server/python/pki/server/cli/subsystem.py
+++ b/base/server/python/pki/server/cli/subsystem.py
@@ -99,6 +99,11 @@ class SubsystemFindCLI(pki.cli.CLI):
                 sys.exit(1)
 
         instance = pki.server.PKIInstance(instance_name)
+
+        if not instance.is_valid():
+            print('ERROR: Invalid instance %s.' % instance_name)
+            sys.exit(1)
+
         instance.load()
 
         self.print_message('%s entries matched' % len(instance.subsystems))
@@ -164,6 +169,11 @@ class SubsystemShowCLI(pki.cli.CLI):
         subsystem_name = args[0]
 
         instance = pki.server.PKIInstance(instance_name)
+
+        if not instance.is_valid():
+            print('ERROR: Invalid instance %s.' % instance_name)
+            sys.exit(1)
+
         instance.load()
 
         subsystem = instance.get_subsystem(subsystem_name)
@@ -222,6 +232,11 @@ class SubsystemEnableCLI(pki.cli.CLI):
         subsystem_name = args[0]
 
         instance = pki.server.PKIInstance(instance_name)
+
+        if not instance.is_valid():
+            print('ERROR: Invalid instance %s.' % instance_name)
+            sys.exit(1)
+
         instance.load()
 
         subsystem = instance.get_subsystem(subsystem_name)
@@ -285,6 +300,11 @@ class SubsystemDisableCLI(pki.cli.CLI):
         subsystem_name = args[0]
 
         instance = pki.server.PKIInstance(instance_name)
+
+        if not instance.is_valid():
+            print('ERROR: Invalid instance %s.' % instance_name)
+            sys.exit(1)
+
         instance.load()
 
         subsystem = instance.get_subsystem(subsystem_name)
@@ -375,6 +395,11 @@ class SubsystemCertFindCLI(pki.cli.CLI):
         subsystem_name = args[0]
 
         instance = pki.server.PKIInstance(instance_name)
+
+        if not instance.is_valid():
+            print('ERROR: Invalid instance %s.' % instance_name)
+            sys.exit(1)
+
         instance.load()
 
         subsystem = instance.get_subsystem(subsystem_name)
@@ -402,6 +427,7 @@ class SubsystemCertShowCLI(pki.cli.CLI):
         print('Usage: pki-server subsystem-cert-show [OPTIONS] <subsystem ID> <cert ID>')
         print()
         print('  -i, --instance <instance ID>    Instance ID (default: pki-tomcat).')
+        print('      --show-all                  Show all attributes.')
         print('  -v, --verbose                   Run in verbose mode.')
         print('      --help                      Show help message.')
         print()
@@ -410,7 +436,7 @@ class SubsystemCertShowCLI(pki.cli.CLI):
 
         try:
             opts, args = getopt.gnu_getopt(argv, 'i:v', [
-                'instance=',
+                'instance=',  'show-all',
                 'verbose', 'help'])
 
         except getopt.GetoptError as e:
@@ -419,11 +445,15 @@ class SubsystemCertShowCLI(pki.cli.CLI):
             sys.exit(1)
 
         instance_name = 'pki-tomcat'
+        show_all = False
 
         for o, a in opts:
             if o in ('-i', '--instance'):
                 instance_name = a
 
+            elif o == '--show-all':
+                show_all = True
+
             elif o in ('-v', '--verbose'):
                 self.set_verbose(True)
 
@@ -451,12 +481,17 @@ class SubsystemCertShowCLI(pki.cli.CLI):
         cert_id = args[1]
 
         instance = pki.server.PKIInstance(instance_name)
+
+        if not instance.is_valid():
+            print('ERROR: Invalid instance %s.' % instance_name)
+            sys.exit(1)
+
         instance.load()
 
         subsystem = instance.get_subsystem(subsystem_name)
-        subsystem_cert = subsystem.get_subsystem_cert(cert_id)
+        cert = subsystem.get_subsystem_cert(cert_id)
 
-        SubsystemCertCLI.print_subsystem_cert(subsystem_cert)
+        SubsystemCertCLI.print_subsystem_cert(cert, show_all)
 
 
 class SubsystemCertExportCLI(pki.cli.CLI):
@@ -568,6 +603,11 @@ class SubsystemCertExportCLI(pki.cli.CLI):
             sys.exit(1)
 
         instance = pki.server.PKIInstance(instance_name)
+
+        if not instance.is_valid():
+            print('ERROR: Invalid instance %s.' % instance_name)
+            sys.exit(1)
+
         instance.load()
 
         subsystem = instance.get_subsystem(subsystem_name)
@@ -684,6 +724,11 @@ class SubsystemCertUpdateCLI(pki.cli.CLI):
         cert_id = args[1]
 
         instance = pki.server.PKIInstance(instance_name)
+
+        if not instance.is_valid():
+            print('ERROR: Invalid instance %s.' % instance_name)
+            sys.exit(1)
+
         instance.load()
 
         subsystem = instance.get_subsystem(subsystem_name)
@@ -723,8 +768,6 @@ class SubsystemCertUpdateCLI(pki.cli.CLI):
 
         self.print_message('Updated "%s" subsystem certificate' % cert_id)
 
-        SubsystemCertCLI.print_subsystem_cert(subsystem_cert)
-
 
 class SubsystemCertValidateCLI(pki.cli.CLI):
 
@@ -783,6 +826,11 @@ class SubsystemCertValidateCLI(pki.cli.CLI):
             cert_id = None
 
         instance = pki.server.PKIInstance(instance_name)
+
+        if not instance.is_valid():
+            print('ERROR: Invalid instance %s.' % instance_name)
+            sys.exit(1)
+
         instance.load()
 
         subsystem = instance.get_subsystem(subsystem_name)
-- 
2.4.11

