Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Let user set a custom path to openssl #111

Merged
merged 7 commits into from
Feb 27, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,13 @@ The format is based on [Keep a Changelog][1], and this project adheres to

## [Unreleased]

### Added

- Add `--set-openssl-path` option to configure transcrypt to use a specific
openssl version instead of the default version found in `$PATH`. This will be
most useful to macOS users who might want to use a newer version of OpenSSL.
This option can be used on init, on upgrade, or by itself.

### Fixed

- Respect Git `core.hooksPath` setting when installing the pre-commit hook. (#104)
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,9 @@ directory.
the password to derive the key from;
defaults to 30 random base64 characters

--set-openssl-path=PATH_TO_OPENSSL
use OpenSSL at this path; defaults to 'openssl' in $PATH

-y, --yes
assume yes and accept defaults for non-specified options

Expand Down
3 changes: 3 additions & 0 deletions man/transcrypt.1.ronn
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ The transcrypt source code and full documentation may be downloaded from
the password to derive the key from;
defaults to 30 random base64 characters

* `--set-openssl-path`=<path_to_openssl>:
use OpenSSL at this path; defaults to 'openssl' in $PATH

* `-y`, `--yes`:
assume yes and accept defaults for non-specified options

Expand Down
42 changes: 42 additions & 0 deletions tests/test_init.bats
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,45 @@ SETUP_SKIP_INIT_TRANSCRYPT=1
[[ "${lines[6]}" = " PASSWORD: abc123" ]]
[[ "${lines[8]}" = " transcrypt -c aes-256-cbc -p 'abc123'" ]]
}

@test "init: transcrypt.openssl-path config setting defaults to 'openssl'" {
init_transcrypt
[[ "$(git config --get transcrypt.openssl-path)" = 'openssl' ]]
}

@test "init: --set-openssl-path changes transcrypt.openssl-path" {
init_transcrypt
[[ "$(git config --get transcrypt.openssl-path)" = 'openssl' ]]
}

@test "init: --set-openssl-path is applied during init" {
init_transcrypt
run ../transcrypt --set-openssl-path=/test/path
[[ "$(git config --get transcrypt.openssl-path)" = "/test/path" ]]
}

@test "init: --set-openssl-path is applied during upgrade" {
init_transcrypt
[[ "$(git config --get transcrypt.openssl-path)" = 'openssl' ]]

# Set openssl path
FULL_OPENSSL_PATH=$(which openssl)

"$BATS_TEST_DIRNAME"/../transcrypt --upgrade --yes --set-openssl-path="$FULL_OPENSSL_PATH"
[[ "$(git config --get transcrypt.openssl-path)" = "$FULL_OPENSSL_PATH" ]]
[[ ! "$(git config --get transcrypt.openssl-path)" = 'openssl' ]]
}

