feat: implement mail-login directadmin plugin
This commit is contained in:
Executable
+93
@@ -0,0 +1,93 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
set -f
|
||||
|
||||
DA_BIN="${MAIL_LOGIN_DA_BIN:-/usr/bin/da}"
|
||||
AUDIT_LOG="${MAIL_LOGIN_AUDIT_LOG:-/usr/local/hitme_plugins/mail-login-helper/logs/audit.log}"
|
||||
STATE_DIR="${MAIL_LOGIN_STATE_DIR:-/usr/local/hitme_plugins/mail-login-helper/state}"
|
||||
|
||||
audit() {
|
||||
dir=$(dirname "$AUDIT_LOG")
|
||||
mkdir -p "$dir"
|
||||
chmod 700 "$dir"
|
||||
printf '{"timestamp":"%s","event":"%s","result":"%s","correlation":"%s","username":"%s","source_host":"%s","client_ip":"%s"}\n' \
|
||||
"$(date -u '+%Y-%m-%dT%H:%M:%SZ')" "$1" "$2" "$3" "$4" "$5" "$6" >> "$AUDIT_LOG"
|
||||
chmod 600 "$AUDIT_LOG"
|
||||
}
|
||||
|
||||
fail() {
|
||||
audit "create_login_url" "failure" "${CORRELATION:-unknown}" "${USERNAME_ARG:-unknown}" "${SOURCE_HOST:-unknown}" "${CLIENT_IP:-unknown}"
|
||||
echo "mail-login helper failed" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
clean_label() {
|
||||
printf '%s' "$1" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9-]/-/g; s/^-*//; s/-*$//'
|
||||
}
|
||||
|
||||
if [ "$#" -eq 0 ] && [ -n "${SSH_ORIGINAL_COMMAND:-}" ]; then
|
||||
# The authorized_keys forced command receives the requested command here.
|
||||
# All accepted fields are validated below before use.
|
||||
set -- $SSH_ORIGINAL_COMMAND
|
||||
fi
|
||||
|
||||
COMMAND="${1:-}"
|
||||
USERNAME_ARG="${2:-}"
|
||||
SOURCE_HOST="${3:-}"
|
||||
SERVER_NAME="${4:-}"
|
||||
TTL="${5:-}"
|
||||
USER_IP_BOUND="${6:-}"
|
||||
CLIENT_IP="${7:-}"
|
||||
REDIRECT_PATH="${8:-}"
|
||||
|
||||
[ "$COMMAND" = "mail-login-create-url" ] || fail
|
||||
printf '%s' "$USERNAME_ARG" | grep -Eq '^[A-Za-z0-9][A-Za-z0-9._-]{0,31}$' || fail
|
||||
printf '%s' "$SOURCE_HOST" | grep -Eq '^[A-Za-z0-9.-]+$' || fail
|
||||
printf '%s' "$SERVER_NAME" | grep -Eq '^[A-Za-z0-9-]{1,32}$' || fail
|
||||
printf '%s' "$TTL" | grep -Eq '^[0-9]+$' || fail
|
||||
[ "$TTL" -ge 5 ] && [ "$TTL" -le 300 ] || fail
|
||||
[ "$USER_IP_BOUND" = "0" ] || [ "$USER_IP_BOUND" = "1" ] || fail
|
||||
printf '%s' "$CLIENT_IP" | grep -Eq '^[0-9A-Fa-f:.]+$' || fail
|
||||
case "$REDIRECT_PATH" in
|
||||
/*) ;;
|
||||
*) fail ;;
|
||||
esac
|
||||
case "$REDIRECT_PATH" in
|
||||
//*|*\\*) fail ;;
|
||||
esac
|
||||
printf '%s' "$REDIRECT_PATH" | grep -Eq '^/[A-Za-z0-9._~%/?=+-]*$' || fail
|
||||
|
||||
SERVER_CLEAN=$(clean_label "$SERVER_NAME")
|
||||
USER_CLEAN=$(clean_label "$USERNAME_ARG")
|
||||
TIMESTAMP=$(date '+%s')
|
||||
CORRELATION="autologin-$SERVER_CLEAN-$USER_CLEAN-$TIMESTAMP"
|
||||
|
||||
if [ ${#CORRELATION} -gt 96 ]; then
|
||||
HASH=$(printf '%s' "$CORRELATION" | openssl dgst -sha256 -r 2>/dev/null | awk '{print substr($1,1,10)}')
|
||||
SUFFIX="-$HASH-$TIMESTAMP"
|
||||
BODY=$(printf '%s' "autologin-$SERVER_CLEAN-$USER_CLEAN" | cut -c 1-$((96 - ${#SUFFIX})) | sed 's/-*$//')
|
||||
CORRELATION="$BODY$SUFFIX"
|
||||
fi
|
||||
|
||||
mkdir -p "$STATE_DIR"
|
||||
chmod 700 "$STATE_DIR"
|
||||
|
||||
if [ "$USER_IP_BOUND" = "1" ]; then
|
||||
OUTPUT=$("$DA_BIN" login-url "--user=$USERNAME_ARG" "--redirect-url=$REDIRECT_PATH" "--expiry=${TTL}s" "--ip=$CLIENT_IP") || fail
|
||||
else
|
||||
OUTPUT=$("$DA_BIN" login-url "--user=$USERNAME_ARG" "--redirect-url=$REDIRECT_PATH" "--expiry=${TTL}s") || fail
|
||||
audit "ip_bound_disabled" "warning" "$CORRELATION" "$USERNAME_ARG" "$SOURCE_HOST" "$CLIENT_IP"
|
||||
fi
|
||||
|
||||
URL=$(printf '%s\n' "$OUTPUT" | awk '/https:\/\// {for (i=1;i<=NF;i++) if ($i ~ /^https:\/\//) {print $i; exit}}')
|
||||
[ -n "$URL" ] || fail
|
||||
case "$URL" in
|
||||
https://*/api/login/url?key=*) ;;
|
||||
*) fail ;;
|
||||
esac
|
||||
|
||||
printf '{"timestamp":%s,"correlation":"%s","username":"%s","source_host":"%s","client_ip":"%s","ttl":%s,"ip_bound":%s}\n' \
|
||||
"$TIMESTAMP" "$CORRELATION" "$USERNAME_ARG" "$SOURCE_HOST" "$CLIENT_IP" "$TTL" "$USER_IP_BOUND" > "$STATE_DIR/$CORRELATION.json"
|
||||
chmod 600 "$STATE_DIR/$CORRELATION.json"
|
||||
audit "create_login_url" "success" "$CORRELATION" "$USERNAME_ARG" "$SOURCE_HOST" "$CLIENT_IP"
|
||||
printf 'URL: %s\n' "$URL"
|
||||
Reference in New Issue
Block a user