#!/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