Posted on 01-03-2013 12:35 PM
Hi all,
I wrote a Python script to enable FileVault2 encryption for both the logged in user and our admin account.
I'm passing the admin account name and password via the policy and sys.argv so it doesn't have to be baked in to the script.
I can successfully encrypt a disk with this script by manually running it, running via policy on the login trigger, or via Casper Remote. When I run the same script using SS, I get an error.
The script:
#!/usr/bin/python
# coding: utf-8
"""2012-12-10 jay@techsuperpowers.com"""
"""python script to enable FileVault2 via Casper Self Service"""
import getpass
import os
import commands
import plistlib
import tempfile
import subprocess
import base64
import sys
# if enabling via command line, use 2 and 3 instead of 4 and 5
adminName = sys.argv[4]
adminPass = sys.argv[5]
# we have to decode the already base64 encoded cert since plistlib.Data re-encodes any string as base64
certificate = base64.standard_b64decode('paste your base64 encoded cert from FileVaultMaster.keychain here')
def passwordPrompt():
global name
global password
# assuming cocoadialog exists at this path...
CocoaDialog = "/Library/Application Support/CocoaDialog.app/Contents/MacOS/CocoaDialog"
console_owner = "ls -l /dev/console"
result = commands.getoutput(console_owner)
name = result.split(' ')[3]
# I should probably add some logic to make it at least ask for password twice
cmd = CocoaDialog + " standard-inputbox --title "FileVault Enabler" --no-newline --informative-text "Enter password for "+name+"" --no-cancel --float --no-show"
results = commands.getoutput(cmd)
password = results.split('
')[1]
credentials = [name, password]
return credentials
passwordPrompt()
# this is the plist template
d = { 'Username':adminName,
'Password':adminPass,
'AdditionalUsers':[ { 'Username':name, 'Password':password } ],
'Certificate':plistlib.Data(certificate)
}
def createPlist():
global output_file
output_file = tempfile.NamedTemporaryFile(suffix='.plist')
plistlib.writePlist(d, output_file)
output_file.seek(0)
def encryptVolume():
output_file = tempfile.NamedTemporaryFile(suffix='.plist', delete=False)
plistlib.writePlist(d, output_file)
output_file.seek(0)
plist = output_file.name
# subprocess.check_call("fdesetup enable -inputplist %s" % plist, shell=True)
subprocess.check_call("fdesetup enable -norecoverykey -forcerestart -inputplist < %s" % plist, shell=True)
encryptVolume()
I'll post the error I get in a moment.
Posted on 01-03-2013 01:50 PM
eyemyth's not in the office today, so here's the error:
/usr/sbin/jamf is version 8.62
Executing Policy FV2 TEST...
[STEP 1 of 3]
Mounting smb://caspershare to /Volumes/casp01...
[STEP 2 of 3]
Copying CocoaDialog.pkg...
Installing CocoaDialog.pkg...
Successfully installed CocoaDialog.pkg.
[STEP 3 of 3]
Running script Enable_FileVault2_2012-12-10.py...
Script exit code: 1
Script result: Unexpected FileVaultMaster keychain was found. Moving existing keychain to /Library/Application Support/fdesetup/.
2013-01-02 14:41:17.676 fdesetup[1274:707] fdesetup: Warning: Using certificate option with existing FileVault master keychain. Moved keychain to /Library/Application Support/fdesetup/.
Error: Password is required to add a user.
Error: User authentication failed.
Traceback (most recent call last):
File "/private/tmp/Enable_FileVault2_2012-12-10.py", line 62, in <module>
encryptVolume()
File "/private/tmp/Enable_FileVault2_2012-12-10.py", line 58, in encryptVolume
subprocess.check_call("fdesetup enable -norecoverykey -forcerestart -inputplist < %s" % plist, shell=True)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 511, in check_call
subprocess.CalledProcessError: Command 'fdesetup enable -norecoverykey -forcerestart -inputplist < /var/folders/wq/n4r040jn27z4b8gzsw9_flm9kyml00/T/tmpAkPU9m.plist' returned non-zero exit status 11
Unmounting file server...
Posted on 01-03-2013 01:59 PM
Going by the errors reported, it looks like the admin password is not being passed along. If you hard-code the admin username and password, does it work?
Posted on 01-03-2013 03:29 PM
I tested hard coding the admin password in both the adminName and adminPass variables or the dictionary, but I only tested that when running the script locally. I'll test it in Self Service and see what happens, but I wouldn't really like that as a permanent solution.
I tried a little troubleshooting by running a script that just prints sys.argv[4], sys.argv[5], etc via SS, and all of the arguments got passed there. Maybe it's an odd character in the password that it doesn't like...