#!/bin/bash
# Copyright (c) 2021 Dnssense, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# variables

#buraya eklediginiz seyleri write_current_file yaparken eklemeyi unutmayin

PROG="$(basename "${0}")"
SCRIPT_DIR="$(cd "$(dirname "${0}")" && pwd)"
REGISTER_DOMAIN=https://portal.dnssense.com
SYSLOG_IP1=127.0.0.1
SYSLOG_PORT1=514
SYSLOG_IP2=''
SYSLOG_PORT2=''
DONT_TOUCH_DOMAINS='.dnssense.org,.dns0.org,.whatismyip.com'
ATTACH_DOMAIN='.dns0.org'
REGISTRY_DOMAIN=registry.roksit.com
DNSSENSE_VERSION=1.1.1
DHCP_LOGFILE=''
DNSSENSE_SERVERS='45.129.19.199 45.129.19.200'
OS=''

set -e

find_os() {
    #check lsb_release program exits
    if [[ ! $(which lsb_release) ]]; then
        echo "only supports debian or ubuntu\n"
        exit 1
    fi

    local tmp=$(lsb_release -a | grep 'Debian' | wc -l)
    if [[ $tmp -gt 0 ]]; then
        OS="DEBIAN"
    fi

    tmp=$(lsb_release -a | grep 'Ubuntu' | wc -l)
    if [[ $tmp -gt 0 ]]; then
        OS="UBUNTU"
    fi

    if [[ $OS != "DEBIAN" ]] && [[ $OS != "UBUNTU" ]]; then
        echo "only supports debian or ubuntu\n"
        exit 1
    fi
    echo "current founded os is $OS"
}
install_docker() {
    echo "updating system and install needed packages"
    apt-get -y update

    apt-get -y install \
        apt-transport-https \
        ca-certificates \
        curl \
        jq \
        gnupg \
        lsb-release

    echo "updating system and install needed packages"

    if [[ $(which docker) && $(docker --version) ]]; then
        echo "docker is allready installed"
    else
        echo "installing docker"

        if [ "$OS" == "DEBIAN" ]; then
            curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
            echo \
                "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
        $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list >/dev/null
        fi

        if [ "$OS" == "UBUNTU" ]; then
            curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
            echo \
                "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
        $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list >/dev/null
        fi

        apt-get -y update
        apt-get -y install docker-ce docker-ce-cli containerd.io

    fi

}

check_docker_is_running() {
    echo "checking if docker is running"
    set +e
    pgrep -x dockerd >/dev/null
    local docker_pid_found=$?
    set -e
    if [[ $docker_pid_found -ne 0 ]]; then
        echo "docker service is not running\n"
        echo "trying to start"
        systemctl start docker
    else
        echo "docker is running"
    fi

    set +e
    pgrep -x dockerd >/dev/null
    docker_pid_found=$?
    set -e

    if [[ $docker_pid_found -ne 0 ]]; then
        echo "docker service could not started"
        exit 1
    fi
    systemctl enable docker
}

