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 ''
Example #2
0
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")