#! /usr/bin/python -E # Authors: Rob Crittenden # # Copyright (C) 2009 Red Hat # see file 'COPYING' for use and warranty information # # 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 only # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # import sys import os import subprocess import shutil import glob import traceback from optparse import OptionParser import krbV import tempfile from ipaserver import dsinstance from ipaserver import certs import ipa.ipautil as ipautil def parse_options(): parser = OptionParser() parser.add_option("-g", "--generate", dest="generate", action="store_true", default=False, help="Generate a new CA") parser.add_option("-i", "--issue", dest="issue", action="store_true", default=False, help="issue a server cert") parser.add_option("-s", "--subject", dest="hostname", help="hostname for server cert") parser.add_option("-o", "--pk12", dest="pk12file", help="PKCS#12 file to store new cert in") parser.add_option("-p", "--password", dest="password", help="password for PKCS#12 file") options, args = parser.parse_args() if options.generate and options.issue: parser.error("generate and issue are mutually-exclusive") if options.issue and (not options.hostname or not options.pk12file or not options.password): parser.error("to issue a cert the hostname, PKCS#12 file and password are all required") return options def get_realm_name(): try: c = krbV.default_context() return c.default_realm except Exception, e: return None def main(): options = parse_options() if os.getegid() != 0: print "Must be root to setup server" return 1 realm_name = get_realm_name() ds_dir = dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name)) ca_db = certs.CertDB(ds_dir) tmpdb = certs.CertDB(dir) options, args = parser.parse_args() return options def main(): options = parse_options() if os.getegid() != 0: print "Must be root to setup server" return 1 realm_name = get_realm_name() ds_dir = dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name)) if options.generate: print "Generating new CA certificate in %s" % ds_dir if ipautil.file_exists(ds_dir + "/cert8.db"): raise RuntimeError("Directory server certificate database already exists. Back it up and remove it in order to generate a new one.") ca_db = certs.CertDB(ds_dir) ca_db.create_self_signed() print "Publishing new CA cert to /usr/share/ipa/html/ca.crt" shutil.copy(ca_db.cacert_fname, "/usr/share/ipa/html/ca.crt") print "Publishing new CA cert to /etc/ipa/ca.crt" if options.issue: try: certdir = tempfile.mkdtemp(prefix = "tmp-") tmpdb = certs.CertDB(certdir) ca_db = certs.CertDB(ds_dir) print "Creating temporary certificate database" tmpdb.create_from_cacert(ca_db.cacert_fname) subject = "CN=%s,ou=test-ipa,O=IPA" % options.hostname print "Generating new certificate for %s" % options.hostname tmpdb.create_server_cert("Server-Cert", subject, ca_db) (pk12_fd, pk12_name) = tempfile.mkstemp() os.write(pk12_fd, options.password) os.close(pk12_fd) try: print "Creating PKCS#12 file %s" % options.pk12file tmpdb.export_pkcs12(options.pk12file, pk12_name, "Server-Cert") finally: os.remove(pk12_name) finally: print "Cleaning up" shutil.rmtree(certdir, ignore_errors=True) return 0 try: sys.exit(main()) except SystemExit, e: sys.exit(e) except Exception, e: print str(e) sys.exit(1)