write_default_config() {
    echo "writing /etc/dnssense/dnssense.conf"

    echo "current syslog is ${SYSLOG_IP1}:${SYSLOG_PORT1} enter new value for change"
    read -p "ip: " syslog_ip1
    if [ ! -z "$syslog_ip1" ]; then
        SYSLOG_IP1=$(echo "$syslog_ip1" | cut -d':' -f1)
        local tmp=$(echo "$syslog_ip1" | cut -d':' -f2)
        echo "temp is $tmp"
        if [ ! -z "$tmp" ] && [ "$tmp" != $syslog_ip1 ]; then
            SYSLOG_PORT1=$tmp
        fi
    fi
    echo "selected syslog is ${SYSLOG_IP1}:${SYSLOG_PORT1}"
    echo "-----------------------"
    ##############
    read -p "do you want enter second syslog and port (y/n) " yn
    if [ "$yn" == "y" ]; then

        read -p "ip: " syslog_ip2
        if [ ! -z "$syslog_ip2" ]; then
            SYSLOG_IP2=$(echo $syslog_ip2 | cut -d':' -f1)
            local tmp=$(echo $syslog_ip2 | cut -d':' -f2)
            if [ ! -z "$tmp" ] && [ "$tmp" != $syslog_ip2 ]; then
                SYSLOG_PORT2=$tmp
            fi
        fi
        echo "selected second syslog is ${SYSLOG_IP2}:${SYSLOG_PORT2}"
        echo "-----------------------"

    fi
    #################
    echo "current dont touch domains is ${DONT_TOUCH_DOMAINS} enter new value for change"
    read -p "domains: " dont_touch_domains
    if [ ! -z "$dont_touch_domains" ]; then
        DONT_TOUCH_DOMAINS=$dont_touch_domains

    fi
    echo "selected dont touch domains is ${DONT_TOUCH_DOMAINS}"
    echo "-----------------------"

    ##############
    echo "current attach domain is ${ATTACH_DOMAIN} enter new value for change"
    read -p "domain: " attach_domain
    if [ ! -z "$attach_domain" ]; then
        ATTACH_DOMAIN=$attach_domain

    fi
    echo "selected attach domain is ${ATTACH_DOMAIN}"
    echo "-----------------------"
    ############

    echo "current dhcp log file is ${DHCP_LOGFILE} enter new value for change"
    read -p "file: " file
    if [ ! -z "$file" ]; then
        DHCP_LOGFILE=$file

    fi
    echo "selected dhcp log file is ${ATTACH_DOMAIN}"
    echo "-----------------------"
    ############

    local def_config="register_page   = 127.0.0.1
block_page      = 127.0.0.1
block_pageV6      = ::1
syslog_srv      = ${SYSLOG_IP1}
syslog_port     = ${SYSLOG_PORT1}
syslog_facility = LOG_LOCAL0
maxttl          = 5
# added_domains can hold 10 domains at max.
# each domain should start with dot.
added_domains   =.dnssense.org,.dns0.org
# ip_override can hold 10 domains at max.
ip_override     = 62,18,74
#bu domain ile biten domainlere karışma
dont_touch_domains=${DONT_TOUCH_DOMAINS}
#bu domainleri hiç bir koşulda bloklama, maximum 2048 karakter
dont_block_domains=.dnssense.org,.dns0.org,.dnssense.com,.dnssense.net
captive_domains=.accounts.google.com,.ssl.gstatic.com,.fonts.gstatic.com
#0 ip bazlı, 1 remove add yapar , 2 add remove yapar, 1024 dont touch
work_mode=1024
box_serial=00000
attach_domain=${ATTACH_DOMAIN}
use_mac=1
use_encrypt=1
encrypt_key=key
drop_aaaa=0
use_hash_db=0"

    mkdir -p /etc/dnssense
    echo "$def_config" >"/etc/dnssense/dnssense.conf"
}

write_resolv_conf() {
    echo "writing /etc/dnssense/resolv.docker"
    echo "current dnsservers are $DNSSENSE_SERVERS"
    local nameservers=''
    read -p "do you want to change (y/n) " yn
    if [ "$yn" == "y" ]; then

        DNSSENSE_SERVERS=''
        while :; do
            read -p "enter nameserver ip: " name1
            printf -v str "nameserver $name1\n"
            nameservers+=$str
            printf -v str "$name1 "
            DNSSENSE_SERVERS+=$str
            read -p "do you want to enter a new one (y/n) " yn
            if [ "$yn" != "y" ]; then
                break
            fi
        done

    else
        for server in $DNSSENSE_SERVERS; do
            printf -v str "nameserver $server\n"
            nameservers+=$str
        done
    fi

    echo "selected nameservers"
    echo "$nameservers"
    mkdir -p /etc/dnssense
    echo "$nameservers" >"/etc/dnssense/resolv.docker"
}

