-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from galaxy4public/master
The first release of BootUnlock
- Loading branch information
Showing
14 changed files
with
1,052 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
all: | ||
@build/build.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,9 @@ | ||
# BootUnlock | ||
A helper script that unlocks macOS'es encrypted APFS volumes before login | ||
|
||
To build an macOS package you can either use "make" (if you have Xcode | ||
installed) or just run "build/build.sh" (if you do not want to install Xcode). | ||
The result will be the same: a package is going to be created in the "out" | ||
directory. | ||
|
||
To install the package just open it in Finder and follow the installation prompts. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<?xml version="1.0" encoding="utf-8" standalone="yes"?> | ||
<installer-gui-script minSpecVersion="2"> | ||
<title>BootUnlock</title> | ||
<product id="au.com.openwall.BootUnlock" version="1.0" /> | ||
<background file="background.png" scaling="proportional" alignment="bottomleft"/> | ||
<welcome file="welcome.rtf"/> | ||
<readme file="readme.rtf"/> | ||
<license file="license.rtf"/> | ||
<conclusion file="installed.rtf"/> | ||
<options customize="never" rootVolumeOnly="true" require-scripts="false" /> | ||
<!-- | ||
<domains enable_anywhere="false" enable_currentUserHome="false" enable_localSystem="true" /> | ||
--> | ||
<allowed-os-versions> | ||
<os-version min="10.6.6" /> | ||
</allowed-os-versions> | ||
<choices-outline> | ||
<line choice="au.com.openwall.BootUnlock" /> | ||
</choices-outline> | ||
<choice id="au.com.openwall.BootUnlock" visible="false"> | ||
<pkg-ref id="au.com.openwall.BootUnlock"/> | ||
</choice> | ||
<pkg-ref id="au.com.openwall.BootUnlock">BootUnlock-1.0-dist.pkg</pkg-ref> | ||
</installer-gui-script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
#!/bin/bash | ||
|
||
# Name of the package. | ||
NAME="BootUnlock" | ||
|
||
# Once installed the identifier is used as the filename for a receipt files in /var/db/receipts/. | ||
IDENTIFIER="au.com.openwall.$NAME" | ||
|
||
# Package version number. | ||
VERSION="1.0" | ||
|
||
# The location to copy the contents of files. | ||
INSTALL_LOCATION="/Library/PrivilegedHelperTools/$IDENTIFIER" | ||
|
||
set -eu -o pipefail | ||
|
||
WORK_DIR="${0%/*}" | ||
[ -z "$WORK_DIR" -o "$WORK_DIR" == "$0" ] && WORK_DIR="$(pwd)" ||: | ||
|
||
mkdir -p "$WORK_DIR/../out" ||: | ||
|
||
# pkgbuild need proper permissions on the source files | ||
chmod 0755 "$WORK_DIR/../files/"*.sh | ||
chmod 0644 "$WORK_DIR/../files/"*.xsl | ||
|
||
# Build package. | ||
/usr/bin/pkgbuild \ | ||
--identifier "$IDENTIFIER" \ | ||
--version "$VERSION" \ | ||
--install-location "$INSTALL_LOCATION" \ | ||
--root "$WORK_DIR/../files" \ | ||
--scripts "$WORK_DIR/../scripts" \ | ||
"$WORK_DIR/../out/$NAME-$VERSION-dist.pkg" | ||
|
||
/usr/bin/productbuild \ | ||
--distribution "$WORK_DIR/Distribution.xml" \ | ||
--package-path "$WORK_DIR/../out" \ | ||
--resources "$WORK_DIR/../resources" \ | ||
"$WORK_DIR/../out/$NAME-$VERSION.pkg" | ||
|
||
rm "$WORK_DIR/../out/$NAME-$VERSION-dist.pkg" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> | ||
<xsl:output method="text"/> | ||
<xsl:template match="/"> | ||
<xsl:apply-templates select="/plist/dict[key = 'Containers']/array/dict[key = 'Volumes']/array/dict[key = 'Encryption']"/> | ||
</xsl:template> | ||
<xsl:template match="dict"> | ||
<xsl:apply-templates match="key|string|true|false" mode="dict" select="string[preceding-sibling::key[1]/text() = 'Name']"/> | ||
<xsl:text>:</xsl:text> | ||
<xsl:apply-templates match="key|string|true|false" mode="dict" select="string[preceding-sibling::key[1]/text() = 'APFSVolumeUUID']"/> | ||
<xsl:text>:</xsl:text> | ||
<xsl:apply-templates match="key|string|true|false" mode="dict" select="string[preceding-sibling::key[1]/text() = 'DeviceIdentifier']"/> | ||
<xsl:text>:</xsl:text> | ||
<xsl:apply-templates match="true|false" mode="dict" select="true[preceding-sibling::key[1]/text() = 'Encryption']"/> | ||
<xsl:text>:</xsl:text> | ||
<xsl:apply-templates match="true|false" mode="dict" select="true[preceding-sibling::key[1]/text() = 'Locked']"/> | ||
<xsl:text>
</xsl:text> | ||
</xsl:template> | ||
<xsl:template match="true|false" mode="dict"> | ||
<xsl:value-of select="name()"/> | ||
</xsl:template> | ||
</xsl:stylesheet> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#!/bin/bash | ||
|
||
set -eu -o pipefail | ||
|
||
PATH=/sbin:/bin:/usr/sbin:/usr/bin | ||
|
||
echo "=== $(date) ===" | ||
diskutil apfs list -plist \ | ||
| xsltproc --novalid "${0%/*}/diskutil.xsl" - \ | ||
| grep -E ':true:true$' \ | ||
| cut -f1-3 -d':' \ | ||
| while IFS=: read NAME UUID DEVICE ; do | ||
printf 'Trying to unlock volume "%s" with UUID %s ...\n' "$NAME" "$UUID" | ||
if ! PASSPHRASE=$(${0%/*}/BootUnlock find-generic-password \ | ||
-D 'Encrypted Volume Password' \ | ||
-a "$UUID" -s "$UUID" -w); then | ||
echo 'NOTICE: could not find the secret on the System keychain, skipping the volume.' >&2 | ||
continue | ||
fi | ||
if ! printf '%s' "$PASSPHRASE" | diskutil apfs unlock "$DEVICE" -stdinpassphrase ; then | ||
if [ -z "${PASSPHRASE//[[:digit:][a-fA-F]}" ]; then # This may be a hexadecimal string | ||
echo 'NOTICE: the passphrase looks like a hexdecimal string, re-trying ...' >&2 | ||
if printf '%s' "$PASSPHRASE" | xxd -r -p | diskutil apfs unlock "$DEVICE" -stdinpassphrase; then | ||
continue | ||
fi | ||
fi | ||
echo "ERROR: could not unlock volume '$NAME', skipping the volume." >&2 | ||
continue | ||
fi | ||
done |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
#!/bin/bash | ||
|
||
set -eu -o pipefail | ||
|
||
PATH=/sbin:/bin:/usr/sbin:/usr/bin | ||
|
||
[ "$(id -un)" = root ] \ | ||
|| exec -a "$0" osascript -e " | ||
do shell script quoted form of \"$0\" & space & quoted form of \"$*\" with prompt \"BootUnlock Configurator requires administrative privileges to work with volumes and to update the System keychain.\" with administrator privileges" \ | ||
|| exit 1 | ||
|
||
# Location of the log file | ||
LOG_FILE=/var/log/BootUnlock.log | ||
|
||
# Determine the cannonical location of this script | ||
WORK_DIR="${BASH_SOURCE%/*}" | ||
[ "$WORK_DIR" != "$BASH_SOURCE" ] || WORK_DIR=. | ||
pushd "$WORK_DIR" &>/dev/null | ||
WORK_DIR=$(pwd -P) | ||
popd &>/dev/null | ||
SELF="$WORK_DIR/${0##*/}" | ||
|
||
printf 'Redirecting standard output and errors to "%s" ...\n' "$LOG_FILE" | ||
exec >>"$LOG_FILE" 2>&1 | ||
printf '===[ update.sh: %s ]===\n' "$(date)" | ||
|
||
# A quick and dirty way of determining the root device :) | ||
ROOT_DEVICE=$(df -l / | grep -E '^/dev/' | cut -f1 -d' ' | head -1 | cut -f3- -d/) | ||
|
||
# Get the list of volumes with the encryption enabled | ||
IFS=$'\n' VOLUME=($(diskutil apfs list -plist \ | ||
| xsltproc --novalid "${0%/*}/diskutil.xsl" - \ | ||
| grep -E ':true:(true)?$' \ | ||
| cut -f1-3 -d':' \ | ||
)) | ||
|
||
# Generate a list of volumes for GUI | ||
VOLUME_LIST= | ||
for V in "${VOLUME[@]}" ; do | ||
NAME="${V%%:*}"; V="${V#*:}" | ||
UUID="${V%%:*}"; V="${V#*:}" | ||
DEVICE="${V%%:*}"; V="${V#*:}" | ||
|
||
# macOS can automatically mount the system volume, so there is no point | ||
# of presenting that choice to the user | ||
[ "$DEVICE" != "$ROOT_DEVICE" ] || continue | ||
|
||
VOLUME_LIST="$VOLUME_LIST${VOLUME_LIST:+, }\"$DEVICE > $NAME\"" | ||
done | ||
|
||
RESPONSE=$(osascript -e " | ||
set volumeList to { $VOLUME_LIST } | ||
set unlockList to choose from list volumeList with title \"BootUnlock\" with prompt \" | ||
Please select volume(s) you want to be automatically unlocked during the boot (you can select multiple volumes by holding the Option key)\" multiple selections allowed true empty selection allowed true | ||
") | ||
|
||
if [ -z "$RESPONSE" -o "$RESPONSE" = false ]; then | ||
osascript -e "display alert \"BootUnlock\" message \" | ||
You did not select any volumes, so BootUnlock is not going to do anything at the system boot up time. | ||
If you reconsider and will want to enable unlocking of a particular volume you can re-run the '$SELF' script at a later time | ||
\" as critical" &>/dev/null | ||
exit 0 | ||
fi | ||
|
||
RESPONSE="$(printf '%s' "$RESPONSE" | tr ',' '\n' | sed 's,^[[:space:]]*,,;s,>.*$,,;s,[[:space:]]*$,,')" | ||
|
||
# Real work starts here :) | ||
for V in "${VOLUME[@]}" ; do | ||
NAME="${V%%:*}"; V="${V#*:}" | ||
UUID="${V%%:*}"; V="${V#*:}" | ||
DEVICE="${V%%:*}"; V="${V#*:}" | ||
|
||
# We are going to work only on the volumes selected by the user | ||
printf '%s' "$RESPONSE" | grep -E "^$DEVICE\$" &>/dev/null || continue | ||
|
||
while : ; do # This is a wrapper in case user provides a wrong password | ||
PASSPHRASE=$(osascript -e " | ||
display dialog \"Please provide the passphrase for volume '$NAME':\" with title \"BootUnlock\" buttons { \"Skip\", \"Unlock\" } default button \"Unlock\" with icon file ((path to \"apps\" as text) & \"Utilities:Disk Utility.app:Contents:Resources:AppIcon.icns\") default answer \"\" hidden answer true | ||
") | ||
|
||
PASSPHRASE=$(printf '%s' "$PASSPHRASE" | cut -f3- -d:) | ||
|
||
if printf '%s' "$PASSPHRASE" | diskutil apfs unlock "$DEVICE" -stdinpassphrase -verify -user "$UUID"; then | ||
printf 'Adding password for volume "%s" with UUID %s to the System keychain...\n' "$NAME" "$UUID" | ||
if sudo /usr/bin/security add-generic-password \ | ||
-a "$UUID" -s "$UUID" -l "$NAME" \ | ||
-D 'Encrypted Volume Password' \ | ||
-T '' -T "$WORK_DIR/BootUnlock" \ | ||
-w "$PASSPHRASE" \ | ||
-U \ | ||
/Library/Keychains/System.keychain; then | ||
break | ||
else | ||
osascript -e "display alert \"BootUnlock\" message \" | ||
BootUnlock experienced an internal error while adding password to the System keychain. | ||
Please check the /var/log/BootUnlock.log log file for more information. | ||
\" as critical" &>/dev/null | ||
exit 1 | ||
fi | ||
else | ||
osascript -e "display alert \"BootUnlock\" message \" | ||
The specified password for volume '$NAME' does not seem to be valid. BootUnlock will prompt you for the password again. | ||
If you believe that you are providing the correct password, yet it is not recognised, please check the /var/log/BootUnlock.log log file for more information. | ||
\" as critical" &>/dev/null | ||
fi | ||
done | ||
done | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
{\rtf1\ansi\ansicpg1252\cocoartf1671\cocoasubrtf200 | ||
{\fonttbl\f0\fswiss\fcharset0 Helvetica-Bold;\f1\fswiss\fcharset0 Helvetica;\f2\fnil\fcharset0 Menlo-Regular; | ||
} | ||
{\colortbl;\red255\green255\blue255;\red0\green0\blue0;} | ||
{\*\expandedcolortbl;;\csgray\c0;} | ||
\paperw11900\paperh16840\margl1440\margr1440\vieww17240\viewh12860\viewkind0 | ||
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qc\partightenfactor0 | ||
|
||
\f0\b\fs28 \cf0 BootUnlock\ | ||
\ | ||
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural\qj\partightenfactor0 | ||
\f1\b0 \cf0 It seems that you have successfully installed | ||
\f0\b BootUnlock | ||
\f1\b0 to your system. Now, to test that it works properly it is recommended to reboot the system and try to log in as your normal user account. If everything works as expected you will be able to login and see the volumes you selected earlier to be automatically unlocked.\ | ||
\ | ||
If you decide that BootUnlock is not for you, then you can completely clean it out of your system by removing the | ||
\f2 /Library/PrivilegedHelperTools/au.com.openwall.BootUnlock | ||
\f1 directory and the | ||
\f2 \cf2 \CocoaLigature0 /Library/LaunchDaemons/au.com.openwall.BootUnlock.plist | ||
\f1 file.} |
Oops, something went wrong.