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 3 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 `--openssl-path` option when initializing 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
than the one that comes included.

### Fixed

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

--openssl-path=PATH_TO_OPENSSL
use OpenSSL at this path; defaults to 'openssl' in $PATH.
To change after initialization:
git config transcrypt.openssl-path NEW_PATH

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

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

* `--openssl-path`=<path_to_openssl>:
use OpenSSL at this path; defaults to 'openssl' in $PATH.
To change after initialization:
git config transcrypt.openssl-path NEW_PATH
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm...it would be nice to not ever need to drop to raw git config commands at all. Would it make more sense to have this be named --set-openssl-path and allow it to be called whenever (during initialization or otherwise) to update the setting?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a really good idea. I have made this change, and it makes it much clearer when --set-openssl-path can be used.


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

Expand Down
26 changes: 26 additions & 0 deletions tests/test_init.bats
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,29 @@ 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: --openssl-path argument is applied to transcrypt.openssl-path config-setting" {
FULL_OPENSSL_PATH=$(which openssl)
"$BATS_TEST_DIRNAME"/../transcrypt --cipher=aes-256-cbc --password=abc123 --openssl-path="$FULL_OPENSSL_PATH" --yes
[[ "$(git config --get transcrypt.openssl-path)" = "$FULL_OPENSSL_PATH" ]]
}


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

# Manually change openssl path
FULL_OPENSSL_PATH=$(which openssl)
git config transcrypt.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,11 @@ help() {
the password to derive the key from;
defaults to 30 random base64 characters

--openssl-path=PATH_TO_OPENSSL
use OpenSSL at this path; defaults to 'openssl' in \$PATH.
To change after initialization:
git config transcrypt.openssl-path NEW_PATH

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

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

# used to bypass certain safety checks
requires_existing_config=''
Expand All @@ -996,6 +1008,9 @@ while [[ "${1:-}" != '' ]]; do
--password=*)
password=${1#*=}
;;
--openssl-path=*)
openssl_path=${1#*=}
;;
-y | --yes)
interactive=''
;;
Expand Down