#!/usr/bin/env python import sys, os import subprocess, tempfile import os.path import re from M2Crypto import X509 from string import join from federation.util import abac_pem_type, abac_split_cert, file_expanding_opts class Parser(file_expanding_opts): def __init__(self): file_expanding_opts.__init__(self, usage='%prog [options]') self.add_option('--out', dest='out', help='destination file', action='callback', callback=self.expand_file, type='str', default='./cert.pem') self.add_option('--debug', dest='debug', action='store_true', default=False, help='Just print command') self.add_option('--cert', dest='cert', help='Cretificate to copy subject from') self.add_option('--nokey', dest='include_key', action='store_false', default=True, help='Do not include the key in the generated ID') self.add_option('--cn', dest='cn', default=None, help='Set the CN directly') self.add_option('--openssl', dest='openssl', help='Path to openssl command', default='/usr/bin/openssl') parser = Parser() opts, args = parser.parse_args() delete_key = False if args: key = args[0] else: sys.exit('Expecting a key as a non-optioned argument') ktype = abac_pem_type(key) if ktype == 'both': key, cert = abac_split_cert(key) os.unlink(cert) delete_key = True elif ktype != 'key': sys.exit('Cannot use %s as identity. It is a %s ' % (key, ktype) + 'and we were expecting a key') try: if opts.cn is not None: subj = '/CN=' + opts.cn if len(subj) > 64: subj = subj[0:63] else: c = X509.load_cert(opts.cert) subj = c.get_subject().as_text() if subj.startswith('/'): i = 1 else: i = 0 subj = '/' + re.sub('/', '\/', subj[i:]) tf, tn = tempfile.mkstemp(suffix=".pem") cmd = [opts.openssl, 'req', '-new', '-nodes', '-subj', subj, '-x509', '-days', '3650', '-key', key, '-out', tn] if opts.debug: print join(cmd) sys.exit(0) else: rv = subprocess.call(cmd) if rv == 0: try: of = os.fdopen(os.open(opts.out, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0600), 'w') if opts.include_key: sources = (tn, key) else:sources = (tn,) for inf in sources: f = open(inf, 'r') for line in f: print >>of, line, f.close() of.close() except EnvironmentError, e: sys.exit("Cannot open %s: %s" % (efilename, e.strerror)) else: sys.exit("%s failed: %d" % (opts.openssl, rv)) finally: if delete_key and key: os.unlink(key)