#!/usr/local/bin/python import sys import re import os from optparse import OptionParser # Options class Parser(OptionParser): def __init__(self): OptionParser.__init__(self, usage="%prog [options] file.pem") self.add_option('--cert', dest='cert', default='./cert.pem', help='File to extract certificate into, default: [%default]') self.add_option('--key', dest='key', default='./key.pem', help='File to extract key into, default: [%default]') self.add_option('--force', action='store_true', dest='force', default=False, help=('Overwite existing certificate and key files. ' + \ 'default: [%default]')) class diversion: ''' Wraps up the reqular expression to start and end a diversion, as well as the open file that gets the lines. ''' def __init__(self, start, end, fn): self.start = re.compile(start) self.end = re.compile(end) self.f = open(fn, 'w') # Option validation parser = Parser() opts, args = parser.parse_args() if len(args) == 1: combo = args[0] else: parser.print_help() sys.exit('\nMust have one file argument') if not opts.force: for fn in (opts.cert, opts.key): if os.access(fn, os.F_OK): sys.exit('%s exists. --force to overwite it' % fn) try: # Initialize the diversions divs = [diversion(s, e, fn) for s, e,fn in ( ('\s*-----BEGIN RSA PRIVATE KEY-----$', '\s*-----END RSA PRIVATE KEY-----$', opts.key), ('\s*-----BEGIN CERTIFICATE-----$', '\s*-----END CERTIFICATE-----$', opts.cert))] # walk through the file, beginning a diversion when a start regexp matches # until the end regexp matches. While in the two regexps, print each line # to the ipen diversion file (including the two matches). active = None f = open(combo, 'r') for l in f: if active: if active.end.match(l): print >>active.f, l, active = None else: for d in divs: if d.start.match(l): active = d break if active: print >>active.f, l, # This clause catches all file opening problems, including the diversion opens except EnvironmentError, e: sys.exit("%s: %s" % (e.strerror, e.filename or '?!')) # This is probably unnecessary. Close all the diversion files. for d in divs: d.f.close()