Skip to content

Commit

Permalink
Windows: Introduce 'Non-Admin' mode
Browse files Browse the repository at this point in the history
This allows Easy-RSA to be run in a User's Home directory.

The problem is ONLY caused by 'Windows User Access Control' feedback:

Easy-RSA executable 'mkdir.exe' does not receive an error-on-failure
when Windows UAC has not granted write access to the OpenVPN system
directory: '\Program Files\Openvpn\easy-rsa'

This means that easyrsa cannot successful verify directory creation
by using only the exit status of command 'mkdir.exe'. Instead, easyrsa
must also check that the directory was created via '[ -d pki ] || foo'.

The following changes are required:

* Changes to 'easyrsa-shell-init.sh':

Allow options to be passed from the command line.
The only supported options are: /na or --no-admin

This non_admin mode will change directory to the User's Home directory
and the make full write access checks on the Home directory.

In standard mode, the full write access checks will be run in the default
system folder. And, unless the Windows UAC has granted write access, these
tests will fail as intended. A helpful error message is then printed.

* Changes to 'EasyRSA-Start.bat':

Allow command line options to be passed onto 'easyrsa-shell-init.sh'

For Openvpn-build:
This also allows the creation of a new Windows-Start Menu item:
* 'Start EasyRSA Shell (Non-Admin)'
  Which can pass the '/na' or '--no-admin' flag to 'EasyRSA-Start.bat'

Signed-off-by: Richard T Bonhomme <[email protected]>
  • Loading branch information
TinCanTech committed Jan 30, 2024
1 parent 42e43ad commit 1046770
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 3 deletions.
2 changes: 1 addition & 1 deletion distro/windows/EasyRSA-Start.bat
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
@echo OFF
bin\sh.exe bin\easyrsa-shell-init.sh
bin\sh.exe bin\easyrsa-shell-init.sh %*
96 changes: 94 additions & 2 deletions distro/windows/bin/easyrsa-shell-init.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#!/bin/sh
# shellcheck disable=SC2161,SC1091
# shellcheck disable=SC2161,SC1091,SC2028

# This script is a frontend designed to create & launch a POSIX shell
# environment suitable for use with Easy-RSA. mksh/Win32 is used with this
Expand Down Expand Up @@ -31,6 +31,95 @@ for f in $extern_list; do
fi
done

# Allow options
non_admin=""
while [ "$1" ]; do
case "$1" in
/[Nn][Aa]|--no-adm*)
non_admin=1
echo "Using no-admin mode"
;;
*)
echo "Ignoring unknown option: '$1'"
esac
shift
done

# Access denied
access_denied() {
echo "Access error: $1"
echo "
To use Easy-RSA in a protected system directory, you must have
elevated privileges via 'Windows User Access Control'.
You can try 'run-as admin' but that may also fail.
It is recommended to use Easy-RSA in your User/home directory.
Please try using one of the following solutions:
* Use the Start Menu item: 'Start Easy-RSA Shell (Non-Admin)'
* Or, in a Non-Admin command prompt window, run two commands:
cd '\Program Files\Openvpn\easy-rsa\'
EasyRSA-Start.bat /no-admin
These will start EasyRSA in your user's 'home directory/easy-rsa'
Press enter to exit."

#shellcheck disable=SC2162
read
exit 1
}

# Use home directory/easy-rsa
if [ "$non_admin" ]; then
[ "${HOMEDRIVE}" ] || \
access_denied "Undefined: HOMEDRIVE"
user_home_drv="${HOMEDRIVE}"

[ "${HOMEPATH}" ] || \
access_denied "Undefined: HOMEPATH"
eval "user_home_dir='\\${HOMEPATH}'"

# shellcheck disable=SC2154 # user_home_dir is not assigned
user_home="${user_home_drv}${user_home_dir}"

[ -d "$user_home" ] || \
access_denied "Missing: $user_home"

cd "$user_home" 2>/dev/null || \
access_denied "Access: $user_home"

if [ ! -d easy-rsa ]; then
mkdir easy-rsa 2>/dev/null || \
access_denied "mkdir: easy-rsa"
# Required test
[ -d easy-rsa ] || \
access_denied "Missing: easy-rsa"
fi

cd easy-rsa 2>/dev/null || \
access_denied "Access: easy-rsa"

export HOME="$PWD"
unset -v user_home_drv user_home_dir user_home
fi

# Check for broken administrator access
# https://github.com/OpenVPN/easy-rsa/issues/1072
[ -d "$HOME" ] || access_denied "-d HOME"
win_tst_d="$HOME"/easyrsa-write-test

# Required tests
mkdir "$win_tst_d" 2>/dev/null || access_denied "mkdir"
[ -d "$win_tst_d" ] || access_denied "-d"
echo 1 > "$win_tst_d"/1 2>/dev/null || access_denied "write"
[ -f "$win_tst_d"/1 ] || access_denied "-f"
rm -rf "$win_tst_d" 2>/dev/null || access_denied "rm"
[ ! -d "$win_tst_d" ] || access_denied "! -d"
unset -v win_tst_d
unset -f access_denied

# set_var is defined as any vars file needs it.
# This is the same as in easyrsa, but we _don't_ export
set_var() {
Expand Down Expand Up @@ -62,6 +151,9 @@ echo "Welcome to the EasyRSA 3 Shell for Windows."
echo "Easy-RSA 3 is available under a GNU GPLv2 license."
echo ""
echo "Invoke './easyrsa' to call the program. Without commands, help is displayed."
echo ""
echo "Using directory: $HOME"
echo ""

# Drop to a shell and await input
bin/sh
sh.exe

0 comments on commit 1046770

Please sign in to comment.