diff --git a/plugins/git/install b/plugins/git/install index a0c651eff..965ac77ba 100755 --- a/plugins/git/install +++ b/plugins/git/install @@ -14,6 +14,17 @@ trigger-git-install() { fn-plugin-property-setup "git" migrate_git_vars_0_12_0 "$@" + migrate_netrc_permissions "$@" +} + +migrate_netrc_permissions() { + declare desc="enforces 0600 permissions on a pre-existing .netrc from older dokku versions" + local netrc_file="${DOKKU_ROOT}/.netrc" + + [[ ! -f "$netrc_file" ]] && return 0 + + chmod 600 "$netrc_file" + chown "${DOKKU_SYSTEM_USER}:${DOKKU_SYSTEM_GROUP}" "$netrc_file" } migrate_git_vars_0_12_0() { diff --git a/plugins/git/internal-functions b/plugins/git/internal-functions index 7434f36b0..942e5f77b 100755 --- a/plugins/git/internal-functions +++ b/plugins/git/internal-functions @@ -86,12 +86,21 @@ cmd-git-auth() { if [[ -z "$USERNAME" ]]; then dokku_log_info1 "Removing netrc auth entry for host $HOST" netrc unset "$HOST" - return $? + local exit_code=$? + fn-git-auth-secure-netrc + return $exit_code fi dokku_log_info1 "Setting netrc auth entry for host $HOST" - touch "${DOKKU_ROOT}/.netrc" netrc set "$HOST" "$USERNAME" "$PASSWORD" + fn-git-auth-secure-netrc +} + +fn-git-auth-secure-netrc() { + declare desc="enforces 0600 permissions and dokku ownership on the netrc file" + [[ ! -f "${DOKKU_ROOT}/.netrc" ]] && return 0 + chmod 600 "${DOKKU_ROOT}/.netrc" + chown "${DOKKU_SYSTEM_USER:-dokku}:${DOKKU_SYSTEM_GROUP:-dokku}" "${DOKKU_ROOT}/.netrc" } cmd-git-auth-status() { diff --git a/tests/unit/git_3.bats b/tests/unit/git_3.bats index 88b479585..f1252d30b 100644 --- a/tests/unit/git_3.bats +++ b/tests/unit/git_3.bats @@ -105,6 +105,80 @@ teardown() { echo "status: $status" assert_success assert_output_contains "piped-username:piped-password" + + run /bin/bash -c "stat -c '%a' ${DOKKU_ROOT}/.netrc" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "600" + + run /bin/bash -c "stat -c '%U:%G' ${DOKKU_ROOT}/.netrc" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "dokku:dokku" +} + +@test "(git) git:auth repairs world-readable .netrc" { + run /bin/bash -c "chmod 644 ${DOKKU_ROOT}/.netrc" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "stat -c '%a' ${DOKKU_ROOT}/.netrc" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "644" + + run /bin/bash -c "dokku git:auth github.com username password" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Setting netrc auth entry for host github.com" + + run /bin/bash -c "stat -c '%a' ${DOKKU_ROOT}/.netrc" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "600" + + run /bin/bash -c "stat -c '%U:%G' ${DOKKU_ROOT}/.netrc" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "dokku:dokku" +} + +@test "(git) git:auth unset preserves 0600 on remaining .netrc" { + run /bin/bash -c "dokku git:auth github.com username password" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku git:auth other.example.com user2 pass2" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "chmod 644 ${DOKKU_ROOT}/.netrc" + echo "output: $output" + echo "status: $status" + assert_success + + run /bin/bash -c "dokku git:auth github.com" + echo "output: $output" + echo "status: $status" + assert_success + assert_output_contains "Removing netrc auth entry for host github.com" + + if [[ -f "${DOKKU_ROOT}/.netrc" ]]; then + run /bin/bash -c "stat -c '%a' ${DOKKU_ROOT}/.netrc" + echo "output: $output" + echo "status: $status" + assert_success + assert_output "600" + fi } @test "(git) git:auth-status" {