#!/bin/sh
daemon=lighttpd
PATH=$PATH:/sbin
boot_mode=`pibinfo BootMode`
#DEFINE_SETUPDCASUTH
if [ "$setup_dcsauth" = "" ]; then
setup_dcsauth=no
fi
Server_Enabled=$(tdb get HTTPServer Enable_byte)
if [ $boot_mode = "normal" ] && [ $Server_Enabled -eq "0" ]; then
exit 0
fi
method=digest
die() {
echo $@
exit 1
}
showUsage() {
die "$0 {start|stop|restart|status} [prefix]"
}
dumpAccountKey() {
echo -n "\
AdminUser_ss
AdminPasswd_ss
LiveAuth_byte
SnapAuth_byte
User1_ss
Password1_ss
User2_ss
Password2_ss
User3_ss
Password3_ss
User4_ss
Password4_ss
User5_ss
Password5_ss
User6_ss
Password6_ss
User7_ss
Password7_ss
User8_ss
Password8_ss
User9_ss
Password9_ss
User10_ss
Password10_ss
User11_ss
Password11_ss
User12_ss
Password12_ss
User13_ss
Password13_ss
User14_ss
Password14_ss
User15_ss
Password15_ss
User16_ss
Password16_ss
User17_ss
Password17_ss
User18_ss
Password18_ss
User19_ss
Password19_ss
User20_ss
Password20_ss
Operator1_ss
OperatorPwd1_ss
Operator2_ss
OperatorPwd2_ss
Operator3_ss
OperatorPwd3_ss
Operator4_ss
OperatorPwd4_ss
Operator5_ss
OperatorPwd5_ss
"
}
md5hex() {
echo -n "$1" | md5sum | cut -b -32
}
##### setupUsers() and createCredentials() #####
# create the user credentials for authentication
##########
setupUser() {
cat >> /tmp/lighttpd-htdigest.user << EOM
$1:$mac_realm:$(md5hex "$1:$mac_realm:$2")
$1:nipca:$(md5hex "$1:nipca:$2")
$1:onvif:$(md5hex "$1:onvif:$2")
EOM
}
createCredentials() {
(
flock 200
[ -e "/tmp/lighttpd-htdigest.user" ] && rm -f /tmp/lighttpd-htdigest.user
touch /tmp/lighttpd-htdigest.user
setupUser "$AdminUser_ss" "$AdminPasswd_ss"
[ "$User1_ss" != "" ] && setupUser "$User1_ss" "$Password1_ss"
[ "$User2_ss" != "" ] && setupUser "$User2_ss" "$Password2_ss"
[ "$User3_ss" != "" ] && setupUser "$User3_ss" "$Password3_ss"
[ "$User4_ss" != "" ] && setupUser "$User4_ss" "$Password4_ss"
[ "$User5_ss" != "" ] && setupUser "$User5_ss" "$Password5_ss"
[ "$User6_ss" != "" ] && setupUser "$User6_ss" "$Password6_ss"
[ "$User7_ss" != "" ] && setupUser "$User7_ss" "$Password7_ss"
[ "$User8_ss" != "" ] && setupUser "$User8_ss" "$Password8_ss"
[ "$User9_ss" != "" ] && setupUser "$User9_ss" "$Password9_ss"
[ "$User10_ss" != "" ] && setupUser "$User10_ss" "$Password10_ss"
[ "$User11_ss" != "" ] && setupUser "$User11_ss" "$Password11_ss"
[ "$User12_ss" != "" ] && setupUser "$User12_ss" "$Password12_ss"
[ "$User13_ss" != "" ] && setupUser "$User13_ss" "$Password13_ss"
[ "$User14_ss" != "" ] && setupUser "$User14_ss" "$Password14_ss"
[ "$User15_ss" != "" ] && setupUser "$User15_ss" "$Password15_ss"
[ "$User16_ss" != "" ] && setupUser "$User16_ss" "$Password16_ss"
[ "$User17_ss" != "" ] && setupUser "$User17_ss" "$Password17_ss"
[ "$User18_ss" != "" ] && setupUser "$User18_ss" "$Password18_ss"
[ "$User19_ss" != "" ] && setupUser "$User19_ss" "$Password19_ss"
[ "$User20_ss" != "" ] && setupUser "$User20_ss" "$Password20_ss"
[ "$Operator1_ss" != "" ] && setupUser "$Operator1_ss" "$OperatorPwd1_ss"
[ "$Operator2_ss" != "" ] && setupUser "$Operator2_ss" "$OperatorPwd2_ss"
[ "$Operator3_ss" != "" ] && setupUser "$Operator3_ss" "$OperatorPwd3_ss"
[ "$Operator4_ss" != "" ] && setupUser "$Operator4_ss" "$OperatorPwd4_ss"
[ "$Operator5_ss" != "" ] && setupUser "$Operator5_ss" "$OperatorPwd5_ss"
) 200>/tmp/lock.1
}
##### setupSnapAuth() #####
# setup mod_auth rules depend on SnapAuth_byte
# In the past, user can choice to enable Snapshot auth or not on UI.
# SnapAuth_byte is the flag to control this function.
# Although this function is removed from UI and SnapAuth_byte always equal 1, lighttpd is still keep this flag.
##########
setupSnapAuth() {
# snap auth
if [ "$SnapAuth_byte" -eq 1 ]; then
cat << EOM
\$HTTP["url"] =~ "^/image2/" {
auth.require = ( "" =>
(
"method" => "digest",
"realm" => "$mac_realm",
"require" => "valid-user"
)
)
}
EOM
fi
}
# setup the www config if you want using dcsauth
setupDcsAuthConfig()
{
if [ "$setup_dcsauth" = "yes" ]; then
cat << EOM
\$HTTP["url"] =~ "^/(video|audio|dev|dev2|volumes|image|users|ptz|config)/" {
dcsauth.require = "enable"
}
\$HTTP["url"] =~ "^/cgi/admin/(adv_snapshot_cont.cgi|videoclip.cgi|recorder.cgi|adv_do.cgi)|^/cgi/ptdc.cgi" {
dcsauth.require = "enable"
}
\$HTTP["url"] =~ "^/cgi/" {
\$HTTP["url"] !~ "^/cgi/admin/(adv_snapshot_cont.cgi|videoclip.cgi|recorder.cgi|adv_do.cgi)|^/cgi/ptdc.cgi" {
auth.require = ( "" =>
(
"method" => "$method",
"realm" => "$mac_realm",
"require" => "valid-user"
)
)
}
}
EOM
fi
}
# setup the www config which not using dcs auth
setupNormalAuthConfig()
{
if [ "$setup_dcsauth" = "no" ]; then
cat << EOM
\$HTTP["url"] =~ "^/(video|audio|dev|dev2|volumes|image|cgi)/" {
auth.require = ( "" =>
(
"method" => "$method",
"realm" => "$mac_realm",
"require" => "valid-user"
)
)
}
\$HTTP["url"] =~ "^/(users|ptz|config)/" {
auth.require = ( "" =>
(
"method" => "$method",
"realm" => "nipca",
"require" => "valid-user"
)
)
}
EOM
fi
}
##### setupLiveAuth() #####
# setup mod_auth rules depend on LiveAuth_byte
# In the past, user can choice to enable live auth or not on UI.
# LiveAuth_byte is the flag to control this function.
# Although this function is removed from UI and LiveAuth_byte always equal 1, lighttpd is still keep this flag.
##########
setupLiveAuth() {
if [ "$LiveAuth_byte" -eq 1 ]; then
setupSnapAuth
cat << EOM
\$HTTP["url"] =~ "^/(av2|event2|m|play2|volumes2|dev3|directview|$lighttpd_lang)/" {
auth.require = ( "" =>
(
"method" => "$method",
"realm" => "$mac_realm",
"require" => "valid-user"
)
)
}
\$HTTP["url"] =~ "^/wss" {
auth.require = ( "" =>
(
"method" => "$method",
"realm" => "$mac_realm",
"require" => "valid-user"
)
)
}
\$HTTP["url"] =~ "^/vaview.htm" {
auth.require = ( "" =>
(
"method" => "$method",
"realm" => "$mac_realm",
"require" => "valid-user"
)
)
}
\$HTTP["url"] =~ "^/vjview.htm" {
auth.require = ( "" =>
(
"method" => "$method",
"realm" => "$mac_realm",
"require" => "valid-user"
)
)
}
EOM
fi
}
##### setupAuthRules() #####
# setupAuthRules (old name is setupAuth) is a function to setup realm and http auth method for each folders
# The folders not display here means user can access them without any authentication.
# you can check mod_auth to get more info
##########
setupAuthRules() {
lighttpd_lang="eng|cht|chn|de|es|it|fr|pt"
# write rule that enable/disable by tdb config here
setupLiveAuth
setupNormalAuthConfig
setupDcsAuthConfig
# write rule that always need auth here
cat << EOM
\$HTTP["url"] =~ "^/onvif/" {
auth.require = ( "" =>
(
"method" => "digest",
"realm" => "onvif",
"require" => "valid-user"
)
)
}
\$HTTP["url"] !~ "^/cgi/" {
\$HTTP["url"] =~ "^/(.*/admin/|auth/|.*/mainFrame.cgi)" {
auth.require = ( "" =>
(
"method" => "$method",
"realm" => "$mac_realm",
"require" => "user=$AdminUser_ss"
)
)
}
}
EOM
}
config_http_https() {
# set http and https base info here
echo "server.port = $HttpPort_num" >> /tmp/lighttpd-inc.conf
if [ -e "/tmp/server.pem" ]; then
cat >> /tmp/lighttpd-inc.conf << EOM
# setup https for ipv4
\$SERVER["socket"] == ":$HttpsPort_num" {
ssl.engine = "enable"
ssl.pemfile = "/tmp/server.pem"
ssl.use-sslv2 = "disable"
ssl.use-sslv3 = "disable"
ssl.cipher-list = "RC4-MD5 RC4-SHA AES128-SHA AES256-SHA DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DES-CBC3-SHA"
}
EOM
else
echo "https pem doesn't exist."
fi
}
config_http_only() {
# set redirect rule for Http only here
# rewrite rule will redirect https link to http
if [ "$SSLEnable_b" = "0" ] ; then
if [ "$HttpsPort_num" = "443" ]; then
echo -n '$HTTP["scheme"] == "https" {
$HTTP["host"] =~ ".*" {
url.redirect = (".*" => "http://%0' >> /tmp/lighttpd-inc.conf
echo -n ":$HttpPort_num" >> /tmp/lighttpd-inc.conf
echo '$0")
}
}' >> /tmp/lighttpd-inc.conf
else
echo -n '$HTTP["scheme"] == "https" {
$HTTP["host"] =~ "(.*)(\:[0-9]*)$" {
url.redirect = (".*" => "http://%1' >> /tmp/lighttpd-inc.conf
echo -n ":$HttpPort_num" >> /tmp/lighttpd-inc.conf
echo '$0")
}
}' >> /tmp/lighttpd-inc.conf
fi
fi
}
config_https_only() {
# set redirect rule for Https only here
# rewrite rule will redirect http link to https
if [ "$SSLEnable_b" = "2" ] ; then
if [ "$HttpPort_num" != "80" ]; then
echo -n '$HTTP["scheme"] == "http" {
$HTTP["url"] !~ "^/(video|audio|image|common|users|config)/|cgi/web_event.cgi|cgi/eventstream.cgi" {
$HTTP["host"] =~ "(.*)(\:[0-9]*)$" {
url.redirect = (".*" => "https://%1' >> /tmp/lighttpd-inc.conf
echo -n ":$HttpsPort_num" >> /tmp/lighttpd-inc.conf
echo '$0")
}
}
}' >> /tmp/lighttpd-inc.conf
else
echo -n '$HTTP["scheme"] == "http" {
$HTTP["url"] !~ "^/(video|audio|image|common|users|config)/|cgi/web_event.cgi|cgi/eventstream.cgi" {
$HTTP["host"] =~ ".*" {
url.redirect = (".*" => "https://%0' >> /tmp/lighttpd-inc.conf
echo -n ":$HttpsPort_num" >> /tmp/lighttpd-inc.conf
echo '$0")
}
}
}' >> /tmp/lighttpd-inc.conf
fi
fi
}
config_ipv6() {
# echo "server.use-ipv6 = \"enable\"" >> /tmp/lighttpd-inc.conf
if [ $IPv6_Enabled -eq "1" ]; then
cat >> /tmp/lighttpd-inc.conf << EOM
\$SERVER["socket"] == "[::]:$HttpPort_num" {server.use-ipv6 = "enable"}
EOM
if [ -e "/tmp/server.pem" ]; then
cat >> /tmp/lighttpd-inc.conf << EOM
# setup https for ipv6
\$SERVER["socket"] == "[::]:$HttpsPort_num" {
ssl.engine = "enable"
server.use-ipv6 = "enable"
ssl.pemfile = "/tmp/server.pem"
ssl.use-sslv2 = "disable"
ssl.use-sslv3 = "disable"
ssl.cipher-list = "RC4-MD5 RC4-SHA AES128-SHA AES256-SHA DHE-RSA-AES128-SHA DHE-RSA-AES256-SHA DES-CBC3-SHA"
}
EOM
fi # /tmp/server.pem exist
fi
}
config_ecr_client() {
[ -f "/sbin/ecr_client" ] && \
echo "server.max-keep-alive-requests = 128" >> /tmp/lighttpd-inc.conf && \
echo "server.max-keep-alive-idle = 30" >> /tmp/lighttpd-inc.conf && \
echo "server.max-read-idle = 60" >> /tmp/lighttpd-inc.conf && \
echo "server.max-write-idle = 360" >> /tmp/lighttpd-inc.conf
}
config_auth() {
createCredentials
setupAuthRules >> /tmp/lighttpd-inc.conf
echo "auth.require.accept.provision = $(admin-accept)" >> /tmp/lighttpd-inc.conf
echo "auth.require.accept.url = \"/auth/\"" >> /tmp/lighttpd-inc.conf
echo "auth.require.accept.pattern = \"\/auth\/.*|\/config\/user_mod.cgi\"" >> /tmp/lighttpd-inc.conf
}
start() {
! pids=$(pidof $daemon) || die "$daemon($pids) is already running."
echo -n "Startting $daemon... "
[ -x $binary ] || die "$binary is not a valid application"
export LD_LIBRARY_PATH=$prefix/lib
export PREFIX=$prefix
##### read config and set variable here #####
eval $(dumpAccountKey | tdb get HTTPAccount)
HttpPort_num=$(tdb get HTTPServer Port_num)
[ "$HttpPort_num" != "" ] || HttpPort_num=80
HttpsPort_num=$(tdb get HTTPServer HTTPSPort_num)
[ "$HttpsPort_num" != "" ] || HttpsPort_num=443
SSLEnable_b=$(tdb get HTTPS Enable_byte)
IPv6_Enabled=$(tdb get IPv6 Enable_byte)
model=$( [ $(pibinfo Wireless) -eq 1 ] && tdb get System ModelW_ss || tdb get System Model_ss )
mac_realm="${model}_$(pibinfo MacAddress | cut -b 16-17)"
##### read config end #####
##### create and setup dynamic conf file "lighttpd-inc.conf" here ######
echo > /tmp/lighttpd-inc.conf # create file
config_auth
config_http_https
config_http_only
config_https_only
config_ipv6
config_ecr_client
###### create dynamci config file end #######
#if sd card is already inserted, we should check
[ -d "/mnt/usb/$model" ] && [ ! -L "/var/www/volumes/local" ] && ln -sf /mnt/usb/$model /var/www/volumes/local
[ -d "/mnt/usb/$model" ] && [ ! -L "/var/www/volumes2/local" ] && ln -sf /mnt/usb/$model /var/www/volumes2/local
# start...
$binary -f $prefix/etc/lighttpd/lighttpd.conf -m $prefix/lib
echo "ok."
kill -USR1 $(pidof rtspd | cut -d' ' -f1)
}
status() {
echo -n "$daemon"
pids=$(pidof $daemon) && echo "($pids) is running." || echo " is stop."
}
stop() {
pids=$(pidof $daemon) || { echo "$daemon is not running." && return 1; }
echo -n "Stopping $daemon... "
kill $(echo $pids | cut -d' ' -f1)
sleep 1
pids=$(pidof $daemon) && killall -9 $daemon && sleep 1 && pids=$(pidof $daemon) && die "ng." || echo "ok."
#Send CMD_WEBSERVER_STOPPED command
send_cmd watchdog 777 0 0 > /dev/null 2>&1
}
reloadAdmin() {
# Although original reloadAdmin() has some difference between start() function,
# such as reloadAdmin() doesn't to set normal user's account. But the difference is not important.
# We don't need two funtion that almost the same, it will increase the effort to maintain and implement lighttpd.sh.
# Use stop()+start() to replace the original reloadAdmin() function.
# But don't remove reloadAdmin function because of finder will call it.
stop
start
}
action=$1
prefix=$2
end=$3
[ "$end" = "" ] && [ "$action" != "" ] || showUsage
[ "$prefix" = "" ] || [ -d "$prefix" ] || die "$prefix is not a valid directory"
conf=$prefix/etc/$daemon.conf
binary=$prefix/sbin/$daemon
case $action in
start)
start
;
stop)
stop
;
restart)
stop
start
;
status)
status
;
reloadAdmin)
reloadAdmin
;
updateAccount)
eval $(dumpAccountKey | tdb get HTTPAccount)
model=$( [ $(pibinfo Wireless) -eq 1 ] && tdb get System ModelW_ss || tdb get System Model_ss )
mac_realm="${model}_$(pibinfo MacAddress | cut -b 16-17)"
createCredentials
# send SIGHUP to reload plugin modules
pids=$(pidof $daemon) || { echo "$daemon is not running." && return 1; }
kill -SIGHUP $(echo $pids | cut -d' ' -f1)
# restart rtspd
kill -USR1 $(pidof rtspd | cut -d' ' -f1)
;
*)
showUsage
;
esac
exit 0