write_current_file() {
    local DEST=/tmp/dnssense.sh
    cp "$SCRIPT_DIR/$PROG" "$DEST"

    local replace=$(cat "$DEST" | grep REGISTER_DOMAIN | head -1)
    sed -i "s+$replace+REGISTER_DOMAIN=${REGISTER_DOMAIN}+g" "$DEST"

    replace=$(cat "$DEST" | grep SYSLOG_IP1 | head -1)
    sed -i "s+$replace+SYSLOG_IP1=${SYSLOG_IP1}+g" "$DEST"

    replace=$(cat "$DEST" | grep SYSLOG_PORT1 | head -1)
    sed -i "s+$replace+SYSLOG_PORT1=${SYSLOG_PORT1}+g" "$DEST"

    replace=$(cat "$DEST" | grep SYSLOG_IP2 | head -1)
    sed -i "s+$replace+SYSLOG_IP2=${SYSLOG_IP2}+g" "$DEST"

    replace=$(cat "$DEST" | grep SYSLOG_PORT2 | head -1)
    sed -i "s+$replace+SYSLOG_PORT2=${SYSLOG_PORT2}+g" "$DEST"

    replace=$(cat "$DEST" | grep DONT_TOUCH_DOMAINS | head -1)
    sed -i "s+$replace+DONT_TOUCH_DOMAINS=${DONT_TOUCH_DOMAINS}"+g "$DEST"

    replace=$(cat "$DEST" | grep ATTACH_DOMAIN | head -1)
    sed -i "s+$replace+ATTACH_DOMAIN=${ATTACH_DOMAIN}+g" "$DEST"

    replace=$(cat "$DEST" | grep REGISTRY_DOMAIN | head -1)
    sed -i "s+$replace+REGISTRY_DOMAIN=${REGISTRY_DOMAIN}+g" "$DEST"

    replace=$(cat "$DEST" | grep DNSSENSE_VERSION | head -1)
    sed -i "s+$replace+DNSSENSE_VERSION=${DNSSENSE_VERSION}+g" "$DEST"

    replace=$(cat "$DEST" | grep DHCP_LOGFILE | head -1)
    sed -i "s+$replace+DHCP_LOGFILE='${DHCP_LOGFILE}'+g" "$DEST"

    replace=$(cat "$DEST" | grep DNSSENSE_SERVERS | head -1)
    sed -i "s+$replace+DNSSENSE_SERVERS='${DNSSENSE_SERVERS}'+g" "$DEST"

    replace=$(cat "$DEST" | grep OS | head -1)
    sed -i "s+$replace+OS='${OS}'+g" "$DEST"

    cp "$DEST" /usr/local/sbin/dnssense.sh
    chmod +x /usr/local/sbin/dnssense.sh
}
download_var_file() {
    echo "current install domain is ${REGISTER_DOMAIN} enter new value for change"
    read -p "domain: " domain
    if [ ! -z "$domain" ]; then
        REGISTER_DOMAIN=$domain
    fi
    echo "selected install domain is ${REGISTER_DOMAIN}"
    echo "-----------------------"

    curl --silent "$REGISTER_DOMAIN/download/docker/dnssense.var.sh" -o dnssense.var.sh
    source dnssense.var.sh

}

