mirror of
https://github.com/TheLocehiliosan/yadm
synced 2026-03-02 03:49:29 +00:00
Create secured private dirs (#74)
Directories are created prior to merge during clone, and prior to any Git command run. This directly addresses CVE-2017-11353. When cloning a repo which includes data in a .ssh or .gnupg directory, if those directories do not exist at the time of cloning, yadm will create the directories with mask 0700 prior to merging the fetched data into the work-tree. When running a Git command and .ssh or .gnupg directories do not exist, create those directories with mask 0700 prior to running the Git command. However, do not create those directories if yadm.auto-private-dirs is false.
This commit is contained in:
@@ -440,3 +440,140 @@ EOF
|
||||
remote_output=$(GIT_DIR="$T_DIR_REPO" git remote show)
|
||||
[ "$remote_output" = "origin" ]
|
||||
}
|
||||
|
||||
@test "Command 'clone' (local insecure .ssh and .gnupg data, no related data in repo)" {
|
||||
echo "
|
||||
Local .ssh/.gnupg data exists and is insecure
|
||||
but yadm repo contains no .ssh/.gnupg data
|
||||
local insecure data should remain accessible
|
||||
(yadm is hands-off)
|
||||
"
|
||||
#; setup scenario
|
||||
rm -rf "$T_DIR_WORK" "$T_DIR_REPO"
|
||||
mkdir -p "$T_DIR_WORK/.ssh"
|
||||
mkdir -p "$T_DIR_WORK/.gnupg"
|
||||
touch "$T_DIR_WORK/.ssh/testfile"
|
||||
touch "$T_DIR_WORK/.gnupg/testfile"
|
||||
find "$T_DIR_WORK" -exec chmod a+rw '{}' ';'
|
||||
|
||||
#; run clone (with debug on)
|
||||
run "${T_YADM_Y[@]}" clone -d -w "$T_DIR_WORK" "$REMOTE_URL"
|
||||
|
||||
#; validate status and output
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ Initialized ]]
|
||||
[[ "$output" =~ initial\ private\ dir\ perms\ drwxrwxrwx.+\.ssh ]]
|
||||
[[ "$output" =~ initial\ private\ dir\ perms\ drwxrwxrwx.+\.gnupg ]]
|
||||
[[ "$output" =~ pre-merge\ private\ dir\ perms\ drwxrwxrwx.+\.ssh ]]
|
||||
[[ "$output" =~ pre-merge\ private\ dir\ perms\ drwxrwxrwx.+\.gnupg ]]
|
||||
[[ "$output" =~ post-merge\ private\ dir\ perms\ drwxrwxrwx.+\.ssh ]]
|
||||
[[ "$output" =~ post-merge\ private\ dir\ perms\ drwxrwxrwx.+\.gnupg ]]
|
||||
# standard perms still apply afterwards unless disabled with auto.perms
|
||||
test_perms "$T_DIR_WORK/.gnupg" "drwx------"
|
||||
test_perms "$T_DIR_WORK/.ssh" "drwx------"
|
||||
|
||||
}
|
||||
|
||||
@test "Command 'clone' (local insecure .gnupg data, related data in repo)" {
|
||||
echo "
|
||||
Local .gnupg data exists and is insecure
|
||||
and yadm repo contains .gnupg data
|
||||
.gnupg dir should be secured post merge
|
||||
"
|
||||
#; setup scenario
|
||||
IN_REPO=(.bash_profile .vimrc .gnupg/gpg.conf)
|
||||
setup
|
||||
rm -rf "$T_DIR_WORK" "$T_DIR_REPO"
|
||||
mkdir -p "$T_DIR_WORK/.gnupg"
|
||||
touch "$T_DIR_WORK/.gnupg/testfile"
|
||||
find "$T_DIR_WORK" -exec chmod a+rw '{}' ';'
|
||||
|
||||
#; run clone (with debug on)
|
||||
run "${T_YADM_Y[@]}" clone -d -w "$T_DIR_WORK" "$REMOTE_URL"
|
||||
|
||||
#; validate status and output
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ Initialized ]]
|
||||
[[ "$output" =~ initial\ private\ dir\ perms\ drwxrwxrwx.+\.gnupg ]]
|
||||
[[ "$output" =~ pre-merge\ private\ dir\ perms\ drwxrwxrwx.+\.gnupg ]]
|
||||
[[ "$output" =~ post-merge\ private\ dir\ perms\ drwxrwxrwx.+\.gnupg ]]
|
||||
test_perms "$T_DIR_WORK/.gnupg" "drwx------"
|
||||
}
|
||||
|
||||
@test "Command 'clone' (local insecure .ssh data, related data in repo)" {
|
||||
echo "
|
||||
Local .ssh data exists and is insecure
|
||||
and yadm repo contains .ssh data
|
||||
.ssh dir should be secured post merge
|
||||
"
|
||||
#; setup scenario
|
||||
IN_REPO=(.bash_profile .vimrc .ssh/config)
|
||||
setup
|
||||
rm -rf "$T_DIR_WORK" "$T_DIR_REPO"
|
||||
mkdir -p "$T_DIR_WORK/.ssh"
|
||||
touch "$T_DIR_WORK/.ssh/testfile"
|
||||
find "$T_DIR_WORK" -exec chmod a+rw '{}' ';'
|
||||
|
||||
#; run clone (with debug on)
|
||||
run "${T_YADM_Y[@]}" clone -d -w "$T_DIR_WORK" "$REMOTE_URL"
|
||||
|
||||
#; validate status and output
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ Initialized ]]
|
||||
[[ "$output" =~ initial\ private\ dir\ perms\ drwxrwxrwx.+\.ssh ]]
|
||||
[[ "$output" =~ pre-merge\ private\ dir\ perms\ drwxrwxrwx.+\.ssh ]]
|
||||
[[ "$output" =~ post-merge\ private\ dir\ perms\ drwxrwxrwx.+\.ssh ]]
|
||||
test_perms "$T_DIR_WORK/.ssh" "drwx------"
|
||||
}
|
||||
|
||||
@test "Command 'clone' (no existing .gnupg, .gnupg data tracked in repo)" {
|
||||
echo "
|
||||
Local .gnupg does not exist
|
||||
and yadm repo contains .gnupg data
|
||||
.gnupg dir should be created and secured prior to merge
|
||||
tracked .gnupg data should be user accessible only
|
||||
"
|
||||
#; setup scenario
|
||||
IN_REPO=(.bash_profile .vimrc .gnupg/gpg.conf)
|
||||
setup
|
||||
rm -rf "$T_DIR_WORK"
|
||||
mkdir -p "$T_DIR_WORK"
|
||||
rm -rf "$T_DIR_REPO"
|
||||
|
||||
#; run clone (with debug on)
|
||||
run "${T_YADM_Y[@]}" clone -d -w "$T_DIR_WORK" "$REMOTE_URL"
|
||||
|
||||
#; validate status and output
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ Initialized ]]
|
||||
[[ ! "$output" =~ initial\ private\ dir\ perms ]]
|
||||
[[ "$output" =~ pre-merge\ private\ dir\ perms\ drwx------.+\.gnupg ]]
|
||||
[[ "$output" =~ post-merge\ private\ dir\ perms\ drwx------.+\.gnupg ]]
|
||||
test_perms "$T_DIR_WORK/.gnupg" "drwx------"
|
||||
}
|
||||
|
||||
@test "Command 'clone' (no existing .ssh, .ssh data tracked in repo)" {
|
||||
echo "
|
||||
Local .ssh does not exist
|
||||
and yadm repo contains .ssh data
|
||||
.ssh dir should be created and secured prior to merge
|
||||
tracked .ssh data should be user accessible only
|
||||
"
|
||||
#; setup scenario
|
||||
IN_REPO=(.bash_profile .vimrc .ssh/config)
|
||||
setup
|
||||
rm -rf "$T_DIR_WORK"
|
||||
mkdir -p "$T_DIR_WORK"
|
||||
rm -rf "$T_DIR_REPO"
|
||||
|
||||
#; run clone (with debug on)
|
||||
run "${T_YADM_Y[@]}" clone -d -w "$T_DIR_WORK" "$REMOTE_URL"
|
||||
|
||||
#; validate status and output
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ Initialized ]]
|
||||
[[ ! "$output" =~ initial\ private\ dir\ perms ]]
|
||||
[[ "$output" =~ pre-merge\ private\ dir\ perms\ drwx------.+\.ssh ]]
|
||||
[[ "$output" =~ post-merge\ private\ dir\ perms\ drwx------.+\.ssh ]]
|
||||
test_perms "$T_DIR_WORK/.ssh" "drwx------"
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ function count_introspect() {
|
||||
Exit with 0
|
||||
"
|
||||
|
||||
count_introspect "configs" 0 12 'yadm\.auto-alt'
|
||||
count_introspect "configs" 0 13 'yadm\.auto-alt'
|
||||
}
|
||||
|
||||
@test "Command 'introspect' (repo)" {
|
||||
|
||||
102
test/118_accept_assert_private_dirs.bats
Normal file
102
test/118_accept_assert_private_dirs.bats
Normal file
@@ -0,0 +1,102 @@
|
||||
load common
|
||||
load_fixtures
|
||||
status=;output=; #; populated by bats run()
|
||||
|
||||
IN_REPO=(.bash_profile .vimrc)
|
||||
|
||||
setup() {
|
||||
destroy_tmp
|
||||
build_repo "${IN_REPO[@]}"
|
||||
rm -rf "$T_DIR_WORK"
|
||||
mkdir -p "$T_DIR_WORK"
|
||||
}
|
||||
|
||||
@test "Private dirs (private dirs missing)" {
|
||||
echo "
|
||||
When a git command is run
|
||||
And private directories are missing
|
||||
Create private directories prior to command
|
||||
"
|
||||
|
||||
#; confirm directories are missing at start
|
||||
[ ! -e "$T_DIR_WORK/.gnupg" ]
|
||||
[ ! -e "$T_DIR_WORK/.ssh" ]
|
||||
|
||||
#; run status
|
||||
export DEBUG=yes
|
||||
run "${T_YADM_Y[@]}" status
|
||||
|
||||
#; validate status and output
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ On\ branch\ master ]]
|
||||
|
||||
#; confirm private directories are created
|
||||
[ -d "$T_DIR_WORK/.gnupg" ]
|
||||
test_perms "$T_DIR_WORK/.gnupg" "drwx------"
|
||||
[ -d "$T_DIR_WORK/.ssh" ]
|
||||
test_perms "$T_DIR_WORK/.ssh" "drwx------"
|
||||
|
||||
#; confirm directories are created before command is run
|
||||
[[ "$output" =~ Creating.+/.gnupg/.+Creating.+/.ssh/.+Running\ git\ command\ git\ status ]]
|
||||
}
|
||||
|
||||
@test "Private dirs (private dirs missing / yadm.auto-private-dirs=false)" {
|
||||
echo "
|
||||
When a git command is run
|
||||
And private directories are missing
|
||||
But auto-private-dirs is false
|
||||
Do not create private dirs
|
||||
"
|
||||
|
||||
#; confirm directories are missing at start
|
||||
[ ! -e "$T_DIR_WORK/.gnupg" ]
|
||||
[ ! -e "$T_DIR_WORK/.ssh" ]
|
||||
|
||||
#; set configuration
|
||||
run "${T_YADM_Y[@]}" config --bool "yadm.auto-private-dirs" "false"
|
||||
|
||||
#; run status
|
||||
run "${T_YADM_Y[@]}" status
|
||||
|
||||
#; validate status and output
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ On\ branch\ master ]]
|
||||
|
||||
#; confirm private directories are not created
|
||||
[ ! -e "$T_DIR_WORK/.gnupg" ]
|
||||
[ ! -e "$T_DIR_WORK/.ssh" ]
|
||||
}
|
||||
|
||||
@test "Private dirs (private dirs exist / yadm.auto-perms=false)" {
|
||||
echo "
|
||||
When a git command is run
|
||||
And private directories exist
|
||||
And yadm is configured not to auto update perms
|
||||
Do not alter directories
|
||||
"
|
||||
|
||||
#shellcheck disable=SC2174
|
||||
mkdir -m 0777 -p "$T_DIR_WORK/.gnupg" "$T_DIR_WORK/.ssh"
|
||||
|
||||
#; confirm directories are preset and open
|
||||
[ -d "$T_DIR_WORK/.gnupg" ]
|
||||
test_perms "$T_DIR_WORK/.gnupg" "drwxrwxrwx"
|
||||
[ -d "$T_DIR_WORK/.ssh" ]
|
||||
test_perms "$T_DIR_WORK/.ssh" "drwxrwxrwx"
|
||||
|
||||
#; set configuration
|
||||
run "${T_YADM_Y[@]}" config --bool "yadm.auto-perms" "false"
|
||||
|
||||
#; run status
|
||||
run "${T_YADM_Y[@]}" status
|
||||
|
||||
#; validate status and output
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ On\ branch\ master ]]
|
||||
|
||||
#; confirm directories are still preset and open
|
||||
[ -d "$T_DIR_WORK/.gnupg" ]
|
||||
test_perms "$T_DIR_WORK/.gnupg" "drwxrwxrwx"
|
||||
[ -d "$T_DIR_WORK/.ssh" ]
|
||||
test_perms "$T_DIR_WORK/.ssh" "drwxrwxrwx"
|
||||
}
|
||||
Reference in New Issue
Block a user