1#!/usr/bin/python 2# 3# gkhandmake - manually create a recorded snippet 4# 5# gkhandmake path type source outputfile 6# 7import sys 8import os 9import signal 10import errno 11import subprocess 12import plistlib 13 14 15# 16# Usage and fail 17# 18def usage(): 19 print >>sys.stderr, "Usage: %s program specfile outputfile" % sys.argv[0] 20 sys.exit(2) 21 22def fail(whatever): 23 print >>sys.stderr, "%s: %s" % (sys.argv[0], whatever) 24 sys.exit(1) 25 26 27# 28# Argument processing 29# 30if len(sys.argv) != 4: 31 usage() 32path=os.path.abspath(sys.argv[1]) 33specfile=sys.argv[2] 34outputfile = sys.argv[3] 35type=1 # always execution 36 37 38# 39# If the output file already exists, bail 40# 41if os.path.exists(outputfile): 42 fail("already exists: %s" % outputfile) 43 44 45# 46# We'll let the detached signature live in case we need to inspect it 47# 48sigpath = "/tmp/%s.dsig" % os.path.basename(path.strip('/')) 49 50 51# 52# Generate an adhoc detached signature with the given resource specification 53# 54 55display = subprocess.check_call(["/usr/bin/codesign", 56 "--sign", "-", 57 "--detached", sigpath, 58 "--resource-rules", specfile, 59 path 60]) 61 62 63# 64# Now verify it so we can extract the cdhash 65# 66display = subprocess.Popen(["/usr/bin/codesign", 67 "--display", "--verbose=3", 68 "--detached", sigpath, 69 path 70], stderr=subprocess.PIPE) 71(stdout, stderr) = display.communicate() 72 73cdhash = None 74for line in stderr.split('\n'): 75 if line.startswith("CDHash="): 76 cdhash = line[7:] 77 break 78if cdhash is None: 79 fail("no cdhash in generated signature?!") 80 81 82# 83# Pack up a single (detached) signature as a snippet 84# under the given path 85# 86with open(sigpath, "r") as sigfile: 87 sigdata = sigfile.read() 88auth = { } 89sigs = { } 90 91auth[path] = dict( 92 type=type, 93 path=path, 94 status=9, 95 cdhash=cdhash 96) 97 98sigs[path] = dict( 99 type=type, 100 path=path, 101 signature=plistlib.Data(sigdata) 102) 103gkedict = dict( 104 authority = auth, 105 signatures = sigs 106) 107plistlib.writePlist(gkedict, outputfile) 108 109sys.exit(0) 110