def run(): if os.geteuid() != 0: print 'DigiCert Express Install must be run as root.' exit() parser = argparse.ArgumentParser( description= 'Express Install. Let DigiCert manage your certificates for you! ' 'Run the following commands in the order shown below, or choose "all" to do everything in one step.' ) parser.add_argument('--version', action='version', version='Express Install %s' % pkg_resources.require('digicert_express')[0].version) subparsers = parser.add_subparsers( help='Choose from the command options below:') dependency_check_parser = subparsers.add_parser( 'dep_check', help="Check for and install any needed dependencies") dependency_check_parser.set_defaults(func=check_for_deps) restart_apache_parser = subparsers.add_parser( 'restart_apache', help='Restart Apache and verify SSL configuration') restart_apache_parser.add_argument( "--domain", action="store", nargs="?", help="Domain to verify after the restart") restart_apache_parser.set_defaults(func=restart_apache) all_parser = subparsers.add_parser( "all", help='Download your certificate and secure your domain in one step') all_parser.add_argument("--domain", action="store", help="Domain name to secure") all_parser.add_argument( "--key", action="store", help="Path to private key file used to order certificate") all_parser.add_argument( "--api_key", action="store", help="Skip authentication step with a DigiCert API key") all_parser.add_argument("--order_id", action="store", help="DigiCert order ID for certificate") all_parser.set_defaults(func=do_everything) args = parser.parse_args() try: print '' LOGGER.info( 'DigiCert Express Install Web Server Configuration Utility') print '' verify_requirements() args.func(args) except Exception, e: raise e LOGGER.error(e) print ''
def locate_cfg_file(cfg_file_names, file_type, prompt=True, validate_key=False, cert=None, default_search_path=CFG_PATH): """ :param cfg_file_names: list of file names to loop through :param file_type: :param prompt: boolean, set to true and will ask user for a path to the file :param validate_key: :param cert: :param default_search_path: :return: """ LOGGER.info("Looking for {0}...".format(file_type)) if isinstance(cfg_file_names, basestring): names = [cfg_file_names] else: names = cfg_file_names for cfg_file_name in names: file_path = os.path.join(default_search_path, cfg_file_name) if os.path.exists(file_path): return_file = True if validate_key: if not cert or not express_utils.validate_key(file_path, cert): return_file = False if return_file: return file_path # Search the filesystem for cfg_file_name in names: sudo_user_name = os.getenv("SUDO_USER") sudo_user_home = "%s/%s" % ("/home", sudo_user_name) command = "find {0} -type f -name {1}".format(sudo_user_home, cfg_file_name) files = os.popen(command).read().splitlines() if len(files) > 0: matching_files = list() for file in files: if validate_key: if cert and express_utils.validate_key(file, cert): matching_files.append(file) else: matching_files.append(file) if len(matching_files) == 1: return matching_files[0] elif len(matching_files) > 1: resp = None while not resp: for i in range(0, len(matching_files)): print "{0}.\t{1}".format(i + 1, matching_files[i]) resp = raw_input( "\nPlease select the {0} you wish to secure " "from the list above (q to quit): ".format(file_type)) if resp != 'q': # validate the input, catch any exceptions from casting to an int and validate the # int value makes sense try: if int(resp) > len(matching_files) or int( resp) < 0: raise ValueError except ValueError as e: resp = None print "" print "ERROR: Invalid number, please try again." print "" else: continue if resp and resp != 'q': selection = int(resp) - 1 return matching_files[selection] if prompt: # At this point we haven't found any matching files so we need to prompt for one file_path = None try: while not file_path: try: answer = raw_input( "Do you have a private key for the certificate you want to install? [y/n] " ) if answer and answer.strip().lower() == 'y': file_path = raw_input( 'Please provide a full absolute path to the file: ' ) else: file_path = 'q' return '' if os.path.exists(file_path): if validate_key and cert: if not express_utils.validate_key(file_path, cert): raise Exception( "This key ({0}) does not match your certificate ({1}), please try again." .format(file_path, cert)) else: break else: break if len(file_path): raise Exception('No such file or directory: "%s"' % file_path) file_path = None except Exception, e: file_path = None print e.message print '' except KeyboardInterrupt: print '' LOGGER.error('No valid file selected.') print '' return file_path
def do_everything_with_args(order_id='', domain='', api_key='', key=''): raw_input( "I'll attempt to secure virtual hosts configured on this web server with an SSL certificate. Press ENTER to continue." ) print '' LOGGER.info("Looking up order info") order_id, domain, common_name = express_client.get_order_and_domain_info( order_id, domain) if order_id: #and not domain: # 1. get the order info for order_id, domain and common_name LOGGER.info("Querying for issued certificates with order_id %s" % order_id) # 2. look for key, chain and csr cert = parsers.locate_cfg_file( '%s.crt' % express_utils.replace_chars(common_name), 'Certificate', prompt=False, default_search_path="{0}/{1}".format( CFG_PATH, express_utils.replace_chars(domain))) chain = parsers.locate_cfg_file( ['DigiCertCA.crt'], 'Certificate chain', prompt=False, default_search_path="{0}/{1}".format( CFG_PATH, express_utils.replace_chars(domain))) key = parsers.locate_cfg_file('%s.key' % express_utils.replace_chars(common_name), 'Private key', validate_key=True, cert=cert, default_search_path="{0}/{1}".format( CFG_PATH, express_utils.replace_chars(domain))) if cert and chain and key: LOGGER.info("Found cert, chain and key") LOGGER.info("Installing cert for domain: %s" % domain) dns_names = express_utils.get_dns_names_from_openssl(cert) _install_multidomain_cert(order_id, domain, dns_names, cert, key=key, chain=chain) finalize_and_restart(domain) return if not cert and not chain and not key: LOGGER.info("Did not find cert, chain and key, proceeding...") _process(domain, order_id, failed_pk_check=False) finalize_and_restart(domain) return if cert and chain and not key: LOGGER.info("Found cert and chain but not key, proceeding...") _process(domain, order_id, failed_pk_check=True) finalize_and_restart(domain) return else: LOGGER.error("ERROR: You must specify a valid domain or order id")