register_docker_image() {

    echo "current registry domain is ${REGISTRY_DOMAIN} enter new value for change"
    read -p "domain: " domain
    if [ ! -z "$domain" ]; then
        REGISTRY_DOMAIN=$domain
    fi
    echo "selected REGISTRY_URL is ${REGISTRY_DOMAIN}"
    echo "-----------------------"

    echo "login to registry"
    docker login $REGISTRY_DOMAIN
    echo "-----------------------"

    echo "checking dnssense latest version"
    DNSSENSE_VERSION=$(curl --silent "$REGISTER_DOMAIN/download/docker/version.txt")
    echo "founded dnssense version $DNSSENSE_VERSION"
    echo "-----------------------"

    echo "downloading image"
    docker pull "$REGISTRY_DOMAIN/dnssense/dns.sense:$DNSSENSE_VERSION"

    if [ "$(docker ps -aq -f name=dnssense)" ]; then
        docker stop dnssense || true && docker rm -f dnssense || true
    fi

    docker run -d --restart unless-stopped --name=dnssense -t -i --net=host \
        -e PORT=5353 \
        -v /etc/dnssense/resolv.docker:/etc/resolv.docker \
        -v /etc/dnssense/dnssense.conf:/etc/dnssense.conf \
        "$REGISTRY_DOMAIN/dnssense/dns.sense:$DNSSENSE_VERSION"

    if [ "$(docker ps -aq -f name=dnssense)" ]; then
        if [ ! "$(docker ps -aq -f status=exited -f name=dnssense)" ]; then
            echo "dnssense container is working on port 5353 on host network"
            echo "you can make destination nat with iptables"
            echo "iptables -t nat -A PREROUTING  -d \$INTERFACE_IP -p udp -m udp --dport 53 -j DNAT --to-destination \$INTERFACE_IP:5353"
        else
            echo "dnssense container is not working"
            exit 1
        fi
    else
        echo "there is no dnssense container"
        exit 1
    fi

    echo "downloading scripts"

    curl --silent "$REGISTER_DOMAIN/download/docker/dnssense.register.sh" --output /tmp/dnssense.register.sh
    sed -i "s+REGISTERURL=replace+REGISTERURL=${REGISTER_DOMAIN}+g" /tmp/dnssense.register.sh
    cp /tmp/dnssense.register.sh /usr/local/sbin/
    chmod +x /usr/local/sbin/dnssense.register.sh

    write_current_file

    echo "register with dnssense.register.sh"
}

install() {
    echo "installing"
    download_var_file
    install_docker
    check_docker_is_running
    write_default_config
    write_resolv_conf
    register_docker_image

}
uninstall() {
    echo "uninstalling"
    echo "removing docker image"
    docker stop dnssense || true && docker rm -f dnssense || true
    echo "removing conf files"
    rm -rf /etc/dnssense
    echo "removing exec files"
    rm -f /usr/local/sbin/dnssense*

}
dnssense_status() {
    if [ "$(docker ps -aq -f name=dnssense)" ]; then
        if [ ! "$(docker ps -aq -f status=exited -f name=dnssense)" ]; then
            echo "dnssense container is working"
        else
            echo "dnssense container is not working"
        fi
    else
        echo "there is no dnssense container"
    fi
}
dnssense_restart() {
    docker restart dnssense
    echo "restarted"
}
dnssense_stop() {
    docker stop dnssense
    echo "stoped"
}
dnssense_start() {
    docker start dnssense
    echo "started"
}
dnssense_version() {
    echo "current version ${DNSSENSE_VERSION}"
}

usage() {
    echo "This script must be run with super-user privileges."
    echo -e "USAGE: ${PROG} [-iuh]\n"
}

help_exit() {

    echo "This is a utility script for deploying Dnssense in a
Debian environment\n"
    usage
    echo "
Options:
  -h, --help
              shows help.
  -i, --install
              install Dnssense docker container and scripts.
  -u, --uninstall
              uninstall Dnssense docker container and scripts.
      --restart
              restart Dnssense docker container
      --stop
              stop Dnssense docker container
      --start
              start Dnssense docker container
      --status
              status of Dnssense docker container

"
}

# if less than two arguments supplied, display usage
if [ $# -ne 1 ]; then
    help_exit
    exit 1
fi

# check whether user had supplied -h or --help . If yes display usage
if [[ "$1" == "--help" ]] || [[ "$1" == "-h" ]]; then
    help_exit
    exit 0
fi

# display usage if the script is not run as root user
if [[ "$EUID" -ne 0 ]]; then
    echo "This script must be run as root!"
    exit 1
fi

find_os

if [[ "$1" == "--install" ]] || [[ "$1" == "-i" ]]; then
    install
    exit 0
fi

if [[ "$1" == "--uninstall" ]] || [[ "$1" == "-u" ]]; then
    uninstall
    exit 0
fi

if [[ "$1" == "--stop" ]]; then
    dnssense_stop
    exit 0
fi

if [[ "$1" == "--start" ]]; then
    dnssense_start
    exit 0
fi

if [[ "$1" == "--restart" ]]; then
    dnssense_restart
    exit 0
fi

if [[ "$1" == "--status" ]]; then
    dnssense_status
    exit 0
fi

if [[ "$1" == "--version" ]]; then
    dnssense_version
    exit 0
fi
