#!/bin/sh
# html2pager - version 0.1
#
# Copyright (C) 2006, Jeremy Laidman
# under the GNU General Public License.
# For details: http://www.gnu.org/licenses/gpl.txt
#
# a web interface to gnokii, written in bourne shell, cos we know it's there
# assumes we're being run from (x)inetd, doesn't work as CGI (yet)
# Todo:
# - ensure we can't be compromised by dodgy characters
# - some degree of logging
# - authentication
# Bugs, problems, caveats:
# - there are probably some bash-ism
#------------------------------------------------------------#
FORMFILE=`dirname $0`/"pager.html"
GNOKII=/usr/local/gnokii/bin/gnokii
#------------------------------------------------------------#
# default form if FORMFILE doesn't exist
FORM='
Pager Form
Pager Form
'
#------------------------------------------------------------#
die() {
while [ $# -gt 0 ]; do
echo "$1"
shift
done
exit 0
}
cleanread() {
read -t30 L
( IFS="
"; set - $L; echo $1 )
unset L
}
split() {
# give me names of var and val global variables
# and a separator string
# and a string of the form "bla=moo"
# and I'll set VAR=bla and VAL=moo
L_VAR1=$1
L_VAR2=$2
L_SEP=$3
L_STRING=$4
#echo "STR=$L_STRING"
#echo "LHS="${L_STRING%%=*}
#echo "RHS="${L_STRING#?*=}
# these barf on some chars (eg single quotes) so we just ignore
eval $L_VAR1=${L_STRING%%=*} 2>/dev/null
eval $L_VAR2=${L_STRING#?*=} 2>/dev/null
#echo "VAL is $VAL"
}
send_message() {
# run gnokii and send the message
# return error message, or blank if OK
NUM=$1
MSG=$2
echo "$MSG" | $GNOKII --sendsms "$NUM" 2>&1
RC=$?
case $RC in
0) :;; # all OK, no return
1) echo "Run failed ";; # gnokii failed, will have error already
127) echo "Exec failed";;
*) echo "Unexpected error: $RC";;
esac
# returns empty on failure
}
#------------------------------------------------------------#
REQUEST=`cleanread`
set - $REQUEST
if [ $# -lt 2 -o $# -gt 3 ]; then
die "HTTP/1.0 501 badly formatted request [$REQUEST]"
fi
if [ $# -eq 2 ]; then
die "HTTP/1.0 505 HTTP version 0.9 unsupported"
fi
TYPE="$1"
URI="$2"
VER="$3"
if [ "$VER" != "HTTP/1.0" -a "$VER" != "HTTP/1.1" ]; then
die "HTTP/1.0 505 HTTP Version $VER unsupported"
fi
case $TYPE in
[Gg][Ee][Tt]) TYPE="GET";;
[Pp][Uu][Tt]) TYPE="PUT";;
[Pp][Oo][Ss][Tt]) TYPE="POST";;
[Hh][Ee][Aa][Dd]) TYPE="HEAD";;
*) die "HTTP/1.0 500 Method $TYPE not supported"
esac
if [ "$TYPE" != "GET" -a "$TYPE" != "HEAD" ]; then
die "HTTP/1.0 501 Method $TYPE not supported"
fi
# need to get rest of the lines until newline
LINE=`cleanread`
LINE=`echo $LINE`
while [ "$LINE" ]; do
# we have a header
LINE=`cleanread`
done
# extract info from URI, note that this breaks with an empty var=val section
IFSSAVE="$IFS"
IFS='?&'
set - $URI
IFS="$IFSSAVE"
shift # get past the "?"
LINE="$1"
while [ "$LINE" ]; do
# some escaping to protect us
LINE=${LINE//\"/%22}
LINE=${LINE//\&/%26}
LINE=${LINE//\'/%27}
LINE=${LINE//\(/%28}
LINE=${LINE//\)/%29}
LINE=${LINE//\;/%3b}
LINE=${LINE//\\/%5c} # unlikely to ever get this
split "VAR" "VAL" "=" $LINE
case $VAR in
number) NUMBER=$VAL;;
message) MESSAGE=$VAL;;
debug) DEBUG=$VAL;;
esac
shift
LINE=$1
done
# + and , don't need escaping for later on, so we turn them back
# now to let the cleanup work
NUMBER=${NUMBER//\%2[bB]/+}
NUMBER=${NUMBER//\%2[cC]/,}
NUMBER=${NUMBER//[^,+0-9]/} # strip non-numerics but not + or ,
if [ ! "$NUMBER" -o ! "$MESSAGE" ]; then
if [ -f $FORMFILE ]; then
cat $FORMFILE
exit
else
if [ "$FORM" ]; then
echo "$FORM"
else
die "HTTP/1.0 501 Number or message not specified" \
"" \
"Please specify number=nnn and message=text"
fi
fi
exit
fi
# present results
echo "HTTP/1.0 200 OK"
echo "Content-type: text/plain"
echo ""
[ "$TYPE" = "HEAD" ] && exit
if [ "$DEBUG" ]; then
echo "Debug mode on"
echo "Requested $TYPE on $URI"
echo "Number: $NUMBER"
echo "Message: $MESSAGE"
fi
# clean up message containing escapes
NL="
"
MESSAGE=${MESSAGE//\%0[dD]%0[aA]/$NL}
MESSAGE=${MESSAGE//\%0[dDaA]/$NL}
MESSAGE=${MESSAGE//\%20/\ }
MESSAGE=${MESSAGE//\%21/\!}
MESSAGE=${MESSAGE//\%22/\"} # may need to escape the quote
MESSAGE=${MESSAGE//\%23/\#}
MESSAGE=${MESSAGE//\%24/\$}
MESSAGE=${MESSAGE//\%25/\%}
MESSAGE=${MESSAGE//\%26/\&}
MESSAGE=${MESSAGE//\%27/\'}
MESSAGE=${MESSAGE//\%28/\(}
MESSAGE=${MESSAGE//\%29/\)}
MESSAGE=${MESSAGE//\%2[aA]/*}
MESSAGE=${MESSAGE//\%2[bB]/+}
MESSAGE=${MESSAGE//\%2[cC]/,}
MESSAGE=${MESSAGE//\%2[dD]/-}
MESSAGE=${MESSAGE//\%2[eE]/\.}
MESSAGE=${MESSAGE//\%2[fF]/\/}
MESSAGE=${MESSAGE//\%30/0}
MESSAGE=${MESSAGE//\%31/1}
MESSAGE=${MESSAGE//\%32/2}
MESSAGE=${MESSAGE//\%33/3}
MESSAGE=${MESSAGE//\%34/4}
MESSAGE=${MESSAGE//\%35/5}
MESSAGE=${MESSAGE//\%36/6}
MESSAGE=${MESSAGE//\%37/7}
MESSAGE=${MESSAGE//\%38/8}
MESSAGE=${MESSAGE//\%39/9}
MESSAGE=${MESSAGE//\%3[aA]/:}
MESSAGE=${MESSAGE//\%3[bB]/;}
MESSAGE=${MESSAGE//\%3[cC]/<}
MESSAGE=${MESSAGE//\%3[dD]/=}
MESSAGE=${MESSAGE//\%3[eE]/>}
MESSAGE=${MESSAGE//\%3[fF]/?}
MESSAGE=${MESSAGE//\%40/@}
MESSAGE=${MESSAGE//\%5[bB]/\[}
MESSAGE=${MESSAGE//\%5[cC]/\\} # perhaps this is a bad idea
MESSAGE=${MESSAGE//\%5[dD]/\]}
MESSAGE=${MESSAGE//\%5[eE]/\^}
MESSAGE=${MESSAGE//\%5[fF]/\_}
MESSAGE=${MESSAGE//\%60/\`}
MESSAGE=${MESSAGE//\%7[bB]/\{}
MESSAGE=${MESSAGE//\%7[cC]/\|}
MESSAGE=${MESSAGE//\%7[dD]/\}}
MESSAGE=${MESSAGE//\%7[eE]/\~}
echo "$MESSAGE" >/tmp/bla
RESULT=`send_message $NUMBER $MESSAGE`
if [ "$RESULT" ]; then
echo "FAILED"
echo "$RESULT"
echo "NUMBER=[$NUMBER]"
echo "MESSAGE=[$MESSAGE]"
else
echo "OK"
fi