@test "init: transcrypt.openssl-path config setting is retained with --upgrade" {
init_transcrypt
[[ "$(git config --get transcrypt.openssl-path)" = 'openssl' ]]

# Set openssl path
FULL_OPENSSL_PATH=$(which openssl)
run ../transcrypt --set-openssl-path="$FULL_OPENSSL_PATH"''

# Retain transcrypt.openssl-path config setting on upgrade
"$BATS_TEST_DIRNAME"/../transcrypt --upgrade --yes
[[ "$(git config --get transcrypt.openssl-path)" = "$FULL_OPENSSL_PATH" ]]
[[ ! "$(git config --get transcrypt.openssl-path)" = 'openssl' ]]
}
37 changes: 26 additions & 11 deletions transcrypt
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ run_safety_checks() {
fi

# check for dependencies
for cmd in {column,grep,mktemp,openssl,sed,tee}; do
for cmd in {column,grep,mktemp,"${openssl_path}",sed,tee}; do
command -v "$cmd" >/dev/null || die 'required command "%s" was not found' "$cmd"
done

Expand All @@ -140,12 +140,12 @@ run_safety_checks() {
# unset the cipher variable if it is not supported by openssl
validate_cipher() {
local list_cipher_commands
if openssl list-cipher-commands &>/dev/null; then
if "${openssl_path}" list-cipher-commands &>/dev/null; then
# OpenSSL < v1.1.0
list_cipher_commands='openssl list-cipher-commands'
list_cipher_commands="${openssl_path} list-cipher-commands"
else
# OpenSSL >= v1.1.0
list_cipher_commands='openssl list -cipher-commands'
list_cipher_commands="${openssl_path} list -cipher-commands"
fi

local supported
Expand Down Expand Up @@ -198,7 +198,7 @@ get_password() {
if [[ $answer =~ $YES_REGEX ]] || [[ ! $answer ]]; then
local password_length=30
local random_base64
random_base64=$(openssl rand -base64 $password_length)
random_base64=$(${openssl_path} rand -base64 $password_length)
password=$random_base64
else
printf 'Password: '
Expand Down Expand Up @@ -299,8 +299,9 @@ save_helper_scripts() {
else
cipher=$(git config --get --local transcrypt.cipher)
password=$(git config --get --local transcrypt.password)
salt=$(openssl dgst -hmac "${filename}:${password}" -sha256 "$filename" | tr -d '\r\n' | tail -c16)
ENC_PASS=$password openssl enc -$cipher -md MD5 -pass env:ENC_PASS -e -a -S "$salt" -in "$tempfile"
openssl_path=$(git config --get --local transcrypt.openssl-path)
salt=$("${openssl_path}" dgst -hmac "${filename}:${password}" -sha256 "$filename" | tr -d '\r\n' | tail -c16)
ENC_PASS=$password "$openssl_path" enc -$cipher -md MD5 -pass env:ENC_PASS -e -a -S "$salt" -in "$tempfile"
fi
fi
EOF
Expand All @@ -311,7 +312,8 @@ save_helper_scripts() {
trap 'rm -f "$tempfile"' EXIT
cipher=$(git config --get --local transcrypt.cipher)
password=$(git config --get --local transcrypt.password)
tee "$tempfile" | ENC_PASS=$password openssl enc -$cipher -md MD5 -pass env:ENC_PASS -d -a 2>/dev/null || cat "$tempfile"
openssl_path=$(git config --get --local transcrypt.openssl-path)
tee "$tempfile" | ENC_PASS=$password "$openssl_path" enc -$cipher -md MD5 -pass env:ENC_PASS -d -a 2>/dev/null || cat "$tempfile"
EOF

cat <<-'EOF' >"${GIT_DIR}/crypt/textconv"
Expand All @@ -321,7 +323,8 @@ save_helper_scripts() {
if [[ -s $filename ]]; then
cipher=$(git config --get --local transcrypt.cipher)
password=$(git config --get --local transcrypt.password)
ENC_PASS=$password openssl enc -$cipher -md MD5 -pass env:ENC_PASS -d -a -in "$filename" 2>/dev/null || cat "$filename"
openssl_path=$(git config --get --local transcrypt.openssl-path)
ENC_PASS=$password "$openssl_path" enc -$cipher -md MD5 -pass env:ENC_PASS -d -a -in "$filename" 2>/dev/null || cat "$filename"
fi
EOF

Expand Down Expand Up @@ -478,6 +481,7 @@ save_configuration() {
git config transcrypt.version "$VERSION"
git config transcrypt.cipher "$cipher"
git config transcrypt.password "$password"
git config transcrypt.openssl-path "$openssl_path"

# write the filter settings
if [[ -d $(git rev-parse --git-common-dir) ]]; then
Expand Down Expand Up @@ -646,8 +650,8 @@ uninstall_transcrypt() {
pre_commit_hook="${GIT_HOOKS}/pre-commit"
pre_commit_hook_installed="${GIT_HOOKS}/pre-commit-crypt"
if [[ -f "$pre_commit_hook" ]]; then
hook_md5=$(openssl md5 -hex <"$pre_commit_hook")
installed_md5=$(openssl md5 -hex <"$pre_commit_hook_installed")
hook_md5=$("${openssl_path}" md5 -hex <"$pre_commit_hook")
installed_md5=$("${openssl_path}" md5 -hex <"$pre_commit_hook_installed")
if [[ "$hook_md5" = "$installed_md5" ]]; then
rm "$pre_commit_hook"
else
Expand Down Expand Up @@ -721,6 +725,8 @@ upgrade_transcrypt() {
# Keep current cipher and password
cipher=$(git config --get --local transcrypt.cipher)
password=$(git config --get --local transcrypt.password)
# Keep current openssl-path, or set to default if no existing value
openssl_path=$(git config --get --local transcrypt.openssl-path 2>/dev/null || printf '%s' "$openssl_path")

# Keep contents of .gitattributes
ORIG_GITATTRIBUTES=$(cat "$GIT_ATTRIBUTES")
Expand Down Expand Up @@ -872,6 +878,9 @@ help() {
the password to derive the key from;
defaults to 30 random base64 characters

--set-openssl-path=PATH_TO_OPENSSL
use OpenSSL at this path; defaults to 'openssl' in \$PATH

-y, --yes
assume yes and accept defaults for non-specified options

Expand Down Expand Up @@ -973,6 +982,7 @@ rekey=''
show_file=''
uninstall=''
upgrade=''
openssl_path='openssl'

# used to bypass certain safety checks
requires_existing_config=''
Expand All @@ -996,6 +1006,11 @@ while [[ "${1:-}" != '' ]]; do
--password=*)
password=${1#*=}
;;
--set-openssl-path=*)
openssl_path=${1#*=}
# Immediately apply config setting
git config transcrypt.openssl-path "$openssl_path"
;;
-y | --yes)
interactive=''
;;
Expand Down