#!/bin/bash
# CTparental
#
# par Guillaume MARSAT
# Corrections orthographiques par Pierre-Edouard TESSIER
# une partie du code est tirée du script alcasar-bl.sh créé par Franck BOUIJOUX et Richard REY
# présente dans le code du projet alcasar en version 2.6.1 ; web page http://www.alcasar.net/

# This script is distributed under the Gnu General Public License (GPL)
DIR_CONF="/etc/CTparental"
DIR_SHARE="/usr/share/CTparental"
FILE_CONF="$DIR_CONF/CTparental.conf"
if [ -f "$DIR_CONF/CTparental.conf" ];then
    if [ "$( grep -c "^LANG=" $FILE_CONF )" -ge 1 ] ;then
        LANG="$( grep "^LANG" $FILE_CONF | cut -d "=" -f2 )"
        export LANG
    fi
fi
DIRLOCALE=${DIRLOCALE:="/usr/share/locale"}
#chargement des locales.
set -a
source /usr/bin/gettext.sh
set +a
export TEXTDOMAINDIR="$DIRLOCALE"
export TEXTDOMAIN="ctparental"
CHEMINCTPARENTLE="$(readlink -f "$0")"


## imports du plugin de la distribution si il existe
if [ -f "${DIR_CONF}/dist.conf" ];then 
source "${DIR_CONF}/dist.conf"
fi

#### UID MINIMUM pour les UTILISATEURS
if [ -f /etc/login.defs ] ; then
UID_MIN="$(awk /^UID_MIN/'{print $2}' /etc/login.defs)"
UID_MAX="$(awk /^UID_MAX/'{print $2}' /etc/login.defs)"
SYS_UID_MIN="$(awk /SYS_UID_MIN/'{print $2}' /etc/login.defs)"
SYS_UID_MAX="$(awk /SYS_UID_MAX/'{print $2}' /etc/login.defs)"
fi
UID_MIN=${UID_MIN:=1000}
UID_MAX=${UID_MAX:=60000}
SYS_UID_MIN=${SYS_UID_MIN:=100}
SYS_UID_MAX=${SYS_UID_MAX:=999}
UIDGUEST=${UIDGUEST:=998}
NOGROUP=${NOGROUP:="nogroup"}
BADNAMEOPTION=${BADNAMEOPTION:=" --badname  "} 
NOLOGINSHELL=${NOLOGINSHELL:="/usr/sbin/nologin"}
# considère comme root tous les utilisateurs avec un uid inférieur ou
# égal à 499,ce qui permet à apt-get,urpmi,yum... de lancer le script
# sans erreur.
if [ ! $UID -lt 499 ]; then
    gettext 'Root rights needed to run this script.'
    echo ""
    exit 1
fi
## On ne fait rien si ctparental est déja en cours de traitement long.
PIDFILE="/var/run/CTparental.pid"
PIDFILEWAIT="/var/run/CTparentalwait.pid"
if [ -f $PIDFILE ];then
    pidtest=$(cat $PIDFILE)
    if [ "$( ps -A | grep -c "$pidtest")" -eq 0 ] ; then
        rm -f $PIDFILE
    else
        ## si déja 2 processus sont lancer on ferme le nouveaux.
        if [ -f $PIDFILEWAIT ] ; then
            gettext 'Too many processes already in progress, please try again later.'
            echo ""
            exit 2
        fi
        echo $$ > $PIDFILEWAIT
        ## on attend que le processus déja en cour ce termine max 55 secondes
        eval_gettext "Waiting for the end of the process \$pidtest"
        for ((count=0 ; 55 - count ; count++))
        do
            sleep 1
            echo -n "."
            if [ "$( ps -A | grep -c "$pidtest")" -eq 0 ] ; then
                rm -f $PIDFILE
                break
            fi
        done
        echo ""
        ## si le processus et encore en cour au bout de 55 seconde on abendonne l'éxecution d'un nouveaux processus
        if [ "$( ps -A | grep -c "$pidtest")" -ge 1 ] ; then
            gettext 'The wait is too long please try again later.'
            echo ""
            rm -f $PIDFILEWAIT
            exit 2
        fi
        rm -f $PIDFILEWAIT
    fi
fi
echo $$ > $PIDFILE

noinstalldep=${noinstalldep:=0}
nomanuel=${nomanuel:=0}

SED="/bin/sed -i"
SAFE_CONF="$DIR_CONF/CTsafe.conf"
FILE_GCTOFFCONF="$DIR_CONF/GCToff.conf"
FILE_HCOMPT="$DIR_CONF/CThourscompteur"
FILE_HCONF="$DIR_CONF/CThours.conf"
FILE_NOHCOMPTIP="$DIR_CONF/nohcoutip"

## patch ssh.service pour le forcer a attendre que les interface soit bien lancer et configurée avant de démarrer.
## et éviter l'erreur suivante https://www.debian-fr.xyz/viewtopic.php?f=8&t=1445
if [ -f /lib/systemd/system/ssh.service ] ; then
    if [ "$( grep -c "network-online.target" /lib/systemd/system/ssh.service)" -eq 0 ] ; then
        $SED "s?^After=.*?After=network-online.target auditd.service?g" /lib/systemd/system/ssh.service
    fi
fi

## pour éviter les conflit avec dnsmasq
if [ -f /etc/systemd/resolved.conf ] ; then
    if [ "$( grep -c "DNSStubListener=udp" /etc/systemd/resolved.conf)" -eq 0 ] ; then
        $SED "s?.*DNSStubListener=.*?DNSStubListener=udp?g" /etc/systemd/resolved.conf
        systemctl restart systemd-resolved
    fi
fi
if [ ! -f $FILE_CONF ] ; then
    mkdir -p $DIR_CONF
    mkdir -p "$DIR_SHARE"/
    {
    echo '
LASTUPDATE=0
#LANG=fr_FR.UTF-8

## currently 3 languages are supported, English, French and Spanish.
## by default the application takes the default language of the local system or if not supported english but we can
## force with one of the following values provided you have it
## activate in the local system example under Debian via the "dpkg-reconfigure locales" command.
## possible values for LANG
## es_AR.UTF-8, es_BO.UTF-8, es_CL.UTF-8, es_CO.UTF-8
## es_CR.UTF-8, es_CU.UTF-8, es_DO.UTF-8, es_EC.UTF-8
## es_ES.UTF-8, es_GT.UTF-8, es_HN.UTF-8, es_MX.UTF-8
## es_NI.UTF-8, es_PA.UTF-8, es_PE.UTF-8, es_PR.UTF-8
## es_PY.UTF-8, es_SV.UTF-8, es_US.UTF-8, es_UY.UTF-8
## es_VE.UTF-8, en_BE.UTF-8, fr_CA.UTF-8, fr_CH.UTF-8
## en_EN.UTF-8, en_LU.UTF-8
## taking into account in the web interface requires to restart the service lighttpd

WHITEIPONLY=OFF
DNSCRYPT=BLACK
AUTOUPDATE=OFF
HOURSCONNECT=OFF
GCTOFF=OFF
PRIVOXYDF=ON
REDIRECT=ON
LOGNFT=OFF
LOGDNS=OFF
LOGLOGIN=OFF
# Parfeux minimal.
IPRULES=OFF
MD5DREAB=
MD5IPT=
MD5FILE_NOHCOMPTIP=
I_WAN_IPV4=
I_WAN_IPV6=
IP_BOX_IPV4=
IP_BOX_IPV6=
IP_IWAN_IPV4=
IP_IWAN_IPV6=
'
    } > $FILE_CONF

fi

if [ ! -f $SAFE_CONF ] ; then
    {
    echo '
SAFEGOOGLE
SAFEYOUTUBE
SAFEBING
SAFEDUCK
SAFEQWANT
'
    } > $SAFE_CONF

fi

FILTRAGEISOFF="$( grep -c "DNSCRYPT=OFF" $FILE_CONF )"

tempDIR=${tempDIR:="/tmp/alcasar"}
tempDIRRamfs=${tempDIRRamfs:="/tmp/alcasarRamfs"}
if [ ! -d $tempDIRRamfs ]; then mkdir -p "${tempDIRRamfs}"; fi
RougeD="\033[1;31m"
BleuD="\033[1;36m"
#VertD="\033[1;32m"
Fcolor="\033[0m"
NUMVER=${NUMVER:="$(dpkg -l 2>/dev/null | grep ctparental | grep ii | awk '{print $2"-"$3}')"}
COMMONFILEGS=${COMMONFILEGS:="common-auth"}
GESTIONNAIREDESESSIONS=${GESTIONNAIREDESESSIONS:=" login gdm lightdm slim kdm xdm lxdm gdm3 "}
FILEPAMTIMECONF=${FILEPAMTIMECONF:="/etc/security/time.conf"}
DIRPAM=${DIRPAM:="/etc/pam.d/"}
DAYS=${DAYS:="$(gettext "Monday") $(gettext "Tuesday") $(gettext "Wednesday") $(gettext "Thursday") $(gettext "Friday") $(gettext "Saturday") $(gettext "Sunday") "}
DAYS=( "$DAYS" )
DAYSPAM=( Mo Tu We Th Fr Sa Su )
DAYSSYSTEMD=( Mon Tue Wed Thu Fri Sat Sun ) 
PROXYport=${PROXYport:="8888"}
E2GUport=${E2GUport:="8080"}
PROXYuser=${PROXYuser:="privoxy"}
SRVPROXY=${SRVPROXY:="privoxy"}
FILCHANGELOGGZ=${FILCHANGELOGGZ:="/usr/share/doc/ctparental/changelog.Debian.gz"}
#### DEPENDANCES par DEFAUT #####
DEPENDANCES=${DEPENDANCES:=" console-data e2guardian dnscrypt-proxy lighttpd lighttpd-mod-magnet php-cgi libnotify-bin notification-daemon iptables-persistent rsyslog privoxy openssl libnss3-tools whiptail dnsutils rsyslog rsync openssh-server "}

#### PAQUETS EN CONFLIT par DEFAUT #####
CONFLICTS=${CONFLICTS:=" dansguardian mini-httpd apache2 firewalld "}

#### COMMANDES de services par DEFAUT #####
CMDSERVICE=${CMDSERVICE:="service "}
SRVHTTP=${SRVHTTP:="lighttpd"}
FPMSOCK=${FPMSOCK:="$(find /var/run/php/ -type s -name "*fpm*" 2> /dev/null)"}
NGINXCONF=${NGINXCONF:="/etc/nginx/nginx.conf"}
PHPFPMCONF=${PHPFPMCONF:="/etc/php/php-fpm.d/www.conf"}
FUNCNGINXCONF=${FUNCNGINXCONF:="confnginx"}
PHPFPMrestart=${PHPFPMrestart:="systemctl restart php-fpm "}
PHPFPMenable=${PHPFPMenable:="systemctl enable php-fpm "}
SRVHTTPstart=${SRVHTTPstart:="systemctl start lighttpd "}
SRVHTTPstop=${SRVHTTPstop:="systemctl stop lighttpd "}
SRVHTTPrestart=${SRVHTTPrestart:="systemctl restart lighttpd "}
DNSCRYPTBIN=${DNSCRYPTBIN:="/usr/sbin/dnscrypt-proxy"}
CTparentalSshdStart=${CTparentalSshdStart:="systemctl start CTparentalSshd "}
CTparentalSshdStop=${CTparentalSshdStop:="systemctl stop CTparentalSshd "}
CTparentalSshdRestart=${CTparentalSshdRestart:="systemctl restart CTparentalSshd "}
CTparentallogfirewallRestart=${CTparentallogfirewallRestart:="systemctl restart CTparentallogfirewall "}
CTparentallogfirewallStart=${CTparentallogfirewallStart:="systemctl start CTparentallogfirewall "}
CTparentallogfirewallStop=${CTparentallogfirewallStop:="systemctl stop CTparentallogfirewall "}
DNSCRYPTstart=${DNSCRYPTstart:="systemctl start CTparentaldnscrypt-proxy "}
DNSCRYPTstop=${DNSCRYPTstop:="systemctl stop CTparentaldnscrypt-proxy "}
DNSCRYPTrestart=${DNSCRYPTrestart:="systemctl restart CTparentaldnscrypt-proxy "}
NWMANAGERrestart=${NWMANAGERrestart:="systemctl restart NetworkManager " }
NFTABLESsaveFILE=${NFTABLESsaveFILE:="/etc/CTparental/nftables-save.nft"}
SKILLUSER=${SKILLUSER:="/usr/bin/pkill -KILL -u %i"}
GREPADMINUSER=${GREPADMINUSER:="( root$)|( root )|( sudo$)|( sudo )|(^sudo )"}

function nftsave () {
nft list ruleset > "$NFTABLESsaveFILE"
chown root:root "$NFTABLESsaveFILE"
chmod 750 "$NFTABLESsaveFILE"
}

LOGNFT=$(grep LOGNFT= "$FILE_CONF" | cut -d"=" -f2)
if [ "$LOGNFT" = "ON" ];then
LOG4ACCEPT='log prefix "ip4tables-accept"'
LOG4REJECT='log prefix "ip4tables-reject"'
LOG6ACCEPT='log prefix "ip6tables-accept"'
LOG6REJECT='log prefix "ip6tables-reject"'
else
LOG4ACCEPT=''
LOG4REJECT=''
LOG6ACCEPT=''
LOG6REJECT=''
fi

LOGDAYROTATE=${LOGDAYROTATE:="366"}
LOGMONTHROTATE=${LOGMONTHROTATE:="12"}
FILEROTATEWTMP=${FILEROTATEWTMP:="/etc/logrotate.d/wtmp"}
FILEROTATEBTMP=${FILEROTATEBTMP:="/etc/logrotate.d/btmp"}
FILEROTATEDNS=${FILEROTATEDNS:="/etc/logrotate.d/CTdnscrypt"}
NFTABLESsave=${NFTABLESsave:="nftsave"}

E2GUARDIANrestart=${E2GUARDIANrestart:="systemctl restart e2guardian "}
PROXYrestart=${PROXYrestart:="systemctl restart privoxy "}
RSYSLOGRESTART=${RSYSLOGRESTART:="systemctl restart rsyslog "}
PING4=${PING4:="ping -4 "}
PING6=${PING6:="ping -6 "}
if [ -f "$DIR_CONF"/ctsync.conf ];then
PORTSSH=$( grep "PORTSSH=" "$DIR_CONF"/ctsync.conf | cut -d"=" -f2)
else
touch "$DIR_CONF"/ctsync.conf
fi
PORTSSH=${PORTSSH:=8022}
clientsync=0

#### LOCALISATION du fichier PID lighttpd par defaut ####
LIGHTTPpidfile=${LIGHTTPpidfile:="/var/run/lighttpd.pid"}

#### LOCALISATION du fichier de chargement de modules ####
DIRMODULESLOAD=${DIRMODULESLOAD:="/etc/modules-load.d"}
DIRMODULESPROB=${DIRMODULESPROB:="/etc/modprobe.d"}
FILEMODULESLOAD=${FILEMODULESLOAD:="$DIRMODULESLOAD/nftable.conf"}
FILEMODULESPROB=${FILEMODULESPROB:="$DIRMODULESPROB/nftable.conf"}

RSYSLOGCTPARENTAL=${RSYSLOGCTPARENTAL:="/etc/rsyslog.d/10-nftables.conf"}

#### COMMANDES D'ACTIVATION DES SERVICES AU DEMARRAGE DU PC ####
ENHTTP=${ENHTTP:=""}
ENCTparentalSshd=${ENCTparentalSshd:="systemctl enable CTparentalSshd "}
DICTparentalSshd=${ENCTparentalSshd:="systemctl disable CTparentalSshd "}
ENCTparentalfirewall=${ENCTparentalfirewall:="systemctl enable CTparentalfirewall "}
DICTparentalfirewall=${DICTparentalfirewall:="systemctl disable CTparentalfirewall "}
ENCTparentallogfirewall=${ENCTparentallogfirewall:="systemctl enable CTparentallogfirewall "}
DICTparentallogfirewall=${DICTparentallogfirewall:="systemctl disable CTparentallogfirewall "}
ENDNSCRYPT=${ENDNSCRYPT:="systemctl enable CTparentaldnscrypt-proxy "}
DIDNSCRYPT=${DIDNSCRYPT:="systemctl disable CTparentaldnscrypt-proxy "}
ENNWMANAGER=${ENNWMANAGER:=""}
ENNFTABLESsave=${ENNFTABLESsave:=""}
ENE2GUARDIAN=${ENE2GUARDIAN:=""}
ENPROXY=${ENPROXY:=""}
ENNETWORK=${ENNETWORK:=""}
BINSYSTEMCTL=${BINSYSTEMCTL:="/usr/bin/systemctl"}
BINSYSCTL=${BINSYSCTL:="/sbin/sysctl"}
FILESYSCTL=${FILESYSCTL:="/etc/sysctl.conf"}
DIRE2G=${DIRE2G:="/etc/e2guardian/"}
DIRE2GLANG=${DIRE2GLANG:="/usr/share/e2guardian/languages"}
NEWTEMPLETE2G=${NEWTEMPLETE2G:="$DIR_SHARE"/confe2guardian}
FILEConfe2gu=${FILEConfe2gu:=$DIRE2G"e2guardian.conf"}
FILEConfe2guf1=${FILEConfe2guf1:=$DIRE2G"e2guardianf1.conf"}
DREAB="$DIR_CONF/domaine-rehabiliter"
REABDIP="$DIR_CONF/dip-rehabiliter.conf"
IPV4REAB="$DIR_CONF/ipv4-rehabiliter"
IPV6REAB="$DIR_CONF/ipv6-rehabiliter"
E2GUXSITELIST=$DIRE2G"lists/exceptionsitelist"
DNSCRYPTSERVEURS=${DNSCRYPTSERVEURS:="'google','cloudflare'"}
DNSCRYPTMINISIGNURL=${DNSCRYPTMINISIGNURL:="https://raw.githubusercontent.com/DNSCrypt/dnscrypt-resolvers/master/v3/minisign.pub"}
DNSCRYPTSPCACHEFILE=${DNSCRYPTSPCACHEFILE:="/var/cache/CTdnscrypt-proxy/public-resolvers.md"}
DNSCRYPTPUBURL=${DNSCRYPTPUBURL:="https://download.dnscrypt.info/resolvers-list/v3/public-resolvers.md"}
DNSCRYPTMINKEY="$(wget $DNSCRYPTMINISIGNURL -q -O- | grep -v " " | grep -v "#" )"
DNSCRYPTMINKEY=${DNSCRYPTMINKEY:="RWQf6LRCGA9i53mlYecO4IzT51TGPpvWucNSCh1CBM0QTaLn73Y7GFO3"}
DNSCRYPTCONF=${DNSCRYPTCONF:="$DIR_CONF/dnscrypt-proxy.toml"}
DNSCRYPTBL=${DNSCRYPTBL:="$DIR_CONF/dnscrypt-blocked-names.txt"}
DNSCRYPTWL=${DNSCRYPTWL:="$DIR_CONF/dnscrypt-allowed-names.txt"}
DNSCRYPTCR=${DNSCRYPTCR:="$DIR_CONF/dnscrypt-cloaking-rules.txt"}

