diff options
author | Endi S. Dewata <edewata@redhat.com> | 2017-03-15 08:13:35 +0100 |
---|---|---|
committer | Endi S. Dewata <edewata@redhat.com> | 2017-03-15 19:36:53 +0100 |
commit | 07135b5906f97a8c68148a07484e63d6896f410b (patch) | |
tree | d849bdce0673b7367249b2ff581256e9eaff5fc9 /base/common/python | |
parent | 3253d852eb50d30f30a37800f0cf16898a038b6c (diff) | |
download | pki-07135b5906f97a8c68148a07484e63d6896f410b.tar.gz pki-07135b5906f97a8c68148a07484e63d6896f410b.tar.xz pki-07135b5906f97a8c68148a07484e63d6896f410b.zip |
Added cascading configuration for PKI CLI.
The PKI CLI has been modified to support cascading configuration
files: default, system-wide, and user-specific configuration.
The existing Python-based PKI CLI was moved into pki.cli.main
module. A new shell script was added as a replacement which will
read the configuration files and invoke the Python module.
Diffstat (limited to 'base/common/python')
-rw-r--r-- | base/common/python/pki/cli/main.py | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/base/common/python/pki/cli/main.py b/base/common/python/pki/cli/main.py new file mode 100644 index 000000000..53e1b893a --- /dev/null +++ b/base/common/python/pki/cli/main.py @@ -0,0 +1,236 @@ +#!/usr/bin/python +# 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) 2014 Red Hat, Inc. +# All rights reserved. +# + +from __future__ import absolute_import +from __future__ import print_function +import shlex +import subprocess +import sys +import traceback + +import pki.cli +import pki.cli.pkcs12 + + +PYTHON_COMMANDS = ['pkcs12-import'] + + +class PKICLI(pki.cli.CLI): + + def __init__(self): + super(PKICLI, self).__init__( + 'pki', 'PKI command-line interface') + + self.database = None + self.password = None + self.password_file = None + self.token = None + + self.add_module(pki.cli.pkcs12.PKCS12CLI()) + + def get_full_module_name(self, module_name): + return module_name + + def print_help(self): + print('Usage: pki [OPTIONS]') + print() + print(' --client-type <type> PKI client type (default: java)') + print(' -d <path> Client security database location ' + + '(default: ~/.dogtag/nssdb)') + print(' -c <password> Client security database password ' + + '(mutually exclusive to the -C option)') + print(' -C <path> Client-side password file ' + + '(mutually exclusive to the -c option)') + print(' --token <name> Security token name') + print() + print(' -v, --verbose Run in verbose mode.') + print(' --debug Show debug messages.') + print(' --help Show help message.') + print() + + super(PKICLI, self).print_help() + + def execute_java(self, args, stdout=sys.stdout): + + # read Java home + value = subprocess.check_output( + '. /usr/share/pki/etc/pki.conf && . /etc/pki/pki.conf && echo $JAVA_HOME', + shell=True) + java_home = value.decode(sys.getfilesystemencoding()).strip() + + # read PKI library + value = subprocess.check_output( + '. /usr/share/pki/etc/pki.conf && . /etc/pki/pki.conf && echo $PKI_LIB', + shell=True) + pki_lib = value.decode(sys.getfilesystemencoding()).strip() + + # read logging configuration path + value = subprocess.check_output( + '. /usr/share/pki/etc/pki.conf && . /etc/pki/pki.conf && echo $LOGGING_CONFIG', + shell=True) + logging_config = value.decode(sys.getfilesystemencoding()).strip() + + cmd = [ + java_home + '/bin/java', + '-Djava.ext.dirs=' + pki_lib, + '-Djava.util.logging.config.file=' + logging_config, + 'com.netscape.cmstools.cli.MainCLI' + ] + + # restore options for Java commands + + if self.database: + cmd.extend(['-d', self.database]) + + if self.password: + cmd.extend(['-c', self.password]) + + if self.password_file: + cmd.extend(['-C', self.password_file]) + + if self.token and self.token != 'internal': + cmd.extend(['--token', self.token]) + + if self.verbose: + cmd.extend(['--verbose']) + + cmd.extend(args) + + if self.verbose: + print('Java command: %s' % ' '.join(cmd)) + + subprocess.check_call(cmd, stdout=stdout) + + def execute(self, argv): + + # append global options + value = subprocess.check_output( + '. /usr/share/pki/etc/pki.conf && . /etc/pki/pki.conf && echo $PKI_CLI_OPTIONS', + shell=True) + value = value.decode(sys.getfilesystemencoding()).strip() + args = shlex.split(value) + args.extend(argv[1:]) + + client_type = 'java' + + pki_options = [] + command = None + cmd_args = [] + + # read pki options before the command + # remove options for Python module + + i = 0 + while i < len(args): + # if arg is a command, stop + if args[i][0] != '-': + command = args[i] + break + + # get database path + if args[i] == '-d': + self.database = args[i + 1] + pki_options.append(args[i]) + pki_options.append(args[i + 1]) + i = i + 2 + + # get database password + elif args[i] == '-c': + self.password = args[i + 1] + pki_options.append(args[i]) + pki_options.append(args[i + 1]) + i = i + 2 + + # get database password file path + elif args[i] == '-C': + self.password_file = args[i + 1] + pki_options.append(args[i]) + pki_options.append(args[i + 1]) + i = i + 2 + + # get token name + elif args[i] == '--token': + self.token = args[i + 1] + pki_options.append(args[i]) + pki_options.append(args[i + 1]) + i = i + 2 + + # check verbose option + elif args[i] == '-v' or args[i] == '--verbose': + self.set_verbose(True) + pki_options.append(args[i]) + i = i + 1 + + # check debug option + elif args[i] == '--debug': + self.set_verbose(True) + self.set_debug(True) + pki_options.append(args[i]) + i = i + 1 + + # get client type + elif args[i] == '--client-type': + client_type = args[i + 1] + pki_options.append(args[i]) + pki_options.append(args[i + 1]) + i = i + 2 + + else: # otherwise, save the arg for the next module + cmd_args.append(args[i]) + i = i + 1 + + # save the rest of the args + while i < len(args): + cmd_args.append(args[i]) + i = i + 1 + + if self.verbose: + print('PKI options: %s' % ' '.join(pki_options)) + print('PKI command: %s %s' % (command, ' '.join(cmd_args))) + + if client_type == 'python' or command in PYTHON_COMMANDS: + (module, module_args) = self.parse_args(cmd_args) + module.execute(module_args) + + elif client_type == 'java': + self.execute_java(cmd_args) + + else: + raise Exception('Unsupported client type: ' + client_type) + + +if __name__ == '__main__': + + cli = PKICLI() + + try: + cli.execute(sys.argv) + + except subprocess.CalledProcessError as e: + if cli.verbose: + print('ERROR: %s' % e) + elif cli.debug: + traceback.print_exc() + sys.exit(e.returncode) + + except KeyboardInterrupt: + print() + sys.exit(-1) |