#!/usr/bin/python # # gkhandmake - manually create a recorded snippet # # gkhandmake path type source outputfile # import sys import os import signal import errno import subprocess import plistlib # # Usage and fail # def usage(): print >>sys.stderr, "Usage: %s program specfile outputfile" % sys.argv[0] sys.exit(2) def fail(whatever): print >>sys.stderr, "%s: %s" % (sys.argv[0], whatever) sys.exit(1) # # Argument processing # if len(sys.argv) != 4: usage() path=os.path.abspath(sys.argv[1]) specfile=sys.argv[2] outputfile = sys.argv[3] type=1 # always execution # # If the output file already exists, bail # if os.path.exists(outputfile): fail("already exists: %s" % outputfile) # # We'll let the detached signature live in case we need to inspect it # sigpath = "/tmp/%s.dsig" % os.path.basename(path.strip('/')) # # Generate an adhoc detached signature with the given resource specification # display = subprocess.check_call(["/usr/bin/codesign", "--sign", "-", "--detached", sigpath, "--resource-rules", specfile, path ]) # # Now verify it so we can extract the cdhash # display = subprocess.Popen(["/usr/bin/codesign", "--display", "--verbose=3", "--detached", sigpath, path ], stderr=subprocess.PIPE) (stdout, stderr) = display.communicate() cdhash = None for line in stderr.split('\n'): if line.startswith("CDHash="): cdhash = line[7:] break if cdhash is None: fail("no cdhash in generated signature?!") # # Pack up a single (detached) signature as a snippet # under the given path # with open(sigpath, "r") as sigfile: sigdata = sigfile.read() auth = { } sigs = { } auth[path] = dict( type=type, path=path, status=9, cdhash=cdhash ) sigs[path] = dict( type=type, path=path, signature=plistlib.Data(sigdata) ) gkedict = dict( authority = auth, signatures = sigs ) plistlib.writePlist(gkedict, outputfile) sys.exit(0)