#!/usr/bin/python # Authors: # Endi S. Dewata # # 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 PKI client type (default: java)') print(' -d Client security database location ' + '(default: ~/.dogtag/nssdb)') print(' -c Client security database password ' + '(mutually exclusive to the -C option)') print(' -C Client-side password file ' + '(mutually exclusive to the -c option)') print(' --token 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 RESTEasy library path value = subprocess.check_output( '. /usr/share/pki/etc/pki.conf && . /etc/pki/pki.conf && echo $RESTEASY_LIB', shell=True) resteasy_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() # construct classpath classpath = [ '/usr/share/java/commons-cli.jar', '/usr/share/java/commons-codec.jar', '/usr/share/java/commons-httpclient.jar', '/usr/share/java/commons-io.jar', '/usr/share/java/commons-lang.jar', '/usr/share/java/commons-logging.jar', '/usr/share/java/httpcomponents/httpclient.jar', '/usr/share/java/httpcomponents/httpcore.jar', '/usr/share/java/jackson/jackson-core-asl.jar', '/usr/share/java/jackson/jackson-jaxrs.jar', '/usr/share/java/jackson/jackson-mapper-asl.jar', '/usr/share/java/jackson/jackson-mrbean.jar', '/usr/share/java/jackson/jackson-smile.jar', '/usr/share/java/jackson/jackson-xc.jar', '/usr/share/java/jaxb-api.jar', '/usr/share/java/ldapjdk.jar', '/usr/share/java/servlet.jar', resteasy_lib + '/jaxrs-api.jar', resteasy_lib + '/resteasy-atom-provider.jar', resteasy_lib + '/resteasy-client.jar', resteasy_lib + '/resteasy-jaxb-provider.jar', resteasy_lib + '/resteasy-jaxrs.jar', resteasy_lib + '/resteasy-jaxrs-jandex.jar', resteasy_lib + '/resteasy-jackson-provider.jar', '/usr/share/java/pki/pki-nsutil.jar', '/usr/share/java/pki/pki-cmsutil.jar', '/usr/share/java/pki/pki-certsrv.jar', '/usr/share/java/pki/pki-tools.jar', '/usr/lib64/java/jss4.jar', '/usr/lib/java/jss4.jar' ] cmd = [ 'java', '-cp', ':'.join(classpath), '-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() exit(e.returncode)