#!/bin/sh BOLD="\033[1m" NORM="\033[0m" INFO="$BOLD Info: $NORM" ERROR="$BOLD *** Error: $NORM" WARNING="$BOLD * Warning: $NORM" INPUT="$BOLD => $NORM" _quote() { echo $1 | sed 's/[]\/()$*.^|[]/\\&/g' } check_jffs_enabled () { if [ "`nvram get jffs2_format`" == "1" ]; then echo -e "$ERROR JFFS partition is scheduled to be reformatted" echo -e "$ERROR Please reboot to format or disable that setting and try again. Exiting..." exit 1 fi JFFS2_ENABLED=`nvram get jffs2_enable` JFFS2_SCRIPTS=`nvram get jffs2_scripts` if [ $JFFS2_ENABLED -ne 1 ] || [ $JFFS2_SCRIPTS -ne 1 ]; then echo -e "$INFO JFFS custom scripts and configs are not enabled. Enabling them" nvram set jffs2_enable=1 nvram set jffs2_scripts=1 nvram commit else echo -e "$INFO JFFS custom scripts and configs are already enabled" fi } choose_dnscrypt_server () { if [ $1 -eq 1 ] && [ -z $2 ]; then echo -e "$INFO Available DNS servers: " INDEX=0 while read LINE; do if [ $INDEX -eq 0 ]; then INDEX=1 continue fi SERVER="`echo $LINE|cut -d',' -f1,2,3|sed 's/,/: /'`" echo -e " $INDEX) $SERVER" SERVER="`echo $SERVER | cut -d':' -f1`" eval "ITEM$INDEX=$SERVER" INDEX=$((INDEX+1)) done < /jffs/dnscrypt/dnscrypt-resolvers.csv fi case $1 in 1) echo -en "$INPUT Please choose DNS server\n$BOLD[1-`expr $INDEX - 1`]$NORM: " ;; 2) echo -en "$INPUT Please choose 2nd DNS server or press n to skip\n$BOLD[1-`expr $INDEX - 1`/n]$NORM: " ;; esac read TMP if [ $1 -eq 2 ] && [ "$TMP" == "$CHOSEN" ]; then echo -e "$ERROR Duplicate selection! Retrying..." choose_dnscrypt_server $1 x return fi CHOSEN=$TMP if [ $1 -eq 2 ] && [ $CHOSEN == "n" ]; then write_conf DNS$1 "" return fi if [ -z "`echo $CHOSEN | grep -E '^[0-9]+$'`" ]; then echo -e "$ERROR Invalid character entered! Retrying..." choose_dnscrypt_server $1 x return fi if [ $CHOSEN -lt 1 ] || [ $CHOSEN -gt `expr $INDEX - 1` ] ; then echo -e "$ERROR Chosen DNS server number is not in range! Retrying..." choose_dnscrypt_server $1 x return fi eval ITEM="\$ITEM$CHOSEN" write_conf DNS$1 "$ITEM" [ "`echo $ITEM | grep cisco`" ] && CISCO_ENABLED=1 [ $1 -eq 1 ] && choose_dnscrypt_server 2 } cleanup () { local TARG=/jffs/dnscrypt rm -f $TARG/dnscrypt-fw-rules $TARG/dnscrypt-start $TARG/dnsmasq-dnscrypt-reconfig $TARG/fake-hwclock* $TARG/init-start $TARG/services-stop } create_dir () { mkdir -p "$1" if [ $? -ne 0 ]; then echo -e "$ERROR Unable to create $1! Exiting..." exit 1 fi } del_between_magic () { local TARG=$1 MAGIC=$2 BOUNDS=`grep -n -F "$MAGIC" $TARG|cut -d':' -f1|tr '\n' ','` if [ "$BOUNDS" ]; then sed -i "${BOUNDS%,}d" $TARG fi } del_jffs_script () { local TARG=$1 local OP=$2 if [ "$3" == "x" ]; then LINE_NUM=`grep -n -F "[ -x /jffs/dnscrypt/" $TARG|grep -v manager|cut -d':' -f1` else LINE_NUM=`grep -n -F "[ -x /jffs/dnscrypt/" $TARG|cut -d':' -f1` fi [ -z $LINE_NUM ] && return sed -i "${LINE_NUM}d" $TARG if [ $LINE_NUM -gt 1 ]; then LINE_NUM=$((LINE_NUM-1)) LINE_ABOVE=`sed "$LINE_NUMq;d" $TARG` [ -z "$LINE_ABOVE" ] && sed -i "${LINE_NUM}d" $TARG fi } download_file () { cd "$1" shift PERM="$1" shift for URL in "$@"; do FILENAME="`basename $URL`" MD5SUM_OLD="`[ -f $FILENAME ] && md5sum $FILENAME|cut -d' ' -f1`" MD5SUM_CURR="`curl -L -k -s \"${URL}.md5sum\"`" if [ "$MD5SUM_CURR" == "$MD5SUM_OLD" ]; then echo -e "$INFO $FILENAME is up to date. Skipping..." else echo -e "$INFO Downloading $FILENAME" curl -L -k -s -O "$URL" && chmod $PERM $FILENAME fi done } inst_dnscrypt () { local TARG=/jffs/dnscrypt create_dir $TARG download_file $TARG 644 https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v1/dnscrypt-resolvers.csv download_file $TARG 755 $URL_GEN/manager $URL_ARCH/dnscrypt-proxy $URL_ARCH/nonroot write_jffs_script /jffs/scripts/dnsmasq.postconf $TARG/manager dnsmasq write_jffs_script /jffs/scripts/wan-start $TARG/manager dnscrypt-start choose_dnscrypt_server 1 [ "$CISCO_ENABLED" == "1" ] && yesno_query "Do you want to set up OpenDNS account ip update" "inst_ip_update 1" "inst_ip_update 0" || inst_ip_update 0 yesno_query "Do you want to redirect all DNS resolutions on your network through dnscrypt?" "write_jffs_script /jffs/scripts/firewall-start $TARG/manager fw-rules" "del_jffs_script /jffs/scripts/firewall-start fw-rules" echo -e "$INFO Install a (P)RNG for better cryptographic operations" inst_random } inst_ip_update () { if [ "$1" -eq 0 ]; then write_conf OPENDNS_USER "" write_conf OPENDNS_PASSWORD "" return fi echo -en "$INPUT Please enter OpenDNS username$NORM: " read -r USERNAME echo -en "$INPUT Please enter OpenDNS password$NORM: " read -r PW1 echo -en "$INPUT Please reenter OpenDNS password$NORM: " read -r PW2 if [ "$PW1" != "$PW2" ]; then echo -e "$ERROR Password entered incorrectly! Exiting..." exit 1 fi write_conf OPENDNS_USER "\"$USERNAME\"" write_conf OPENDNS_PASSWORD "\"$PW1\"" } inst_random () { local TARG=/jffs/dnscrypt create_dir $TARG if [ -z $1 ]; then echo -e "$INFO Available random number generator providers:" echo -e " 1) HAVEGED (Preferred if you do not have a HW RNG)" echo -e " 2) RNGD (Preferred if you have a HW RNG)" fi echo -e "$INFO If you choose a HW RNG, please have it plugged in now before" echo -e "$INFO proceeding with your selection." echo -en "$INPUT Please enter the number designates your selection$NORM: " read CHOSEN case $CHOSEN in 1) rm -f rngd stty download_file $TARG 755 $URL_ARCH/haveged $URL_GEN/manager write_conf RAN_PRV haveged ;; 2) rm -f haveged download_file $TARG 755 $URL_ARCH/rngd $URL_ARCH/stty $URL_GEN/manager write_conf RAN_PRV rngd inst_ran_dev || return ;; *) echo -e "$ERROR Invalid character entered! Retrying..." inst_random x return ;; esac write_jffs_script /jffs/scripts/init-start $TARG/manager init-start write_jffs_script /jffs/scripts/services-stop $TARG/manager services-stop } inst_ran_dev () { if [ -c /dev/ttyACM0 ]; then PRODSTR=`cat /sys/class/tty/ttyACM0/device/uevent | grep ^PRODUCT\=` VID=`echo $PRODSTR | cut -d '=' -f 2 | cut -d '/' -f 1` PID=`echo $PRODSTR | cut -d '=' -f 2 | cut -d '/' -f 2` if [ "$VID" == "4d8" ] && [ "$PID" == "f5fe" ]; then echo -e "$INFO Found TrueRNG USB HW RNG" RNG_DEV=ttyACM0 fi if [ "$VID" == "16d0" ] && [ "$PID" == "aa0" ]; then echo -e "$INFO Found TrueRNGpro USB HW RNG" RNG_DEV=ttyACM0 fi if [ "$VID" == "1d50" ] && [ "$PID" == "6086" ]; then echo -e "$INFO Found OneRNG USB HW RNG" RNG_DEV=ttyACM0 fi if [ "$VID" == "20df" ] && [ "$PID" == "1" ]; then echo -e "$INFO Found EntropyKey USB HW RNG" RNG_DEV=ttyACM0 fi fi if [ -z $RNG_DEV ]; then echo -e "$ERROR Unable to find any HW RNG device! Retrying..." inst_random x return 1 fi write_conf RNG_DEV "/dev/$RNG_DEV" } yesno_query () { QUERY=$1 YES_FUNC=$2 NO_FUNC=$3 echo -en "$INPUT $QUERY $BOLD[y/n]$NORM: " read YESNO case $YESNO in y|Y) eval $YES_FUNC ;; n|N) eval $NO_FUNC ;; *) echo -e "$ERROR Invalid input!" yesno_query "$@" ;; esac } write_conf () { local TARG=/jffs/dnscrypt/.config KEY="$1" VALUE="$2" [ -f /jffs/dnscrypt/.opendns-auth ] && mv /jffs/dnscrypt/.opendns-auth $TARG && chmod 644 $TARG if [ ! -f $TARG ]; then touch $TARG && chmod 644 $TARG fi if [ "`grep $KEY $TARG`" ]; then VALUE=$(_quote $2) sed -i "/^$KEY=/s/=.*/=$VALUE/" $TARG else echo "$KEY=$VALUE" >> $TARG fi } write_jffs_script () { local TARG=$1 FILENAME="`basename \"$TARG\"`" COMMAND=$2 OP=$3 if [ ! -f $TARG ]; then echo -e "$INFO Creating $FILENAME file" echo "#!/bin/sh" > $TARG fi chmod 755 $TARG $COMMAND del_between_magic $TARG dnscrypt-asuswrt-installer if [ `grep -c -F "[ -x $COMMAND ] && $COMMAND $OP" $TARG` -gt 0 ]; then echo -e "$INFO $FILENAME file already configured" else echo -e "$INFO Configure $FILENAME file for dnscrypt" if [ "`grep \"^$COMMAND\" $TARG`" ]; then sed -i "s~^$COMMAND~[ -x $COMMAND ] \&\& $COMMAND $OP~" $TARG else del_jffs_script $TARG $OP x [ `tail -1 $TARG|grep -c '^$'` -eq 0 ] && echo "" >> $TARG echo "[ -x $COMMAND ] && $COMMAND $OP" >> $TARG fi fi } [ $1 ] && BRANCH=$1 || BRANCH=master URL_GEN=https://raw.githubusercontent.com/thuantran/dnscrypt-asuswrt-installer/$BRANCH/gen URL_ARCH=https://github.com/thuantran/dnscrypt-asuswrt-installer/raw/$BRANCH case $(uname -m) in armv7l) URL_ARCH=$URL_ARCH/armv7 echo -e "$INFO Detected ARM architecture." ;; mips) URL_ARCH=$URL_ARCH/mips echo -e "$INFO Detected MIPSEL architecture." ;; *) echo "This is unsupported platform, sorry." exit 1 ;; esac check_jffs_enabled cleanup echo -e "$INFO Choose what you want to do:" echo -e " 1) Install dnscrypt and (P)RNG" echo -e " 2) Install (P)RNG only" echo -en "$INPUT Please enter the number designates your selection or any other key to exit$NORM: " read CHOSEN case $CHOSEN in 1) echo -e "$INFO This operation will install dnscrypt-proxy and related files (<1MB)" echo -e "$INFO to jffs, no other data will be changed." echo -e "$INFO Also some start scripts will be installed/modified as required." echo yesno_query "Do you want to install dnscrypt-proxy to /jffs" inst_dnscrypt "exit 0" ;; 2) echo -e "$INFO This operation will install a (P)RNG (<0.5MB)" echo -e "$INFO to jffs, no other data will be changed." echo -e "$INFO Also some start scripts will be installed/modified as required." echo yesno_query "Do you want to install (P)RNG to /jffs" inst_random "exit 0" ;; *) echo -e "$ERROR Invalid character entered! Exiting..." exit 1 ;; esac echo -e "$INFO Setup completed!" echo -e "$INFO Please reboot your router for the changes to take effect!"