#!/bin/sh
#
# Copyright (c) 2006 David Bird <david@coova.com>
# Licensed under GPL. See http://coova.org/
#

IPTABLES="/sbin/iptables"
IFCONFIG="/sbin/ifconfig"
ARPCHECK=$RUN_D/chilli.arp
LKFILE=$RUN_D/chilli.run
MAIN_CONF=/etc/chilli/main.conf
LOCAL_CONF=/etc/chilli/local.conf
HS_CONF=/etc/chilli/hs.conf
HS_TEMP=/tmp/hs.conf
RUN_D=/var/run
CMDSOCK=$RUN_D/chilli.sock
PIDFILE=$RUN_D/chilli.pid

[ -f /etc/chilli/defaults ] \
    && . /etc/chilli/defaults

[ -f /etc/sysconfig/chilli ] \
    && . /etc/sysconfig/chilli

HS_UAMPORT=${HS_UAMPORT:-3990}
HS_RADIUS=${HS_RADIUS:-$HS_UAMSERVER}
HS_RADSECRET=${HS_RADSECRET:-$HS_UAMSECRET}
HS_RADAUTH=${HS_RADAUTH:-1812}
HS_RADACCT=${HS_RADACCT=1813}
HS_ADMUSR=${HS_ADMUSR:-chillispot}
HS_ADMPWD=${HS_ADMPWD:-chillispot}
HS_ADMINTERVAL=${HS_ADMINTERVAL:-60}

HS_RADCONF=${HS_RADCONF:-on}
HS_RADCONF_SERVER=${HS_RADCONF_SERVER:-rad01.coova.org}
HS_RADCONF_SERVERS=${HS_RADCONF_SERVERS:+$(echo "$HS_RADCONF_SERVERS"|sed 's/[;, ]/ /g')}
HS_RADCONF_SECRET=${HS_RADCONF_SECRET:-coova-anonymous}
HS_RADCONF_AUTHPORT=${HS_RADCONF_AUTHPORT:-1812}
HS_RADCONF_ACCTPORT=${HS_RADCONF_ACCTPORT:-1813}
HS_RADCONF_USER=${HS_RADCONF_USER:-coovachilli}
HS_RADCONF_PWD=${HS_RADCONF_PWD:-coovachilli}
HS_DNS_DOMAIN=${HS_DNS_DOMAIN:-lan}
HS_MACAUTHMODE=${HS_MACAUTHMODE:-local}
HS_USELOCALUSERS=${HS_USELOCALUSERS:-off}

bailout() { echo $1; exit; }

check_required() {
    [ -z "$HS_MODE" ]  && bailout "HS_MODE is required"
    [ -z "$HS_NASID" ] && bailout "HS_NASID is required"
    [ -z "$HS_NETWORK"   -o -z "$HS_NETMASK"   ] && bailout "HS_NETWORK and HS_NETMASK are required"
    [ -z "$HS_UAMLISTEN" ] && bailout "HS_UAMLISTEN is required"
}
    
