-
Notifications
You must be signed in to change notification settings - Fork 48
Crypt after OS Updates and Upgrades
Updates and upgrades to macOS commonly remove Crypt from authorizationdb. This could lead to unexpected situations, such as the machine not being encrypted on first login, or Crypt losing the ability to force FV2.
For Crypt to function, the following lines must be included in authorizationdb:
<string>Crypt:Check,privileged</string>
<string>Crypt:CryptGUI</string>
<string>Crypt:Enablement,privileged</string>
Presence of these lines can be confirmed via
/usr/bin/security authorizationdb read system.login.console
This can be managed via a configuration management tool (Puppet, Salt, etc), or via the following Munki checkinstall script, which will force a reinstall of Crypt if the authorizationdb entries are absent. If you are using AutoPkg, use the Crypt recipe from Graham's repo which includes this script already. If you are importing manually, be sure to update %version% in the script below to a string with the version of Crypt2 you are deploying with that pkginfo.
#!/Library/ManagedFrameworks/Python/Python3.framework/Versions/Current/bin/python3
"""This installcheck script template evaluates the installed version
of Crypt as well as if Crypt is included properly in the authdb."""
from subprocess import check_output
from packaging import version
import plistlib
import os
def get_mechs():
"""returns a list of all current authdb mechs"""
cmd = ["/usr/bin/security", "authorizationdb", "read", "system.login.console"]
cur_mech_plist = plistlib.loads(check_output(cmd))
mechs_only = cur_mech_plist["mechanisms"]
return mechs_only
def get_crypt_vers():
"""returns the installed version of the Crypt bundle"""
try:
f = open(
"/Library/Security/SecurityAgentPlugins/Crypt.bundle/Contents/Info.plist",
"rb",
)
except:
print("Unable to open Crypt bundle to get version")
exit(0)
try:
plist = plistlib.load(f)
except:
print("Unable to get plist info from Crypt bundle")
exit(0)
f.close()
return plist["CFBundleShortVersionString"]
def main():
"""Checks if Crypt is properly installed and up to date. Note that the version var
below is auto-substituted by AutoPkg - if you are adding this installcheck manually,
be sure to insert the proper version number."""
pkg_vers = "%version%"
install_items = [
"/Library/Security/SecurityAgentPlugins/Crypt.bundle",
"/Library/LaunchDaemons/com.grahamgilbert.crypt.plist",
"/Library/Crypt/checkin",
"/Library/Crypt/python",
"/Library/Crypt/Python.framework",
"/Library/Security/SecurityAgentPlugins/Crypt.bundle",
]
for item in install_items:
if not os.path.exists(item):
# we are missing a needed file - Crypt is damaged or not installed
exit(0)
# check if Crypt is up to date
installed_vers = get_crypt_vers()
if version.parse(installed_vers) < version.parse(pkg_vers):
# we are out of date compared to the pkg version
exit(0)
mechs = ["Crypt:Check,privileged", "Crypt:CryptGUI", "Crypt:Enablement,privileged"]
current_mechs = get_mechs()
for crypt_mech in mechs:
if crypt_mech not in current_mechs:
# mechs are not in place
exit(0)
# all mechs in place and version is up to date
exit(1)
if __name__ == "__main__":
main()
If you're not using Munki and/or deploying a managed Python 3 runtime, a shell-only method of checking the authorizationdb entries is outlined here.