Skip to content

Instantly share code, notes, and snippets.

@arubdesu
Created December 2, 2014 14:02
Show Gist options
  • Save arubdesu/08fb38909557a1b13785 to your computer and use it in GitHub Desktop.
Save arubdesu/08fb38909557a1b13785 to your computer and use it in GitHub Desktop.
mManual rotate process leveraging crypt client tools
#!/usr/bin/env python
import sys
import os
import optparse
import subprocess
import platform
from urllib2 import Request, urlopen, URLError
# TODO: move to NSURL
import urllib
# will go away once user/pass handling comes from .app
from getpass import getpass
# importing common functions from the code already in the app bundle
# currently only used for plistlib replace and getting prefs
sys.path.append("/usr/local/crypt/Crypt.app/Contents/Resources")
import FVUtils
import FoundationPlist
def root_check():
uid_check = os.geteuid()
if uid_check != 0:
# pull out these debug statements later
print "Must run as root or sudo"
p.print_help()
sys.exit(1)
def os_check():
"""Gets major os x version, checks for 10.9+"""
this_os = int(platform.mac_ver()[0].split('.')[1])
if not this_os >= 9:
# pull out these debug statements later
print "Rotate process only works on 10.9 and higher"
sys.exit(1)
def get_serial():
"""Returns the serial number of the Mac"""
serial_wquotes = subprocess.check_output(
"/usr/sbin/ioreg -c IOPlatformExpertDevice | /usr/bin/awk /IOPlatformSerialNumber/'{print $4}'", shell=True)
return serial_wquotes.strip()
def get_hostname():
"""Returns the hostname of the Mac"""
return os.uname()[1]
def build_rotateplist(username, password):
"""Builds plist with which to rotate recovery key"""
rotate_inputplist = {"Username": username, "Password": password}
input_plist = FoundationPlist.writePlistToString(rotate_inputplist)
return input_plist
def escrow_key(key, username, serial, macname):
theurl = FVUtils.pref('ServerURL') + "/checkin/"
mydata = [('serial', serial), ('recovery_password', key),
('username', username), ('macname', macname)]
print "Debug in escrow_key: %s" % mydata
mydata = urllib.urlencode(mydata)
req = Request(theurl, mydata)
has_error = False
try:
response = urlopen(req)
print response
except URLError, e:
if hasattr(e, 'reason'):
print 'We failed to reach a server.'
print 'Reason: ', e.reason
has_error = True
elif hasattr(e, 'code'):
print "The server couldn't fulfill the request"
print 'Error code: ', e.code
has_error = True
if has_error:
plistdata = {'recovery_key': key, 'username': username}
FoundationPlist.writePlist(plistdata, '/private/var/root/recovery_key.plist')
os.chmod('/private/var/root/recovery_key.plist', 0700)
else:
print key
theplist = '/private/var/root/recovery_key.plist'
if os.path.exists(theplist):
os.remove(theplist)
def main():
"""gimme some main"""
os_check()
root_check()
p = optparse.OptionParser()
p.set_usage("""Usage: Temp testing before integrating with Crypt GUI.
Must be run as root or with sudo.
%prog [options]""")
p.add_option('--username', '-u', dest='username')
options, arguments = p.parse_args()
password = getpass("Enter password: ")
macname = get_hostname()
if not (options.username and password):
print "Please supply a FileVault-unlock-authorized username and password"
p.print_help()
sys.exit(1)
input_plist = build_rotateplist(options.username, password)
p = subprocess.Popen(['/usr/bin/fdesetup', 'changerecovery', '-personal',
'-outputplist', '-inputplist'], stdout=subprocess.PIPE, stdin=subprocess.PIPE,
stderr=subprocess.PIPE)
(stdout_data, err) = p.communicate(input=input_plist)
try:
fv_status = FoundationPlist.readPlistFromString(stdout_data)
recovery_key = fv_status['RecoveryKey']
serial = fv_status['SerialNumber']
username = options.username
escrow_key(recovery_key.strip(), username, serial, macname)
except:
print "Something upstream failed, sorry"
print stdout_data
sys.exit(1)
sys.exit(0)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment