diff options
| author | Guilhem Moulin <guilhem@debian.org> | 2021-02-22 03:30:32 +0100 | 
|---|---|---|
| committer | Guilhem Moulin <guilhem@debian.org> | 2021-02-22 03:30:32 +0100 | 
| commit | d1be19ea9484f4c48af2de54266465d49bb1281d (patch) | |
| tree | 768da9388a9ea6ed42d8d818a6433a4871a1172e /tests/drop-privileges | |
| parent | 847ae99fb1ed73fd77c6ffd30f2c554ab5892fde (diff) | |
| parent | 3eba02ef820a393bd5781be9f8fcda1611ae7c3d (diff) | |
Merge tag 'v0.8.0' into debian/latest
Release version 0.8.0
Diffstat (limited to 'tests/drop-privileges')
| -rw-r--r-- | tests/drop-privileges | 166 | 
1 files changed, 166 insertions, 0 deletions
| diff --git a/tests/drop-privileges b/tests/drop-privileges new file mode 100644 index 0000000..0596e31 --- /dev/null +++ b/tests/drop-privileges @@ -0,0 +1,166 @@ +# Check privilige drop: UID/GID changes, chdir, environment, and file +# descriptors + +# create wrapper to inspect processes +STATUSDIR="/dev/shm/lacme-wrap" +install -oroot -groot -m0755 /dev/stdin /run/lacme-wrap <<-EOF +	#!/bin/sh +	set -ue +	PATH="/usr/bin:/bin" +	export PATH + +	prefix="$STATUSDIR/\${1##*[/-]}" +	cat </proc/\$\$/status >"\$prefix/status" +	pwd >"\$prefix/cwd" +	stat -c "%U:%G %#a" . >"\$prefix/cwd-mod" +	sort -z </proc/\$\$/environ | tr "\\0" "\\n" >"\$prefix/environ" +	( find -P /proc/\$\$/fd -mindepth 1 \! -lname "\$0" -printf "%P %#m %U:%G %l\\n" >"\$prefix/fd" ) + +	exec "\$@" +EOF + +# also check privilege drop for the spawned accountd +adduser --system --group \ +       --home /nonexistent --no-create-home \ +       --gecos "lacme account user" \ +       --quiet lacme-account +sed -ri 's|^#user\s*=\s*$|user = lacme-account|' /etc/lacme/lacme.conf +sed -ri 's|^#group\s*=\s*$|group = lacme-account|' /etc/lacme/lacme.conf +chown lacme-account: /etc/lacme/account.key + +install -oroot -groot -dm0755 -- "$STATUSDIR" +install -olacme-account -groot -dm0700 -- "$STATUSDIR/accountd" +install -o_lacme-client -groot -dm0700 -- "$STATUSDIR/client" +install -o_lacme-www    -groot -dm0700 -- "$STATUSDIR/webserver" + +# test with a group that's not the primary group (nogroup) of _lacme-www etc +addgroup --system nogroup2 +sed -ri 's|^#?group\s*=\s*nogroup$|group = nogroup2|' /etc/lacme/lacme.conf +sed -ri 's|^#?command\s*=.*/lacme-accountd$|command = /run/lacme-wrap /usr/bin/lacme-accountd|' /etc/lacme/lacme.conf +sed -ri 's|^#?command\s*=.*/lacme/client$|command = /run/lacme-wrap /usr/libexec/lacme/client|' /etc/lacme/lacme.conf +sed -ri 's|^#?command\s*=.*/lacme/webserver$|command = /run/lacme-wrap /usr/libexec/lacme/webserver|' /etc/lacme/lacme.conf +sed -ri 's|^#?config\s*=\s*$|config = /etc/lacme/lacme-accountd.conf|' /etc/lacme/lacme.conf + +check_status() { +    local path="$STATUSDIR/$1/status" user="$2" group="$3" +    UID="$(getent passwd "$user"  | cut -sd: -f3)" +    GID="$(getent group  "$group" | cut -sd: -f3)" +    [ -n "$UID" -a -n "$GID" ] || return 1 +    grep -Ex "Uid:\\s+$UID\\s+$UID\\s+$UID\\s+$UID" "$path" || return 1 +    grep -Ex "Gid:\\s+$GID\\s+$GID\\s+$GID\\s+$GID" "$path" || return 1 +    grep -Ex "Groups:\s+$GID\s*" "$path" || return 1 +} +check_cwd() { +    local path="$STATUSDIR/$1/cwd" dir="$2" cwd +    cwd="$(cat <"$path")" || return 1 +    [ "$cwd" = "$dir" ] || return 1 +} + +check_accountd() { +    local socket_ino stderr prefix="$STATUSDIR/accountd" +    check_status accountd lacme-account lacme-account || return 1 +    check_cwd    accountd / || return 1 + +    diff --label="a/accountd/environ" --label="b/accountd/environ" \ +            --color=auto --unified "$prefix/environ" - <<-EOF +		HOME=/nonexistent +		LOGNAME=lacme-account +		PATH=/usr/bin:/bin +		SHELL=/usr/sbin/nologin +		TERM=$TERM +		USER=lacme-account +	EOF + +    stderr="$(readlink -e "/proc/$$/fd/2")" +    socket_ino="$(sed -rn '/^0 .* socket:\[([0-9]+)\]$/ {s//\1/p;q}' "$prefix/fd")" +    [ -n "$socket_ino" ] || return 1 +    grep -Fxq "0 0700 $UID:$GID socket:[$socket_ino]" "$prefix/fd" || return 1 +    grep -Fxq "1 0700 $UID:$GID socket:[$socket_ino]" "$prefix/fd" || return 1 +    grep -Fxq "2 0700 $UID:$GID $stderr" "$prefix/fd" || return 1 +    sed -ri '\#^[012] #d' "$prefix/fd" +    ! test -s "$prefix/fd" || return 1 +} +check_client() { +    local command="$1" cwd="$2" UID GID stdout stderr prefix="$STATUSDIR/client" +    check_status client _lacme-client nogroup2 +    check_cwd    client "$cwd" + +    diff --label="a/client/environ" --label="b/client/environ" \ +            --color=auto --unified "$prefix/environ" - <<-EOF +		DEBUG=0 +		HOME=/nonexistent +		LOGNAME=_lacme-client +		PATH=/usr/bin:/bin +		SHELL=/usr/sbin/nologin +		TERM=$TERM +		USER=_lacme-client +	EOF + +    stdout="$(readlink -e "/proc/$$/fd/1")" +    stderr="$(readlink -e "/proc/$$/fd/2")" +    if [ "$command" = "account" ]; then # no pipe +        grep -Fxq "0 0500 $UID:$GID /dev/null" "$prefix/fd" || return 1 +        grep -Fxq "1 0700 $UID:$GID $stdout"   "$prefix/fd" || return 1 +    elif [ "$command" = "order" ]; then +        grep -Exq "0 0500 $UID:$GID pipe:\[[0-9]+\]" "$prefix/fd" || return 1 +        grep -Exq "1 0300 $UID:$GID pipe:\[[0-9]+\]" "$prefix/fd" || return 1 +    else +        exit 1 +    fi +    grep -Fxq "2 0700 $UID:$GID $stderr" "$prefix/fd" || return 1 +    sed -ri '\#^[012] #d' "$prefix/fd" + +    grep -Exq "[0-9]+ 0700 $UID:$GID socket:\[[0-9]+\]" "$prefix/fd" || return 1 +    sed -ri '0,\#^[0-9]+ .* socket:\[[0-9]+\]$# {//d}' "$prefix/fd" + +    grep -Exq "[0-9]+ 0500 $UID:$GID /etc/lacme/lacme\.conf" "$prefix/fd" || return 1 +    sed -ri '0,\#^[0-9]+ .* /etc/lacme/lacme\.conf$# {//d}' "$prefix/fd" +    ! test -s "$prefix/fd" || return 1 +} +check_webserver() { +    local cwd="$1" UID GID stdout stderr prefix="$STATUSDIR/webserver" +    check_status webserver _lacme-www nogroup2 +    check_cwd    webserver "$cwd" + +    diff --label="a/webserver/environ" --label="b/webserver/environ" \ +            --color=auto --unified "$prefix/environ" - <<-EOF +		DEBUG=0 +		HOME=/nonexistent +		LOGNAME=_lacme-www +		PATH=/usr/bin:/bin +		SHELL=/usr/sbin/nologin +		TERM=$TERM +		USER=_lacme-www +	EOF + +    stdout="$(readlink -e "/proc/$$/fd/1")" +    stderr="$(readlink -e "/proc/$$/fd/2")" +    grep -Fxq "0 0500 $UID:$GID /dev/null"  "$prefix/fd" || return 1 +    grep -Fxq "1 0700 $UID:$GID $stdout" "$prefix/fd" || return 1 +    grep -Fxq "2 0700 $UID:$GID $stderr" "$prefix/fd" || return 1 +    sed -ri '\#^[012] #d' "$prefix/fd" + +    grep -Exq "[0-9]+ 0700 $UID:$GID socket:\[[0-9]+\]" "$prefix/fd" || return 1 +    sed -ri '0,\#^[0-9]+ .* socket:\[[0-9]+\]$# {//d}' "$prefix/fd" +    ! test -s "$prefix/fd" || return 1 +} + +lacme account +check_accountd +check_client account / +! test -e "$STATUSDIR/webserver/status" # account 'command' doesn't start the webserver + +lacme newOrder +check_accountd +challenge_dir="$(cat "$STATUSDIR/webserver/cwd")" +[ "${challenge_dir#"/tmp/acme-challenge."}" != "$challenge_dir" ] || exit 1 +check_client order "$challenge_dir" +check_webserver    "$challenge_dir" + +# the temporary challenge directory is created with permissive mode +diff --label="a/webserver/cwd" --label="b/webserver/cwd" \ +        --color=auto --unified "$STATUSDIR/webserver/cwd-mod" - <<-EOF +	_lacme-client:root 0755 +EOF + +# vim: set filetype=sh : | 
