components/ftp-proxy/ftp-proxy.Solaris/ftp-proxy
author Petr Hoffmann <petr.hoffmann@oracle.com>
Thu, 17 Mar 2016 00:08:54 -0700
changeset 5618 a7df12d981ea
parent 5565 f678cc44b3d0
permissions -rwxr-xr-x
PSARC/2014/291 PFLOGD: Packet Logging for PF PSARC/2014/292 FTP-PROXY: PF FTP-proxy supporting IPv4 NAT 22351416 deliver pflogd 22330374 deliver ftp-proxy

#!/sbin/sh
#
#
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
# Common Development and Distribution License (the "License").
# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
# See the License for the specific language governing permissions
# and limitations under the License.
#
# When distributing Covered Code, include this CDDL HEADER in each
# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
# If applicable, add the following below this CDDL HEADER, with the
# fields enclosed by brackets "[]" replaced with your own identifying
# information: Portions Copyright [yyyy] [name of copyright owner]
#
# CDDL HEADER END
#
#
# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
#

. /lib/svc/share/smf_include.sh

PATH=$PATH:/usr/sbin

# Retrieve an unescaped property value from a method token.
# Arguments:
# - raw method token value
# Outputs:
# - unescaped property value
# Returns:
# - 0 on success
# - 1 when unescaping failed
get_property()
{
	VALUE="$(echo "$1" | /usr/bin/sed 's/\\\(.\)/\1/g')"

	if [[ $? -ne 0 ]]; then
		exit 1
	fi

	echo "$VALUE"
}

failure()
{
	echo "An unknown error occurred. Probably either /usr/bin/sed is"
	echo "missing or system resources are exhausted."
	exit $SMF_EXIT_ERR_FATAL
}

# Exit with error if given variable is empty or unset.
# Arguments:
# - Variable name
# - SMF property the variable's value is obtained from
# Exits when the variable value is empty or unset,
# returns otherwise.
failure_empty_value()
{
	eval "[[ -z \${$1:-} ]] || return 0"
	echo "The ftp-proxy/$2 property cannot be empty."
	exit $SMF_EXIT_ERR_FATAL
}

failure_invalid_value()
{
	echo "The ftp-proxy/$1 property value is invalid."
	exit $SMF_EXIT_ERR_FATAL
}

# store and unescape property values
FTPPX_ANONYMOUS="$(get_property "$2")" || failure
FTPPX_PROXY_ADDRESS="$(get_property "$3")" || failure
FTPPX_PROXY_LISTEN_ADDRESS="$(get_property "$4")" || failure
FTPPX_DEBUG_LEVEL="$(get_property "$5")" || failure
FTPPX_MAXSESSIONS="$(get_property "$6")" || failure
FTPPX_PROXY_LISTEN_PORT="$(get_property "$7")" || failure
FTPPX_REVERSE_MODE_ADDRESS="$(get_property "$8")" || failure
FTPPX_REVERSE_MODE_PORT="$(get_property "$9")" || failure
FTPPX_REWRITE_SOURCE_PORT="$(get_property "${10}")" || failure
FTPPX_TAG="$(get_property "${11}")" || failure
FTPPX_TIMEOUT="$(get_property "${12}")" || failure
FTPPX_LOG="$(get_property "${13}")" || failure

# check the following properties are not empty and add them
# to the command-line used to start the ftp-proxy
typeset -a CMDLINE

failure_empty_value FTPPX_PROXY_ADDRESS proxy-NAT-address
CMDLINE+=( -a "$FTPPX_PROXY_ADDRESS" )

failure_empty_value FTPPX_PROXY_LISTEN_ADDRESS proxy-listen-address
CMDLINE+=( -b "$FTPPX_PROXY_LISTEN_ADDRESS" )

failure_empty_value FTPPX_DEBUG_LEVEL debug-level
CMDLINE+=( -D "$FTPPX_DEBUG_LEVEL" )

failure_empty_value FTPPX_MAXSESSIONS maxsessions
CMDLINE+=( -m "$FTPPX_MAXSESSIONS" )

failure_empty_value FTPPX_PROXY_LISTEN_PORT listen-port
CMDLINE+= ( -p "$FTPPX_PROXY_LISTEN_PORT" )

failure_empty_value FTPPX_TIMEOUT timeout
CMDLINE+=( -t "$FTPPX_TIMEOUT" )

case $FTPPX_ANONYMOUS in
	on)	CMDLINE+=( -A on )
		;;
	off)	# nothing needed
		;;
	*)	failure_invalid_value anonymous-only
		;;
esac

# reverse-mode-address is optional
if [[ -n $FTPPX_REVERSE_MODE_ADDRESS ]]; then
	CMDLINE+=( -R "$FTPPX_REVERSE_MODE_ADDRESS" )
	if [[ -n $FTPPX_REVERSE_MODE_PORT ]]; then
		CMDLINE+=( -P "$FTPPX_REVERSE_MODE_PORT" )
	fi
fi

case $FTPPX_REWRITE_SOURCE_PORT in
	on)	CMDLINE+=( -r on )
		;;
	off)	# nothing needed
		;;
	*)	failure_invalid_value always-use-ftp-data-port
		;;
esac

# tag is optional
if [[ -n $FTPPX_TAG ]]; then
	CMDLINE+=( -T "$FTPPX_TAG" )
fi

case $FTPPX_LOG in
	on)	CMDLINE+=( -v on )
		;;
	all)	CMDLINE+=( -v all )
		;;
	off)	CMDLINE+=( -v off )
		;;
	*)	failure_invalid_value log
		;;
esac

function start_proxy
{
	ANCHOR=$(echo "$SMF_FMRI" | \
	    /usr/bin/cut -f 2- -d / | /usr/bin/tr / :)
	if [[ -z $ANCHOR ]]; then
		echo "Unable to form a valid anchor name."
		exit $SMF_EXIT_ERR_FATAL
	fi
	ANCHOR="_auto/$ANCHOR"
	echo 'anchor "*"' | pfctl -a "$ANCHOR" -f -

	if [[ $? -ne 0 ]]; then
		echo "Unable to load rules into the firewall."
		exit $SMF_EXIT_ERR_FATAL
	fi

	CMDLINE+=( -X "$ANCHOR" )
	smf_clear_env
	ftp-proxy "${CMDLINE[@]}"
}

case "$1" in
	start)
		start_proxy
		;;

	*)
		echo "Usage: $0 \c" >&2
		echo "(start)" >&2
		exit 1
		;;

esac