#!/bin/bash
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2013 IPFire Network Development Team #
# #
# This program is free software: you can redistribute it and/or modify #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or #
# (at your option) any later version. #
# #
# This program is distributed in the hope that it will be useful, #
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
# GNU General Public License for more details. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see . #
# #
###############################################################################
. /usr/lib/network/header-zone
HOOK_SETTINGS="HOOK AUTH INTERFACE_ADDRESS IPV6 MTU PASSWORD PEER_ADDRESS PORT"
HOOK_SETTINGS="${HOOK_SETTINGS} PREFIX PREFIX_DELEGATION REFUSED_AUTH_METHODS"
HOOK_SETTINGS="${HOOK_SETTINGS} USERNAME USE_DHCP"
# User credentials for the dialin.
USERNAME=""
PASSWORD=""
# The physical ethernet port the modem is connected to.
PORT=""
# The IPv4 address of the PPTP server to connect to.
PEER_ADDRESS=""
# Set the authentication mechanism.
AUTH=""
# Maximum Transmission Unit.
# 1492 is a very common value for that.
MTU="1492"
# This hook can work with all authentication methods supported by pppd.
PPP_SUPPORTED_AUTH_METHODS="${PPP_SUPPORTED_AUTH_METHODS}"
# Use DHCP to get a IPv4 Address for the interface.
USE_DHCP="false"
# Request an IPv6 address.
IPV6="true"
# Use IPv6 prefix delegation.
PREFIX_DELEGATION="false"
# A list of refused authentification methods.
REFUSED_AUTH_METHODS=""
function hook_check() {
assert isset USERNAME
assert isset PASSWORD
assert isset PEER_ADDRESS
assert isset IPV6
assert isset PREFIX_DELEGATION
# Check for valid port and IP settings.
if isset PORT; then
assert isset DHCP
# Check if port exists.
assert port_exists ${PORT}
# Check for valid interface address.
assert isset INTERFACE_ADDRESS
if ! ipv4_is_valid "${INTERFACE_ADDRESS}"; then
log ERROR "Invalid interface address. Please use a valid IPv4 address."
return ${EXIT_ERROR}
fi
# Check for a valid network prefix.
assert isinteger PREFIX
if [ ${PREFIX} -gt 30 ]; then
error "PREFIX is greater than 30."
exit ${EXIT_ERROR}
fi
fi
# Check if the peer-address is valid.
if ! ipv4_is_valid "${PEER_ADDRESS}"; then
log ERROR "Invalid peer-address. Please use a valid IPv4 address."
return ${EXIT_ERROR}
fi
# Check if a supported AUTH Mechanism has been given.
isset AUTH && assert isoneof AUTH ${PPP_SUPPORTED_AUTH_METHODS}
}
function hook_parse_cmdline() {
while [ $# -gt 0 ]; do
case "${1}" in
--auth=*)
AUTH="$(cli_get_val ${1})"
;;
--interface-address=*)
INTERFACE_ADDRESS="$(cli_get_val ${1})"
;;
--ipv6=*)
local value="$(cli_get_val "${1}")"
if enabled value; then
IPV6="true"
else
IPV6="false"
fi
;;
--mtu=*)
MTU="$(cli_get_val ${1})"
;;
--password=*)
PASSWORD="$(cli_get_val ${1})"
;;
--peer-address=*)
PEER_ADDRESS="$(cli_get_val ${1})"
;;
--port=*)
PORT="$(cli_get_val ${1})"
;;
--prefix=*)
PREFIX="$(cli_get_val ${1})"
;;
--prefix-delegation=*)
local value="$(cli_get_val "${1}")"
if enabled value; then
PREFIX_DELEGATION="true"
else
PREFIX_DELEGATION="false"
fi
;;
--refuse-auth-methods=*)
REFUSED_AUTH_METHODS="$(cli_get_val ${1})"
;;
--username=*)
USERNAME="$(cli_get_val ${1})"
;;
--use-dhcp=*)
local value="$(cli_get_val "${1}")"
if enabled value; then
USE_DHCP="true"
else
USE_DHCP="false"
fi
;;
*)
warning "Unknown argument: ${1}" >&2
;;
esac
shift
done
}
function hook_up() {
local zone="${1}"
assert isset zone
zone_config_read "${zone}"
# Check if a port will be used.
if isset PORT; then
# Bring up the port.
log DEBUG "Bringing up port '${PORT}'."
port_up "${PORT}"
# Check if DHCP will be used, or a static IP has been configured.
if enabled USE_DHCP; then
# Start dhclient for IPv4 on this zone.
dhclient_start "${PORT}" "ipv4"
else
# Add ip address and network prefix.
ip_address_add "${PORT}" "${INTERFACE_ADDRESS}"/"${PREFIX}"
fi
fi
# Start the ppp daemon.
pppd_start "${zone}"
exit ${EXIT_OK}
}
function hook_down() {
local zone="${1}"
assert isset zone
zone_config_read "${zone}"
# Stop the ppp daemon.
pppd_stop "${zone}"
# Check if a port has been used.
if isset PORT; then
# Stop DHCP-Client or remove static IP address.
if enabled USE_DHCP; then
# Stop dhclient for IPv4 on this zone.
dhclient_stop "${PORT}" "ipv4"
else
# Remove address from interface.
ip_address_del "${PORT}" "${INTERFACE_ADDRESS}"/"${PREFIX}"
fi
# Bring down the port.
log DEBUG "Bringing down port '${PORT}'."
port_down "${PORT}"
fi
exit ${EXIT_OK}
}
function hook_status() {
local zone="${1}"
assert isset zone
cli_device_headline "${zone}"
zone_config_read "${zone}"
# Display port configuration if a port is used.
if isset PORT; then
cli_headline 2 "Configuration"
cli_print_fmt1 2 "IP Address" "${INTERFACE_ADDRESS}"/"${PREFIX}"
cli_print_fmt1 2 "Peer Address" "${PEER_ADDRESS}"
cli_print_fmt1 2 "Port" "${PORT}"
cli_space
fi
cli_headline 2 "Dialin Information"
cli_print_fmt1 2 "Username" "${USERNAME}"
cli_print_fmt1 2 "Password" ""
cli_space
# Exit if zone is down
if ! zone_is_up ${zone}; then
echo # Empty line
exit ${EXIT_ERROR}
fi
cli_headline 2 "Point-to-Point-Tunneling protocol"
local proto
for proto in ${IP_SUPPORTED_PROTOCOLS}; do
routing_db_exists ${zone} ${proto} || continue
local headline
case "${proto}" in
ipv6)
headline="Internet Protocol Version 6"
;;
ipv4)
headline="Internet Protocol Version 4"
;;
*)
headline="Unkown protocol"
;;
esac
cli_headline 3 "${headline}"
cli_print_fmt1 3 "IP address" "$(routing_db_get "${zone}" "${proto}" "local-ip-address")"
cli_print_fmt1 3 "Gateway" "$(routing_db_get "${zone}" "${proto}" "remote-ip-address")"
cli_print_fmt1 3 "DNS servers" "$(routing_db_get "${zone}" "${proto}" "dns")"
cli_space
done
exit ${EXIT_OK}
}
function hook_ppp_write_config() {
local zone="${1}"
assert isset zone
local file="${2}"
assert isset file
# Read in the configuration files.
zone_config_read "${zone}"
# Prepare the command line options for the pptp plugin.
local pptp_commandline="pptp ${PEER_ADDRESS} --nolaunchpppd"
pppd_write_config ${file} \
--interface="${zone}" \
--username="${USERNAME}" \
--password="${PASSWORD}" \
--mtu="${MTU}" \
--auth="${AUTH}" \
--pty="${pptp_commandline}" \
--ipv6="${IPV6}" \
--refuse="${REFUSED_AUTH_METHODS}"
exit ${EXIT_OK}
}