Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ Easy-RSA 3 ChangeLog

3.2.4 (TBD)

* help: Correct build-ca 'rawca' command option (0447f42) (#1374)
* Windows easyrsa-shell-init.sh: Modernize prompt (5bf2e99) (#1374)
* Windows UT: Update 'wop-test.sh' to latest 'easyrsa-shell-init.sh' (ea5b168) (#1374)
* verify_openvpn(): Convert Windows path '\' to *nix path '/' (75a8fdd) (#1374)
* verify_openvpn(): Windows, add check for 'openvpn.exe' (10c6267) (#1374)
* gen-crl: Replace file-move with file-copy-preserve-attribs (4cc1d48) (#1374)
* Windows easyrsa-shell-init.sh: Add non-fatal check for 'openvpn.exe' (bb78615) (#1374)
* Windows easyrsa-shell-init.sh: Require confirmation for User-Home mode (bfa6cfd) (#1374)
* Windows easyrsa-shell-init.sh: Allow Easy-RSA to use '\User\$HOME' (f194da5) (#1374)
* mutual_exclusions(): Include basic checks for --startdate/--enddate (e1478c3) (#1372)
* Windows easyrsa-shell-init.sh: Replace 'read -p' (49b2181) (#1371)
* inline: Include missing OpenVPN TLS key to cause INCOMPLETE warning (d98eee6) (#1368)
Expand Down
227 changes: 131 additions & 96 deletions distro/windows/bin/easyrsa-shell-init.sh
Original file line number Diff line number Diff line change
@@ -1,115 +1,90 @@
#!/bin/sh
# 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
# project; use with other POSIX shells for Windows may require modification to
# this wrapper script.

echo "Easy-RSA starting.."

setup_path="${EASYRSA:-$PWD}"
export PATH="$setup_path;$setup_path/bin;$PATH"
export HOME="$setup_path"

# This prevents reading from a user's .mkshrc if they have one.
# A user who runs mksh for other purposes might have it
export ENV="/disable-env"
# SC2162 - read without -r will mangle backslashes
# SC1091 - Not following source file
# SC1003 - (info): Want to escape a single quote?
# shellcheck disable=SC2162,SC1091,SC1003

# intent confirmation helper func
# modified from easyrsa
confirm() {
prompt="$1"
value="$2"
msg="$3"
input=""
print "\
$msg

Type the word '$value' to continue, or any other input to abort."
printf %s " $prompt"
# shellcheck disable=SC2162 # read without -r - confirm()
read input
printf '\n'
[ "$input" = "$value" ] && return
unset -v EASYRSA_SILENT
notice "Aborting without confirmation."
exit 1
} # => confirm()

# Verify required externals are present
extern_list="which awk cat cp mkdir printf rm"
for f in $extern_list; do
if ! which "${f}.exe" >/dev/null 2>&1; then
echo ""
echo "FATAL: EasyRSA Shell init is missing a required external file:"
echo " ${f}.exe"
echo " Your installation is incomplete and cannot function without the required"
echo " files."
echo ""
#shellcheck disable=SC2162
echo "Press Enter to exit."
# Access denied error
access_denied() {
echo "Cannot locate or use a User-Home directory."
echo "Press [Enter] to exit."
read
exit 1
} # => access_denied()

# Administrator access Required tests
admin_access() {
mkdir "$1" 2>/dev/null || return 1
[ -d "$1" ] || return 1
echo 1 >"$1"/1 2>/dev/null || return 1
[ -f "$1"/1 ] || return 1
rm -rf "$1" 2>/dev/null || return 1
[ ! -d "$1" ] || return 1
} # => admin_access()

# Setup "$HOMEDRIVE\$HOMEPATH\OpenVPN\easy-rsa" directory
use_home_dir() {
if [ "$USERPROFILE" ]; then
# Use $USERPROFILE
user_home="$USERPROFILE"
elif [ "$HOMEDRIVE" ]; then
if [ "$HOMEPATH" ]; then
# Use $HOMEDRIVE and $HOMEPATH
user_home="${HOMEDRIVE}${HOMEPATH}"
else
user_home=
fi
else
user_home=
fi
done

# Allow options
non_admin=""
while [ "$1" ]; do
case "$1" in
/[Nn][Aa]|/no-adm*|--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
full administrator privileges via Windows User Access Control."
echo ""

#shellcheck disable=SC2162
echo "Press Enter to exit."
read
exit 1
}
# If no $user_home was identified
[ "$user_home" ] || access_denied

# 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"
# Use $user_home/openvpn directory
cd "$user_home"/openvpn || access_denied

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

cd easy-rsa 2>/dev/null || \
access_denied "Access: easy-rsa"
# Use $user_home/openvpn/easy-rsa directory
cd easy-rsa 2>/dev/null || access_denied

export HOME="$PWD"
export PATH="$HOME;$PATH"
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
unset -v user_home
} # => use_home_dir()

# set_var is defined as any vars file needs it.
# This is the same as in easyrsa, but we _don't_ export
Expand All @@ -120,6 +95,54 @@ set_var() {
eval "$var=\"\${$var-$value}\""
} #=> set_var()

########################################
# Invocation entry point:

echo "Starting Easy-RSA shell.."

setup_path="${EASYRSA:-$PWD}"
export PATH="$setup_path;$setup_path/bin;$PATH"
export HOME="$setup_path"

# This prevents reading from a user's .mkshrc if they have one.
# A user who runs mksh for other purposes might have it
export ENV="/disable-env"

# Check for broken administrator access
# https://github.com/OpenVPN/easy-rsa/issues/1072
if admin_access "$HOME"/easyrsa-write-test; then
sec_lev='#'
else
echo "
To use Easy-RSA in a protected system directory, you must have
full administrator privileges via Windows User Access Control."

confirm "Continue without administrator access ? " yes "
Easy-RSA will now try to use your User-Home directory."

use_home_dir
sec_lev='$'
echo "
NOTICE:
Easy-RSA has been auto-configured to run in your User-Home directory."
fi

# Verify required externals are present
extern_list="which awk cat cp mkdir printf rm grep sed"
for f in $extern_list; do
if ! which "${f}.exe" >/dev/null 2>&1; then
echo ""
echo "FATAL: EasyRSA Shell init is missing a required external file:"
echo " ${f}.exe"
echo " Your installation is incomplete and cannot function without"
echo " the required files."
echo ""
echo "Press Enter to exit."
read
exit 1
fi
done

# Check for a usable openssl bin, referencing vars if present
[ -r "vars" ] && EASYRSA_CALLER=1 . "vars" 2>/dev/null
if [ -z "$EASYRSA_OPENSSL" ] && ! which openssl.exe >/dev/null 2>&1; then
Expand All @@ -135,18 +158,30 @@ fi
exit 1
}

# Check for openvpn executable
if which openvpn.exe >/dev/null 2>&1; then
EASYRSA_OPENVPN="$(which openvpn.exe | sed s/'\\'/'\/'/g)" || {
echo "verify_openvpn - Failed to convert openvpn path."
echo "Press Enter to exit."
read
exit 1
}
export EASYRSA_OPENVPN="$EASYRSA_OPENVPN"
else
echo "WARNING: openvpn.exe is not in your system PATH."
echo "EasyRSA will not be able to generate OpenVPN TLS keys."
fi

# Set prompt and welcome message
export PS1='
EasyRSA Shell
# '
export PS1="$USERNAME@$COMPUTERNAME $HOME
EasyRSA-Shell: $sec_lev "

echo ""
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
sh.exe
43 changes: 29 additions & 14 deletions easyrsa3/easyrsa
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ Command list:
serial|check-serial <SERIAL>
display-dn <form> <DIR/FILE_NAME>
show-eku <file_name_base>|<DIR/FILE_NAME>
rand <decimal_number>"
rand <decimal_number>
"
} # => usage()

# Detailed command help
Expand Down Expand Up @@ -187,8 +188,8 @@ Usage: easyrsa [ OPTIONS.. ] <COMMAND> <TARGET> [ cmd-opts.. ]"
Creates a new CA"

opts="
* raw-ca - ONLY use SSL binary to input CA password
raw (Equivalent to global option '--raw-ca')
* rawca - ONLY use SSL binary to input CA password
(Equivalent to global option '--rawca|--raw-ca')

* nopass - Do not encrypt the private key (Default: encrypted)
(Equivalent to global option '--nopass|--no-pass')
Expand Down Expand Up @@ -1567,7 +1568,7 @@ build_ca() {
nopass)
[ "$prohibit_no_pass" ] || EASYRSA_NO_PASS=1
;;
rawca|raw-ca)
rawca)
# option --raw-ca demands user interaction
# which forbids --batch
[ "$EASYRSA_BATCH" ] && user_error \
Expand Down Expand Up @@ -3546,11 +3547,7 @@ gen_crl() {
die "CRL Generation failed."

# Move temp-files to target-files
mv "$out_file_tmp" "$out_file" || mv_temp_error=1
if [ "$mv_temp_error" ]; then
#rm -f "$out_file"
die "Failed to move temp CRL file."
fi
cp -p "$out_file_tmp" "$out_file" || die "Failed to move temp CRL file."

# Copy to DER - As published by OpenSSL
if "$EASYRSA_OPENSSL" crl -in "$out_file" -out "$out_der" \
Expand Down Expand Up @@ -3972,14 +3969,32 @@ ${cipher:+You will then enter a new password for this key.$NL}"

# Verify OpenVPN binary
verify_openvpn() {
# Try to find openvpn
set_var EASYRSA_OPENVPN "$(which openvpn)"
if [ -f "$EASYRSA_OPENVPN" ]; then
verbose \
"verify_openvpn - EASYRSA_OPENVPN='$EASYRSA_OPENVPN'"
verbose "verify_openvpn; Preset EASYRSA_OPENVPN='$EASYRSA_OPENVPN'"
return
fi

# Try to find openvpn *nix
if which openvpn >/dev/null 2>&1; then
set_var EASYRSA_OPENVPN "$(which openvpn)"
else
user_error "Cannot find an OpenVPN binary."
# Try to find openvpn.exe, specifically for Windows
# Assign temp-file for Windows path name
ovpn_path_tmp=""
easyrsa_mktemp ovpn_path_tmp

if which openvpn.exe > "$ovpn_path_tmp"; then
# shellcheck disable=SC1003 # (info): Want to escape a single quote?
ovpn_path="$(sed s/'\\'/'\/'/ "$ovpn_path_tmp")" || \
die "verify_openvpn - Failed to convert openvpn path."
set_var EASYRSA_OPENVPN "$ovpn_path"
else
user_error "\
An 'openvpn' binary is not in your system PATH.
EasyRSA can not generate OpenVPN TLS keys."
fi
fi
verbose "verify_openvpn; Set EASYRSA_OPENVPN='$EASYRSA_OPENVPN'"
} # => verify_openvpn()

# OpenVPN TLS Auth/Crypt Key
Expand Down
Loading
Loading