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 then 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
checks 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 31, 2024
1 parent 42e43ad commit c2823c4
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 c2823c4

Please sign in to comment.