MAINCONFHTTPD=${MAINCONFHTTPD:="/etc/lighttpd/lighttpd.conf"}
DIRCONFAVAILABLEHTTPD=${DIRCONFAVAILABLEHTTPD:="/etc/lighttpd/conf-available"}
DIRCONFENABELEDHTTPD=${DIRCONFENABELEDHTTPD:="/etc/lighttpd/conf-enabled"}
CTPARENTALCONFHTTPD=${CTPARENTALCONFHTTPD:="$DIRCONFAVAILABLEHTTPD/90-CTparental.conf"}
DIRWWW=${DIRWWW:="/var/www"}
DIRadminHTML=${DIRadminHTML:="$DIRWWW/CTadmin"}
PASSWORDFILEHTTPD=${PASSWORDFILEHTTPD:="${DIRadminHTML}/arp1_md5.password"}
REALMADMINHTTPD=${REALMADMINHTTPD:="admin.ct.local"}
CADIR=${CADIR:="/usr/local/share/ca-certificates/ctparental"}
UPDATECASYSTEM=${UPDATECASYSTEM:="update-ca-certificates"}
PEMSRVDIR=${PEMSRVDIR:="/etc/ssl/private"}
CMDINSTALL=""
ADDUSERTOGROUP=${ADDUSERTOGROUP:="gpasswd -a "}
DELUSERTOGROUP=${DELUSERTOGROUP:="gpasswd -d "}
ETCPRIVOXY=${ETCPRIVOXY:="/etc/privoxy"}
PRIVOXYCONF=${PRIVOXYCONF:="$ETCPRIVOXY/config"}
PRIVOXYUSERA=${PRIVOXYUSERA:="$ETCPRIVOXY/user.action"}
PRIVOXYCTA=${PRIVOXYCTA:="$ETCPRIVOXY/ctparental.action"}
TINYPROXYCONF=${TINYPROXYCONF:="/etc/tinyproxy/tinyproxy.conf"}
XSESSIONFILE=${XSESSIONFILE:="/etc/X11/Xsession"}
REPCAMOZ=${REPCAMOZ:="/usr/share/ca-certificates/mozilla/"}
DOMAINEDEPOTS=${DOMAINEDEPOTS:=$(cat /etc/apt/sources.list /etc/apt/sources.list.d/* 2>/dev/null | grep "^deb" | cut -d"/" -f3 | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | sed -e "s/^www././g" | cut -d " " -f1 )}
TIMERALERT=${TIMERALERT:=10}
NEWPASSGRUB2=${NEWPASSGRUB2:="grub-mkpasswd-pbkdf2"}
BOOTREPGRUB2=${BOOTREPGRUB2:="/boot/grub"}
BL_SERVER="dsi.ut-capitole.fr"
BL_T=${BL_T:="http://$BL_SERVER/blacklists/download/blacklists.tar.gz"}
FILMD5BL_T=${FILMD5BL_T:="http://$BL_SERVER/blacklists/download/MD5SUM.LST"}
BL_CT=${BL_CT:="https://gitlab.com/marsat/bl_ctparental/raw/master/blacklists2.tar.gz"}
FILMD5CT=${FILMD5CT:="https://gitlab.com/marsat/bl_ctparental/raw/master/MD5SUM.LST"}
## BL_DIPOSSI contien la blacklist ossi avec les noms de domaine les ipv6 et les ipv4 que l'on veut ajouter 
## ne bloque que les utilisateurs filtrés
BL_DIPOSSI="$DIR_CONF/dip-blackliste.conf"
## FILEIPBLACKLIST ne se configure que en manuel et bloque tous le mondes même root
FILEIPBLACKLIST="$DIR_CONF/ip-blackliste.conf"
FILEFIRWALLCONF="$DIR_CONF/nftables.conf"
FILEIPTIMEWEB="$DIR_CONF/nftables-timerweb"
CATEGORIES_ENABLED="$DIR_CONF/categories-enabled.conf"
CATEGORIES_AVAILABLE="$DIR_CONF/categories-available.conf"
BL_CATEGORIES_AVAILABLE="$DIR_CONF/bl-categories-available"
WL_CATEGORIES_AVAILABLE="$DIR_CONF/wl-categories-available"
DIR_DNS_FILTER_AVAILABLE="$DIR_CONF/dnsfilter-available"
DIR_IPV4_FILTER_AVAILABLE="$DIR_CONF/ipv4filter-available"
DIR_IPV6_FILTER_AVAILABLE="$DIR_CONF/ipv6filter-available"
DIR_IPV4_FILTER_ENABLED="$DIR_CONF/ipv4filter-enable"
DIR_IPV6_FILTER_ENABLED="$DIR_CONF/ipv6filter-enable"
DIR_IPV6_WHITELIST_ENABLED="$DIR_CONF/ipv6whitelist-enable"
DIR_IPV4_WHITELIST_ENABLED="$DIR_CONF/ipv4whitelist-enable"
THISDAYS=$(( $(date +%Y) * 365 + $(date +%j | sed -e "s/^0*//g") ))
USERHTTPD=${USERHTTPD:=$( grep $DIRWWW /etc/passwd  | cut -d":" -f1)}
GROUPHTTPD=${GROUPHTTPD:=$( grep "$USERHTTPD" /etc/group | cut -d":" -f1)}

DEFAULTRESOVCONF=${DEFAULTRESOVCONF:="/etc/default/resolvconf"}
BINRESOLVCONF=${BINRESOLVCONF:="/sbin/resolvconf"}
OPENRESOLVCONF=${OPENRESOLVCONF:="/etc/resolvconf.conf"}

NFTCHAINNATipv4=${NFTCHAINNATipv4:="nft_chain_nat_ipv4"}
NFTCHAINNATipv6=${NFTCHAINNATipv6:="nft_chain_nat_ipv6"}

if [ "$(yum help 2> /dev/null | wc -l )" -ge 50 ] ; then
    ## "Distribution basée sur yum exemple redhat, fedora..."
    CMDINSTALL=${CMDINSTALL:="yum install "}
    CMDREMOVE=${CMDREMOVE:="rpm -e "}
fi
urpmi --help > /dev/null 2>&1
if [ $? -eq 1 ] ; then
    ## "Distribution basée sur urpmi exemple mandriva..."
    CMDINSTALL=${CMDINSTALL:="urpmi -a --auto "}
    CMDREMOVE=${CMDREMOVE:="rpm -e "}
fi
apt-get -h > /dev/null 2>&1
if [ $? -eq 0 ] ; then
    ## "Distribution basée sur apt-get exemple debian, ubuntu ..."
    CMDINSTALL=${CMDINSTALL:="apt-get -y --force-yes install "}
    CMDREMOVE=${CMDREMOVE:="dpkg --purge  "}
fi

eopkg --help > /dev/null 2>&1
if [ $? -eq 1 ] ; then
    ## "Distribution basée sur eopkg exemple Solus..."
    CMDINSTALL=${CMDINSTALL:="eopkg install "}
    CMDREMOVE=${CMDREMOVE:="eopkg remove "}
fi

pacman --help > /dev/null 2>&1
if [ $? -eq 0 ] ; then
    ## "Distribution basée sur pacman exemple Manjaro..."
    CMDINSTALL=${CMDINSTALL:="pacman -S "}
    CMDREMOVE=${CMDREMOVE:="pacman -R "}
fi

zypper --help > /dev/null 2>&1
if [ $? -eq 0 ] ; then
    ## "Distribution basée sur zypper exemple OpenSUSE..."
    CMDINSTALL=${CMDINSTALL:="zypper install "}
    CMDREMOVE=${CMDREMOVE:="zypper remove "}
fi

if [ -z "$CMDINSTALL" ] ; then
    gettext 'No known package manager was detected.'
    set -e
    exit 1
fi
if [ "${1}" = "-i" ];then
## on créer les tables par defaults ( via import de fichier car si non impossible de configurer les prioritées négatives )
nft -f /usr/share/CTparental/nftctparental.nft
fi
source "$DIR_SHARE/ConfLanIs"
source "$DIR_SHARE/get_free_uid_sys"
source "$DIR_SHARE/nftdisableconflict"



function wgeturlok() {
wget -q --spider $1
if [ $? -eq 0 ]; then
     echo 1
     return 1
else
     echo 0
     return 0
fi
}

function networkisoknext() {
    ipv4ok=0
    $PING4 -c1 -w1 "$ipbox_ipv4" 2>/dev/null 1>/dev/null
    if [ $? -eq  0 ];then
    ipv4ok=1
    fi

    ipv6ok=0
    $PING6 -c1 -w1 "$ipbox_ipv6" 2>/dev/null 1>/dev/null
    if [ $? -eq  0 ];then
    ipv6ok=1
    fi

    if [ $ipv4ok -eq 0 ];then
    if [ $ipv6ok -eq 0 ];then
       gettext 'error recovering network settings'
       echo
       exit 0
    fi
    fi
}

PRIVATE_IP4="127.0.0.10"
PRIVATE_IP6="fd00::127:10"
ADMIN_IP4=${ADMIN_IP4:="127.0.0.11"}
ADMIN_IP6=${ADMIN_IP6:="fd00::127:11"}



FILE_tmp=${FILE_tmp:="$tempDIRRamfs/filetmp.txt"}
FILE_tmpSizeMax=${FILE_tmpSizeMax:="256M"}  # 70 Min, Recommend 128M
LOWRAM=${LOWRAM:=0}
if [ "$LOWRAM" -eq 0 ] ; then
    MFILEtmp="mount -t tmpfs -o size=$FILE_tmpSizeMax tmpfs $tempDIRRamfs"
    UMFILEtmp="umount $tempDIRRamfs"
else
    MFILEtmp=""
    UMFILEtmp=""
fi


function initblenabled() {
    {
    echo 'adult
adultsearchengine
agressif
ctparental
dangerous_material
cryptojacking
dating
drogue
gambling
hacking
malware
marketingware
mixed_adult
phishing
redirector
publicite
ddos
sect
strict_redirector
strong_redirector
tricheur
warez
tor_nodes
ultrasurf_nodes
ct_doh_dot_doq
doh
stalkerware
vpn
bitcoin
ossi'
    } > $CATEGORIES_ENABLED
    echo > ${DNSCRYPTBL:?}
    echo > ${DNSCRYPTWL:?}
    echo > ${DNSCRYPTCR:?}
    rm -rf ${DIR_IPV6_FILTER_ENABLED:?}/
    mkdir $DIR_IPV6_FILTER_ENABLED 2>/dev/null
    rm -rf ${DIR_IPV4_FILTER_ENABLED:?}/
    mkdir $DIR_IPV4_FILTER_ENABLED 2>/dev/null
    rm -rf ${DIR_IPV6_WHITELIST_ENABLED:?}/
    mkdir $DIR_IPV6_WHITELIST_ENABLED 2>/dev/null
    rm -rf ${DIR_IPV4_WHITELIST_ENABLED:?}/
    mkdir $DIR_IPV4_WHITELIST_ENABLED 2>/dev/null
    $SED "s?^MD5DREAB.*?MD5DREAB=?g" $FILE_CONF
    chown root:"$GROUPHTTPD" "$CATEGORIES_ENABLED"
    chmod 664 "$CATEGORIES_ENABLED"
}

function confe2guardian() {
    # replace the default deny HTML page
    echo "<confe2guardian>"
    $SED "s?^loglevel =.*?loglevel = 0?g" "$FILEConfe2gu"
    $SED "s?^languagedir =.*?languagedir = \'$DIRE2GLANG\'?g" "$FILEConfe2gu"
    $SED "s?^language =.*?language = 'french'?g" "$FILEConfe2gu"
    $SED "s?^logexceptionhits =.*?logexceptionhits = 0?g" "$FILEConfe2gu"
    $SED "s?^filterip =.*?filterip = $PRIVATE_IP4?g" "$FILEConfe2gu"
    $SED "s?^proxyip =.*?proxyip = $PRIVATE_IP4?g" "$FILEConfe2gu"
    $SED "s?^#proxyip =.*?proxyip = $PRIVATE_IP4?g" "$FILEConfe2gu"
    $SED "s?^filterports =.*?filterports = $E2GUport?g" "$FILEConfe2gu"
    $SED "s?^proxyport =.*?proxyport = $PROXYport?g" "$FILEConfe2gu"
    $SED "s?^#proxyport =.*?proxyport = $PROXYport?g" "$FILEConfe2gu"
    $SED "s?^transparenthttpsport =.*?#transparenthttpsport = 8443?"  "$FILEConfe2gu"
    $SED "s?^proxytimeout =.*?proxytimeout = 10?"  "$FILEConfe2gu"
    $SED "s?^connecttimeout =.*?connecttimeout = 10?"  "$FILEConfe2gu"
    $SED "s?^httpworkers =.*?httpworkers = 100?"  "$FILEConfe2gu"   
    $SED "s?.*UNCONFIGURED.*?#UNCONFIGURED?g" "$FILEConfe2gu"
    {
    echo "
#Blanket Block.  To block all sites except those in the
#exceptionsitelist and greysitelist files, remove
#the # from the next line to leave only a '**':
#**

#Blanket SSL/CONNECT Block.  To block all SSL
#and CONNECT tunnels except to addresses in the
#exceptionsitelist and greysitelist files, remove
#the # from the next line to leave only a '**s':
#**s

#Blanket IP Block.  To block all sites specified only as an IP,
#remove the # from the next line to leave only a '*ip':
#*ip

#Blanket SSL/CONNECT IP Block.  To block all SSL and CONNECT
#tunnels to sites specified only as an IP,
#remove the # from the next line to leave only a '**ips':
#**ips

$(gettext "#the domain filtering is handled by dnscrypt-proxy, do not touch this file!")
"
    } > "$DIRE2G"lists/bannedsitelist
    $E2GUARDIANrestart
    cp -f "$NEWTEMPLETE2G"/template.html "$DIRE2GLANG"/ukenglish/
    cp -f "$NEWTEMPLETE2G"/template-fr.html "$DIRE2GLANG"/french/template.html
    sed -i "s/é/\&eacute;/g" "$DIRE2GLANG"/french/messages
    sed -i "s/è/\&egrave;/g" "$DIRE2GLANG"/french/messages
    $E2GUARDIANrestart
    echo "</confe2guardian>"
}

function privoxydefaultfilteroff() {
    $SED "s?^PRIVOXYDF.*?PRIVOXYDF=OFF?g" $FILE_CONF
    $SED "s?^actionsfile match-all.action.*?#actionsfile match-all.action?g" "$PRIVOXYCONF"
    $SED "s?^actionsfile default.action.*?#actionsfile default.action?g" "$PRIVOXYCONF"
    $SED "s?^filterfile default.filter.*?#filterfile default.filter?g" "$PRIVOXYCONF"
    $PROXYrestart
}

function privoxydefaultfilteron() {
    $SED "s?^PRIVOXYDF.*?PRIVOXYDF=ON?g" $FILE_CONF
    $SED "s?#actionsfile match-all.action.*?actionsfile match-all.action?g" "$PRIVOXYCONF"
    $SED "s?#actionsfile default.action.*?actionsfile default.action?g" "$PRIVOXYCONF"
    $SED "s?#filterfile default.filter.*?filterfile default.filter?g" "$PRIVOXYCONF"
    $PROXYrestart
}

function conftinyproxy() {
    echo "<conftinyproxy>"
    $SED "s?^Port .*?Port 8888?" "$TINYPROXYCONF"
    $SED "s?^Listen .*?Port Listen $PRIVATE_IP4?" "$TINYPROXYCONF"
    echo "</conftinyproxy>"
}

function confproxy() {
if [ $SRVPROXY = "privoxy" ] ; then
    confprivoxy
fi
if [ $SRVPROXY = "tinyproxy" ] ; then
    conftinyproxy
fi
}

function confprivoxy() {
    echo "<confprivoxy>"
    $SED "s?^debug.*?debug = 0?g"  "$PRIVOXYCONF"
    test=$( grep -c "^listen-address.*" "$PRIVOXYCONF" )
    ligneipv4=$( sed -n '/^listen-address.*/=' "$PRIVOXYCONF" | sed '1q;d' )
    if [ "$test" -eq "1" ] ; then
    ligneipv6=$((ligneipv4 + 1))
    $SED "$ligneipv4 s?^listen-address.*?listen-address  $PRIVATE_IP4:$PROXYport?"  "$PRIVOXYCONF"
    $SED "$ligneipv6""i\listen-address  [$PRIVATE_IP6]:$PROXYport" "$PRIVOXYCONF"
    else
    ligneipv6=$( sed -n '/^listen-address.*/=' "$PRIVOXYCONF" | sed '2q;d' )
    $SED "$ligneipv4 s?^listen-address.*?listen-address  $PRIVATE_IP4:$PROXYport?"  "$PRIVOXYCONF" #ipv4
    $SED "$ligneipv6 s?^listen-address.*?listen-address  [$PRIVATE_IP6]:$PROXYport?"  "$PRIVOXYCONF" #ipv6
    fi
    unset test
    test=$(grep -c "actionsfile ctparental.action" "$PRIVOXYCONF" )
    if [ "$test" -ge "1" ] ; then
    $SED "s?actionsfile.*ctparental.*?actionsfile ctparental\.action      # ctparental customizations?g" "$PRIVOXYCONF"
    else
    nline=$(grep "actionsfile.*user.action" "$PRIVOXYCONF" -n | cut -d":" -f1)
    $SED "$nline""i\actionsfile ctparental.action      # ctparental customizations" "$PRIVOXYCONF"
    fi
    $SED "s?^accept-intercepted-requests.*?accept-intercepted-requests 1 ?" "$PRIVOXYCONF"
    $SED "s?^keep-alive-timeout.*?keep-alive-timeout 20 ?" "$PRIVOXYCONF"
    $SED "s?^#.*receive-buffer-size 32768?receive-buffer-size 32768?" "$PRIVOXYCONF"
    unset test
    {
    echo '{{alias}}
+crunch-all-cookies = +crunch-incoming-cookies +crunch-outgoing-cookies
-crunch-all-cookies = -crunch-incoming-cookies -crunch-outgoing-cookies
 allow-all-cookies  = -crunch-all-cookies -session-cookies-only -filter{content-cookies}
 allow-popups       = -filter{all-popups} -filter{unsolicited-popups}
+block-as-image     = +block{Blocked image request.} +handle-as-image
-block-as-image     = -block
fragile     = -block -crunch-all-cookies -filter -fast-redirects -hide-referer -prevent-compression
shop        = -crunch-all-cookies allow-popups
myfilters   = +filter{html-annoyances} +filter{js-annoyances} +filter{all-popups}\
              +filter{webbugs} +filter{banners-by-size}
allow-ads   = -block -filter{banners-by-size} -filter{banners-by-link}
{ fragile }
'
echo "http://${REALMADMINHTTPD}.*"
echo 'http://privet.ct.local.*
http://localhost.*
# BING Add &adlt=strict
{+redirect{s@$@&adlt=strict@}}
.bing./.*[&?]q=
{-redirect}
.bing./.*&adlt=strict

{+redirect{s@http://.*/images/close.*.png@http://privet.ct.local/images/X32px.png@}}
.*

{+redirect{s@http://.*/close.*.png@http://privet.ct.local/images/X32px.png@}}
.*

'
    } >  $PRIVOXYCTA

    $PROXYrestart
    echo "</confprivoxy>"
}

function  gensalt() {   
local length=${1:-8}
tr -dc A-Za-z0-9_ < /dev/urandom | head -c "${length}" | xargs
}

function addadminhttpdapr1md5php () {
    if [ ! -f "$PASSWORDFILEHTTPD" ]; then touch "$PASSWORDFILEHTTPD"; fi
    USERADMINHTTPD=${1}
    pass=${2}
    echo -n "${USERADMINHTTPD}:" > "$PASSWORDFILEHTTPD"
    openssl passwd -apr1 -salt "$(gensalt)" "${pass}" >> "$PASSWORDFILEHTTPD"
    chown root:"$USERHTTPD" "$PASSWORDFILEHTTPD"
    chmod 640 "$PASSWORDFILEHTTPD"
}


function download() {
	echo "<download>"
    rm -rf $tempDIR
    mkdir -p $tempDIR
    # on attend que la connection remonte suite au redémarrage de networkmanager
    echo "$(gettext 'Waiting to connect to Toulouse server:')"
    i=1
    while [ "$(wgeturlok "$BL_T" )" -eq 0 ]
    do
    echo -n .
    sleep 1
    i=$(( i + 1 ))
    # si au bout de 40 secondes on n'a toujours pas de connection on considère qu'il y a une erreur
    if [ $i -ge 20 ];then
       # on tente de redémarer networkmager pour resoudre d'éventuel problèmes de configuration
       if [ $i -eq 20 ];then
       $NWMANAGERrestart
       fi
       if [ $i -ge 60 ];then
          # on abendonne car il y a surement un problème plus grave.
          echo "$(gettext 'Connection to Toulouse server is impossible.')"
          set -e
          exit 1
       fi
    fi
    done
    echo "$(gettext 'connection established:')"
    
    # optention de la somme md5 des derniere version des bl 
    {
wget -O - $FILMD5BL_T 2>/dev/null | grep blacklists.tar.gz 
wget -O - $FILMD5CT 2>/dev/null | grep blacklists2.tar.gz 
} > $tempDIR/allblmd5
    newblmd5sum="$({
cat $tempDIR/allblmd5
} | md5sum | cut -d " " -f1)"
    ## les 2 somme md5 non pas réussi a ètre récupérées probablement a cause d'un problème de téléchargement.
    if [ $(grep -c "[blacklists.tar.gz|blacklists2.tar.gz]" $tempDIR/allblmd5) -lt 2 ];then
        echo "
        $(gettext 'error when downloading, process interrupted')
        "
        echo "$FILMD5BL_T"
        echo "$FILMD5CT"
        rm -rf $tempDIR
        set -e
        exit 1
    fi
    if [ -f $DIR_CONF/blacklists.tar.gz.md5sum ]; then
		oldblmd5sum="$(cat $DIR_CONF/blacklists.tar.gz.md5sum)"
    else
        oldblmd5sum=" "
    fi
    # on télécharge en ca de changemant su une des bl.
    if [ "$newblmd5sum" = "$oldblmd5sum" ];then
        echo "$(gettext 'blacklists are already up to date')"
        rm -rf $tempDIR
        set -e
        exit 1    
    fi
    wget -q -P $tempDIR $BL_T 2>&1 | cat
    if [ ! $? -eq 0 ]; then
        echo "$(gettext 'error when downloading, process interrupted')"
        echo "$BL_T"
        rm -rf $tempDIR
        set -e
        exit 1
    fi
    tarfile=$(basename "$BL_T")
    tar -xzf "$tempDIR/$tarfile" -C $tempDIR
    if [ ! $? -eq 0 ]; then
        echo "$(gettext 'archive extraction error, process interrupted')"
        set -e
        exit 1
    fi
       
    # on télécharge aussi la blacklist personalisée de ctparental
    wget -q -P $tempDIR $BL_CT 2>&1 | cat
    if [ ! $? -eq 0 ]; then
        echo "$(gettext 'error when downloading, process interrupted')"
        echo "$BL_CT"
        rm -rf $tempDIR
        set -e
        exit 1
    fi
    tarfile=$(basename "$BL_CT")
    tar -xzf "$tempDIR/$tarfile" -C $tempDIR
    if [ ! $? -eq 0 ]; then
        echo "$(gettext 'archive extraction error , process interrupted')"
        set -e
        exit 1
    fi
    echo -n $newblmd5sum > $DIR_CONF/blacklists.tar.gz.md5sum
    sedtempdir=$(echo $tempDIR | sed -e "s?\/?\\\/?g")
    find $tempDIR -type f -name domains -exec md5sum {} \; | sed -e "s/  $sedtempdir\/blacklists//g" > $tempDIR/categoriesmd5sum 
    mkdir $DIR_DNS_FILTER_AVAILABLE 2>/dev/null
    mkdir $DIR_IPV4_FILTER_AVAILABLE 2>/dev/null
    mkdir $DIR_IPV6_FILTER_AVAILABLE 2>/dev/null
    echo "</download>"
}

function autoupdateon() {
    $SED "s?^AUTOUPDATE.*?AUTOUPDATE=ON?g" $FILE_CONF
    if [ -f $BINSYSTEMCTL ] ; then
    {
     echo "[Unit]
Description=updates parental control from the blacklist of the University of Toulouse
After=network-online.target


[Service]
User=root
WorkingDirectory=/root/
ExecStart=$CHEMINCTPARENTLE -dl
Type=oneshot

[Install]
WantedBy=default.target

"
} > /etc/systemd/system/CTparentalaup.service
# on redémare le démon systemd pour prendre en compte ce nouveau service
systemctl daemon-reload
{
echo "
[Unit]
Description=updates parental control from the blacklist of the University of Toulouse every week

[Timer]
# on attent 5 minute après le boot
OnBootSec=5min
# toute les semaines
OnUnitActiveSec=1w
# Autoriser la persistence entre les reboot
Persistent=true
[Install]
WantedBy=timers.target
"
} > /etc/systemd/system/CTparentalaup.timer
systemctl enable CTparentalaup.timer
systemctl start CTparentalaup.timer
   else
   		## on utise cron si systemd n'est pas présent
		{
		echo "export PATH=$PATH
* * * * * USER=root ID=CTparentalaup FREQ=7d $CHEMINCTPARENTLE -dl" 
		} > /etc/cron.d/CTparentalaup
		/etc/rc.d/rc.crond restart
   
   fi
}

function autoupdateoff() {
     $SED "s?^AUTOUPDATE.*?AUTOUPDATE=OFF?g" $FILE_CONF
      if [ -f $BINSYSTEMCTL ] ; then
		 systemctl disable CTparentalaup.timer
		 systemctl stop CTparentalaup.timer
		 rm -f /etc/systemd/system/CTparentalaup.service
		 rm -f /etc/systemd/system/CTparentalaup.timer
		 # on redémare le démon systemd pour prendre en compte ce nouveau service
		 systemctl daemon-reload
     else
         rm -f /etc/cron.d/CTparentalaup
         /etc/rc.d/rc.crond restart
     fi

}

function adapt() {
    echo "<adapt>"
    date +%H:%M:%S
    $DNSCRYPTstop
    $MFILEtmp
    if [ ! -f $BL_DIPOSSI ] ; then
       echo > $BL_DIPOSSI
    fi
    if [ ! -f $REABDIP ] ; then
       echo > $REABDIP
    fi

    if [ ! -f $DIR_CONF/categoriesmd5sum ];then
       echo > $DIR_CONF/categoriesmd5sum
       chmod 744 $DIR_CONF/categoriesmd5sum
    fi
    if [ -d $tempDIR  ] ; then
        TMP_CATEGORIES_AVAILABLE="$tempDIR"/categories_available
        echo -n > $TMP_CATEGORIES_AVAILABLE
        echo -n > $WL_CATEGORIES_AVAILABLE
        echo -n > $BL_CATEGORIES_AVAILABLE
        if [ ! -f $DIR_DNS_FILTER_AVAILABLE/ossi.conf ] ; then
            echo > $DIR_DNS_FILTER_AVAILABLE/ossi.conf
        fi
        if [ ! -f $DIR_IPV4_FILTER_AVAILABLE/ossi.conf ] ; then
            echo > $DIR_IPV4_FILTER_AVAILABLE/ossi.conf
        fi
        if [ ! -f $DIR_IPV6_FILTER_AVAILABLE/ossi.conf ] ; then
            echo > $DIR_IPV6_FILTER_AVAILABLE/ossi.conf
        fi
        gettext 'Toulouse Blacklist and WhiteList migration process. Please wait.'
        cd "$tempDIR"/blacklists
        for categorie in *
        do
            if [ -d "$categorie" ] ; then
            if [ ! -L "$categorie" ] ; then
                echo "$categorie" >> $TMP_CATEGORIES_AVAILABLE
                echo -n "."
                catmd5sumtest=0
                ## on mais a jour si un changement a eux lieux dans la categorie
                if [ "$(grep "/$categorie/" $tempDIR/categoriesmd5sum | cut -d"/" -f1)" != "$(grep "/$categorie/" $DIR_CONF/categoriesmd5sum | cut -d"/" -f1)" ];then 
                   catmd5sumtest=1
                   grep -E "^(((2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}).){3}(2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}))($|/(([1-9])|([1-2][0-9])|(3[0-2]))$)" "$tempDIR"/blacklists/"$categorie"/domains > $DIR_IPV4_FILTER_AVAILABLE/"$categorie".conf
                   grep -E "^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))($|/(([1-9])|([1-9][0-9])|(1[0-1][0-9])|(12[0-8]))$)" "$tempDIR"/blacklists/"$categorie"/domains > $DIR_IPV6_FILTER_AVAILABLE/"$categorie".conf
                   #cp -f "$tempDIR"/blacklists/"$categorie"/domains "$FILE_tmp"
                   ## on ne garde que les nom de domaine valide (suppressions ivpv4 ipv6 les entrée xx.blogspot.xx ..)
                   ## supprime xx--xxxx , -xxxx , xxxx-.xxxx , #xxxx , ligne vide , ligne contenent de caractèrs spéciaux 
                   ## voir https://www.generation-nt.com/reponses/nom-domaine-caracteres-speciaux-entraide-231588.html#943863
                   ## on supprime les 1313541 entrées xx.blogspot.xx
                   ## dans la catégorie adult qui sont gérées par
                   ## une liste beaucoup plus courte dans la
                   ## catégorie ctparental
                   grep -vE  "^(.{2}--)|\..{2}--|^(.*-\.)|^(-)|^(#)|[+äâëêïîöôüûàçèé&\!@,]|^$|.*blogspot\..*|^((2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})\.){3}(2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})$" "$tempDIR"/blacklists/"$categorie"/domains | grep -vE "^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$" | awk '{ gsub("\\.+\\.",".");print }' > "$DIR_DNS_FILTER_AVAILABLE"/"$categorie".conf

                fi
                if [ -e "$tempDIR"/blacklists/"$categorie"/usage ] ; then
                   if [ "$(grep -c "white" "$tempDIR"/blacklists/"$categorie"/usage)" -ge 1 ] ;then
                       echo "$categorie" >> $WL_CATEGORIES_AVAILABLE
                   else
                       echo "$categorie" >> $BL_CATEGORIES_AVAILABLE
                   fi
                else
                   echo "$categorie" >> $BL_CATEGORIES_AVAILABLE
                fi
            fi
            fi
        done
        echo > "$CATEGORIES_AVAILABLE"
        cat "$TMP_CATEGORIES_AVAILABLE" >> "$CATEGORIES_AVAILABLE"
        echo -n "."
        ## gestion de la blacklist ossi (ipv4 + ipv6 + dns) 
        # suppression des @IP, de caractères acccentués et des lignes commentées ou vides
        ##cp -f $BL_DIPOSSI "$FILE_tmp"
        grep -E "^(((2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}).){3}(2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}))($|/(([1-9])|([1-2][0-9])|(3[0-2]))$)" $BL_DIPOSSI > $DIR_IPV4_FILTER_AVAILABLE/ossi.conf
        grep -E "^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))($|/(([1-9])|([1-9][0-9])|(1[0-1][0-9])|(12[0-8]))$)" $BL_DIPOSSI > $DIR_IPV6_FILTER_AVAILABLE/ossi.conf
        grep -vE  "^(.{2}--)|\..{2}--|^(.*-\.)|^(-)|^(#)|[+äâëêïîöôüûàçèé&\!@,]|^$|.*blogspot\..*|^((2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})\.){3}(2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})$" $BL_DIPOSSI | grep -vE "^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$" | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" > "$DIR_DNS_FILTER_AVAILABLE"/ossi.conf
        ## IPv6 et v4 Whiteliste
        grep -E "^(((2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}).){3}(2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}))($|/(([1-9])|([1-2][0-9])|(3[0-2]))$)" $REABDIP > $DIR_IPV4_FILTER_AVAILABLE/wossi.conf
        grep -E "^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))($|/(([1-9])|([1-9][0-9])|(1[0-1][0-9])|(12[0-8]))$)" $REABDIP > $DIR_IPV6_FILTER_AVAILABLE/wossi.conf       

        cp -f $tempDIR/categoriesmd5sum $DIR_CONF/categoriesmd5sum
 
    else
        mkdir -p  $tempDIR
        echo -n "."
        ## gestion de la blacklist ossi (ipv4 + ipv6 + dns) 
        # suppression des @IP, de caractères acccentués et des lignes commentées ou vides
        grep -E "^(((2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}).){3}(2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}))($|/(([1-9])|([1-2][0-9])|(3[0-2]))$)" $BL_DIPOSSI > $DIR_IPV4_FILTER_AVAILABLE/ossi.conf
        grep -E "^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))($|/(([1-9])|([1-9][0-9])|(1[0-1][0-9])|(12[0-8]))$)" $BL_DIPOSSI > $DIR_IPV6_FILTER_AVAILABLE/ossi.conf
        grep -vE  "^(.{2}--)|\..{2}--|^(.*-\.)|^(-)|^(#)|[+äâëêïîöôüûàçèé&\!@,]|^$|.*blogspot\..*|^((2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})\.){3}(2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})$" $BL_DIPOSSI | grep -vE "^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$" | awk '{ gsub("\\.+\\.",".");print }' > "$DIR_DNS_FILTER_AVAILABLE"/ossi.conf

        grep -E "^(((2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}).){3}(2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}))($|/(([1-9])|([1-2][0-9])|(3[0-2]))$)" $REABDIP > $DIR_IPV4_FILTER_AVAILABLE/wossi.conf
        grep -E "^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))($|/(([1-9])|([1-9][0-9])|(1[0-1][0-9])|(12[0-8]))$)" $REABDIP > $DIR_IPV6_FILTER_AVAILABLE/wossi.conf       
 
    fi
    echo
    $UMFILEtmp
    cd "$(dirname "$(readlink -f "$0")")"
    rm -rf $tempDIR
    date +%H:%M:%S
    echo "</adapt>"
}

function catChoice() {
    echo "<catChoice>"
    if [ ! -f $REABDIP ] ; then
        echo > "$REABDIP"
    fi
    dreabmd5old=$(grep MD5DREAB= "$FILE_CONF" | cut -d"=" -f2)
    md5new="$({
cat "$REABDIP" "$CATEGORIES_ENABLED" "$SAFE_CONF"
echo "$DOMAINEDEPOTS"
md5sum $DIR_DNS_FILTER_AVAILABLE/* | grep -v ossi.conf
md5sum $DIR_IPV6_FILTER_AVAILABLE/* | grep -v ossi.conf
md5sum $DIR_IPV4_FILTER_AVAILABLE/* | grep -v ossi.conf
} | md5sum | awk {'print $1'})"
     ## évite de lancer la moulinette de réhabilitation des domaines
     ## quand aucun changement ne le nécéssite.
     if [ ! "$dreabmd5old" = "$md5new" ]; then
    echo > ${DNSCRYPTBL:?}
    echo > ${DNSCRYPTWL:?}
    echo > ${DNSCRYPTCR:?}
    rm -rf ${DIR_IPV6_FILTER_ENABLED:?}/
    mkdir $DIR_IPV6_FILTER_ENABLED 2>/dev/null
    rm -rf ${DIR_IPV4_FILTER_ENABLED:?}/
    mkdir $DIR_IPV4_FILTER_ENABLED 2>/dev/null
    rm -rf ${DIR_IPV6_WHITELIST_ENABLED:?}/
    mkdir $DIR_IPV6_WHITELIST_ENABLED 2>/dev/null
    rm -rf ${DIR_IPV4_WHITELIST_ENABLED:?}/
    mkdir $DIR_IPV4_WHITELIST_ENABLED 2>/dev/null
    while read CATEGORIE
    do
        if [ "$(grep -c "$CATEGORIE" "$BL_CATEGORIES_AVAILABLE")" -ge "1" ] ; then
           cat $DIR_DNS_FILTER_AVAILABLE/"$CATEGORIE".conf >> $DNSCRYPTBL
           cp -f $DIR_IPV6_FILTER_AVAILABLE/"$CATEGORIE".conf $DIR_IPV6_FILTER_ENABLED/"$CATEGORIE".conf
           cp -f $DIR_IPV4_FILTER_AVAILABLE/"$CATEGORIE".conf $DIR_IPV4_FILTER_ENABLED/"$CATEGORIE".conf
        else
           cat $DIR_DNS_FILTER_AVAILABLE/"$CATEGORIE".conf >> $DNSCRYPTWL
           cp -f $DIR_IPV6_FILTER_AVAILABLE/"$CATEGORIE".conf $DIR_IPV6_WHITELIST_ENABLED/"$CATEGORIE".conf
           cp -f $DIR_IPV4_FILTER_AVAILABLE/"$CATEGORIE".conf $DIR_IPV4_WHITELIST_ENABLED/"$CATEGORIE".conf
        fi
    done < $CATEGORIES_ENABLED
    reabdomaine
    $SED "s?^MD5DREAB.*?MD5DREAB=$md5new?" $FILE_CONF

    fi
    cat $DIR_DNS_FILTER_AVAILABLE/ossi.conf >> $DNSCRYPTBL
    cp -f $DIR_IPV6_FILTER_AVAILABLE/ossi.conf $DIR_IPV6_FILTER_ENABLED/ossi.conf
    cp -f $DIR_IPV4_FILTER_AVAILABLE/ossi.conf $DIR_IPV4_FILTER_ENABLED/ossi.conf
    cp -f $DIR_IPV6_FILTER_AVAILABLE/wossi.conf $DIR_IPV6_WHITELIST_ENABLED/wossi.conf
    cp -f $DIR_IPV4_FILTER_AVAILABLE/wossi.conf $DIR_IPV4_WHITELIST_ENABLED/wossi.conf

    nftablesreload
    $DNSCRYPTstart
    echo "</catChoice>"
}

function reabdomaine() {
    echo "<reabdomaine>"
    date +%H:%M:%S
    $MFILEtmp
    if [ ! -f $REABDIP ] ; then
    echo > "$REABDIP"
    fi
    if [ ! -f ${DIR_IPV4_WHITELIST_ENABLED}/wossi.conf ] ; then
        echo > ${DIR_IPV4_WHITELIST_ENABLED}/wossi.conf
    fi
    if [ ! -f ${DIR_IPV6_WHITELIST_ENABLED}/wossi.conf ] ; then
        echo > ${DIR_IPV6_WHITELIST_ENABLED}/wossi.conf
    fi
    if [ ! -f $DNSCRYPTBL ] ; then
         echo > $DNSCRYPTBL
    fi

    grep -E "^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))($|/(([1-9])|([1-9][0-9])|(1[0-1][0-9])|(12[0-8]))$)" "$REABDIP" | sed 's/\//\\\//g' > $IPV6REAB
    grep -E "^(((2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}).){3}(2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}))($|/(([1-9])|([1-2][0-9])|(3[0-2]))$)" "$REABDIP" | sed 's/\//\\\//g' > $IPV4REAB
    grep -vE  "^(.{2}--)|\..{2}--|^(.*-\.)|^(-)|^(#)|[+äâëêïîöôüûàçèé&\!@,]|^$|.*blogspot\..*|^((2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})\.){3}(2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2})$" $REABDIP    | grep -vE "^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))$" | awk '{ gsub("\\.+\\.",".");print }' > $DREAB

    echo
    gettext 'Application whitelisting (restored area):'
    cat $DREAB > $DNSCRYPTWL
    echo -n "."
    echo "$DOMAINEDEPOTS" >> $DNSCRYPTWL
    echo "$BL_SERVER" | sed -e "s? ??"  >> $DNSCRYPTWL
    echo -n "."
    while read CATEGORIE
    do
    if [ "$(grep -c "$CATEGORIE" "$BL_CATEGORIES_AVAILABLE" )" -ge "1" ] ; then
        echo -n "."   
        while read -r IPV4
        do
        cp -f $DIR_IPV4_FILTER_ENABLED/"$CATEGORIE".conf "$FILE_tmp"
        $SED "/$IPV4/d" "$FILE_tmp"
        cp -f "$FILE_tmp" $DIR_IPV4_FILTER_ENABLED/"$CATEGORIE".conf
        done < $IPV4REAB
        
        while read -r IPV6
        do
        cp -f $DIR_IPV6_FILTER_ENABLED/"$CATEGORIE".conf "$FILE_tmp"
        $SED "/$IPV6/d" "$FILE_tmp"
        cp -f "$FILE_tmp" $DIR_IPV6_FILTER_ENABLED/"$CATEGORIE".conf
        done < $IPV6REAB
    fi
    done < $CATEGORIES_ENABLED
    {
    echo 'localhost
127.0.0.1'
    echo "$PRIVATE_IP4
$ADMIN_IP4
$BL_SERVER"
    for domain in $DOMAINEDEPOTS
    do
        echo "$domain"
    done
    cat $DREAB | sed -e"s/^\.//" | sed -e"s/^www.//"
    }  > "$E2GUXSITELIST"
    echo
    $UMFILEtmp
    rm -f "$FILE_tmp"
    date +%H:%M:%S

    {
    if [ "$( grep -c "^SAFEGOOGLE" $SAFE_CONF )" -eq 1 ];then
        echo "www.google.*  forcesafesearch.google.com"
    fi
    if [ "$( grep -c "^SAFEYOUTUBE" $SAFE_CONF )" -eq 1 ];then
        echo "www.youtube.com          restrictmoderate.youtube.com
m.youtube.com            restrictmoderate.youtube.com
youtubei.googleapis.com  restrictmoderate.youtube.com
youtube.googleapis.com   restrictmoderate.youtube.com
www.youtube-nocookie.com restrictmoderate.youtube.com"
    fi
    if [ "$( grep -c "^SAFEBING" $SAFE_CONF )" -eq 1 ];then
         echo "*.bing.com             strict.bing.com"
    fi
    if [ "$( grep -c "^SAFEDUCK" $SAFE_CONF )" -eq 1 ];then
         echo "=duckduckgo.com $ADMIN_IP4"
         echo "=duckduckgo.com $ADMIN_IP6"

    fi
    if [ "$( grep -c "^SAFEQWANT" $SAFE_CONF  )" -eq 1 ];then
         echo "www.qwant.com $ADMIN_IP4"
         echo "www.qwant.com $ADMIN_IP6"
    fi
    echo "$REALMADMINHTTPD $ADMIN_IP4"
    echo "$REALMADMINHTTPD $ADMIN_IP6"
    echo "privet.ct.local $PRIVATE_IP4"
    echo "privet.ct.local $PRIVATE_IP6"
    } > $DNSCRYPTCR

    echo "</reabdomaine>"
}

function genfilerotatedns() {
{
echo "
/var/log/CTdnscrypt-proxy/*.log {
        daily
        missingok
        rotate $LOGDAYROTATE
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
        service rsyslog restart ; sleep 5
        endscript
}
"
} > $FILEROTATEDNS   
}

function dnscryptproxyon() {
echo "<dnscryptproxyon>"
LOGDNS=$(grep LOGDNS= "$FILE_CONF" | cut -d"=" -f2)
if [ "$LOGDNS" = "ON" ];then
DNSCRYPTNXLOG=${DNSCRYPTNXLOG:="/var/log/CTdnscrypt-proxy/nx.log"}
DNSCRYPTQUERYLOG=${DNSCRYPTQUERYLOG:="/var/log/CTdnscrypt-proxy/query_names.log"}
DNSCRYPTBLLOG=${DNSCRYPTBLLOG:="/var/log/CTdnscrypt-proxy/blocked-names.log"}
DNSCRYPTWLLOG=${DNSCRYPTWLLOG:="/var/log/CTdnscrypt-proxy/allowed-names.log"}
else
DNSCRYPTNXLOG="/dev/null"
DNSCRYPTQUERYLOG="/dev/null"
DNSCRYPTBLLOG="/dev/null"
DNSCRYPTWLLOG="/dev/null"
fi

DNSCRYPTIPLISTSEP=","
DNSCRYPTIPV6ON="true"
DNSCRYPTNOAAAA="false"
DNSCRYPTIPLISTV6="'[$PRIVATE_IP6]:54'"
if [ -z $ip_i_WAN_ipv6 ] ; then
DNSCRYPTIPV6ON="false"
DNSCRYPTIPLISTV6=""
DNSCRYPTIPLISTSEP=""
DNSCRYPTNOAAAA="true"
fi
DNSCRYPTIPV4ON="true"
DNSCRYPTIPLISTV4="'$PRIVATE_IP4:54'"
if [ -z $ip_i_WAN_ipv4 ] ; then
DNSCRYPTIPV4ON="false"
DNSCRYPTIPLISTV4=""
DNSCRYPTIPLISTSEP=""
fi


{
echo "
##https://github.com/DNSCrypt/dnscrypt-proxy/blob/master/dnscrypt-proxy/example-dnscrypt-proxy.toml
# Empty listen_addresses to use systemd socket activation
## List of local addresses and ports to listen to. Can be IPv4 and/or IPv6.
## Example with both IPv4 and IPv6:
## listen_addresses = ['127.0.0.1:53', '[::1]:53']
##
## To listen to all IPv4 addresses, use listen_addresses = ['0.0.0.0:53']
## To listen to all IPv4+IPv6 addresses, use listen_addresses = ['[::]:53']
listen_addresses = [${DNSCRYPTIPLISTV4}${DNSCRYPTIPLISTSEP}${DNSCRYPTIPLISTV6}]
server_names = [$DNSCRYPTSERVEURS]
dnscrypt_servers = true
doh_servers = true
ipv6_servers = $DNSCRYPTIPV6ON
ipv4_servers = $DNSCRYPTIPV4ON
require_dnssec = true

block_ipv6 = $DNSCRYPTNOAAAA

###############################
#        Cloaking rules       #
###############################
## Cloaking returns a predefined address for a specific name.
## In addition to acting as a HOSTS file, it can also return the IP address
## of a different name. It will also do CNAME flattening.
##
## Example map entries (one entry per line)
## example.com     10.1.1.1
## www.google.com  forcesafesearch.google.com

cloaking_rules = '$DNSCRYPTCR'

###########################
#        DNS cache        #
###########################
## Enable a DNS cache to reduce latency and outgoing traffic
cache = true
## Cache size
cache_size = 4096
## Minimum TTL for cached entries
cache_min_ttl = 2400
## Maximum TTL for cached entries
cache_max_ttl = 86400
## Minimum TTL for negatively cached entries
cache_neg_min_ttl = 60
## Maximum TTL for negatively cached entries
cache_neg_max_ttl = 600

## Automatic log files rotation
# Maximum log files size in MB - Set to 0 for unlimited.
#log_files_max_size = 10
# How long to keep backup files, in days
#log_files_max_age = 7
# Maximum log files backups to keep (or 0 to keep all backups)
#log_files_max_backups = 1
[query_log]
#  file = '/var/log/CTdnscrypt-proxy/query.log'
  file = '$DNSCRYPTQUERYLOG'

[nx_log]
#  file = '/var/log/CTdnscrypt-proxy/nx.log'
  file = '$DNSCRYPTNXLOG'

[sources]
  [sources.'public-resolvers']
  url = '$DNSCRYPTPUBURL'
  cache_file = '$DNSCRYPTSPCACHEFILE'
  minisign_key = '$DNSCRYPTMINKEY'
  refresh_delay = 72
  prefix = ''

######################################################
#        Pattern-based blocking (blocklists)         #
######################################################

## Blocklists are made of one pattern per line. Example of valid patterns:
##
##   example.com
##   =example.com
##   *sex*
##   ads.*
##   ads*.example.*
##   ads*.example[0-9]*.com
##
## Example blocklist files can be found at https://download.dnscrypt.info/blocklists/
## A script to build blocklists from public feeds can be found in the
## 
[blocked_names]
## Path to the file of blocking rules (absolute, or relative to the same directory as the config file)
blocked_names_file = '$DNSCRYPTBL'
## Optional path to a file logging blocked queries
log_file = '$DNSCRYPTBLLOG'
## Optional log format: tsv or ltsv (default: tsv)
# log_format = 'tsv'
[blocked_ips]
## géré par nftables
[allowed_names]
## Path to the file of allow list rules (absolute, or relative to the same directory as the config file)
allowed_names_file = '$DNSCRYPTWL'
## Optional path to a file logging allowed queries
# log_file = 'allowed-names.log'
log_file = '$DNSCRYPTWLLOG'
## Optional log format: tsv or ltsv (default: tsv)
# log_format = 'tsv'

"

} > $DNSCRYPTCONF

LOGDNS=$(grep LOGDNS= "$FILE_CONF" | cut -d"=" -f2)
if [ "$LOGDNS" = "ON" ];then
	if [ ! -f $FILEROTATEDNS ] ; then
	   genfilerotatedns
	fi

	if [ "$(grep -c "rotate $LOGDAYROTATE" $FILEROTATEDNS)" -eq "0" ] ;then
	   genfilerotatedns
	fi
fi

if [ "$(grep -c "whitelist_enable" $CATEGORIES_ENABLED )" -eq "0" ] ; then

    $SED "s?^DNSCRYPT.*?DNSCRYPT=BLACK?g" $FILE_CONF
else
   echo "*.*" > "$DNSCRYPTBL"
   $SED "s?^DNSCRYPT.*?DNSCRYPT=WHITE?" $FILE_CONF
fi
$DNSCRYPTrestart
$E2GUARDIANrestart
$PROXYrestart
	
echo "</dnscryptproxyon>"
}


function dnscryptproxyoff() {
    echo "<dnscryptproxyoff>"
    $SED "s?^DNSCRYPT.*?DNSCRYPT=OFF?" $FILE_CONF
    echo "</dnscryptproxyoff>"
}

function nftglobal() {
    echo "<nftglobal>"
 
    ### IP indésirables
    echo "<$FILEIPBLACKLIST>"
        nft add set ip filter ipv4filterforall { type ipv4_addr\;flags interval\;}
        nft add set ip6 filter ipv6filterforall { type ipv6_addr\;flags interval\;}
        {
        echo -n 'table ip filter {
    set ipv4filterforall {
        type ipv4_addr 
        flags interval
        elements = {'
        grep -E "^(((2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}).){3}(2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}))($|/(([1-9])|([1-2][0-9])|(3[0-2]))$)" ${FILEIPBLACKLIST} | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | sed -e 's/$/,/g' | sed -e '$ s/.$//'
        echo '       }
    }
}'

        } > /tmp/ipv4filterforall
        ## si element non vide 
        if [ $(grep -cE "elements = {.*\." /tmp/ipv4filterforall) -eq 1 ];then
            nft -f /tmp/ipv4filterforall
            nft add rule ip filter output ip daddr @ipv4filterforall $LOG4REJECT reject
            nft add rule ip filter input ip saddr @ipv4filterforall drop
        fi
        #rm -f /tmp/ipv4filterforall
        {
        echo -n 'table ip6 filter {
    set ipv6filterforall {
        type ipv6_addr
        flags interval
        elements = {'
        grep -E "^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))($|/(([1-9])|([1-9][0-9])|(1[0-1][0-9])|(12[0-8]))$)" ${FILEIPBLACKLIST} | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | sed -e 's/$/,/g' | sed -e '$ s/.$//'
        echo '       }
    }
}'

        } > /tmp/ipv6filterforall
        if [ $(grep -cE "elements = {.*:" /tmp/ipv6filterforall) -eq 1 ];then
            nft -f /tmp/ipv6filterforall
            nft add rule ip6 filter output ip6 daddr @ipv6filterforall $LOG6REJECT reject
            nft add rule ip6 filter input ip6 saddr @ipv6filterforall drop
        fi
    echo "</$FILEIPBLACKLIST>"
    

    ### ACCEPT ALL interface loopback ###
	nft insert rule ip filter output oif lo accept
	nft insert rule ip6 filter output oif lo accept
	nft insert rule ip filter input iif lo accept
	nft insert rule ip6 filter input iif lo accept
	
	
    ## autoriser le multicast dns (mDNS)
    nft add rule ip filter input udp sport 5353 accept 
    nft add rule ip filter output udp dport 5353 $LOG4ACCEPT accept 
    nft add rule ip6 filter input udp sport 5353 accept
    nft add rule ip6 filter output udp dport 5353 $LOG6ACCEPT accept
   
   
    
    ## Link-Local Multicast Name Resolution (LLMNR)
    nft add rule ip filter input udp dport 5355 $LOG4ACCEPT accept 
    nft add rule ip filter output udp dport 5355 $LOG4ACCEPT accept 
    nft add rule ip6 filter input udp dport 5353 $LOG6ACCEPT accept
    nft add rule ip6 filter output udp dport 5353 $LOG6ACCEPT accept
    nft add rule ip filter input tcp dport 5355 ct state new $LOG4ACCEPT accept  
    nft add rule ip filter output tcp dport 5355 $LOG4ACCEPT accept 
    nft add rule ip6 filter input tcp dport 5353 ct state new $LOG6ACCEPT accept
    nft add rule ip6 filter output tcp dport 5353 ct state new  $LOG6ACCEPT accept
   
     


    ## accépter requette ipv6 de recherche de routeurs
    nft add rule ip6 filter output ip6 daddr ff02::2  accept 
    nft add rule ip6 filter output ip6 daddr ff02::16  accept

    ### accepte en entrée les connexions déjà établies (en gros cela
    ### permet d'accepter les connexions initiées par son propre PC)
    nft add rule ip filter input ct state established,related accept
    nft add rule ip6 filter input ct state established,related accept

    ### DHCP
    nft add rule ip filter output udp sport 68 udp dport 67 accept 
    nft add rule ip filter input udp sport 67 udp dport 68 accept 
    nft add rule ip6 filter output udp sport 68 udp dport 67 accept 
    nft add rule ip6 filter input udp sport 67 udp dport 68 accept 

    ### DNS indispensable pour naviguer facilement sur le web ###
    nft add rule ip filter output udp dport 53 accept 
    nft add rule ip filter output tcp dport 53 ct state new $LOG4ACCEPT accept 
    nft add rule ip filter output ip daddr $PRIVATE_IP4 udp dport 54 accept
    nft add rule ip filter output ip daddr $PRIVATE_IP4 tcp dport 54 ct state new $LOG4ACCEPT accept 
    nft add rule ip6 filter output udp dport 53 accept 
    nft add rule ip6 filter output tcp dport 53 ct state new $LOG4ACCEPT accept 
    nft add rule ip6 filter output ip6 daddr $PRIVATE_IP6 udp dport 54 accept
    nft add rule ip6 filter output ip6 daddr $PRIVATE_IP6 tcp dport 54 ct state new $LOG4ACCEPT accept  
  
  
    ### HTTP navigation internet non sécurisée ###
    nft add rule ip filter output tcp dport 80 ct state new $LOG4ACCEPT counter accept
    nft add rule ip6 filter output tcp dport 80 ct state new $LOG6ACCEPT counter accept 
 
    
    ### HTTPS pour le site des banques .... ###
    nft add rule ip filter output tcp dport 443 ct state new $LOG4ACCEPT counter accept
    nft add rule ip6 filter output tcp dport 443 ct state new $LOG6ACCEPT counter accept

    
    # On autorise les requêtes FTP vers l'éxtèrieurs
    nft add rule ip filter output tcp dport 21 ct state new $LOG4ACCEPT counter accept
    nft add rule ip filter output ct state related,established  counter accept
    nft add rule ip6 filter output tcp dport 21 ct state new $LOG6ACCEPT counter accept   
    nft add rule ip6 filter output ct state related,established  counter accept
       
    ### ping ... autorise l'icmp et l'icmpv6  ###
    nft add rule ip filter output icmp type {echo-reply, destination-unreachable, source-quench, redirect, echo-request, time-exceeded, parameter-problem, timestamp-request, timestamp-reply, info-request, info-reply, address-mask-request, address-mask-reply, router-advertisement, router-solicitation} accept
    nft add rule ip6 filter output icmpv6 type {destination-unreachable, packet-too-big, time-exceeded, echo-request, echo-reply, mld-listener-query, mld-listener-report, mld-listener-reduction, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, nd-redirect, parameter-problem, router-renumbering} accept
    nft add rule ip filter input icmp type {echo-reply, destination-unreachable, source-quench, redirect, echo-request, time-exceeded, parameter-problem, timestamp-request, timestamp-reply, info-request, info-reply, address-mask-request, address-mask-reply, router-advertisement, router-solicitation} accept
    nft add rule ip6 filter input icmpv6 type {destination-unreachable, packet-too-big, time-exceeded, echo-request, echo-reply, mld-listener-query, mld-listener-report, mld-listener-reduction, nd-router-solicit, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert, nd-redirect, parameter-problem, router-renumbering} accept
    ### clientNTP ... syncro à un serveur de temps ###
    nft add rule ip filter output udp dport 123 accept
    nft add rule ip6 filter output udp dport 123 accept


    # On autorise l'incmpv6 sur les liens locaux
    nft add rule ip6 filter input meta l4proto ipv6-icmp ip6 daddr fe80::/10 counter accept
    nft add rule ip6 filter input meta l4proto ipv6-icmp ip6 saddr fe80::/10 counter accept
    
    # An autorise le ssh en sortie vers les liens locaux (client)
    nft add rule ip6 filter output ip6 daddr fe80::/10 tcp dport $PORTSSH ct state new $LOG6ACCEPT accept
    # An autorise le ssh en entré depuis une ip de liens locaux (srvsync)
    if [ "$(grep -c "SRVSYNC=ON" "$DIR_CONF"/ctsync.conf)" -eq 1 ] ;then
        nft add rule ip6 filter input ip6 saddr fe80::/10 tcp dport $PORTSSH ct state new $LOG6ACCEPT accept
    fi
    

    
    echo "<$FILEFIRWALLCONF>"
    source "$FILEFIRWALLCONF"
    echo "</$FILEFIRWALLCONF>"

    ### LOG ### Log tout ce qui qui n'est pas accepté par une règle précédente
    nft add rule ip6 filter output $LOG6REJECT counter 
    nft add rule ip6 filter input $LOG6REJECT counter
    nft add rule ip filter output $LOG4REJECT counter
    nft add rule ip filter input $LOG4REJECT counter
    
    ## on rejete toutes les autres demandes en sortie ( évite le temps d'attente de la pocicy drop )
    nft add rule ip filter output reject
    nft add rule ip6 filter output reject
    
   
    echo "</nftglobal>"
}

function initfilenftables() {
    {
    echo '
## infos sur les tables crées par ctparental .
# table ip filter
# table ip nat
# table ip6 filter
# table ip6 nat
# dans toute les tables les chaines suivantes sont crée:
# input pour INPUT
# output pout OUTPUT
# forward pour FORWARD
# dans les tables nat et nat6 les chaines supplémentaires sont crée:
# prerouting pour PREROUTING
# postrouting pour POSTROUTING
# use this variables for logs
# LOG4ACCEPT='log prefix "ip4tables-accept"'
# LOG4REJECT='log prefix "ip4tables-reject"'
# LOG6ACCEPT='log prefix "ip6tables-accept"'
# LOG6REJECT='log prefix "ip6tables-reject"'
# exemple :
# nft add rule ip filter output ct state new $LOG4ACCEPT accept
#
    ### on autorise tous le trafic sortant vers internet.###
#nft add rule ip filter output ct state new $LOG4ACCEPT accept
#nft add rule ip6 filter output ct state new $LOG6ACCEPT accept

    ### on autorise tous le trafic sortant à destination de notre lan (PC imprimante de la maison)
nft add rule ip filter output ip daddr $reseau_box_ipv4 ct state new $LOG4ACCEPT accept
#nft add rule ip6 filter output ip6 daddr $reseau_box_ipv6_g ct state new $LOG6ACCEPT accept

    ### on acepte tous le trafic entrant en provenence de notre lan (PC imprimante de la maison)
nft add rule ip filter input ip daddr $reseau_box_ipv4 ct state new $LOG4ACCEPT accept
#nft add rule ip6 filter input ip6 daddr $reseau_box_ipv6_g ct state new $LOG6ACCEPT accept

    ### IMAP smtp pop ###
nft add rule ip filter output tcp dport { 143, 993, 995, 465, 587 } ct state new $LOG4ACCEPT accept
nft add rule ip6 filter output tcp dport { 143, 993, 995, 465, 587 } ct state new $LOG4ACCEPT accept

'
    } >  $FILEFIRWALLCONF

    chown root:root  $FILEFIRWALLCONF
    chmod 750  $FILEFIRWALLCONF
}

function genfilerotatelogin() {
{
    echo "# no packages own wtmp -- we'll rotate it here
/var/log/wtmp {
    missingok
    monthly
    create 0664 root utmp
    minsize 1M
    rotate $LOGMONTHROTATE
}
"
} > $FILEROTATEWTMP

{
    echo "# no packages own btmp -- we'll rotate it here
/var/log/btmp {
    missingok
    monthly
    create 0660 root utmp
    rotate $LOGMONTHROTATE
}
"
} > $FILEROTATEBTMP

}

LOGLOGIN=$(grep LOGLOGIN= "$FILE_CONF" | cut -d"=" -f2)
if [ "$LOGLOGIN" = "ON" ];then
    if [ ! -e $FILEROTATEWTMP ] ; then
       genfilerotatelogin
    fi
    if [ "$(grep -c "rotate $LOGMONTHROTATE" $FILEROTATEWTMP)" -eq "0" ];then
       genfilerotatelogin
    fi
    if [ ! -e $FILEROTATEBTMP ] ; then
       genfilerotatelogin
    fi
    if [ "$(grep -c "rotate $LOGMONTHROTATE" $FILEROTATEBTMP)" -eq "0" ];then
       genfilerotatelogin
    fi
fi

function genfilerotatednf() {
{
    echo "
/var/log/nftables/*.log {
        daily
        missingok
        rotate $LOGDAYROTATE
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
        service rsyslog restart ; sleep 5
        endscript
}
"
} > /etc/logrotate.d/nftables
}

function nftablesreload() {

    echo "<nftablesreload>"
    
    if [ $(systemctl is-enabled rsyslog.service 2>/dev/null | grep -c [a-z]) -ge 1 ];then
    if [ ! -e $RSYSLOGCTPARENTAL ] ;  then
    mkdir /var/log/nftables/
    chown root:adm /var/log/nftables
    chmod 751 /var/log/nftables
    echo > /var/log/nftables/nftablesipv4.log
    echo > /var/log/nftables/nftablesipv6.log
    {
    echo '
:msg,contains,"ip4tables-reject" /var/log/nftables/nftablesipv4.log
&~

:msg,contains,"ip4tables-accept" /var/log/nftables/nftablesipv4.log
&~

:msg,contains,"ip6tables-reject" /var/log/nftables/nftablesipv4.log
&~

:msg,contains,"ip6tables-accept" /var/log/nftables/nftablesipv6.log
&~

'
    } > $RSYSLOGCTPARENTAL
    if [ -e /etc/systemd/system/CTparentallogfirewall.service ] ; then
    	$DICTparentallogfirewall
		$CTparentallogfirewallStop
        rm -f /etc/systemd/system/CTparentallogfirewall.service
        systemctl daemon-reload
    fi
    $RSYSLOGRESTART
    fi
    else
    # si la distribution ne possede pas rsyslog, on utilise un scripte basé sur journalctl 
    if [ ! -e /etc/systemd/system/CTparentallogfirewall.service ] ; then
        {
    echo '[Unit]
Description=CTparental log file nftables
Wants=network.target
After=network-online.target

[Service]
ExecStart=/usr/bin/CTlognft
Type=simple

[Install]
WantedBy=default.target

'
    } > /etc/systemd/system/CTparentallogfirewall.service
    chmod 664 /etc/systemd/system/CTparentallogfirewall.service
    systemctl daemon-reload
    $ENCTparentallogfirewall
    $CTparentallogfirewallStart
    fi
    fi
    if [ ! -e /etc/logrotate.d/nftables ] ; then
       genfilerotatednf
    fi
    if [ "$(grep -c "rotate $LOGDAYROTATE" /etc/logrotate.d/nftables)" -eq "0" ];then
       genfilerotatednf
    fi
    if [ ! -f $FILEIPTIMEWEB ]; then 
    touch $FILEIPTIMEWEB
    chown root:root  $FILEIPTIMEWEB
    chmod 750  $FILEIPTIMEWEB
    fi
    if [ ! -f $FILEIPBLACKLIST ]; then 
    {
    echo '# enter here the addresses to be filtered for all the system, including root and privileged accounts.
# - one ip per line.
# - ipv4 address or subnet ipv4 / mask (ip/xxx.xxx.xxx.xxx or ip/1 to 32)
# - ipv6 address or subnet ipv6 / mask (ip/ 1 to 128)
# examples:
# 10.10.2.3
# 192.168.182.0/24
# 2001:db8::f23f
# 2001:db8::/44'
    } >  $FILEIPBLACKLIST
    chown root:root  $FILEIPBLACKLIST
    chmod 750  $FILEIPBLACKLIST
    
    fi
    if [ ! -f $FILEFIRWALLCONF ]; then 
    initfilenftables
    fi
    # on force la regénération des règles du parfeu sauf si c'est un une tache planifiée.
    if [ $arg1 != "-cron" ];then
        md5iptold="-old"
    else
        md5iptold=$(grep MD5IPT= "$FILE_CONF" | cut -d"=" -f2)
    fi
    md5iptnew="$({
md5sum ${FILEIPBLACKLIST} ${FILEFIRWALLCONF} ${FILEIPTIMEWEB} ${FILE_GCTOFFCONF}
listeusers
md5sum ${DIR_IPV4_FILTER_ENABLED}/*
md5sum ${DIR_IPV6_FILTER_ENABLED}/*
md5sum ${DIR_IPV6_WHITELIST_ENABLED}/*
md5sum ${DIR_IPV4_WHITELIST_ENABLED}/*
grep -c IPRULES=ON $FILE_CONF
echo "$FILTRAGEISOFF"
} | md5sum | awk {'print $1'})"
    #echo "$md5iptold = $md5iptnew"
    # on regénère les règles que si ce n'est pas une tache planifier ou si une changement dans la conf système à eu lieux entre 2 taches. 
    if [ ! "$md5iptold" = "$md5iptnew" ]; then
        ### SUPPRESSION de TOUTES LES ANCIENNES TABLES (OUVRE TOUT!!) ###
        nft flush ruleset
        ## on créer les tables par defaults ( via import de fichier car si non impossible de configurer les prioritées négatives )
        nft -f /usr/share/CTparental/nftctparental.nft

        if [ ! "$FILTRAGEISOFF" -eq 1 ];then
        # création des blacklist ipv4 et ipv6  
        nft add set ip filter ipv4filter { type ipv4_addr\;flags interval\;}
        nft add set ip6 filter ipv6filter { type ipv6_addr\;flags interval\;}
        nft add set ip filter ipv4whiteliste { type ipv4_addr\;flags interval\;}
        nft add set ip6 filter ipv6whiteliste { type ipv6_addr\;flags interval\;}
        {
        echo -n 'table ip filter {
    set ipv4filter {
        type ipv4_addr 
        flags interval
        elements = {'
        cat ${DIR_IPV4_FILTER_ENABLED}/* | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | sed -e 's/$/,/g' | sed -e '$ s/.$//'
        echo '       }
    }
}'

        } > /tmp/nftipv4filter
        ## si element non vide 
        if [ $(grep -cE "elements = {.*\." /tmp/nftipv4filter) -eq 1 ];then
            nft -f /tmp/nftipv4filter
        fi
        #rm -f /tmp/nftipv4filter
        {
        echo -n 'table ip6 filter {
    set ipv6filter {
        type ipv6_addr
        flags interval
        elements = {'
        cat ${DIR_IPV6_FILTER_ENABLED}/* | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | sed -e 's/$/,/g' | sed -e '$ s/.$//'
        echo '       }
    }
}'

        } > /tmp/nftipv6filter
        if [ $(grep -cE "elements = {.*:" /tmp/nftipv6filter) -eq 1 ];then
            nft -f /tmp/nftipv6filter
        fi
        #rm -f /tmp/nftipv6filter
        
        
		{
        echo -n 'table ip filter {
    set ipv4whiteliste {
        type ipv4_addr 
        flags interval
        elements = {'
        cat ${DIR_IPV4_WHITELIST_ENABLED}/* | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | sed -e 's/$/,/g' | sed -e '$ s/.$//'
        echo '       }
    }
}'

        } > /tmp/ipv4whiteliste
        ## si element non vide 
        if [ $(grep -cE "elements = {.*\." /tmp/ipv4whiteliste) -eq 1 ];then
            nft -f /tmp/ipv4whiteliste
        fi
        #rm -f /tmp/ipv4whiteliste
        {
        echo -n 'table ip6 filter {
    set ipv6whiteliste {
        type ipv6_addr
        flags interval
        elements = {'
        cat ${DIR_IPV6_WHITELIST_ENABLED}/* | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | sed -e 's/$/,/g' | sed -e '$ s/.$//'
        echo '       }
    }
}'

        } > /tmp/ipv6whiteliste
        if [ $(grep -cE "elements = {.*:" /tmp/ipv6whiteliste) -eq 1 ];then
            nft -f /tmp/ipv6whiteliste
        fi
 
 
        # création des wlhcount ipv4 et ipv6  
        nft add set ip filter wlhcountipv4 { type ipv4_addr\;flags interval\;}
        nft add set ip6 filter wlhcountipv6 { type ipv6_addr\;flags interval\;}
        {
        echo -n 'table ip filter {
    set wlhcountipv4 {
        type ipv4_addr 
        flags interval
        elements = {'
        grep -E "^(((2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}).){3}(2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}))($|/(([1-9])|([1-2][0-9])|(3[0-2]))$)" ${FILE_NOHCOMPTIP} | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | sed -e 's/$/,/g' | sed -e '$ s/.$//'
        echo '       }
    }
}'

        } > /tmp/wlhcountipv4
        ## si element non vide 
        if [ $(grep -cE "elements = {.*\." /tmp/wlhcountipv4) -eq 1 ];then
            nft -f /tmp/wlhcountipv4
        fi
        {
        echo -n 'table ip6 filter {
    set wlhcountipv6 {
        type ipv6_addr
        flags interval
        elements = {'
        grep -E "^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))($|/(([1-9])|([1-9][0-9])|(1[0-1][0-9])|(12[0-8]))$)" ${FILE_NOHCOMPTIP} | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | sed -e 's/$/,/g' | sed -e '$ s/.$//'
        echo '       }
    }
}'

        } > /tmp/wlhcountipv6
        if [ $(grep -cE "elements = {.*:" /tmp/wlhcountipv6) -eq 1 ];then
            nft -f /tmp/wlhcountipv6
        fi         
        
        
        #rm -f /tmp/ipv6whiteliste
        ### on garenti l'accès proxy/e2guardian local + interface d'administration ###
        nft add rule ip6 filter output ip6 daddr $PRIVATE_IP6 tcp dport { $E2GUport, $PROXYport , 80 , 443 } accept
        nft add rule ip filter output ip daddr $PRIVATE_IP4 tcp dport { $E2GUport, $PROXYport , 80 , 443  } accept
        nft add rule ip6 filter output ip6 daddr $ADMIN_IP6 tcp dport { $E2GUport, $PROXYport , 80 , 443 } accept
        nft add rule ip filter output ip daddr $ADMIN_IP4 tcp dport { $E2GUport, $PROXYport , 80 , 443  } accept
        # Force privoxy à utiliser dnsmasq sur le port 54 en ipv6 et en ipv4
        nft add rule ip nat output udp dport 53 skuid "$PROXYuser" dnat $PRIVATE_IP4:54
        nft add rule ip nat output tcp dport 53 skuid "$PROXYuser" dnat $PRIVATE_IP4:54
        nft add rule ip6 nat output udp dport 53 skuid "$PROXYuser" dnat [$PRIVATE_IP6]:54
        nft add rule ip6 nat output tcp dport 53 skuid "$PROXYuser" dnat [$PRIVATE_IP6]:54
        #on accepte les ip whiteliste 
        nft add rule ip filter output ip daddr @ipv4whiteliste skuid "$PROXYuser" $LOG4ACCEPT accept
        nft add rule ip6 filter output ip6 daddr @ipv6whiteliste skuid "$PROXYuser" $LOG6ACCEPT accept
        ## on rejet les ip blackliste
        nft add rule ip filter output ip daddr @ipv4filter skuid "$PROXYuser" $LOG4REJECT reject
        nft add rule ip6 filter output ip6 daddr @ipv6filter skuid "$PROXYuser" $LOG6REJECT reject

        ## si on est pas en mode WHITEIPONLY on autorise tous la navigation internet vers toutes les ips par default
        ## si non seule les ip en whiteliste seron autorisé
        if [ "$( grep -c "^DNSCRYPT=WHITE" $FILE_CONF )" -eq 1 ];then
           if [ "$( grep -c "^WHITEIPONLY=ON" $FILE_CONF )" -eq 1 ];then
              ## on reject les ip qui ne sont pas en white liste whiteliste
              nft add rule ip filter output ip daddr != @ipv4whiteliste skuid "$PROXYuser" $LOG4REJECT reject
              nft add rule ip6 filter output ip6 daddr != @ipv6whiteliste skuid "$PROXYuser" $LOG6REJECT reject
           fi
        fi

        #for user in $(listeusers) ; do
        listeusers | while read -r user
        do
            if  [ "$(groups "$user" | grep -c -E "( ctoff$)|( ctoff )|( root$)|( root )" )" -eq 0 ];then
            ## on passe par l'user id pour eviter les bug avec des non d'utilisateurs comportent des caractaires spéciaux exemple: 01-user1
            userid=$(id -u $user )
            ## on accepte les ip whiteliste
            nft add rule ip filter output ip daddr @ipv4whiteliste skuid "$userid" $LOG4ACCEPT accept
            nft add rule ip6 filter output ip6 daddr @ipv6whiteliste skuid "$userid" $LOG6ACCEPT accept
            ## on rejet les ip fournie par la blackliste de toulouse
            nft add rule ip filter output ip daddr @ipv4filter skuid "$userid" $LOG4REJECT reject
            nft add rule ip6 filter output ip6 daddr @ipv6filter skuid "$userid" $LOG6REJECT reject
            ## si on est pas en mode WHITEIPONLY on autorise tous la navigation internet vers toutes les ips par default
            ## si non seule les ip en whiteliste seron autorisé
            if [ "$( grep -c "^DNSCRYPT=WHITE" $FILE_CONF )" -eq 1 ];then
               if [ "$( grep -c "^WHITEIPONLY=ON" $FILE_CONF )" -eq 1 ];then
                  ## on reject les ip qui ne sont pas en white liste whiteliste
                  nft add rule ip filter output ip daddr != @ipv4whiteliste skuid "$userid" $LOG4REJECT reject
                  nft add rule ip6 filter output ip6 daddr != @ipv6whiteliste skuid "$userid" $LOG6REJECT reject
               fi
            fi
            #on redirige les requêtes DNS ipv4 et ipv6 des usagers filtrés sur dnsmasq très important pour l'https.
            nft add rule ip nat output udp dport 53 skuid "$userid" dnat $PRIVATE_IP4:54
            nft add rule ip nat output tcp dport 53 skuid "$userid" dnat $PRIVATE_IP4:54
            nft add rule ip6 nat output udp dport 53 skuid "$userid" dnat [$PRIVATE_IP6]:54
            nft add rule ip6 nat output tcp dport 53 skuid "$userid" dnat [$PRIVATE_IP6]:54
            #force passage par dansguardian pour les utilisateurs filtrés en ipv4
            nft add rule ip nat output ip saddr != 127.0.0.1/8 tcp dport 80 skuid "$userid" dnat $PRIVATE_IP4:"$E2GUport"
            nft add rule ip nat output ip saddr != 127.0.0.1/8 tcp dport "$PROXYport" skuid "$userid" dnat $PRIVATE_IP4:"$E2GUport"
            # e2guardian ne gérant pas encore ipv6 on se contente de privoxy + dnsmasq on force donc le passage par privoxy pour le http.
            nft add rule ip6 nat output ip6 daddr 2000::/3 tcp dport 80 skuid "$userid" dnat [$PRIVATE_IP6]:"$PROXYport"
           fi
        done
           echo "<$FILEIPTIMEWEB>"
           source "$FILEIPTIMEWEB"
           echo "</$FILEIPTIMEWEB>"
           
        ### BLOQUE TOUT PAR DEFAUT (si aucune règle n'est définie par la suite) ###
        nft add chain ip filter input \{ policy drop\; \}
        nft add chain ip filter output \{ policy drop\; \}
        nft add chain ip filter forward \{ policy drop\; \}
        nft add chain ip6 filter input \{ policy drop\; \}
        nft add chain ip6 filter output \{ policy drop\; \}
        nft add chain ip6 filter forward \{ policy drop\; \}

        if [ "$( grep -c IPRULES=ON $FILE_CONF )" -eq 1 ];then
           nftglobal
        else
           ## on LOG et autorise toutes les demandes en entrée et sortie
           nft add rule ip filter output $LOG4ACCEPT counter accept
           nft add rule ip6 filter output $LOG6ACCEPT counter accept
           nft add rule ip filter input $LOG4ACCEPT counter accept
           nft add rule ip6 filter input $LOG6ACCEPT counter accept

        fi

        
        fi

        # Save configuration so that it survives a reboot
        
        $NFTABLESsave
        
        if [ -e "$CADIR"/cactparental.crt ];then
        updatecauser
        fi
    $SED "s?^MD5IPT.*?MD5IPT=$md5iptnew?" $FILE_CONF
    fi
    echo "</nftablesreload>"
}

function updatecauser() {
    echo "<updatecauser>"
    #for user in $(listeusers) ; do
    listeusers | while read -r user
    do
    HOMEPCUSER=$(getent passwd "$user" | cut -d ':' -f6)
    #on installe le cacertificat dans tous les profils firefox
    if [ -d "$HOMEPCUSER/.mozilla/firefox" ] ;then
    #for cert8db in $(find $HOMEPCUSER/.mozilla/firefox/ -mindepth 2 -maxdepth 2 -name "cert8.db")
    find "$HOMEPCUSER/.mozilla/firefox/" -mindepth 2 -maxdepth 2 -name "cert8.db" | while read -r cert8db
    do
        cert8dbdir="$(dirname "${cert8db}")"
        # on supprime tous les anciens certificats
        while true
        do
        certutil -D -d "$cert8dbdir"/ -n"CActparental - ctparental" > /dev/null 2>&1
        if [ ! $? -eq 0 ];then
            break
        fi
        done
        # on ajoute le nouveau certificat
        certutil -A -d "$cert8dbdir"/ -i "$CADIR"/cactparental.crt -n"CActparental - ctparental" -t "CT,c,c"
        chown ${user}:${user} ${cert8db} > /dev/null 2>&1
        chown ${user}:${user} ${cert8dbdir}/key3.db > /dev/null 2>&1
        chown ${user}:${user} ${cert8dbdir}/pkcs11.txt > /dev/null 2>&1
    done
    #for cert9db in $(find $HOMEPCUSER/.mozilla/firefox/ -mindepth 2 -maxdepth 2 -name "cert9.db")
    find $HOMEPCUSER/.mozilla/firefox/ -mindepth 2 -maxdepth 2 -name "cert9.db" | while read -r cert9db
    do
        cert9dbdir=$(dirname ${cert9db});
        # on supprime tous les anciens certificats
        while true
        do
        certutil -D -d sql:"$cert9dbdir"/ -n"CActparental - ctparental" > /dev/null 2>&1
        if [ ! $? -eq 0 ];then
            break
        fi
        done
        certutil -A -d sql:"$cert9dbdir"/ -i "$CADIR"/cactparental.crt -n"CActparental - ctparental" -t "CT,c,c"
        chown ${user}:${user} ${cert9db} > /dev/null 2>&1
        chown ${user}:${user} ${cert9dbdir}/key4.db > /dev/null 2>&1
        chown ${user}:${user} ${cert9dbdir}/pkcs11.txt > /dev/null 2>&1
    done
    fi
    # si firefox et installer avec snap comme sur ubuntu 22.04
    if [ -d "$HOMEPCUSER/snap/firefox/common/.mozilla/firefox" ] ;then
    find $HOMEPCUSER/snap/firefox/common/.mozilla/firefox/ -mindepth 2 -maxdepth 2 -name "cert9.db" | while read -r cert9db
    do
        cert9dbdir=$(dirname ${cert9db});
        # on supprime tous les anciens certificats
        while true
        do
        certutil -D -d sql:"$cert9dbdir"/ -n"CActparental - ctparental" > /dev/null 2>&1
        if [ ! $? -eq 0 ];then
            break
        fi
        done
        certutil -A -d sql:"$cert9dbdir"/ -i "$CADIR"/cactparental.crt -n"CActparental - ctparental" -t "CT,c,c"
        chown ${user}:${user} ${cert9db} > /dev/null 2>&1
        chown ${user}:${user} ${cert9dbdir}/key4.db > /dev/null 2>&1
        chown ${user}:${user} ${cert9dbdir}/pkcs11.txt > /dev/null 2>&1
    done
    fi
    #on install le cacertificat dans tous les profile chrome chromium
    if [ -f "$HOMEPCUSER/.pki/nssdb/cert9.db" ] ;then
        cert9dbdir="$HOMEPCUSER/.pki/nssdb/"
        # on supprime tous les anciens certificats
        while true
        do
        certutil -D -d sql:"$cert9dbdir"/ -n"CActparental - ctparental" > /dev/null 2>&1
        if [ ! $? -eq 0 ];then
            break
        fi
        done
        certutil -A -d sql:"$cert9dbdir"/ -i "$CADIR"/cactparental.crt -n"CActparental - ctparental" -t "CT,c,c"
        chown ${user}:${user} ${cert9db} > /dev/null 2>&1
        chown ${user}:${user} ${cert9dbdir}/key4.db > /dev/null 2>&1
        chown ${user}:${user} ${cert9dbdir}/pkcs11.txt > /dev/null 2>&1
    fi
    # si chromium et installer avec snap comme sur ubuntu 22.04
    if [ -f "$HOMEPCUSER/snap/chromium/current/.pki/nssdb/cert9.db" ] ;then
        cert9dbdir="$HOMEPCUSER/snap/chromium/current/.pki/nssdb/"
        # on supprime tous les anciens certificats
        while true
        do
        certutil -D -d sql:"$cert9dbdir"/ -n"CActparental - ctparental" > /dev/null 2>&1
        if [ ! $? -eq 0 ];then
            break
        fi
        done
        certutil -A -d sql:"$cert9dbdir"/ -i "$CADIR"/cactparental.crt -n"CActparental - ctparental" -t "CT,c,c"
        chown ${user}:${user} ${cert9db} > /dev/null 2>&1
        chown ${user}:${user} ${cert9dbdir}/key4.db > /dev/null 2>&1
        chown ${user}:${user} ${cert9dbdir}/pkcs11.txt > /dev/null 2>&1
    fi
    done
     echo "</updatecauser>"
}

function FoncHTTPDCONF() {
    echo "<FoncHTTPDCONF>"
    $SRVHTTPstop
    mkdir -p "$DIRadminHTML"
    cp -rf "$DIR_SHARE"/www/CTadmin/* "$DIRadminHTML"

    chmod 644 "$FILE_CONF"
    chown root:"$GROUPHTTPD" "$FILE_CONF"

    if [ $nomanuel -eq 0 ]||[ "$arg1" = "-uhtml" ]; then
        configloginpassword
    else
        ## variables récupérees par héritage du script DEBIAN/postinst
        debconfloginhttp="${debconfloginhttp:="admin"}"
        debconfpassword="${debconfpassword:="admin"}"
        addadminhttpdapr1md5php "$debconfloginhttp" "$debconfpassword"
        unset debconfpassword
        unset debconfloginhttp
    fi
    source "$DIR_SHARE/confhttp"
    #chown root:"$GROUPHTTPD" "$IPREAB"
    #chmod 664 "$IPREAB"
    chown root:"$GROUPHTTPD" "$REABDIP"
    chmod 664 "$REABDIP"
    chown root:"$GROUPHTTPD" "$BL_DIPOSSI"
    chmod 664 "$BL_DIPOSSI"
    chown root:"$GROUPHTTPD" "$CATEGORIES_ENABLED"
    chmod 664 "$CATEGORIES_ENABLED"
    chown root:"$GROUPHTTPD" "$SAFE_CONF"
    chmod 664 "$SAFE_CONF"
    chmod 660 /etc/sudoers
    chown root:"$GROUPHTTPD" "${DIRE2G}lists/bannedextensionlist"
    chmod 664 "${DIRE2G}lists/bannedextensionlist"
    chown root:"$GROUPHTTPD" "${DIRE2G}lists/bannedmimetypelist"
    chmod 664 "${DIRE2G}lists/bannedmimetypelist"
    chown root:"$GROUPHTTPD" "${DIRE2G}lists/bannedsitelist"
    chmod 664 "${DIRE2G}lists/bannedsitelist"

    if [ "$(grep -c Defaults:"$USERHTTPD" /etc/sudoers )" -ge "1" ] ; then
    $SED "/^Defaults:$USERHTTPD/d" /etc/sudoers
    fi
    echo "Defaults:$USERHTTPD !requiretty" >> /etc/sudoers

    if [ "$(grep -c "^$USERHTTPD " /etc/sudoers )" -ge "1" ] ; then
    $SED "/^$USERHTTPD /d" /etc/sudoers
    fi
    echo "$USERHTTPD localhost=(root) NOPASSWD:/usr/bin/CTparental *" >> /etc/sudoers

    unset sudotest
    chmod 440 /etc/sudoers
    if [ ! -f $FILE_HCONF ] ; then
        echo > $FILE_HCONF
    fi
    chown root:"$GROUPHTTPD" "$FILE_HCONF"
    chmod 664 "$FILE_HCONF"
    if [ -f "$FILE_GCTOFFCONF" ] ; then
        chown root:"$GROUPHTTPD" "$FILE_GCTOFFCONF"
        chmod 664 "$FILE_GCTOFFCONF"
    fi

    if [ ! -f "$FILE_HCOMPT" ] ; then
        echo "date=$(date +%D)" > "$FILE_HCOMPT"
    fi
    chown root:"$GROUPHTTPD" "$FILE_HCOMPT"
    chmod 664 "$FILE_HCOMPT"

    chown -R root:"$GROUPHTTPD" "$DIRadminHTML"
    find $DIRadminHTML -type d -exec chmod 755 {} \;
    find $DIRadminHTML -type f -exec chmod 744 {} \;
    CActparental
    $SRVHTTPstart
    test=$?
    if [ ! $test -eq 0 ];then
        gettext 'Error launching of lighttpd service'
        set -e
        exit 1
    fi
    echo "</FoncHTTPDCONF>"
}

function configloginpassword() {
     while true
     do
    loginhttp=$(whiptail --title "$(gettext 'Login')" --nocancel --inputbox "$(gettext 'Enter login to the administration interface')
$(gettext '	- Only letters or numbers.')
$(gettext '	- 5 characters minimum:')" 10 60 3>&1 1>&2 2>&3)
    loginhttp="$(echo "$loginhttp" | grep -E "^([a-zA-Z0-9])*$")"
    if [ "${#loginhttp}" -ge 5  ];then
        break
    fi
     done
     while true
     do
    password=$(whiptail --title "$(gettext 'Password')" --nocancel --passwordbox "$(gettext 'Enter your password and press OK to continue.')" 10 60 3>&1 1>&2 2>&3)
    password2=$(whiptail --title "$(gettext 'Password')" --nocancel --passwordbox "$(gettext 'Confirm your password and press OK to continue.')" 10 60 3>&1 1>&2 2>&3)
    if [ "$password" = "$password2" ] ; then
        password="$(echo "$password" | grep -E "^([a-z0-9A-Z]|[&éè~#{}()ç_@à?.;:/\!,\$<>=£\%\]){6,20}$" 2>/dev/null | grep -E "[&éè~#{}()ç_@à?.;:/\!,\$<>=£\%\]" 2>/dev/null | grep -e [a-z] | grep -e [A-Z] 2>/dev/null | grep -e [0-9] 2>/dev/null)"
        if [ "$password" != "" ] ; then
        break
        else
        whiptail --title "$(gettext "Password")" --msgbox "$(gettext "Password is not complex enough, it must contain at least:")
$(gettext "	- 6 to 20 characters total, 1 uppercase, lowercase 1, number 1")
$(gettext '	- and one special character among the following &éè~#{}()ç_@à?.;:/!,$<>=£%')" 14 60
        fi
    else
        whiptail --title "$(gettext "Password")" --msgbox "$(gettext "The password entered is not identical to the first.")" 14 60
    fi
     done
    addadminhttpdapr1md5php "$loginhttp" "$password"

}

function CActparental() {
     echo "<CActparental>"
     DIR_TMP=${TMPDIR-/tmp}/ctparental-mkcert.$$
     mkdir "$DIR_TMP"
     mkdir "$CADIR" 2> /dev/null

     ## création de la clef privée ca et du certificat ca
     openssl genrsa  2048 > "$DIR_TMP"/cactparental.key 2> /dev/null
     openssl req -new -x509 -sha256 -subj "/C=FR/ST=FRANCE/L=ici/O=ctparental/CN=CActparental" -days 5000 -key "$DIR_TMP"/cactparental.key > "$DIR_TMP"/cactparental.crt
     
     ## création clef et certificat admin.ct.local ($REALMADMINHTTPD) et signature par le ca
     openssl genrsa 2048 > "$DIR_TMP"/"$REALMADMINHTTPD".key 2> /dev/null
     openssl req -new -sha256  -subj "/C=FR/ST=FRANCE/L=ici/O=ctparental/CN=$REALMADMINHTTPD" -key "$DIR_TMP"/"$REALMADMINHTTPD".key > "$DIR_TMP"/"$REALMADMINHTTPD".csr
     openssl x509 -req -extfile <(printf "subjectAltName=DNS:$REALMADMINHTTPD") -in "$DIR_TMP"/"$REALMADMINHTTPD".csr -days 5000 -out "$DIR_TMP"/"$REALMADMINHTTPD".crt -CA "$DIR_TMP"/cactparental.crt -CAkey "$DIR_TMP"/cactparental.key -CAcreateserial -CAserial "$DIR_TMP"/ca.srl 2> /dev/null

     ## création du certificat duckduckgo pour redirection vers safe.duckduckgo.com
     openssl genrsa 2048 > "$DIR_TMP"/duckduckgo.key 2> /dev/null
     openssl req -new -sha256 -subj "/C=FR/ST=FRANCE/L=ici/O=ctparental/CN=duckduckgo.com" -key "$DIR_TMP"/duckduckgo.key > "$DIR_TMP"/duckduckgo.csr
     openssl x509 -req  -extfile <(printf "subjectAltName=DNS:duckduckgo.com,DNS:www.duckduckgo.com") -in "$DIR_TMP"/duckduckgo.csr -days 5000 -out "$DIR_TMP"/duckduckgo.crt -CA "$DIR_TMP"/cactparental.crt -CAkey "$DIR_TMP"/cactparental.key -CAserial "$DIR_TMP"/ca.srl 2> /dev/null

     ## création du certificat www.qwant.com pour redirection vers www.qwantjunior.com
     openssl genrsa 2048 > "$DIR_TMP"/qwant.key 2> /dev/null
     openssl req -new -sha256 -subj "/C=FR/ST=FRANCE/L=ici/O=ctparental/CN=www.qwant.com" -key "$DIR_TMP"/qwant.key > "$DIR_TMP"/qwant.csr
     openssl x509 -req -extfile <(printf "subjectAltName=DNS:www.qwant.com,DNS:qwant.com") -in "$DIR_TMP"/qwant.csr -days 5000 -out "$DIR_TMP"/qwant.crt -CA "$DIR_TMP"/cactparental.crt -CAkey "$DIR_TMP"/cactparental.key -CAserial "$DIR_TMP"/ca.srl 2> /dev/null

    ## instalation de la CA dans les ca de confiance.
    cp -f "$DIR_TMP"/cactparental.crt "$CADIR"/
    if [ "$REPCAMOZ" != "none" ];then
        cp -f "$DIR_TMP"/cactparental.crt "$REPCAMOZ" 2> /dev/null
    fi
    ## instalation des certificats serveur
    cat "$DIR_TMP"/"$REALMADMINHTTPD".key "$DIR_TMP"/"$REALMADMINHTTPD".crt > "$PEMSRVDIR"/"$REALMADMINHTTPD".pem
    cat "$DIR_TMP"/duckduckgo.key "$DIR_TMP"/duckduckgo.crt > "$PEMSRVDIR"/duckduckgo.pem
    cat "$DIR_TMP"/qwant.key "$DIR_TMP"/qwant.crt > "$PEMSRVDIR"/qwant.pem
    rm -rf "$DIR_TMP"
    $UPDATECASYSTEM
    updatecauser
    echo "</CActparental>"
}

function install() {
    # on empaiche la réinstall manuel par dessus une install par paquet.
    if [ $nomanuel -eq 0 ]; then
       muninstall=$(gettext "Install by package was detected, please use this command to uninstall ctparental.")
       if [ "$(dpkg -l ctparental | grep -c ^i)" -eq 1 ] ;then
          echo "$muninstall"
          echo "$CMDREMOVE ctparental"
          exit 0
       fi
       if [ "$(rpm -q -a | grep -c ctparental )" -eq 1 ] ;then
          echo "$muninstall"
          echo "$CMDREMOVE ctparental"
          exit 0
       fi
    fi
  
if [ -z "$(id -u _CTdnscrypt-proxy 2> /dev/null)" ]; then
    useradd $BADNAMEOPTION -g $NOGROUP -u $(get_free_uid_sys) --system -K PASS_MAX_DAYS=-1 --home /run/CTdnscrypt-proxy --comment "system user CTparentaldnscrypt-proxy" --shell $NOLOGINSHELL _CTdnscrypt-proxy
fi
# si on et sur un os avec systemd
if [ -f $BINSYSTEMCTL ] ; then
{
   echo " 
    [Unit]
Description=DNSCrypt client proxy
Documentation=https://github.com/DNSCrypt/dnscrypt-proxy/wiki
After=network.target
Before=nss-lookup.target
Wants=nss-lookup.target

[Install]
WantedBy=multi-user.target

[Service]
AmbientCapabilities=cap_net_bind_service
NonBlocking=true
ExecStart=$DNSCRYPTBIN -config $DNSCRYPTCONF
ProtectHome=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectControlGroups=true
MemoryDenyWriteExecute=true

User=_CTdnscrypt-proxy
CacheDirectory=CTdnscrypt-proxy
LogsDirectory=CTdnscrypt-proxy
RuntimeDirectory=CTdnscrypt-proxy
"
} >  /etc/systemd/system/CTparentaldnscrypt-proxy.service
    chmod 664 /etc/systemd/system/CTparentaldnscrypt-proxy.service
    systemctl daemon-reload
    $ENDNSCRYPT
else
## si /etc/rc.d/
{
echo "#!/bin/bash

DNSCRYPTCONFIG=\"$DNSCRYPTCONF\"
DAEMON=\"$DNSCRYPTBIN\"
USER='_CTdnscrypt-proxy'
PIDFILE='/run/CTdnscrypt-proxy/dnscrypt-proxy.pid'

start_instance() {

    mkdir -p \$(dirname \${PIDFILE})
    # The child (unprivileged) process needs write access or the PID will not
    # be written.
    chmod 0700 \$(dirname \${PIDFILE})
    chown \${USER} \$(dirname \${PIDFILE})

    # The new Go-based dnscrypt-proxy no longer has the ability to daemonize.
    # In the absence of a standard Slackware daemon tool we'll use nohup. :(
    nohup \$DAEMON -config \${DNSCRYPTCONFIG} -pidfile \${PIDFILE} >> /dev/null 2>&1 &
}

stop_instance() {
    if [ ! -r \${DNSCRYPTCONFIG} ]; then
        echo 'No configuration for Ctparentaldnscrypt-proxy found!'
        return
    fi
    if [ -z \${PIDFILE} ]; then
        echo 'No PID configuration for Ctparentaldnscrypt-proxy found!'
        return
    fi
    if [ ! -r \${PIDFILE} ]; then
        echo 'Ctparentaldnscrypt-proxy is not running!'
        return
    fi
    echo 'Stopping Ctparentaldnscrypt-proxy ...'
    kill \$(cat \${PIDFILE})
}

status_instance() {
    if [ ! -r \${DNSCRYPTCONFIG} ]; then
        echo 'No configuration for Ctparentaldnscrypt-proxy found!'
        return
    fi
    if [ -z \${PIDFILE} ]; then
        echo 'No PID configuration for Ctparentaldnscrypt-proxy found!'
        return
    fi
    if [ ! -r \${PIDFILE} ]; then
        echo 'Ctparentaldnscrypt-proxy is not running.'
        return
    fi
    PID=\$(cat \${PIDFILE})
    if [ -z \"\$PID\" ]; then
        echo 'PID file is empty! Ctparentaldnscrypt-proxy does not appear to be running, but there is a stale PID file.'
    elif kill -0 \$PID ; then
        echo 'Ctparentaldnscrypt-proxy is running.'
    else
        echo 'Ctparentaldnscrypt-proxy is not running, but there is a stale PID file.'
    fi
}


case \"\$1\" in
    'start')
        start_instance
        ;;
    'stop')
        stop_instance
        ;;
    'restart')
        stop_instance
        start_instance
        ;;
    'status')
        status_instance
        ;;
    *)
        echo \"Usage: \$0 {start|stop|restart|status}\"
        exit 1
        ;;
esac
"	
} >  /etc/rc.d/rc.CTparentaldnscrypt-proxy
$ENDNSCRYPT
fi 

    mkdir -p ${DIR_IPV4_FILTER_ENABLED} 2>/dev/null
    mkdir -p ${DIR_IPV6_FILTER_ENABLED} 2>/dev/null
    echo > ${DIR_IPV4_FILTER_ENABLED}/ossi.conf
    echo > ${DIR_IPV6_FILTER_ENABLED}/ossi.conf
    $SED "/.* ${REALMADMINHTTPD} /d" /etc/hosts
    $SED "/.ct.local /d" /etc/hosts
    {
    echo "$ADMIN_IP4 $REALMADMINHTTPD "
    echo "$ADMIN_IP6 $REALMADMINHTTPD "
    } >> /etc/hosts
    if [ -f $BINSYSCTL ] ; then
        if [ ! -f $FILESYSCTL ]; then
           echo > $FILESYSCTL
        fi
        if [ "$( grep -c "net.ipv6.conf.all.disable_ipv6=" "$FILESYSCTL" )" -ge "1" ] ; then
        $SED "s?^net.ipv6.conf.all.disable_ipv6=.*?net.ipv6.conf.all.disable_ipv6=0?" "$FILESYSCTL"
        fi
        if [ "$( grep -c "net.ipv6.conf.default.disable_ipv6=" "$FILESYSCTL" )" -ge "1" ] ; then
        $SED "s?^net.ipv6.conf.default.disable_ipv6=.*?net.ipv6.conf.default.disable_ipv6=0?" "$FILESYSCTL"
        fi
        if [ "$( grep -c "net.ipv6.conf.lo.disable_ipv6=" "$FILESYSCTL" )" -ge "1" ] ; then
        $SED "s?^net.ipv6.conf.lo.disable_ipv6=.*?net.ipv6.conf.lo.disable_ipv6=0?" "$FILESYSCTL"
        fi
        if [ "$( grep -c "net.ipv4.ip_forward=" "$FILESYSCTL" )" -ge "1" ] ; then
        $SED "s?^#net.ipv4.ip_forward=.*?net.ipv4.ip_forward=1?" "$FILESYSCTL"
        $SED "s?^net.ipv4.ip_forward=.*?net.ipv4.ip_forward=1?" "$FILESYSCTL"
        else
        echo 'net.ipv4.ip_forward=1' >> "$FILESYSCTL"
        fi
        if [ "$( grep -c "net.ipv6.conf.default.forwarding=" "$FILESYSCTL" )" -ge "1" ] ; then
        $SED "s?^#net.ipv6.conf.default.forwarding=.*?net.ipv6.conf.default.forwarding=1?" "$FILESYSCTL"
        $SED "s?^net.ipv6.conf.default.forwarding=.*?net.ipv6.conf.default.forwarding=1?" "$FILESYSCTL"
        else
        echo 'net.ipv6.conf.default.forwarding=1' >> "$FILESYSCTL"
        fi
        if [ "$( grep -c "net.ipv6.conf.all.forwarding=" "$FILESYSCTL" )" -ge "1" ] ; then
        $SED "s?^#net.ipv6.conf.all.forwarding=.*?net.ipv6.conf.all.forwarding=1?" "$FILESYSCTL"
        $SED "s?^net.ipv6.conf.all.forwarding=.*?net.ipv6.conf.all.forwarding=1?" "$FILESYSCTL"
        else
        echo 'net.ipv6.conf.all.forwarding=1' >> "$FILESYSCTL"
        fi
        $BINSYSCTL -p "$FILESYSCTL"
    fi
    
    ######################
    FILTRAGEISOFF=1
    
# on desactive LLMNR et le MulticastDNS dans systemd-resolved pour pouvoir disocier la resolution de nom par utilisateur via nftables.
    #if [ $(systemctl list-unit-files | grep -c "systemd-resolved.service") -ge 1 ];then
        if [ -f /etc/systemd/resolved.conf ] ; then
        test="$(systemctl is-enabled systemd-resolved.service 2>&1 )"
			if [ "$test" != "masked" ] ; then
			   if [ "$( grep -c "LLMNR=yes" "/etc/systemd/resolved.conf" )" -ge "1" ] ; then
				  $SED "s?^LLMNR=.*?LLMNR=no?" "/etc/systemd/resolved.conf"
				  $SED "s?^#LLMNR=.*?LLMNR=no?" "/etc/systemd/resolved.conf"
				  systemctl restart systemd-resolved.service
			   fi
			   if [ "$( grep -c "MulticastDNS=yes" "/etc/systemd/resolved.conf" )" -ge "1" ] ; then
				  $SED "s?^MulticastDNS=.*?MulticastDNS=no?" "/etc/systemd/resolved.conf"
				  $SED "s?^#MulticastDNS=.*?MulticastDNS=no?" "/etc/systemd/resolved.conf"
				  systemctl restart systemd-resolved.service
			   fi
			fi
        fi
    #fi
 
# évite que systemd-resolved soit interoger directement, ainsi le système utilise l'ip 127.0.0.53 sur l'interface lo.
if [ $(grep -c "resolve \[!UNAVAIL=return\]" /etc/nsswitch.conf) -ge 1 ];then
   $SED "s/resolve \[!UNAVAIL=return\]//" /etc/nsswitch.conf
fi

# on configure les ip pour l'interface ctparental et la page d'interception.
if [ $(systemctl is-enabled systemd-networkd 2>/dev/null | grep -c [a-z] ) -ge 1 ] ; then
	systemctl enable systemd-networkd   
    {
	echo "[Match]
Name=lo
[Network]
Address=127.0.0.1/8
Address=fd00::127:10/128
Address=fd00::127:11/128
"
	} > /etc/systemd/network/ctparentallo.network
    systemctl restart systemd-networkd
else
	if [ ! -f /etc/systemd/system/loctparental.service -a -d /etc/systemd/system/ ];then
		ip addr add fd00::127:10/128 dev lo label lo:1 
		ip addr add fd00::127:11/128  dev lo label lo:2

		{
		echo "#!/bin/bash
	ip addr add fd00::127:10/128 dev lo label lo:1
	ip addr add fd00::127:11/128 dev lo label lo:2

	"
		} > /usr/bin/CTlo
		chmod +x /usr/bin/CTlo

		{
		echo '[Unit]
Description=admin.ct.local and privet.ct.local ipv6 loopback
Wants=network.target
After=network-pre.target dbus.service
Before=network.target 

[Service]
ExecStart=/usr/bin/CTlo
Type=simple

[Install]
WantedBy=default.target
'
		} > /etc/systemd/system/loctparental.service
		chmod 664 /etc/systemd/system/loctparental.service
		systemctl daemon-reload
		systemctl enable loctparental
	else 
		if [ -f /etc/rc.d/rc.inet1.conf ] ; then
		ip -6 address add fd00::127:10/128 dev lo label lo:1 
		ip -6 address add fd00::127:11/128  dev lo label lo:2
		if [ $(grep -c "fd00::127:11/128 dev lo" /etc/rc.d/rc.inet1.conf ) -eq 0 ] ;then
			{
			echo "ip -6 address add fd00::127:11/128 dev lo label lo:1"
			} >> /etc/rc.d/rc.inet1.conf
		fi
		if [ $(grep -c "fd00::127:10/128 dev lo" /etc/rc.d/rc.inet1.conf ) -eq 0 ] ;then
			{
				echo "ip -6 address add fd00::127:10/128 dev lo label lo:2"
			} >> /etc/rc.d/rc.inet1.conf
		fi
		fi
	fi 
fi

    
    if [ $nomanuel -eq 0 ]; then
    cp -rf www "$DIR_SHARE"
    cp -rf confe2guardian "$DIR_SHARE"
    cp -f locale/fr/LC_MESSAGES/ctparental.mo        /usr/share/locale/fr/LC_MESSAGES/
    cp -f locale/es/LC_MESSAGES/ctparental.mo        /usr/share/locale/es/LC_MESSAGES/
    fi
    nftablesreload
    groupadd ctoff

    if [ $nomanuel -eq 0 ]; then
    vim -h > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
       EDIT="vim "
    fi
    nano -h > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
       EDIT=${EDIT:="nano "}
    fi
    vi -h > /dev/null 2>&1
    if [ $? -eq 0 ] ; then
       EDIT=${EDIT:="vi "}
    fi

    if [ -f gpl-3.0.fr.txt ] ; then
       cp -f gpl-3.0.fr.txt "$DIR_SHARE"/
    fi
    if [ -f gpl-3.0.txt ] ; then
       cp -f gpl-3.0.txt "$DIR_SHARE"/
    fi
    if [ -f CHANGELOG ] ; then
       cp -f CHANGELOG "$DIR_SHARE"/
    fi
    if [ -f dist.conf ];then
       cp -f dist.conf "$DIR_SHARE"/dist.conf.orig
       cp -f dist.conf $DIR_CONF/
    fi
    while true; do
       $EDIT $DIR_CONF/dist.conf
       clear
       grep -v -E ^# "$DIR_CONF"/dist.conf | grep -v ^$
       gettext 'Enter: S to continue with these parameters.'
       gettext 'Enter: Q to Quit setup.'
       gettext 'Enter any other choice to change settings.'
       read choi
       case $choi in
        S | s )
           break
           ;;
        Q | q )
           exit
           ;;
       esac
    done

    fi
    if [ -f $DIR_CONF/dist.conf ];then
    source  $DIR_CONF/dist.conf
    fi
    mkdir -p $tempDIR
    mkdir -p $DIR_CONF
    if [ ! -f $CATEGORIES_ENABLED ];then
    initblenabled
    fi
    if [ $noinstalldep -eq 0 ]; then
    for PACKAGECT in $CONFLICTS
    do
       cmd="${CMDREMOVE} ${PACKAGECT}"
       $cmd 2> /dev/null
    done
    fi
    if [ $noinstalldep -eq 0 ]; then
    cmd="${CMDINSTALL} ${DEPENDANCES}"
    $cmd
    fi
    nftdisableconflict
    # on charge le(s) module(s) indispensable(s) pour nftables.
    { 
    echo "
nf_tables
nf_conntrack_ftp
nft_ct
nft_nat
nft_log
$NFTCHAINNATipv4
"
    if [ "$NFTCHAINNATipv6" != "none" ] ;then
    echo "$NFTCHAINNATipv6"
    fi
    } > "$FILEMODULESLOAD"
    # on bloque les modules pouvant aporter des conflits
    { 
    echo '
blacklist ip_tables
blacklist ip_conntrack_ftp
    '
    } >  "$FILEMODULESPROB"
    modprobe nf_tables
    modprobe nf_conntrack_ftp
    modprobe nft_ct
    modprobe nft_nat
    modprobe nft_log
    modprobe $NFTCHAINNATipv4
    if [ "$NFTCHAINNATipv6" != "none" ] ;then
    modprobe $NFTCHAINNATipv6
    fi

    # ajout du service de persistance des nftables.
if [ -f $BINSYSTEMCTL ] ; then
{
    echo "[Unit]
Description=nftables CTparental
Documentation=man:nft(8) http://wiki.nftables.org
Wants=network-pre.target
Before=network-pre.target shutdown.target
Conflicts=shutdown.target
DefaultDependencies=no

[Service]
Type=oneshot
RemainAfterExit=yes
StandardInput=null
ProtectSystem=full
ProtectHome=true
ExecStart=/usr/sbin/nft -f $NFTABLESsaveFILE
ExecReload=/usr/sbin/nft -f $NFTABLESsaveFILE
ExecStop=/usr/sbin/nft flush ruleset

[Install]
WantedBy=sysinit.target

"
    } > /etc/systemd/system/CTparentalfirewall.service
    chmod 664 /etc/systemd/system/CTparentalfirewall.service
else
{
echo "#!/bin/sh
#

case \"\$1\" in
'start')
  /usr/sbin/nft -f $NFTABLESsaveFILE
  ;;
'stop')
  /usr/sbin/nft flush ruleset
  ;;
'restart')
  /usr/sbin/nft flush ruleset
  ExecReload=/usr/sbin/nft -f $NFTABLESsaveFILE
  ;;
*)
  echo \"usage \$0 start|stop|restart\"
esac
"	
} > /etc/rc.d/rc.CTparentalfirewall
    $ENCTparentalfirewall
fi
   # ajout du service sshd dédier a CTparental pour la syncro.
mkdir $DIR_CONF/sshd 2> /dev/null
mkdir $DIR_CONF/.ssh 2> /dev/null

{
echo '# Default settings for openssh-server (CTparentalSshd). 
# Options to pass to sshd
SSHD_OPTS=

'
} > $DIR_CONF/sshd/Envssh
chmod 644 $DIR_CONF/sshd/Envssh
chown root:root $DIR_CONF/sshd/Envssh
if [ -f $BINSYSTEMCTL ] ; then
{
echo "[Unit]
Description=OpenBSD Secure Shell server for CTparental syncro
Documentation=man:sshd(8) man:sshd_config(5)
After=network-online.target auditd.service
ConditionPathExists=!/etc/ssh/sshd_not_to_be_run

[Service]
EnvironmentFile=-$DIR_CONF/sshd/Envssh
ExecStartPre=/usr/sbin/sshd -t -f $DIR_CONF/sshd/csync_sshd_config -h $DIR_CONF/sshd/csync_host_rsa_key
ExecStart=/usr/sbin/sshd -6 -f $DIR_CONF/sshd/csync_sshd_config -h $DIR_CONF/sshd/csync_host_rsa_key
ExecReload=/usr/sbin/sshd -t -f $DIR_CONF/sshd/csync_sshd_config -h $DIR_CONF/sshd/csync_host_rsa_key
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=on-failure
RestartPreventExitStatus=255
Type=notify
RuntimeDirectory=CTparentalSshd
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target
Alias=CTparentalSshd.service"
} > /etc/systemd/system/CTparentalSshd.service
chmod 664 /etc/systemd/system/CTparentalSshd.service

    systemctl daemon-reload
    $ENCTparentalfirewall
    $DICTparentalSshd
else
{
echo "	
#!/bin/sh
# Start/stop/restart the secure shell server:
# Source options
source $DIR_CONF/sshd/Envssh

sshd_start() {
 
  # Start the sshd daemon:
  /usr/sbin/sshd -6 -f $DIR_CONF/sshd/csync_sshd_config -h $DIR_CONF/sshd/csync_host_rsa_key
}

sshd_stop() {
  killall sshd
}

sshd_restart() {
  if [ -r /var/run/CTparentalSshd.pid ]; then
    echo \"WARNING: killing listener process only.  To kill every sshd process, you must\"
    echo \"         use 'rc.sshd stop'.  'rc.sshd restart' kills only the parent sshd to\"
    echo \"         allow an admin logged in through sshd to use 'rc.sshd restart' without\"
    echo \"         being cut off.  If sshd has been upgraded, new connections will now\"
    echo \"         use the new version, which should be a safe enough approach.\"
    kill `cat /var/run/CTparentalSshd.pid`
  else
    echo \"WARNING: There does not appear to be a parent instance of sshd running.\"
    echo \"         If you really want to kill all running instances of sshd (including\"
    echo \"         any sessions currently in use), run '/etc/rc.d/rc.sshd stop' instead.\"
    exit 1
  fi
  sleep 1
  sshd_start
}

case \"\$1\" in
'start')
  sshd_start
  ;;
'stop')
  sshd_stop
  ;;
'restart')
  sshd_restart
  ;;
*)
  echo \"usage \$0 start|stop|restart\"
esac
"


} > /etc/rc.d/rc.CTparentalSshd
$DICTparentalSshd

fi
    #######################
    if [ ! -f blacklists.tar.gz ]
    then
    download
    else
    tar -xzf blacklists.tar.gz -C $tempDIR
    if [ ! $? -eq 0 ]; then
            gettext 'archive extraction error , process interrupted'
            uninstall
            set -e
            exit 1
    fi
    rm -rf ${DIR_DNS_FILTER_AVAILABLE:?}/
    mkdir $DIR_DNS_FILTER_AVAILABLE
    fi
    adapt
    catChoice
    dnscryptproxyon
    $SED "s?^LASTUPDATE.*?LASTUPDATE=$THISDAYS=$(date +%d-%m-%Y\ %T)?g" $FILE_CONF
    confe2guardian
    confproxy
    FoncHTTPDCONF
    activegourpectoff
    FILTRAGEISOFF=0
    rm -f /etc/rsyslog.d/iptables.conf # for old install
    rm -f $RSYSLOGCTPARENTAL
    $RSYSLOGRESTART
    $SED "s?^MD5IPT.*?MD5IPT=0?" $FILE_CONF
    nftablesreload
    $ENHTTP
    $ENDNSCRYPT
    $ENNFTABLESsave
    $ENE2GUARDIAN
    $ENPROXY
    $ENNETWORK
    if [ -f $BINSYSTEMCTL ] ; then
    {
     echo "[Unit]
Description=CTparental avery minutes
After=network-online.target


[Service]
User=root
WorkingDirectory=/root/
ExecStart=$CHEMINCTPARENTLE -cron
Type=oneshot

[Install]
WantedBy=default.target

"
    } > /etc/systemd/system/CTparentalcron.service
# on redémare le démon systemd pour prendre en compte ce nouveau service
systemctl daemon-reload
    {
    echo "
[Unit]
Description=update conf CTparental avery minutes

[Timer]
# on attent 2 minute après le boot
OnBootSec=2min
# toute les minutes aprés le dernier lancement
OnUnitActiveSec=1min
[Install]
WantedBy=timers.target
"
    } > /etc/systemd/system/CTparentalcron.timer
    systemctl enable CTparentalcron.timer
    systemctl start CTparentalcron.timer
    else
		## on utise cron si systemd n'est pas présent
		{
		echo "export PATH=$PATH
*/1 * * * * root $CHEMINCTPARENTLE -cron" 
		} > /etc/cron.d/CTparentalcron
		/etc/rc.d/rc.crond restart
    fi
    autoupdateon
    echo > "$DIR_CONF"/ctsync.conf
}

function nomade() {
    echo "<nomade>"
    #### si il y a un changement dans la conf réseaux ####
    if [ "$i_WAN_ipv4" != "$( grep I_WAN_IPV4 $FILE_CONF | cut -d"=" -f2 )" ] || \
    [ "$i_WAN_ipv6" != "$( grep I_WAN_IPV6 $FILE_CONF | cut -d"=" -f2 )" ] || \
    [ "$ipbox_ipv4" != "$( grep IP_BOX_IPV4 $FILE_CONF | cut -d"=" -f2 )" ] || \
    [ "$ipbox_ipv6" != "$( grep IP_BOX_IPV6 $FILE_CONF | cut -d"=" -f2 )" ] || \
    [ "$ip_i_WAN_ipv4" != "$( grep IP_IWAN_IPV4 $FILE_CONF | cut -d"=" -f2 )" ] || \
    [ "$ip_i_WAN_ipv6" != "$( grep IP_IWAN_IPV6 $FILE_CONF | cut -d"=" -f2 )" ]
    then
    networkisoknext
    # on sauvegarde ces changement dans le fichier de conf CTparental.
    $SED "/^I_WAN_IPV4=/d" "$FILE_CONF"
    $SED "/^I_WAN_IPV6=/d" "$FILE_CONF"
    $SED "/^IP_BOX_IPV4=/d" "$FILE_CONF"
    $SED "/^IP_BOX_IPV6=/d" "$FILE_CONF"
    $SED "/^IP_IWAN_IPV4=/d" "$FILE_CONF"
    $SED "/^IP_IWAN_IPV6=/d" "$FILE_CONF"
    { echo I_WAN_IPV4="$i_WAN_ipv4"
     echo IP_BOX_IPV4="$ipbox_ipv4"
     echo IP_BOX_IPV6="$ipbox_ipv6"
     echo IP_IWAN_IPV4="$ip_i_WAN_ipv4"
     echo IP_IWAN_IPV6="$ip_i_WAN_ipv6"
     echo I_WAN_IPV6="$i_WAN_ipv6"
    } >> $FILE_CONF
    # on modifie la conf dnsmasq
    dnscryptproxyon
    # on reconfigure les règles du pare-feu.
    nftablesreload
     fi
    echo "</nomade>"
}

function updatelistgctoff() {
    if [ ! -f $FILE_GCTOFFCONF ] ; then
    echo -n > $FILE_GCTOFFCONF
    chown root:"$GROUPHTTPD" "$FILE_GCTOFFCONF"
    chmod 664 "$FILE_GCTOFFCONF"
    fi
    $MFILEtmp
    cp -f "$FILE_GCTOFFCONF" "$FILE_tmp"
    #for PCUSER in $(listeusers)
    listeusers | while read -r PCUSER
    do
        ## on ajoute tous les utilisateurs manquants dans la liste
        if [ "$(cat < $FILE_tmp | sed -e "s/^-//" | sed -e "s/^+//" | sed -e "s/^#//" | grep -c -E "^$PCUSER$")" -eq 0 ];then
            if [ "$(groups "$PCUSER" | grep -c -E "$GREPADMINUSER" )" -eq 1 ];then
            #si l'utilisateur fait partie d'un groupe d'administration de la machine on l'ajoute sans filtrage par défaut.
            echo "+$PCUSER" >> $FILE_tmp
            else
            #si non avec filtrage  par défaut.
            echo "#$PCUSER" >> $FILE_tmp
            fi
        fi
        ## on adapte les ligne en cas de changement ajout/suppression d'un group d'administration.
        if [ "$(groups "$PCUSER" | grep -c -E "$GREPADMINUSER" )" -eq 1 ];then
            $SED "s/^#${PCUSER}$/-$PCUSER/" "$FILE_tmp"
            $SED "s/^$${PCUSER}$/+$PCUSER/" "$FILE_tmp"
        else
            $SED "s/^+${PCUSER}$/$PCUSER/" "$FILE_tmp"
            $SED "s/^-${PCUSER}$/#$PCUSER/" "$FILE_tmp"
        fi
    done
    ## on supprimes les lignes vide du fichier.
    $SED '/^$/d' "$FILE_tmp"
    ## on supprime tout ceux qui n'existent plus sur le pc.
    while read line
    do
    PCUSER=$(echo $line | sed -e "s/^-//" | sed -e "s/^+//" | sed -e "s/^#//" )
    groups $PCUSER > /dev/null
    if [ $? -eq 1 ];then
        $SED "/^$${PCUSER}$/d" "$FILE_tmp"
        $SED "/^#${PCUSER}$/d" "$FILE_tmp"
        $SED "/^+${PCUSER}$/d" "$FILE_tmp"
        $SED "/^-${PCUSER}$/d" "$FILE_tmp"
    fi
    if [ ! -d "$(getent passwd $PCUSER | cut -d":" -f6)" ]; then
        $SED "/^$${PCUSER}$/d" "$FILE_tmp"
        $SED "/^#${PCUSER}$/d" "$FILE_tmp"
        $SED "/^+${PCUSER}$/d" "$FILE_tmp"
        $SED "/^-${PCUSER}$/d" "$FILE_tmp"
    fi
    done < $FILE_tmp
    if [ "$(md5sum $FILE_tmp | awk '{print $1}')" = "$(md5sum $FILE_GCTOFFCONF | awk '{print $1}')" ];then
        echo "0"
    else
        echo "1"
        cp -f "$FILE_tmp" "$FILE_GCTOFFCONF"
    fi
    rm -f $FILE_tmp
    $UMFILEtmp
}

function applistegctoff() {
    echo "<applistegctoff>"
    $ADDUSERTOGROUP root ctoff 2> /dev/null
    while read line
    do
        PCUSER=$(echo $line | sed -e "s/^-//" | sed -e "s/^+//" | sed -e "s/^#//" )
        if [ "$(echo "$line" | grep -c "#")" -eq 1 ];then
            $DELUSERTOGROUP "$PCUSER" ctoff 2> /dev/null
        else
            if [ "$(echo "$line" | grep -c "^-")" -eq 1 ];then
                $DELUSERTOGROUP "$PCUSER" ctoff 2> /dev/null
            else
                $ADDUSERTOGROUP "$PCUSER" ctoff 2> /dev/null
            fi
        fi
     done < "$FILE_GCTOFFCONF"
     $SED "s?^MD5IPT.*?MD5IPT=-old?" $FILE_CONF
     echo "</applistegctoff>"
}

function activegourpectoff() {
     echo "<activegourpectoff>"
     groupadd ctoff
     $SED "s?^GCTOFF.*?GCTOFF=ON?" $FILE_CONF
     updatelistgctoff
     applistegctoff
     chown root:"$GROUPHTTPD" "$FILE_GCTOFFCONF"
     chmod 660 "$FILE_GCTOFFCONF"
     
     echo "</activegourpectoff>"
}

function desactivegourpectoff() {
     groupdel ctoff 2> /dev/null
     $SED "s?^GCTOFF.*?GCTOFF=OFF?g" $FILE_CONF
}

function uninstall() {
# On force la désinstall par dpkg ou rpm si l'install a été effectuée par un package.
if [ $nomanuel -eq 0 ]; then
   muninstall=$(gettext "Install by package was detected, please use this command to uninstall ctparental.")
   if [ "$(dpkg -l ctparental | grep -c ^i)" -eq 1 ] ;then
       echo "$muninstall"
       echo "$CMDREMOVE ctparental"
       exit 0
   fi
   if [ "$(rpm -q -a | grep -c ctparental )" -eq 1 ] ;then
       echo "$muninstall"
       echo "$CMDREMOVE ctparental"
       exit 0
   fi
fi
echo "" > "$DIR_CONF"/querylog.conf
$SED "s?^LOGDNS=.*?LOGDNS=OFF?"  "$FILE_CONF"
$SED "s?^LOGNFT=.*?LOGNFT=OFF?"  "$FILE_CONF"
$SED "s?^LOGLOGIN=.*?LOGLOGIN=OFF?"  "$FILE_CONF"
LOG4ACCEPT=''
LOG4REJECT=''
LOG6ACCEPT=''
LOG6REJECT=''
LOGDNS="OFF"
LOGNFT="OFF"
LOGLOGIN="OFF"
LOGMONTHROTATE="1"
genfilerotatelogin
dnscryptproxyon
nftdisableconflict
nftablesreload
rm -rf /var/log/nftables/*
rm -f $RSYSLOGCTPARENTAL
$RSYSLOGRESTART
$SED "/.* ${REALMADMINHTTPD} /d" /etc/hosts
$SED "/.ct.local /d" /etc/hosts
if [ -f "$DIR_CONF"/ctsync.conf ];then
   if [ "$( grep -c "SRVSYNC=ON" "$DIR_CONF"/ctsync.conf )" -eq 1 ];then
      serversyncoff
   fi
   if [ "$(grep -c "CSYNC=ON" "$DIR_CONF"/ctsync.conf)" -eq 1 ] ;then
      clientsyncoff
   fi
 
fi
   nft flush ruleset
   $NFTABLESsave
   $DICTparentalfirewall
   $DIDNSCRYPT
   if [ -f $BINSYSTEMCTL ] ; then
      rm -f /etc/systemd/system/CTparentalfirewall.service
      if [ -f /etc/systemd/system/loctparental.service ] ;then
         systemctl disable loctparental #for old install
         systemctl daemon-reload #for old install
         rm -f /etc/systemd/network/ctparentallo.network
         systemctl disable systemd-networkd  
         rm -f /etc/systemd/system/loctparental.service #for old install
         rm -f /usr/bin/CTlo #for old install
         ip addr delete fd00::127:11/128 dev lo 2> /dev/null
         ip addr delete fd00::127:10/128 dev lo 2> /dev/null
      fi
      systemctl daemon-reload
   else
      if [ -f /etc/rc.d/rc.inet1.conf ] ; then
         ip -6 address delete fd00::127:11/128 dev lo 2> /dev/null
         ip -6 address delete fd00::127:10/128 dev lo 2> /dev/null
         $SED "/fd00::127:11/128/d"  /etc/rc.d/rc.inet1.conf
         $SED "/fd00::127:10/128/d"  /etc/rc.d/rc.inet1.conf
      fi
   fi
   $SED "s?.*IPRULES=.*?IPRULES=OFF?g" $FILE_CONF
   rm -f "$FILEFIRWALLCONF"
   rm -f "$FILEIPBLACKLIST"
   rm -f "$FILEIPTIMEWEB"
   rm -f $RSYSLOGCTPARENTAL
   $RSYSLOGRESTART
   desactivegourpectoff
   autoupdateoff
   dnscryptproxyoff
   FILTRAGEISOFF=1
   nftablesreload
   $SRVHTTPstop
   $DNSCRYPTstop
   if [ $nomanuel -eq 1 ]; then
      # en install par le deb on n'efface pas les fichiers installés par celui-ci
      if [ -f $BINSYSTEMCTL ] ; then
         basename -a $(find /etc/systemd/system/ -type f,l | grep CTparental ) 2> /dev/null | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | while read -r unite
         do
            systemctl stop $unite
            systemctl disable $unite
         done
         rm -f /etc/systemd/system/CTparental*
         systemctl daemon-reload
      else
         rm -rf /etc/cron.d/CTparental*
         /etc/rc.d/rc.crond restart
      fi
         cd "$DIR_CONF"
         $SED "s?^MD5DREAB.*?MD5DREAB=old?" $FILE_CONF
         $SED "s?^MD5IPT.*?MD5IPT=old?" $FILE_CONF
         rm -f $DIR_CONF/categoriesmd5sum
         rm -f $DIR_CONF/blacklists.tar.gz.md5sum
         for file in *
         do
            if [ ! "$(echo "$file" | grep -c -E ".*.conf")" -ge 1 ] ;then
               rm -rf ${DIR_CONF:?}/"$file"
            fi
         done
   else
       rm -rf "$DIRadminHTML"
       rm -rf "$DIR_SHARE"
       rm -rf "$DIR_CONF"
   fi
   rm -rf "$tempDIR"
   rm -f "$CTPARENTALCONFHTTPD"
     

    if [ $noinstalldep -eq 0 ]; then
       for PACKAGECT in $DEPENDANCES
       do
          $CMDREMOVE "$PACKAGECT" 2> /dev/null
       done
    fi

    # désactivation du module ip_conntrack_ftp
    if [ $(grep -c ip_conntrack_ftp "$FILEMODULESLOAD" ) -ge 1 ] ; then
       $SED "s?.*ip_conntrack_ftp.*?#ip_conntrack_ftp?g" "$FILEMODULESLOAD"
    else
       echo "#ip_conntrack_ftp" >> "$FILEMODULESLOAD"
    fi
    modprobe -r ip_conntrack_ftp
    $SED "s?.*ip_conntrack_ftp.*?#ip_conntrack_ftp?g" "$FILEMODULESLOAD"

    rm -f "$PEMSRVDIR"/ct.local.pem
    rm -f "$PEMSRVDIR"/duckduckgo.pem
    rm -f "$PEMSRVDIR"/qwant.pem
    rm -f "$CADIR"/cactparental.crt
    if [ "$REPCAMOZ" != "none" ];then
       rm -f "$REPCAMOZ"/cactparental.crt
    fi
    $UPDATECASYSTEM

    listeusers | while read -r user
    do
       HOMEPCUSER=$(getent passwd "$user" | cut -d ':' -f6)
       find $HOMEPCUSER/ -name "cert8.db"  | grep -v Trash | while read -r cert8db
       do
          cert8dbdir=$(dirname ${cert8db});
          # on supprime tous les anciens certificats
          while true
          do
             certutil -D -d "$cert8dbdir"/ -n"CActparental - ctparental" > /dev/null 2>&1
             if [ ! $? -eq 0 ];then
                break
             fi
          done
       done

       find $HOMEPCUSER/ -name "cert9.db" | grep -v Trash | while read -r cert9db
       do
          cert9dbdir=$(dirname ${cert9db});
          # on supprime tous les anciens certificats
          while true
          do
             certutil -D -d sql:"$cert9dbdir"/ -n"CActparental - ctparental" > /dev/null 2>&1
             if [ ! $? -eq 0 ];then
                break
             fi
          done
       done
    done

    $NFTABLESsave
    rm -f "$DIR_CONF"/ctsync.conf

}

function choiblenabled() {
     echo -n > $CATEGORIES_ENABLED
     clear
     gettext 'Do you want to filter by Blacklist or Whitelist B/W:'
     while true; do
         read choiBW
         case $choiBW in
             B | b )
        cat_av="$BL_CATEGORIES_AVAILABLE"
        break
        ;;
        W | w )
        cat_av="$WL_CATEGORIES_AVAILABLE"
        break
        ;;
    esac
     done

     cat  < $cat_av | while read CATEGORIE
     do
    clear
    gettext 'Choice of filtered categories to apply.'
    echo ""
    eval_gettext "Do you want to enable this category \$CATEGORIE  O/N:"
    (
        while true ; do
        unset choi
        read choi
        case $choi in
            O | o )
            echo "OUI"
            echo "$CATEGORIE" >> "$CATEGORIES_ENABLED"
            break
            ;;
            N | n )
            break
            ;;
        esac
        done
    ) < /dev/tty
     done
}

function errortime1() {
     clear
     at=$(gettext "at")
     and=$(gettext "and")
     h=$(gettext ":")
     or=$(gettext "or")
     echo -e "$(gettext "The start time must be strictly less than the end time:")$RougeD$input$Fcolor "
     echo "exemple: 00${h}00 $at 23${h}59 $or 08${h}00 $at 12${h}00 $and 14${h}00 $at 16${h}50"
     echo -e -n "$RougeD$PCUSER$Fcolor $(gettext "is allowed to connect the") $BleuD${DAYS[$NumDAY]}$Fcolor $(gettext "at:")"
}

function errortime2() {
     clear
     at=$(gettext "at")
     and=$(gettext "and")
     h=$(gettext ":")
     or=$(gettext "or")
     echo -e "$(gettext "Bad syntax:")$RougeD$input$Fcolor "
     echo "exemple: 00${h}00 $at 23${h}59 $or 08${h}00 $at 12${h}00 $and 14${h}00 $at 16${h}50"
     echo -e -n "$RougeD$PCUSER$Fcolor $(gettext "is allowed to connect the") $BleuD${DAYS[$NumDAY]}$Fcolor $(gettext "at:")"
}

function updatetimelogin() {
if [ ! -f $FILEIPTIMEWEB ]; then 
    touch $FILEIPTIMEWEB
fi
if [ ! -f $FILE_NOHCOMPTIP ]; then 
    touch $FILE_NOHCOMPTIP
fi
oldmd5hcomptip=$(grep MD5FILE_NOHCOMPTIP= "$FILE_CONF" | cut -d"=" -f2)
newmd5hcomptip=$(md5sum $FILE_NOHCOMPTIP | awk {'print $1'})
if [ ! "$oldmd5hcomptip" = "$newmd5hcomptip" ]; then
	rm -rf $tempDIR
	mkdir -p $tempDIR
	{
	echo "$PRIVATE_IP4
$PRIVATE_IP6
$ADMIN_IP4
$ADMIN_IP6
::1"
	} >> $FILE_NOHCOMPTIP
	grep -E "^(((2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}).){3}(2[0-5][0-5]|2[0-4][0-9]|1[0-9][0-9]|[0-9]{1,2}))($|/(([1-9])|([1-2][0-9])|(3[0-2]))$)|^((([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}:[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){5}:([0-9A-Fa-f]{1,4}:)?[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){4}:([0-9A-Fa-f]{1,4}:){0,2}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){3}:([0-9A-Fa-f]{1,4}:){0,3}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){2}:([0-9A-Fa-f]{1,4}:){0,4}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){6}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(([0-9A-Fa-f]{1,4}:){0,5}:((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|(::([0-9A-Fa-f]{1,4}:){0,5}((b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b).){3}(b((25[0-5])|(1d{2})|(2[0-4]d)|(d{1,2}))b))|([0-9A-Fa-f]{1,4}::([0-9A-Fa-f]{1,4}:){0,5}[0-9A-Fa-f]{1,4})|(::([0-9A-Fa-f]{1,4}:){0,6}[0-9A-Fa-f]{1,4})|(([0-9A-Fa-f]{1,4}:){1,7}:))($|/(([1-9])|([1-9][0-9])|(1[0-1][0-9])|(12[0-8]))$)" $FILE_NOHCOMPTIP | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" >> $tempDIR/tempfile 
	cp -f $tempDIR/tempfile $FILE_NOHCOMPTIP
	newmd5hcomptip=$(md5sum $FILE_NOHCOMPTIP | awk {'print $1'})
	rm -rf $tempDIR
	$SED "s?^MD5FILE_NOHCOMPTIP.*?MD5FILE_NOHCOMPTIP=$newmd5hcomptip?" $FILE_CONF
fi
#USERSCONECT=$(who | awk '//{print $1}' | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$")
if [ "$( grep -c "$(date +%D)" $FILE_HCOMPT )" -eq 1 ] ; then
    # on incrémente le compteur de temps de connection. Pour
    # chaque utilisateur connecté
    who | awk '//{print $1}' | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | while read -r PCUSER
    do
        userid=$(id -u $PCUSER )
        if [ "$( grep -c "^$PCUSER=user=" $FILE_HCONF )" -eq 1 ] ;then
            if [ "$( grep -c "^$PCUSER=" $FILE_HCOMPT )" -eq 0 ] ;then
                    echo "$PCUSER=1=1" >> $FILE_HCOMPT
            else
                var=$(($( grep "^$PCUSER=" $FILE_HCOMPT | cut -d"=" -f2 ) + 1 ))
                if [ "$(ss -t -e -o state established | grep ":http" | grep uid:$userid | grep -cvf $FILE_NOHCOMPTIP )" -ge 1 ];then
                    varweb=$(($( grep "^$PCUSER=" $FILE_HCOMPT | cut -d"=" -f3 ) + 1 ))
                else
                    varweb=$( grep "^$PCUSER=" $FILE_HCOMPT | cut -d"=" -f3)
                fi
                $SED "s?^$PCUSER=.*?$PCUSER=$var=$varweb?g" $FILE_HCOMPT
                count=$(($( grep "^$PCUSER=user=" $FILE_HCONF | cut -d "=" -f3 ) - var ))
                countweb=$(($( grep "^$PCUSER=user=" $FILE_HCONF | cut -d "=" -f4 ) - varweb ))
                # si le compteur de l'usager dépasse la valeur max
                # autorisée on verrouille le compte et on
                # déconnecte l'utilisateur.
                if [ $count -le 0 ];then
                    systemctl start CTparentalskill@${PCUSER}.service
                    passwd -l "$PCUSER"
                fi

                if [ "$countweb" -le 0 ];then
                    if [ "$( grep -c "skuid $userid" $FILEIPTIMEWEB )" -eq 0 ];then
                        # on bloque l'accès direct , via e2guardian et via le proxy en ipv4
                        echo "nft add rule ip filter output ip daddr != @wlhcountipv4  skuid $userid $LOG4REJECT reject" >> "$FILEIPTIMEWEB"
                        echo "nft add rule ip filter output ip daddr 127.0.0.1/8  skuid $userid tcp dport $E2GUport $LOG4REJECT reject" >> "$FILEIPTIMEWEB"
                        echo "nft add rule ip filter output ip daddr 127.0.0.1/8  skuid $userid tcp dport $PROXYport $LOG4REJECT reject" >> "$FILEIPTIMEWEB"  
                        # on bloque l'accès direct , via le proxy en ipv6 e2guardiane n'écoutentpas en ipv6                    
                        echo "nft add rule ip6 filter output ip6 daddr != @wlhcountipv6 skuid $userid $LOG6REJECT reject" >> "$FILEIPTIMEWEB"
                        echo "nft add rule ip6 filter output ip6 daddr $PRIVATE_IP6  skuid $userid tcp dport $PROXYport $LOG6REJECT reject" >> "$FILEIPTIMEWEB"
                        nftablesreload
                    fi
                else
                    if [ "$( grep -c "skuid $userid" $FILEIPTIMEWEB )" -ge 1 ];then
                        $SED "/skuid $userid/d" $FILEIPTIMEWEB
                        nftablesreload
                    fi
                fi
            fi
        else
            # on efface les lignes relatives à cet utilisateur
            if [ "$( grep -c "skuid $userid" $FILEIPTIMEWEB )" -ge 1 ];then
                $SED "/skuid $userid/d" $FILEIPTIMEWEB
                nftablesreload
            fi
            $SED "/^$PCUSER=/d" $FILE_HCOMPT
        fi
    done
else
     # on réactive tous les comptes
     listeusers | while read -r PCUSER
     do
         passwd -u "$PCUSER"
     done
     # on remet tous les compteurs à zéro.
     echo "date=$(date +%D)" > $FILE_HCOMPT
     echo > $FILEIPTIMEWEB
     nftablesreload
fi
}

function requiredpamtime() {
     TESTGESTIONNAIRE=0
     if [ ! -f $DIRPAM$COMMONFILEGS ] ; then
        for FILE in $GESTIONNAIREDESESSIONS
        do
          if [ -f "$DIRPAM""$FILE" ];then
             if [ "$( grep -c "^account required pam_time.so" "$DIRPAM$FILE" )" -eq 0  ] ; then
                $SED "1i account required pam_time.so"  "$DIRPAM$FILE"
             fi
             TESTGESTIONNAIRE=1
          fi
        done
    if [ $TESTGESTIONNAIRE -eq 0 ] ; then
        gettext 'No known session manager has been detected.'
        gettext 'so it is impossible to activate the time control connections'
        desactivetimelogin
        exit 1
    fi
     else
        if [ "$( grep -c "^account required pam_time.so" "$DIRPAM$COMMONFILEGS")" -eq 0  ] ; then
           $SED "1i account required pam_time.so"  $DIRPAM$COMMONFILEGS
        fi
     fi

     if [ ! -f $FILEPAMTIMECONF.old ] ; then
    cp $FILEPAMTIMECONF $FILEPAMTIMECONF.old
     fi
     echo "*;*;root;Al0000-2400" > $FILEPAMTIMECONF
}

function activetimelogin() {
    requiredpamtime

    listeusers | while read -r PCUSER
    do
    HOMEPCUSER=$(getent passwd "$PCUSER" | cut -d ':' -f6)
    $SED "/^$PCUSER=/d" $FILE_HCONF
    eval_gettext "\$PCUSER is allowed to connect 7/7 24/24 O/N?"
    choi=""
    while true; do
        read choi
            case $choi in
        O | o )
            alltime="O"
            echo "$PCUSER=admin=" >> $FILE_HCONF
               break
            ;;
        N| n )
            alltime="N"
            clear
            eval_gettext "\$PCUSER is allowed to connect X minutes per day
X (1 a 1440) = "
            while true; do
            read choi
            if [ "$choi" -ge 1 ];then
                if [ "$choi" -le 1440 ];then
                timesession=$choi
                break
                fi
            fi
            gettext "X must take a value between 1 and 1440
"
            done
            clear
            eval_gettext "\$PCUSER is allowed to surf the Internet X minutes per day
X ( 1 a \$timesession )= "
            while true; do
            read choi
            if [ "$choi" -ge 1 ];then
                if [ "$choi" -le "$timesession" ];then
                timeweb=$choi
                break
                fi
            fi
            eval_gettext "X must take a value between 1 and $timesession
"
            done
            echo "$PCUSER=user=$timesession=$timeweb" >> $FILE_HCONF
            break
            ;;
        esac
    done

    for NumDAY in 0 1 2 3 4 5 6
    do
        if [ $alltime = "O" ];then
        break
        fi

            clear
            at=$(gettext "at")
            and=$(gettext "and")
            h=$(gettext ":")
            or=$(gettext "or")
            echo "exemple: 00${h}00 $at 23${h}59 $or 08${h}00 $at 12${h}00 $and 14${h}00 $at 16${h}50"
            echo -e -n "$RougeD$PCUSER$Fcolor $(gettext "is allowed to connect the") $BleuD${DAYS[$NumDAY]}$Fcolor $(gettext "at:")"
            while true; do
        read choi
        input=$choi
        # mise en forme de la variable choi pour pam
        choi=$(echo "$choi" | sed -e "s/$h//g" | sed -e "s/ //g" | sed -e "s/$at/-/g" | sed -e "s/$and/:/g" )
        if [ "$( echo "$choi" | grep -E -c "^([0-1][0-9]|2[0-3])[0-5][0-9]-([0-1][0-9]|2[0-3])[0-5][0-9]$|^([0-1][0-9]|2[0-3])[0-5][0-9]-([0-1][0-9]|2[0-3])[0-5][0-9]:([0-1][0-9]|2[0-3])[0-5][0-9]-([0-1][0-9]|2[0-3])[0-5][0-9]$" )" -eq 1 ];then
                    int1=$(echo "$choi" | cut -d ":" -f1 | cut -d "-" -f1)
                    int2=$(echo "$choi" | cut -d ":" -f1 | cut -d "-" -f2)
                    int3=$(echo "$choi" | cut -d ":" -f2 | cut -d "-" -f1)
                    int4=$(echo "$choi" | cut -d ":" -f2 | cut -d "-" -f2)
                    if [ "$int1" -lt "$int2" ];then
            if [ ! "$(echo "$choi" | grep -E -c ":")" -eq 1 ] ; then
                            if [ "$NumDAY" -eq 6 ] ; then
                HORAIRESPAM="$HORAIRESPAM${DAYSPAM[$NumDAY]}$int1-$int2"
                            else
                HORAIRESPAM="$HORAIRESPAM${DAYSPAM[$NumDAY]}$int1-$int2|"
                            fi
                            m1=${int1:2:4}
                            h1=${int1:0:2}
                            m2=${int2:2:4}
                            h2=${int2:0:2}
                echo "$PCUSER=$NumDAY=$h1${h}h$m1:$h2${h}h$m2" >> "$FILE_HCONF"
                break
            else
                            if [ "$int2" -lt "$int3" ];then
                if [ "$int3" -lt "$int4" ];then
                    if [ "$NumDAY" -eq 6 ] ; then
                    HORAIRESPAM="$HORAIRESPAM${DAYSPAM[$NumDAY]}$int1-$int2|${DAYSPAM[$NumDAY]}$int3-$int4"
                    else
                    HORAIRESPAM="$HORAIRESPAM${DAYSPAM[$NumDAY]}$int1-$int2|${DAYSPAM[$NumDAY]}$int3-$int4|"
                    fi
                    m1=${int1:2:4}
                    h1=${int1:0:2}
                    m2=${int2:2:4}
                    h2=${int2:0:2}
                    m3=${int3:2:4}
                    h3=${int3:0:2}
                    m4=${int4:2:4}
                    h4=${int4:0:2}
                    ## minutes heures jourdumois mois jourdelasemaine utilisateur  commande
                    echo "$PCUSER=$NumDAY=$h1${h}h$m1:$h2${h}h$m2:$h3${h}h$m3:$h4${h}h$m4" >> "$FILE_HCONF"
                    break
                else
                    errortime1
                fi
                            else
                errortime1
                            fi
            fi
                    else
            errortime1
                    fi
        else
                    errortime2
        fi
            done
        done
     done
    echo >> $FILE_HCONF
    $SED "s?^HOURSCONNECT.*?HOURSCONNECT=ON?" $FILE_CONF
    readTimeFILECONF
}

function desactivetimelogin() {
    echo "<desactivetimelogin>"
    for FILE in $GESTIONNAIREDESESSIONS
    do
    $SED "/account required pam_time.so/d" "$DIRPAM""$FILE" 2> /dev/null
    done
    $SED "/account required pam_time.so/d" "$DIRPAM""$COMMONFILEGS" 2> /dev/null
    
    if [ -f $FILEPAMTIMECONF.old ];then
    cat $FILEPAMTIMECONF.old > $FILEPAMTIMECONF
    fi
    if [ -f $BINSYSTEMCTL ] ; then
		basename -a $(find /etc/systemd/system/ -type f,l | grep CTparentalskill ) 2> /dev/null | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | while read -r unite
		do
		systemctl stop $unite
		systemctl disable $unite
		done
		basename -a $(find /etc/systemd/system/ -type f,l | grep CTparentalnotify ) 2> /dev/null | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | while read -r unite
		do
		systemctl stop $unite
		systemctl disable $unite
		done
		rm -f /etc/systemd/system/CTparentalnotify*
		systemctl daemon-reload
    else
         rm -rf /etc/cron.d/CTparentalskill*
         rm -rf /etc/cron.d/CTparentalnotify*
         /etc/rc.d/rc.crond restart
    fi
    $SED "s?^HOURSCONNECT.*?HOURSCONNECT=OFF?" $FILE_CONF
    #for PCUSER in $(listeusers)
    listeusers | while read -r PCUSER
    do
    passwd -u "$PCUSER" > /dev/null
    done
    # on remet tous les compteurs à zéro.
    echo "date=$(date +%D)" > $FILE_HCOMPT
    echo > $FILE_HCONF
    echo > $FILEIPTIMEWEB
    nftablesreload
    echo "</desactivetimelogin>"
}

source "$DIR_SHARE/listeusers"

function readTimeFILECONF() {
    requiredpamtime
   if [ -f $BINSYSTEMCTL ] ; then
   ## on créer le service instancifier pout fermer les session utilisateurs
   ## plus d'info ici https://access.redhat.com/documentation/fr-fr/red_hat_enterprise_linux/7/html/system_administrators_guide/sect-managing_services_with_systemd-unit_files
    {
     echo "[Unit]
Description=fermeture de la session de %I
After=network-online.target

[Service]
User=root
WorkingDirectory=/root/
ExecStart=$SKILLUSER
Type=oneshot

[Install]
WantedBy=default.target

"
} > "/etc/systemd/system/CTparentalskill@.service"

    {
     echo '[Unit]
Description=notify the user %I if necessary
After=network-online.target

[Service]
User=%i
WorkingDirectory=~
ExecStart=/usr/bin/CTparentalnotify
Type=oneshot

[Install]
WantedBy=default.target

'
} > "/etc/systemd/system/CTparentalnotify@.service"

	# on redémare le démon systemd pour prendre en compte ce nouveau service
	systemctl daemon-reload
	## on desactive les anciennes taches planifiés via systemd timer.
	basename -a $(find /etc/systemd/system/ -type f,l | grep CTparentalskill ) 2> /dev/null | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | while read -r unite
	do
	systemctl stop $unite
	systemctl disable $unite
	done
	basename -a $(find /etc/systemd/system/ -type f,l | grep CTparentalnotify ) 2> /dev/null | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | while read -r unite
	do
	systemctl stop $unite
	systemctl disable $unite
	done
   
    else
      ## on utise cron si systemd n'est pas présent
      rm -rf /etc/cron.d/CTparentalskill*
      rm -rf /etc/cron.d/CTparentalnotify*
      /etc/rc.d/rc.crond restart
    fi
    
    
    #for PCUSER in $(listeusers)
    listeusers | while read -r PCUSER
    do
    if [ -f $BINSYSTEMCTL ] ; then
    {
    echo "[Unit]
Description=notify the user ${PCUSER} if necessary

[Timer]
OnBootSec=1min
OnUnitActiveSec=1min
Unit=CTparentalnotify@${PCUSER}.service

[Install]
WantedBy=timers.target
"
     } > /etc/systemd/system/CTparentalnotify${PCUSER}.timer
    systemctl enable CTparentalnotify${PCUSER}.timer
    systemctl start CTparentalnotify${PCUSER}.timer
    else
    ## on utise cron si systemd n'est pas présent
	{
	echo "export PATH=$PATH
*/1 * * * *  USER=root  $PCUSER" 
	} > /etc/cron.d/CTparentalnotify${PCUSER}
	/etc/rc.d/rc.crond restart
    fi
    HOMEPCUSER=$(getent passwd "$PCUSER" | cut -d ':' -f6)
    HORAIRESPAM=""
      userisconfigured="0"

    while read line
    do

        if [ "$( echo "$line" | grep -E -c "^$PCUSER=[0-6]=" )" -eq 1 ] ; then
        echo "$line"
        NumDAY=$(echo "$line" | cut -d"=" -f2)
        h1=$(echo "$line" | cut -d"=" -f3 | cut -d":" -f1 | cut -d"h" -f1)
        m1=$(echo "$line" | cut -d"=" -f3 | cut -d":" -f1 | cut -d"h" -f2)
        h2=$(echo "$line" | cut -d"=" -f3 | cut -d":" -f2 | cut -d"h" -f1)
        m2=$(echo "$line" | cut -d"=" -f3 | cut -d":" -f2 | cut -d"h" -f2)
        h3=$(echo "$line" | cut -d"=" -f3 | cut -d":" -f3 | cut -d"h" -f1)
        m3=$(echo "$line" | cut -d"=" -f3 | cut -d":" -f3 | cut -d"h" -f2)
        h4=$(echo "$line" | cut -d"=" -f3 | cut -d":" -f4 | cut -d"h" -f1)
        m4=$(echo "$line" | cut -d"=" -f3 | cut -d":" -f4 | cut -d"h" -f2)
        if [ "$(echo -n "$h3""$m3" | wc -c)" -gt 2 ]; then
             if [ "$NumDAY" -eq 6 ] ; then
                HORAIRESPAM="$HORAIRESPAM${DAYSPAM[$NumDAY]}$h1$m1-$h2$m2|${DAYSPAM[$NumDAY]}$h3$m3-$h4$m4"

            else
                HORAIRESPAM="$HORAIRESPAM${DAYSPAM[$NumDAY]}$h1$m1-$h2$m2|${DAYSPAM[$NumDAY]}$h3$m3-$h4$m4|"
            fi
            if [ -f $BINSYSTEMCTL ] ; then
            {
            echo "[Unit]
Description=fermeture de la session de ${PCUSER} 1

[Timer]
# on attent 5 minute après le boot
OnCalendar=${DAYSSYSTEMD[$NumDAY]} *-*-* ${h2}:${m2}:00
Unit=CTparentalskill@${PCUSER}.service

[Install]
WantedBy=timers.target
"
            } > /etc/systemd/system/CTparentalskill${PCUSER}${DAYSSYSTEMD[$NumDAY]}1.timer
            
            {
            echo "[Unit]
Description=fermeture de la session de ${PCUSER} 2

[Timer]
# on attent 5 minute après le boot
OnCalendar=${DAYSSYSTEMD[$NumDAY]} *-*-* ${h4}:${m4}:00
Unit=CTparentalskill@${PCUSER}.service

[Install]
WantedBy=timers.target
"
            } > /etc/systemd/system/CTparentalskill${PCUSER}${DAYSSYSTEMD[$NumDAY]}2.timer
            systemctl enable CTparentalskill${PCUSER}${DAYSSYSTEMD[$NumDAY]}1.timer
            systemctl enable CTparentalskill${PCUSER}${DAYSSYSTEMD[$NumDAY]}2.timer
            systemctl start CTparentalskill${PCUSER}${DAYSSYSTEMD[$NumDAY]}1.timer
            systemctl start CTparentalskill${PCUSER}${DAYSSYSTEMD[$NumDAY]}2.timer
            else
            ## on utise cron si systemd n'est pas présent
			{
			echo "export PATH=$PATH
${m2} ${h2} * * $NumDAY USER=root $SKILLUSER $PCUSER
${m4} ${h4} * * $NumDAY USER=root $SKILLUSER $PCUSER" 
			} > /etc/cron.d/CTparentalskill${PCUSER}${DAYSSYSTEMD[$NumDAY]}
			/etc/rc.d/rc.crond restart
            fi
            userisconfigured="1"

        else
            if [ "$NumDAY" -eq 6 ] ; then
            HORAIRESPAM="$HORAIRESPAM${DAYSPAM[$NumDAY]}$h1$m1-$h2$m2"
            else
            HORAIRESPAM="$HORAIRESPAM${DAYSPAM[$NumDAY]}$h1$m1-$h2$m2|"
            fi
            if [ -f $BINSYSTEMCTL ] ; then
            {
            echo "[Unit]
Description=fermeture de la session de ${PCUSER} 1

[Timer]
# on attent 5 minute après le boot
OnCalendar=${DAYSSYSTEMD[$NumDAY]} *-*-* ${h2}:${m2}:00
Unit=CTparentalskill@${PCUSER}.service

[Install]
WantedBy=timers.target
"
            } > /etc/systemd/system/CTparentalskill${PCUSER}${DAYSSYSTEMD[$NumDAY]}1.timer
            systemctl enable CTparentalskill${PCUSER}${DAYSSYSTEMD[$NumDAY]}1.timer
            systemctl start CTparentalskill${PCUSER}${DAYSSYSTEMD[$NumDAY]}1.timer
            else
            ## on utise cron si systemd n'est pas présent
			{
			echo "export PATH=$PATH
${m2} ${h2} * * * $NumDAY USER=root $SKILLUSER $PCUSER" 
			} > /etc/cron.d/CTparentalskill${PCUSER}${DAYSSYSTEMD[$NumDAY]}
			/etc/rc.d/rc.crond restart
            fi
            userisconfigured="1"
        fi
        fi
    done < $FILE_HCONF
    if [ $userisconfigured -eq 1 ] ; then
        echo "*;*;$PCUSER;$HORAIRESPAM" >> $FILEPAMTIMECONF
        ## on deconecte l'utilisateur pour prendre en compte un eventuel blocage imédia.
        systemctl start CTparentalskill@${PCUSER}.service
    else
        echo "*;*;$PCUSER;Al0000-2400" >> $FILEPAMTIMECONF
        $SED "/^$PCUSER=/d" $FILE_HCOMPT
        passwd -u "$PCUSER"
    fi
    done
    
    $SED "s?^HOURSCONNECT.*?HOURSCONNECT=ON?g" $FILE_CONF

}

function confgrub2() {
    PTNlogin='^[a-zA-Z]*$'
    ##Passage en keymap us pour le password comme ça quel que soit
    ##votre clavier le mot de passe correspond bien aux touches
    ##frappées. Ce qui évite de se prendre la tête pour le clavier
    ##avec le mot de passe grub.

    #apt-get install console-data
    layout1="$( grep "XKBLAYOUT" /etc/default/keyboard  | awk -F "\"" '{print $2}' | awk -F "," '{print $1}')"
    setxkbmap us
    loadkeys us
    clear
    gettext 'keymap is in qwerty us in grub menu.
    - Only letters or numbers.
    - 4 characters minimum.
Enter login to the superuser of grub2 :'
    while true; do
    read logingrub
    if [ "$(expr "$logingrub" : "$PTNlogin")" -gt 4  ];then
            break
    else
            clear
        gettext 'keymap is in qwerty us in grub menu.
    - Only letters or numbers.
    - 4 characters minimum.
Enter login to the superuser of grub2 :'
    fi
    done
    echo > /tmp/passgrub
    while [ "$(awk '{print $NF}' /tmp/passgrub | grep -c grub.)" -eq 0 ];do
    $NEWPASSGRUB2 | tee /tmp/passgrub
    done
    passwordgrub=$(awk '{print $NF}' /tmp/passgrub | grep grub.)
    ##on rebascule sur la keymap system
    setxkbmap "$layout1"
    loadkeys "$layout1"
    vide=""
    cat << EOF > /etc/grub.d/99_password
#!/bin/sh
## ce script doit être lancé en dernier !!!
## on restreint uniquement les menus de "setup uefi" , " recovery mode "
## ainsi que tous les submenu.
## seul les menuentry et submenu de premier niveau prennent en compte les paramètres d’accès utilisateurs.
## ce qui implique que l'ajout de --unrestricted a un submenu est récursif  !!
cat << ${vide}EOF
set superusers="$logingrub"
password_pbkdf2 $logingrub $passwordgrub
${vide}EOF
confunrestricted () {
        ## fonction lancée en tache de fond par la commande
        ## confunrestricted &
        ## elle attend la fin de l’exécution de tous les scripts  update grub
        ## puis modifie le fichier $BOOTREPGRUB2/grub.cfg pour y ajouter le droits a tout le monde
        cd /etc/grub.d/
        for file in *
        do
        if [ "\$(echo "\$file" | grep -E -c "[0-9][0-9]_")" -eq 1 ];then
            if [ -z "\$processupdategrub" ] ; then
                processupdategrub=\$file
            else
                processupdategrub=\$processupdategrub","\$file
            fi
        fi
        done
        while [ "\$(ps -C "\$processupdategrub" -o pid= | wc -l)" -gt 2 ]
        do
            sleep 0.2
        done
        sync
        cp $BOOTREPGRUB2/grub.cfg /tmp/grub.cfg.new
        while read -r linecfg
        do
            if [ "\$(echo "\$linecfg" | grep -E "menuentry " | grep -v "uefi-firmware" | grep -c -v "recovery mode" )" -eq 1 ];then
                line2=\$(echo "\$linecfg" | sed -e 's/ {/ --unrestricted { /g')
                sed -i "s|\$linecfg|\$line2|" $BOOTREPGRUB2/grub.cfg
            fi
        done < /tmp/grub.cfg.new
        rm /tmp/grub.cfg.new
    }
confunrestricted &
EOF
    chmod 755 /etc/grub.d/99_password
    update-grub2
}

function exportconf() {
    if [ ! -e "$FILEFIRWALLCONF" ] ;  then
    echo > "$FILEFIRWALLCONF"
    fi
    if [ ! -e "$FILEIPBLACKLIST" ] ;  then
    echo > "$FILEIPBLACKLIST"
    fi
    date="$( date +%y.%m.%d )"
    ## on ajoute un fichier indiquant la version majeur de ctparental ayant cree le fichier de conf
    VMAJEURACTUEL="$(cat $FILCHANGELOGGZ | gunzip | sed -n "1 p" | cut -d " " -f2 | sed "s/[().-]//g" | cut -c -3)"
    echo "VCONF=$VMAJEURACTUEL" > "$DIR_CONF"/VCONF
    FILEexpconf=${FILEexpconf:=$(echo "$DIRexpconf"/CTparental.conf."$date".tar.gz | sed -e "s|\/\{2,10\}|\/|g" )}
    tar -cvzf "$FILEexpconf" "$DIR_CONF"/wl-categories-available "$DIR_CONF"/categories-enabled.conf \
    "$DIR_CONF"/CThourscompteur "$DIR_CONF"/CTsafe.conf "$DIR_CONF"/bl-categories-available \
    "$DIR_CONF"/CThours.conf  "$DIR_CONF"/dnsfilter-available/ "$DIR_CONF"/ipv6filter-available/ "$DIR_CONF"/ipv4filter-available/ \
    "$DIR_CONF"/CTparental.conf "$DIR_CONF"/dip-rehabiliter.conf "$DIR_CONF"/dip-blackliste.conf \
    "$DIR_CONF"/GCToff.conf "$PRIVOXYCONF" "$PRIVOXYUSERA" "$PRIVOXYCTA" "$DIR_CONF"/VCONF \
    "$DIRE2G"lists/bannedmimetypelist "$DIRE2G"lists/bannedextensionlist "$DIRE2G"lists/bannedsitelist \
    "$FILEFIRWALLCONF" "$FILEIPBLACKLIST" "$DIR_CONF"/.ssh/ /home/ctsync/.ssh/ "$DIR_CONF"/sshd/ "$DIR_CONF"/ctsync.conf 2>/dev/null
    rm -f "$DIR_CONF"/VCONF

    chmod 744 "$FILEexpconf"
    eval_gettext "Conf exported to \$FILEexpconf
"
}

function importconf() {
    # si l'archive contient bien la bonne liste de fichiers.
    dirtar=$(echo "$DIR_CONF" | sed -e "s/\///1")
    dir2gtar=$(echo "$DIRE2G" | sed -e "s/\///1")
    privoxyconftar=$(echo "$PRIVOXYCONF" | sed -e "s/\///1")
    privoxyuseratar=$(echo "$PRIVOXYUSERA" | sed -e "s/\///1")
    privoxyctatar=$(echo "$PRIVOXYCTA" | sed -e "s/\///1")
    filefirewallconftar=$(echo "$FILEFIRWALLCONF" | sed -e "s/\///1")
    fileipblacklisttar=$(echo "$FILEIPBLACKLIST" | sed -e "s/\///1")
    ## pour la compatibilitée client e2guardian <= serveur dansguardian
    if [ -d /etc/dansguardian ] ;then
        rm -rf /etc/dansguardian 
    fi
    dreabmd5old=$(grep MD5DREAB= "$FILE_CONF" | cut -d"=" -f2)
    ## si la version ctparental ayans genere le fichier de conf et trops differante on considaire le fichier non compatible.
    VMAJEURACTUEL="$(cat $FILCHANGELOGGZ | gunzip | sed -n "1 p" | cut -d " " -f2 | sed "s/[().-]//g" | cut -c -3)"
    tar -xvzf "$FILEimpconf" -C / "$dirtar"/VCONF 
    if [ $? -eq 0 ] ;then
        VCONF=$(grep "VCONF=" "$DIR_CONF"/VCONF | cut -d"=" -f2) 
        rm -f "$DIR_CONF"/VCONF
    else
        VCONF=0
    fi
    if [ $VMAJEURACTUEL -eq $VCONF ] ;then
        ## si on fait in import manuel
        if [ $clientsync -eq 0 ];then
            tar -xvzf "$FILEimpconf" -C /
            # si on a faire a une conf iptables
            if [ "$(grep -i -c "iptables" $FILEFIRWALLCONF)" -ge 1 ] ; then 
                initfilenftables
            fi
            if [ -f "$DIR_CONF"/ctsync.conf ];then
                if [ "$( grep -c "SRVSYNC=ON" "$DIR_CONF"/ctsync.conf )" -eq 1 ];then
                    clientsyncoff
                    serversyncon
                    tar -xvzf "$FILEimpconf" -C / home/ctsync/.ssh/authorized_keys $dirtar/sshd/csync_host_rsa_key $dirtar/sshd/csync_host_rsa_key.pub $dirtar/sshd/Envssh
                    chown ctsync:ctsync /home/ctsync/.ssh/authorized_keys
                    chmod 644 /home/ctsync/.ssh/authorized_keys
                    chmod 644 $DIR_CONF/sshd/Envssh
                    chown root:root $DIR_CONF/sshd/Envssh
                    chown root:root $DIR_CONF/sshd/csync_host_rsa_key
                    chmod 600 $DIR_CONF/sshd/csync_host_rsa_key
                    chown root:root $DIR_CONF/sshd/csync_host_rsa_key.pub
                    chmod 644 $DIR_CONF/sshd/csync_host_rsa_key.pub
                    $CTparentalSshdRestart
                    
                fi
                if [ "$( grep -c "CSYNC=ON" "$DIR_CONF"/ctsync.conf )" -eq 1 ];then
                    serversyncoff
                    useradd --shell /bin/bash --create-home --system ctsync
                    chmod 750 /home/ctsync
                    password=$(genpasswd)
                    echo "ctsync:$password" | chpasswd
                    tar -xvzf "$FILEimpconf" -C / home/ctsync/.ssh/ $dirtar/.ssh/known_hosts
                    chown root:root /home/ctsync/.ssh/id_rsa
                    chmod 600 /home/ctsync/.ssh/id_rsa
                    chown root:root $DIR_CONF/.ssh/known_hosts
                    chmod 644 $DIR_CONF/.ssh/known_hosts
                    ## on desactive les anciennes taches planifiés via systemd timer.
                    basename -a $(find /etc/systemd/system/ -type f,l | grep CTparentalcsync ) 2> /dev/null | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | while read -r unite
                    do
                    systemctl stop $unite
                    systemctl disable $unite
                    done
                    {
                    echo '[Unit]
Description=sync on CTparental server
After=network-online.target

[Service]
User=root
WorkingDirectory=/root/
ExecStart=/usr/bin/CTparental -csync
Type=oneshot

[Install]
WantedBy=default.target

'
                    } > "/etc/systemd/system/CTparentalcsync.service"
                    # on redémare le démon systemd pour prendre en compte ce nouveau service
                    systemctl daemon-reload
                    {
                    echo "[Unit]
Description=sync on CTparental server

[Timer]
OnBootSec=10min
OnUnitActiveSec=10min
RandomizedDelaySec=5min
Unit=CTparentalcsync.service

[Install]
WantedBy=timers.target
"
                    } > /etc/systemd/system/CTparentalcsync.timer
                    systemctl enable CTparentalcsync.timer
                    systemctl start CTparentalcsync.timer
                fi
            fi
        else
            ## si l'import est éféctué par la syncro client serveur
            if [ ! "$(tar -tf "$FILEimpconf" | grep -c "$dir2gtar" )" -eq 1 ] ;then
                dir2gtar="etc/dansguardian/"
            fi
            tar -xvzf "$FILEimpconf" -C / "$dirtar"/wl-categories-available "$dirtar"/categories-enabled.conf \
            "$dirtar"/CThourscompteur "$dirtar"/CTsafe.conf "$dirtar"/dip-blackliste.conf "$dirtar"/bl-categories-available \
            "$dirtar"/CThours.conf  "$dirtar"/dnsfilter-available/ "$dirtar"/ipv4filter-available "$dirtar"/ipv6filter-available \
            "$dirtar"/CTparental.conf "$dirtar"/dip-rehabiliter.conf \
            "$dirtar"/GCToff.conf "$privoxyconftar" "$privoxyuseratar" "$privoxyctatar" \
            "$dir2gtar"lists/bannedmimetypelist "$dir2gtar"lists/bannedextensionlist "$dir2gtar"lists/bannedsitelist \
            "$filefirewallconftar" "$fileipblacklisttar"
            # si on a faire a une conf iptables
            if [ "$(grep -i -c "iptables" $FILEFIRWALLCONF)" -ge 1 ] ; then 
                initfilenftables
            fi
            if [ -d /etc/dansguardian ] ;then
                cp -rf /etc/dansguardian/*  "$DIRE2G"
                rm -rf /etc/dansguardian
            fi
        fi
        $SED "s?^MD5DREAB.*?MD5DREAB=$dreabmd5old?g" $FILE_CONF
        $SED "s?^MD5IPT.*?MD5IPT=old?g" $FILE_CONF
        FILTRAGEISOFF="$( grep -c "DNSCRYPT=OFF" $FILE_CONF )"
        if [ ! "$FILTRAGEISOFF" -eq 1 ];then
            adapt
            catChoice
            dnscryptproxyon
        else
            desactivegourpectoff
            autoupdateoff
            dnscryptproxyoff
            FILTRAGEISOFF=1
            nftablesreload
        fi
        if [ "$( grep -c GCTOFF=ON $FILE_CONF )" -eq 1 ];then
            activegourpectoff
        else
            desactivegourpectoff
        fi
        if [ "$( grep -c HOURSCONNECT=ON $FILE_CONF )" -eq 1 ];then
            readTimeFILECONF
        else
            desactivetimelogin
        fi

    else
        VCOMPATIBLE=$(echo "$(cat $FILCHANGELOGGZ | gunzip | sed -n "1 p" | cut -d " " -f2 | cut -c -5).xx-x.x)" )
        if [ $clientsync -eq 0 ];then
            eval_gettext "\$FILEimpconf is not a compatible configuration file"
            echo ""
        else
            eval_gettext "the CTparental server version is not \$VCOMPATIBLE"
            echo ""
        fi
    fi
}

function genpasswd() {
  local length=${1:-8}
  tr -dc A-Za-z0-9_ < /dev/urandom | head -c ${length} | xargs
}
function expsync () {
    if [ "$(grep -c "SRVSYNC=ON" "$DIR_CONF"/ctsync.conf )" -eq 1 ];then
    if [ ! -e "/home/ctsync/MD5EXPSYNC.txt" ] ;  then
        touch "/home/ctsync/MD5EXPSYNC.txt"
    fi
     md5old=$(cat "/home/ctsync/MD5EXPSYNC.txt" | awk {'print $1'})
     md5new="$({ cat "$DIR_CONF"/wl-categories-available "$DIR_CONF"/categories-enabled.conf \
 "$DIR_CONF"/CThourscompteur "$DIR_CONF"/CTsafe.conf "$DIR_CONF"/dip-blackliste.conf "$DIR_CONF"/bl-categories-available \
 "$DIR_CONF"/CThours.conf  "$DIR_CONF"/dnsfilter-available/* "$DIR_CONF"/ipv6filter-available/* "$DIR_CONF"/ipv4filter-available/* \
 "$DIR_CONF"/CTparental.conf "$DIR_CONF"/dip-rehabiliter.conf \
 "$DIR_CONF"/GCToff.conf "$PRIVOXYCONF" "$PRIVOXYUSERA" "$PRIVOXYCTA" \
 "$DIRE2G"lists/bannedmimetypelist "$DIRE2G"lists/bannedextensionlist "$DIRE2G"lists/bannedsitelist \
 "$FILEFIRWALLCONF" "$FILEIPBLACKLIST" /home/ctsync/.ssh/authorized_keys | md5sum | awk {'print $1'} 
 })"
        if [ ! "$md5old" = "$md5new" ]; then
        FILEexpconf="/home/ctsync/confCTparental.tar.gz"
        exportconf
        echo $md5new > /home/ctsync/MD5EXPSYNC.txt
        md5sum /home/ctsync/confCTparental.tar.gz > /home/ctsync/confCTparental.tar.gz.md5
        fi
    fi
}
function serversyncon () {
    echo "<serversyncon>"
    $ENCTparentalSshd
    if [ "$(grep -c "CSYNC=ON" "$DIR_CONF"/ctsync.conf)" -eq 1 ] ;then
        echo "$(gettext "You must first disable client mode")"
    else
            if [ "$i_WAN_ipv6" =  "nointerface" ];then
            i_WAN=$i_WAN_ipv4
            SRVipv6linklocal=$(ip addr show $i_WAN_ipv4  | grep inet6 | awk '{print $2}' | grep "fe80" | cut -d"/" -f1)
            else
            i_WAN=$i_WAN_ipv6
            SRVipv6linklocal=$(ip addr show $i_WAN_ipv6  | grep inet6 | awk '{print $2}' | grep "fe80" | cut -d"/" -f1)
            fi
            useradd --shell /bin/bash --create-home --system ctsync 2>/dev/null
            chown root:ctsync /home/ctsync
            chmod 770 /home/ctsync
            passwordsrv=$(genpasswd)
            echo "ctsync:$passwordsrv" | chpasswd
            rm -rf /home/ctsync/.ssh
            mkdir -p /home/ctsync/.ssh
            touch /home/ctsync/.ssh/authorized_keys
            chown ctsync:ctsync /home/ctsync/.ssh/authorized_keys
            chmod 644 /home/ctsync/.ssh/authorized_keys
            SFTPPATH=$(find / -type f -name sftp-server -executable 2>/dev/null)
            { echo "
Port $PORTSSH
AddressFamily inet6
ListenAddress ${SRVipv6linklocal}%${i_WAN}
#ListenAddress ::
#SyslogFacility AUTH
#LogLevel INFO
StrictModes yes
PubkeyAuthentication yes
AuthorizedKeysFile    .ssh/authorized_keys
PasswordAuthentication no
PermitEmptyPasswords no
UsePAM no
AllowAgentForwarding no
AllowTcpForwarding no
X11Forwarding no
PrintMotd no
Banner none
AcceptEnv LANG LC_*
# override default of no subsystems
Subsystem    sftp    $SFTPPATH
Match User ctsync
        PasswordAuthentication yes
        ForceCommand /usr/bin/CTctsync_ssh
        AllowTcpForwarding no"
        
} > ${DIR_CONF}/sshd/csync_sshd_config
rm -f ${DIR_CONF}/sshd/csync_host_* 2> /dev/null
ssh-keygen -q -t rsa -f ${DIR_CONF}/sshd/csync_host_rsa_key -N ''
chown root:root ${DIR_CONF}/sshd/csync_host_rsa_key
chmod 600 ${DIR_CONF}/sshd/csync_host_rsa_key
chown root:root ${DIR_CONF}/sshd/csync_host_rsa_key.pub
chmod 644 ${DIR_CONF}/sshd/csync_host_rsa_key.pub
        $CTparentalSshdRestart

        {
        echo "# $(gettext "to enable sync with this server, run the following commands on the client on your local network that you want to synchronize")
CTparental -syncon \"$SRVipv6linklocal\" \"$passwordsrv\" \"$PORTSSH\"

SRVipv6linklocal=$SRVipv6linklocal
SRVSYNC=ON
CSYNC=OFF
PORTSSH=$PORTSSH
"
        } > "$DIR_CONF"/ctsync.conf
        cat "$DIR_CONF"/ctsync.conf
        chown root:"$GROUPHTTPD" "$DIR_CONF"/ctsync.conf
        chmod 640 "$DIR_CONF"/ctsync.conf
        expsync > /dev/null
        if [ -f $BINSYSTEMCTL ] ; then
            {
            echo '[Unit]
Description=expsync off CTparental server
After=network-online.target

[Service]
User=root
WorkingDirectory=/root/
ExecStart=/usr/bin/CTparental -expsync
Type=oneshot

[Install]
WantedBy=default.target

'
            } > "/etc/systemd/system/CTparentalexpsync.service"
            # on redémare le démon systemd pour prendre en compte ce nouveau service
            systemctl daemon-reload

            {
            echo "[Unit]
Description=expsync off CTparental server

[Timer]
OnBootSec=10min
OnUnitActiveSec=15min
Unit=CTparentalexpsync.service

[Install]
WantedBy=timers.target
"
            } > /etc/systemd/system/CTparentalexpsync.timer
            systemctl enable CTparentalexpsync.timer
            systemctl start CTparentalexpsync.timer
        else
            rm -f /etc/cron.d/CTparentalexpsync
            {
          	echo "export PATH=$PATH
*/15 * * * *  USER=root  /usr/bin/CTparental -expsync" 
	        } > /etc/cron.d/CTparentalexpsync
	        /etc/rc.d/rc.crond restart  
        fi

    fi
echo "</serversyncon>"
}

function serversyncoff () {
    $CTparentalSshdStop
    $DICTparentalSshd
    pkill -u ctsync
    deluser --quiet --system --remove-home ctsync 
    if [ -f $BINSYSTEMCTL ] ; then
       ## on desactive les anciennes taches planifiés via systemd timer.
       basename -a $(find /etc/systemd/system/ -type f,l | grep CTparentalexpsync ) 2> /dev/null | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | while read -r unite
       do
           systemctl stop $unite
           systemctl disable $unite
       done
       rm -f /etc/systemd/system/CTparentalexpsync*
       systemctl daemon-reload
    else
            rm -f /etc/cron.d/CTparentalexpsync
	        /etc/rc.d/rc.crond restart   
    fi
    $SED "s?^SRVSYNC=.*?SRVSYNC=OFF?g" "$DIR_CONF"/ctsync.conf
}

function clientsyncon () {
    echo "<clientsyncon>"
    if [ "$i_WAN_ipv6" =  "nointerface" ];then
            i_WAN=$i_WAN_ipv4
    else
            i_WAN=$i_WAN_ipv6
    fi
    SRVipv6linklocal=$1
    passwordsrv=$2
    PORTSSH=$3
    if [ "$( grep -c "SRVSYNC=ON" "$DIR_CONF"/ctsync.conf )" -eq 1 ];then
        echo "$(gettext "You must first disable server mode")"
    else
        useradd --shell /bin/bash --create-home --system ctsync
        chown root:ctsync /home/ctsync
        chmod 770 /home/ctsync
        password=$(genpasswd)
        echo "ctsync:$password" | chpasswd
        rm -rf /home/ctsync/.ssh 2> /dev/null
        mkdir -p /home/ctsync/.ssh 2> /dev/null
        rm -rf $DIR_CONF/.ssh 2> /dev/null
        mkdir -p $DIR_CONF/.ssh 2> /dev/null
        ## pour les distributions basée sur ubuntu évite des erreurs ssh-copy-id
        export HOME=/root
        echo "$(gettext "The requested password is:")
    $passwordsrv
    "
        ssh-keygen -t rsa -b 2048 -P "" -f /home/ctsync/.ssh/id_rsa -q
        chown root:root /home/ctsync/.ssh/id_rsa
        chmod 600 /home/ctsync/.ssh/id_rsa
        ssh-copy-id -o UserKnownHostsFile=$DIR_CONF/.ssh/known_hosts -o StrictHostKeyChecking=no -i /home/ctsync/.ssh/id_rsa.pub -p $PORTSSH ctsync@${SRVipv6linklocal}%${i_WAN}
        if [ -f $BINSYSTEMCTL ] ; then
           ## on desactive les anciennes taches planifiés via systemd timer.
           basename -a $(find /etc/systemd/system/ -type f,l | grep CTparentalcsync ) 2> /dev/null | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | while read -r unite
           do
              systemctl stop $unite
              systemctl disable $unite
           done
        
           {
           echo '[Unit]
Description=sync on CTparental server
After=network-online.target

[Service]
User=root
WorkingDirectory=$DIR_CONF/
ExecStart=/usr/bin/CTparental -csync
Type=oneshot

[Install]
WantedBy=default.target

'
           } > "/etc/systemd/system/CTparentalcsync.service"
           # on redémare le démon systemd pour prendre en compte ce nouveau service
           systemctl daemon-reload

           {
           echo "[Unit]
Description=sync on CTparental server

[Timer]
OnBootSec=10min
OnUnitActiveSec=10min
RandomizedDelaySec=5min
Unit=CTparentalcsync.service

[Install]
WantedBy=timers.target
"
           } > /etc/systemd/system/CTparentalcsync.timer
           systemctl enable CTparentalcsync.timer
           systemctl start CTparentalcsync.timer
        else
            rm -f /etc/cron.d/CTparentalcsync
            {
          	echo "export PATH=$PATH
*/10 * * * *  USER=root  /usr/bin/CTparental -csync" 
	        } > /etc/cron.d/CTparentalcsync
	        /etc/rc.d/rc.crond restart     
        fi
        {
        echo "
SRVipv6linklocal=$SRVipv6linklocal
PORTSSH=$PORTSSH
CSYNC=ON
SRVSYNC=OFF
"
        } > "$DIR_CONF"/ctsync.conf
        chown root:"$GROUPHTTPD" "$DIR_CONF"/ctsync.conf
        chmod 640 "$DIR_CONF"/ctsync.conf
        clientsync
    fi
    echo "</clientsyncon>"
}

function clientsyncoff () {
    pkill -u ctsync
    deluser --quiet --system --remove-home ctsync
    if [ -f $BINSYSTEMCTL ] ; then
        ## on desactive les anciennes taches planifiés via systemd timer.
        basename -a $(find /etc/systemd/system/ -type f,l | grep CTparentalcsync ) 2> /dev/null | awk '{cnts[$0]} END { for (v in cnts) print v}' | grep -v "^$" | while read -r unite
        do
           systemctl stop $unite
           systemctl disable $unite
        done
        rm -f /etc/systemd/system/CTparentalcsync*
        systemctl daemon-reload
    else
        rm -f /etc/cron.d/CTparentalcsync
        /etc/rc.d/rc.crond restart
    fi
    $SED "s?^CSYNC=.*?CSYNC=OFF?" "$DIR_CONF"/ctsync.conf

}

function clientsync () {
    if [ "$i_WAN_ipv6" =  "nointerface" ];then
            i_WAN=$i_WAN_ipv4
    else
            i_WAN=$i_WAN_ipv6
    fi
    export HOME=/root
    SRVipv6linklocal=$(grep "SRVipv6linklocal=" "$DIR_CONF"/ctsync.conf | cut -d"=" -f2)
    echo $SRVipv6linklocal
    PORTSSH=$(grep "PORTSSH=" "$DIR_CONF"/ctsync.conf | cut -d"=" -f2)
    rsync --chmod 755 -av -e "ssh -o UserKnownHostsFile=$DIR_CONF/.ssh/known_hosts -i /home/ctsync/.ssh/id_rsa -p $PORTSSH" ctsync@[${SRVipv6linklocal}%${i_WAN}]:/home/ctsync/confCTparental.tar.gz.md5 /home/ctsync/confCTparental.tar.gz.md5
    error1=$?
    rsync --chmod 755 -av -e "ssh -o UserKnownHostsFile=$DIR_CONF/.ssh/known_hosts -i /home/ctsync/.ssh/id_rsa -p $PORTSSH" ctsync@[${SRVipv6linklocal}%${i_WAN}]:/home/ctsync/confCTparental.tar.gz /home/ctsync/confCTparental.tar.gz
    error2=$?
    if [ $(( $error1 + $error2 )) -ge 1 ] ;then
    exit 1
    fi
    md5fileorig=$(grep " " "/home/ctsync/confCTparental.tar.gz.md5" | awk {'print $1'})
    md5filenew=$( md5sum /home/ctsync/confCTparental.tar.gz | awk {'print $1'})
    ## on sassure que les fichiers sont pas corrompus.
    if [ "$md5fileorig" = "$md5filenew" ]; then
        if [ -f /home/ctsync/confCTparental.tar.gz.md5.old ];then
            echo "$md5fileorig  = $md5filenew"
            md5fileorig=$(grep " " "/home/ctsync/confCTparental.tar.gz.md5.old" | awk {'print $1'})
            ## on verifie si il y a un changement dans la conf
            if [ ! "$md5fileorig" = "$md5filenew" ]; then
                FILEimpconf=/home/ctsync/confCTparental.tar.gz
                clientsync=1
                importconf
                md5sum /home/ctsync/confCTparental.tar.gz > /home/ctsync/confCTparental.tar.gz.md5.old
            fi
        else
            FILEimpconf=/home/ctsync/confCTparental.tar.gz
            clientsync=1
            importconf
            md5sum /home/ctsync/confCTparental.tar.gz > /home/ctsync/confCTparental.tar.gz.md5.old
        fi
    fi
}

# and func # ne pas effacer cette ligne !!

usage="$(gettext "Use"): CTparental    {-i }|{ -u }|{ -dl }|{ -ubl }|{ -rl }|{ -on }|{ -off }|{ -cble }|{ -dble }
             |{ -tlo }|{ -tlu }|{ -uhtml }|{ -aupon }|{ -aupoff }|{ -aup }
-i$(gettext "        => Install parental control on the computer (desktop PC).")
-u$(gettext "        => uninstall the Parental Control Computer (desktop PC).")
-dl$(gettext "        => updates parental control from the blacklist of the University of Toulouse.")
-force$(gettext "        => if placed after -dl forces the download even if we are already up to date.")
-ubl$(eval_gettext "        => To be done after each change of the file \$BL_DIPOSSI")
-rl$(eval_gettext "        => To be done after each change of the file \$REABDIP")
-on$(gettext "        => Enable parental control")
-off$(gettext "        => Disable parental control")
-cble$(gettext "        => Set the filter mode by whitelist or blacklist (default)
          and the categories that you want to activate.")
-dble$(gettext "        => Reset the default active categories and blacklist filtering.")
-tlo$(gettext "        => Enable and configure the login time restrictions for users.")
-tlu$(gettext "        => Disable the login time restrictions for users.")
-uhtml$(gettext "        => initializes the HTML interface, which includes login and password.")
-aupon$(gettext "        => Enable the automatic update of the Toulouse blacklist (every 7 days).")
-aupoff$(gettext "        => Disable the automatic update of the Toulouse blacklist.")
-aup$(gettext "        => as -dl but only if there is no update for more than 7 days.")
-nodep$(gettext "        => if placed after -i or -u allows not install / uninstall the dependencies, useful if
          we prefer to install them by hand, or for the postinst and prerm script of deb.
          examples:
                  CTparental -i -nodep
                  CTparental -u -nodep")
-nomanuel$(gettext "   => used only for the postinst and prerm script.")
-gcton$(eval_gettext "        => Enable a group of privileged users that will not undergo filtering.
          exemples:
                  CTparental -gctulist
                  Comment all users that you want to filter in \$FILE_GCTOFFCONF
                  CTparental -gctalist")
-gctoff$(gettext "        => Disable privileged group.")
          $(gettext "all users of the system undergo the filtering!")
-gctalist$(eval_gettext "   => Add / Delete users in the ctoff group based on the config file, \$FILE_GCTOFFCONF")
-ipton$(gettext "        => Enable rules of custom firewall.")
-iptoff$(gettext "        => Disable rules of custom firewall.")
-grubPon$(gettext "    => Enable the superuser of grub2.")
-grubPoff$(gettext "   => Disable the superuser of grub2.")
-pfoff$(gettext "        => Disable default rules privoxy.")
-pfon$(gettext "        => Enable default rules privoxy. (default is Enable)")
-exp$(gettext "        => Export configuration.
          exemple:
                  CTparental -exp /home/myhomedir/")
-imp$(gettext "        => Import a configuration.
          exemple:
                  CTparental -imp /home/myhomedir/CTparental.conf.yy.mm.dd.tar.gz")
-logon$(gettext "   => For debugging.
          Enabling dnscrypt-proxy log in the /var/log/CTdnscrypt-proxy/*.log file.
          Enabling nftables log in the  /var/log/nftables/nftablesipv4.log nftablesipv6.log file.
          set 1 years logrotates logins, nftables, dnscrypt-proxy.")
-logoff$(gettext "  => To disable log of dnscrypt-proxy and nftables.")
-setadmin$(gettext "    => To change the login couple password.")
-expsync$(gettext "    => To update the conf distribute by the server.")
-srvon$(gettext "    => To activate the server role.")
-srvoff$(gettext "    => to disable the server role.")
-syncon$(gettext "    => To activate the client role.")
-syncoff$(gettext "    => to disable the client role.")
-csync$(gettext "    => To synchronize the client with the server.")
"
arg1=${1}
case $arg1 in
    -\? | -h* | --h*)
        echo "$usage"
    ;;
    -i )
        if [ $# -ge 2 ]; then          
            if [ $2 = "-nodep" ]; then
                noinstalldep=1
            fi
            if [ $# == 3 ]; then
                if [ $3 = "-nomanuel" ]; then
                    nomanuel=1
                fi
            fi
        fi
        networkisoknext
        install
    ;;
    -u )
        if [ $# -ge 2 ]; then
            if [ $2 = "-nodep" ]; then
                noinstalldep=1
            fi
        fi
        if [ $# -ge 3 ]; then
            if [ $3 = "-nomanuel" ]; then
                nomanuel=1
            fi
        fi
        uninstall
    ;;
    -dl )
        if [ ! "$FILTRAGEISOFF" -eq 1 ];then
            if [ $# -ge 2 ]; then
               if [ $2 = "-force" ]; then
                  echo  > $DIR_CONF/blacklists.tar.gz.md5sum
                  echo  > $DIR_CONF/categoriesmd5sum
               fi
            fi
            networkisoknext
            download
            adapt
            catChoice
            dnscryptproxyon
            $SED "s?^LASTUPDATE.*?LASTUPDATE=$THISDAYS=$(date +%d-%m-%Y\ %T)?" $FILE_CONF
        fi
    ;;
    -ubl )
        if [ ! "$FILTRAGEISOFF" -eq 1 ];then
            networkisoknext
            adapt
            catChoice
            dnscryptproxyon
        fi
    ;;
    -uhtml )
            networkisoknext
            FoncHTTPDCONF
    ;;
    -rl )
        if [ ! "$FILTRAGEISOFF" -eq 1 ];then
            networkisoknext
            catChoice
            dnscryptproxyon
        fi
    ;;
    -on )
        networkisoknext
        FILTRAGEISOFF=0
        dnscryptproxyon
        nftablesreload
        activegourpectoff
        autoupdateon
    ;;
    -off )
        desactivegourpectoff
        autoupdateoff
        dnscryptproxyoff
        FILTRAGEISOFF=1
        nftablesreload
    ;;
    -wlo )
    if [ ! "$FILTRAGEISOFF" -eq 1 ];then
        networkisoknext
        dnsmasqwhitelistonly
    fi
    ;;
    -cble )
        if [ ! "$FILTRAGEISOFF" -eq 1 ];then
            networkisoknext
            choiblenabled
            catChoice
            dnscryptproxyon
        fi
    ;;
    -dble )
        if [ ! "$FILTRAGEISOFF" -eq 1 ];then
            networkisoknext
            initblenabled
            catChoice
            dnscryptproxyon
        fi
    ;;
    -tlo )
        activetimelogin
    ;;
    -tlu )
        desactivetimelogin
    ;;
    -trf )
        readTimeFILECONF
    ;;
    -aupon )
        if [ ! "$FILTRAGEISOFF" -eq 1 ];then
            autoupdateon
        fi
    ;;
    -aupoff )
        autoupdateoff
    ;;
    -gcton )
        if [ ! "$FILTRAGEISOFF" -eq 1 ];then
            networkisoknext
            activegourpectoff
            nftablesreload
        fi
    ;;
    -gctoff )
        desactivegourpectoff
        nftablesreload
    ;;
    -gctulist )
        if [ ! "$FILTRAGEISOFF" -eq 1 ];then
            updatelistgctoff
        fi
    ;;
    -gctalist )
        if [ ! "$FILTRAGEISOFF" -eq 1 ];then
            networkisoknext
            if [ "$(updatelistgctoff)" -eq 1 ];then
                updatecauser
            fi
            unset test
            applistegctoff
            nftablesreload
        fi
    ;;
    -ipton )
        networkisoknext
        $SED "s?.*IPRULES.*?IPRULES=ON?" $FILE_CONF
        nftdisableconflict
        nftablesreload
        $RSYSLOGRESTART
        echo -e "$RougeD $(eval_gettext 'to add custom rules edit the file 
$FILEFIRWALLCONF 
then run the command CTparental -ipton') 

$(eval_gettext 'to add ipv4/ipv6 blacklist edit the file 
$FILEIPBLACKLIST 
then run the command CTparental -ipton') 
 $Fcolor"
    ;;
    -iptoff )
        $SED "s?.*IPRULES=.*?IPRULES=OFF?" $FILE_CONF
        nftdisableconflict
        nftablesreload
        #rm -f $RSYSLOGCTPARENTAL
        $RSYSLOGRESTART
    ;;
    -cron )
        # appelé toutes les minutes par cron pour activer/désactiver
        # les usagers ayant des restrictions de temps journalier de
        # connexion.
        if [ "$( grep -c "HOURSCONNECT=ON" $FILE_CONF )" -eq 1 ];then
            updatetimelogin
        fi
        if [ ! "$FILTRAGEISOFF" -eq 1 ];then
            # appelé toutes les minutes par cron pour modifier la
            # configuration en cas de changement de réseau.
            nomade
            # appelé toutes les minutes par cron pour activer le
            # filtrage sur les usagers nouvellement créés.
            if [ $(updatelistgctoff) -eq 1 ];then
            applistegctoff
            nftablesreload
            fi
            updatecauser
        fi
    ;;
    -dgreload )
        $E2GUARDIANrestart
    ;;
    -grubPon )
        confgrub2
    ;;
    -grubPoff )
        rm -rf /etc/grub.d/99_password
        update-grub2
    ;;
    -pfoff )
        privoxydefaultfilteroff
    ;;
    -pfon )
        privoxydefaultfilteron
    ;;

    -wipon )
       if [ ! "$FILTRAGEISOFF" -eq 1 ];then
            networkisoknext
            $SED "s?^WHITEIPONLY=.*?WHITEIPONLY=ON?"  "$FILE_CONF"
            adapt
            catChoice
            dnscryptproxyon
       fi
    ;;
    -wipoff )
       if [ ! "$FILTRAGEISOFF" -eq 1 ];then
            networkisoknext
            $SED "s?^WHITEIPONLY=.*?WHITEIPONLY=OFF?"  "$FILE_CONF"
            adapt
            catChoice
            dnscryptproxyon
       fi
    ;;
    -logon )
        {
			echo "log-queries"
            echo "log-facility=/var/log/dnsmasq/query.log"
        } > "$DIR_CONF"/querylog.conf
        $SED "s?^LOGDNS=.*?LOGDNS=ON?"  "$FILE_CONF"
        $SED "s?^LOGNFT=.*?LOGNFT=ON?"  "$FILE_CONF"
        $SED "s?^LOGLOGIN=.*?LOGLOGIN=ON?"  "$FILE_CONF"
        LOG4ACCEPT='log prefix "ip4tables-accept"'
        LOG4REJECT='log prefix "ip4tables-reject"'
        LOG6ACCEPT='log prefix "ip6tables-accept"'
        LOG6REJECT='log prefix "ip6tables-reject"'
        LOGDNS="ON"
        LOGNFT="ON"
        LOGLOGIN="ON"
        genfilerotatelogin
        dnscryptproxyon
        nftdisableconflict
        nftablesreload
        $RSYSLOGRESTART
    ;;
    -logoff )
        echo "" > "$DIR_CONF"/querylog.conf
        $SED "s?^LOGDNS=.*?LOGDNS=OFF?"  "$FILE_CONF"
        $SED "s?^LOGNFT=.*?LOGNFT=OFF?"  "$FILE_CONF"
        $SED "s?^LOGLOGIN=.*?LOGLOGIN=OFF?"  "$FILE_CONF"
        LOG4ACCEPT=''
        LOG4REJECT=''
        LOG6ACCEPT=''
        LOG6REJECT=''
        LOGDNS="OFF"
        LOGNFT="OFF"
        LOGLOGIN="OFF"
        LOGMONTHROTATE="1"
        genfilerotatelogin
        dnscryptproxyon
        nftdisableconflict
        nftablesreload
        rm -rf /var/log/nftables/*
        rm -rf /var/log/CTdnscrypt-proxy/*
        rm -f $RSYSLOGCTPARENTAL
        $RSYSLOGRESTART
    ;;
    -exp )
        if [ $# == 2 ]; then
            DIRexpconf=$2
            if [ ! -d "$DIRexpconf" ];then
                gettext 'Invalid directory path!'
                exit 0
            fi
        else
            echo "$(gettext "Missing argument, directory path")";
            echo "CTparental -exp \"/directory/path\"";
            exit 0
        fi
        exportconf
    ;;
    -imp )
        if [ $# == 2 ]; then
            FILEimpconf=$2
            if [ ! -e "$FILEimpconf" ];then
                gettext 'Error opening the file'
                exit 0
            fi
        else
            echo "$(gettext "Missing argument, fileconf path")";
            echo "CTparental -imp \"/directory/fileconf\"";
            exit 0
        fi
        importconf
    ;;
    -cainstall )
        updatecauser
    ;;
    -setadmin )
        if [ $# == 3 ]; then
            addadminhttpdapr1md5php $2 $3
        else
            echo "$(gettext "Missing argument, login or password")";
            echo "CTparental -setadmin \"login\" \"password\" ";
        fi
    ;;
    -srvon )
        serversyncon
    ;;
    -srvoff )
        serversyncoff
    ;;
    -expsync )
        expsync
    ;;
    -syncon )
        if [ $# == 4 ]; then
            clientsyncon $2 $3 $4
        else
        echo "$(gettext "Missing argument, Ipv6 server or password or port")"
        echo "CTparental -syncon \"fe80::ffff:eeee:dddd:aaaa\" \"srvpassword\" \"22\" ";
        fi
    ;;
    -syncoff )
        clientsyncoff
    ;;
    -csync )
        clientsync
    ;;
    -v )
    echo "$NUMVER"
    ;;
    *)
    echo "$(gettext "Unknown argument"):$1";
    echo "$usage";
    exit 1
    ;;
esac

rm -rf $PIDFILE

exit 0