configs1=
addconfig1() { [ -n "$*" ] && configs1="$configs1
$*"; }
configs2=
addconfig2() { [ -n "$*" ] && configs2="$configs2
$*"; }

writeconfig() {
    [ "$HS_ANYIP" = "on" ] && {
	addconfig1 "uamanyip"
	HS_STATIP=${HS_STATIP:-"192.168.0.0"}
    }
    addconfig1 ${HS_DYNIP:+"dynip $HS_DYNIP/${HS_DYNIP_MASK:-255.255.255.0}"}
    addconfig1 ${HS_STATIP:+"statip $HS_STATIP/${HS_STATIP_MASK:-255.255.255.0}"}
    addconfig1 ${HS_SSID:+"ssid $HS_SSID"}
    addconfig1 ${HS_NASIP:+"nasip $HS_NASIP"}
    addconfig1 ${HS_NASMAC:+"nasmac $HS_NASMAC"}
    addconfig1 ${HS_DNS_DOMAIN:+"domain $HS_DNS_DOMAIN"}
    addconfig1 ${HS_DNS1:+"dns1 $HS_DNS1"}
    addconfig1 ${HS_DNS2:+"dns2 $HS_DNS2"}

    addconfig1 ${HS_UAMHOMEPAGE:+"uamhomepage $(eval echo $HS_UAMHOMEPAGE)"}
    addconfig1 ${HS_WWWDIR:+"wwwdir $HS_WWWDIR"}

    HS_MACALLOW=$(echo $HS_MACALLOW|sed 's/ /,/g')
    HS_MACALLOW=$(echo $HS_MACALLOW|sed 's/[:-]//g')
    addconfig1 ${HS_MACALLOW:+"macallowed $HS_MACALLOW"}

    HS_UAMALLOW=$(echo $HS_UAMALLOW|sed 's/ /,/g')
    uamallow=${HS_UAMALLOW:+",$HS_UAMALLOW"}

    [ "$HS_WEB_ADMIN" = "http"  ] || [ "$HS_WEB_ADMIN" = "both" ] && webadmin="$webadmin,$HS_UAMLISTEN:80"
    [ "$HS_WEB_ADMIN" = "https" ] || [ "$HS_WEB_ADMIN" = "both" ] && webadmin="$webadmin,$HS_UAMLISTEN:443"
    [ "$HS_LOCAL" = "on" ] && webadmin="$webadmin,$HS_UAMLISTEN:3443"
    [ "$HS_MACAUTHMODE" = "local" ] && addconfig1 "macallowlocal"
    [ "$HS_PAP_OK" = "on" ] && addconfig1 "papalwaysok"
    [ "$HS_USELOCALUSERS" = "on" ] && {
	touch /etc/chilli/localusers
	addconfig1 "localusers /etc/chilli/localusers"
    }

    [ -n "$HS_LOC_NAME" ] && {
	isocc=$(echo    "$HS_LOC_ISOCC"  | sed 's/[^a-zA-Z]//g')
	cc=$(echo       "$HS_LOC_CC"     | sed 's/[^0-9]//g')
	ac=$(echo       "$HS_LOC_AC"     | sed 's/[^0-9]//g')
	network=$(echo  "$HS_LOC_NETWORK"| sed 's/[^a-zA-Z0-9]/_/g')
	provider=$(echo "$HS_PROVIDER"   | sed 's/[^a-zA-Z0-9]/_/g')
	[ -n "$provider" ] && provider="$provider,"
	[ -n "$HS_SSID" ] && { 
	    [ -n "$network" ] && network="${network}_"
	    network="$network$HS_SSID"
	}
	loc_name=$(echo "$HS_LOC_NAME"   | sed 's/[^a-zA-Z0-9]/_/g')
	loc_id="isocc=$isocc,cc=$cc,ac=$ac,network=$provider$network"
	addconfig1 "radiuslocationname $loc_name"
	addconfig1 "radiuslocationid $loc_id"
    }

    # Application walled garden entries:
    [ "$HS_USE_MAP" = "on" ] && addconfig1 "uamallowed www.google.com,maps.google.com,mt.google.com,kh.google.com,labs.google.com"

    (cat <<EOF
# THIS FILE IS AUTOMATICALLY GENERATED
cmdsocket       $CMDSOCK
pidfile         $PIDFILE
net		$HS_NETWORK/$HS_NETMASK
uamlisten	$HS_UAMLISTEN
uamport         $HS_UAMPORT
dhcpif		$HS_TAPIF
adminuser       $HS_ADMUSR
adminpasswd     $HS_ADMPWD
uamallowed	coova.org,$HS_UAMSERVER,$HS_RADIUS$webadmin$uamallow
uamanydns
$configs1
EOF
    ) > $MAIN_CONF 
    if [ "x$HS_RADCONF" != "xon" -a "x$HS_RADCONF" != "xurl" ]; then 
	rm -f $HS_CONF 2>/dev/null

	[ "$HS_MACAUTH" = "on" ] && addconfig2 "macauth"
	[ -n "$HS_POSTAUTH_PROXY" -a -n "$HS_POSTAUTH_PROXYPORT" ] && {
	    addconfig2 "postauthproxy $HS_POSTAUTH_PROXY"
	    addconfig2 "postauthproxyport $HS_POSTAUTH_PROXYPORT"
	}

	(cat <<EOF
radiusserver1	$HS_RADIUS
radiusserver2	$HS_UAMSERVER
radiussecret	$HS_RADSECRET
radiusauthport  $HS_RADAUTH
radiusacctport  $HS_RADACCT
uamserver	$(eval echo $HS_UAMFORMAT)
radiusnasid	$HS_NASID
uamsecret	$HS_UAMSECRET
$configs2
EOF
	) >> $MAIN_CONF 
    fi
}

checkfornew() {
    if [ -x /usr/bin/cmp ]; then
	cmp -s $HS_TEMP $HS_CONF || (
	    mv $HS_TEMP $HS_CONF
	    killall -HUP chilli 2>/dev/null >/dev/null
	)
    else
        # no diff, so lets copy and let chilli
        # refresh on its own (interval option)
	mv $HS_TEMP $HS_CONF
    fi
}

radiusconfig() {
    touch $LOCAL_CONF $HS_CONF 
    if [ "x$HS_RADCONF" = "xurl" ]; then 
	for s in "$HS_RADCONF_URL $HS_RADCONF_URLS"; do
	    sep='?'
	    opt=
	    qs="config=chilli&mac=$HS_NASMAC&nasid=$HS_NASID&nasip=$HS_NASIP&ssid=$HS_SSID"
	    [ "$s" = "$(echo $s|awk -F'?' '{ print $1 }')" ] || sep='&'
	    [ "$HS_RADCONF_USER" = "" ] || opt="-u '$HS_RADCONF_USER:$HS_RADCONF_PWD'"
	    curl -k -A CoovaAP $opt "$s$sep$qs" 2>/dev/null > $HS_TEMP && { checkfornew; break; }
	done
    elif [ "x$HS_RADCONF" = "xon" ]; then 
	for s in "$HS_RADCONF_SERVER $HS_RADCONF_SERVERS"; do
	    chilli_radconfig \
		-c /dev/null \
		--radiusserver1="$HS_RADCONF_SERVER" \
		--radiussecret="$HS_RADCONF_SECRET" \
		--radiusauthport="$HS_RADCONF_AUTHPORT" \
		--radiusacctport="$HS_RADCONF_ACCTPORT" \
		--adminuser="$HS_RADCONF_USER" \
		--adminpasswd="$HS_RADCONF_PWD" \
		> $HS_TEMP && {	checkfornew; break; }
	done
    else
	chilli_radconfig > $HS_TEMP && { checkfornew; break; }
    fi
}

