From b4a66e2ac733ae56f0ecc2069f1429ae769be1d3 Mon Sep 17 00:00:00 2001
From: Bob Mottram <bob@freedombone.net>
Date: Tue, 27 Nov 2018 14:15:54 +0000
Subject: [PATCH] Add muted words

---
 src/freedombone-installer                | 107 +++++++++++++++++++
 src/freedombone-utils-firewall           |  53 +++++++++
 src/freedombone-utils-webadmin           |   1 +
 webadmin/EN/blocking_words_template.html | 130 +++++++++++++++++++++++
 webadmin/blocking.php                    |  12 ++-
 5 files changed, 302 insertions(+), 1 deletion(-)
 create mode 100644 webadmin/EN/blocking_words_template.html

diff --git a/src/freedombone-installer b/src/freedombone-installer
index a086a2fb5..bb95685cc 100755
--- a/src/freedombone-installer
+++ b/src/freedombone-installer
@@ -69,6 +69,9 @@ APP_BEING_INSTALLED=
 # contains the blocked users and domains
 FIREWALL_DOMAINS=/root/${PROJECT_NAME}-firewall-domains.cfg
 
+# contains words or phrases to be blocked
+MUTED_WORDS=/root/${PROJECT_NAME}-firewall-words.cfg
+
 local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local
 
 webadmin_install_dir="/var/www/${local_hostname}/htdocs/admin"
@@ -100,6 +103,7 @@ remove_user_file="$webadmin_install_dir/.remove_user.txt"
 change_password_file="$webadmin_install_dir/changepassword.dat"
 install_state_file="/root/.install_state.txt"
 blocklist_file="$webadmin_install_dir/.blocklist.txt"
+muted_words_file="$webadmin_install_dir/.blocklistwords.txt"
 bridgeslist_file="$webadmin_install_dir/.bridgeslist.txt"
 INSTALL_DIR=/root/build
 webadmin_user='admin'
@@ -1270,6 +1274,7 @@ function after_setup_has_finished {
     increment_install_progress
 
     regenerate_blocklist
+    regenerate_blocklist_muted_words
 
     increment_install_progress
 
@@ -1936,6 +1941,21 @@ function regenerate_blocklist {
     fi
 }
 
+function regenerate_blocklist_muted_words {
+    if [ ! -f "$MUTED_WORDS" ]; then
+        touch "$MUTED_WORDS"
+    fi
+    local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local
+    webadmin_install_dir="/var/www/${local_hostname}/htdocs/admin"
+    if [ -f "$webadmin_install_dir/blocking_words_template.html" ]; then
+        cp "$webadmin_install_dir/blocking_words_template.html" "$webadmin_install_dir/blocking_words.html"
+        blockedlistwords=$(sed 's@[/\&]@\\&@g;s/$/\\/' "$MUTED_WORDS"; echo .)
+        blockedlistwords=${blockedlistwords%.}
+        sed -i "s|BLOCKEDWORDSLIST|$blockedlistwords|g" "$webadmin_install_dir/blocking_words.html"
+        chown www-data:www-data "$webadmin_install_dir/blocking_words.html"
+    fi
+}
+
 function regenerate_bridges {
     if [ ! -f "/root/.webadmin_torbridges" ]; then
         touch "/root/.webadmin_torbridges"
@@ -2472,6 +2492,47 @@ function update_email_blocklists {
     done
 }
 
+function update_email_muted_words {
+    MUTED_WORDS_OLD="$1"
+    MUTED_WORDS_NEW="${1}.new"
+
+    if [ -f "$MUTED_WORDS_OLD" ]; then
+        # remove email blocks
+        for d in /home/*/ ; do
+            USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
+            if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
+                while read -r block_line; do
+                    if [ "$block_line" ]; then
+                        # does not exist in the new version
+                        if ! grep -q "$block_line" "$MUTED_WORDS_NEW"; then
+                            "${PROJECT_NAME}-ignore" -u "$USERNAME" -t "$block_line"
+                        fi
+                    fi
+                done < "$MUTED_WORDS_OLD"
+            fi
+        done
+    fi
+
+    # add email blocks
+    for d in /home/*/ ; do
+        USERNAME=$(echo "$d" | awk -F '/' '{print $3}')
+        if [[ $(is_valid_user "$USERNAME") == "1" ]]; then
+            while read -r block_line; do
+                if [ "$block_line" ]; then
+                    if [ -f "$MUTED_WORDS_OLD" ]; then
+                        # does not exist in the old version
+                        if ! grep -q "$block_line" "$MUTED_WORDS_OLD"; then
+                            "${PROJECT_NAME}-ignore" -u "$USERNAME" -t "$block_line"
+                        fi
+                    else
+                        "${PROJECT_NAME}-ignore" -u "$USERNAME" -t "$block_line"
+                    fi
+                fi
+            done < "$MUTED_WORDS_NEW"
+        fi
+    done
+}
+
 function update_blocklist {
     if [ -f "$blocklist_file" ]; then
 
@@ -2572,6 +2633,51 @@ function update_blocklist {
     fi
 }
 
+function update_muted_words {
+    if [ -f "$muted_words_file" ]; then
+
+        if [ -f "${MUTED_WORDS}.new" ]; then
+            rm "${MUTED_WORDS}.new"
+        fi
+        touch "${MUTED_WORDS}.new"
+
+        # add an extra line, otherwise the last line may not parse
+        echo "" >> "$muted_words_file"
+
+        blocked_lines_ctr=0
+        while read -r line; do
+            if [ $blocked_lines_ctr -gt 1024 ]; then
+                # This prevents someone copy-pasting a giant amount of text
+                # into the blocklist. If you're legitimately blocking more
+                # than this number then you probably have other problems to
+                # think about and should consider whitelisting instead
+                break
+            fi
+            blocked_lines_ctr=$((blocked_lines_ctr + 1))
+
+            if [ "$line" ]; then
+                # remove leading and trailing spaces
+                newline="$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
+                line="$newline"
+
+                if [ ${#line} -gt 1 ]; then
+                    blocked_words_str=$(echo "$line" | awk '{print tolower($0)}')
+                    if ! grep -q "$blocked_words_str" "${MUTED_WORDS}.new"; then
+                        echo "$blocked_words_str" >> "${MUTED_WORDS}.new"
+                    fi
+                fi
+            fi
+        done < "$muted_words_file"
+
+        update_email_muted_words "${MUTED_WORDS}"
+
+        mv "${MUTED_WORDS}" "${MUTED_WORDS}.backup"
+        mv "${MUTED_WORDS}.new" "${MUTED_WORDS}"
+        rm "$muted_words_file"
+        regenerate_blocklist_muted_words
+    fi
+}
+
 function import_translations {
     if [ -f "$translations_import_file" ]; then
         translations_language=
@@ -3109,6 +3215,7 @@ do
                     webadmin_factory_reset
                     webadmin_change_password
                     update_blocklist
+                    update_muted_words
                     update_dynamic_dns
                     webadmin_monitor_ip_changes
                     update_system_monitor
diff --git a/src/freedombone-utils-firewall b/src/freedombone-utils-firewall
index 83f9c8567..fe281b7ec 100755
--- a/src/freedombone-utils-firewall
+++ b/src/freedombone-utils-firewall
@@ -30,6 +30,7 @@
 
 FIREWALL_CONFIG=$HOME/${PROJECT_NAME}-firewall.cfg
 FIREWALL_DOMAINS=$HOME/${PROJECT_NAME}-firewall-domains.cfg
+FIREWALL_DOMAINS=$HOME/${PROJECT_NAME}-firewall-words.cfg
 FIREWALL_EIFACE=eth0
 EXTERNAL_IPV4_ADDRESS=
 FIREFOX_TELEMETRY_IP='52.88.27.118'
@@ -620,6 +621,28 @@ function firewall_block_domain {
     regenerate_webadmin_blocklist
 }
 
+function firewall_block_words {
+    blocked_words="$1"
+    if [ ! -f "$MUTED_WORDS" ]; then
+        touch "$MUTED_WORDS"
+    fi
+    if ! grep -q "$blocked_words" "$MUTED_WORDS"; then
+        echo "${blocked_words}" >> "$MUTED_WORDS"
+
+        # run the blocking rules now
+        if [ -f /usr/bin/gnusocial-firewall ]; then
+            /usr/bin/gnusocial-firewall
+        fi
+        if [ -f /usr/bin/postactiv-firewall ]; then
+            /usr/bin/postactiv-firewall
+        fi
+        if [ -f /usr/bin/pleroma-blocking ]; then
+            /usr/bin/pleroma-blocking
+        fi
+    fi
+    regenerate_webadmin_blocklist_muted_words
+}
+
 function firewall_block_ip {
     blocked_ip="$1"
     if [[ "$blocked_ip" == *'@'* ]]; then
@@ -684,6 +707,20 @@ function firewall_unblock_domain {
     regenerate_webadmin_blocklist
 }
 
+function firewall_unblock_words {
+    unblocked_words="$1"
+
+    if [ ! -f "$MUTED_WORDS" ]; then
+        touch "$MUTED_WORDS"
+    fi
+
+    if grep -q "${unblocked_words}" "$MUTED_WORDS"; then
+        sed -i "/${unblocked_domain}/d" "$MUTED_WORDS"
+    fi
+
+    regenerate_webadmin_blocklist_muted_words
+}
+
 function firewall_drop_spoofed_packets {
     if [[ $(is_completed "${FUNCNAME[0]}") == "1" ]]; then
         return
@@ -740,4 +777,20 @@ function regenerate_webadmin_blocklist {
     fi
 }
 
+function regenerate_webadmin_blocklist_muted_words {
+    if [ ! -f "$MUTED_WORDS" ]; then
+        touch "$MUTED_WORDS"
+    fi
+    local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local
+    webadmin_install_dir="/var/www/${local_hostname}/htdocs/admin"
+    if [ -f "$webadmin_install_dir/blocking_words_template.html" ]; then
+        cp "$webadmin_install_dir/blocking_words_template.html" "$webadmin_install_dir/blocking_words.html"
+        blockedlistwords=$(sed 's@[/\&]@\\&@g;s/$/\\/' "$MUTED_WORDS"; echo .)
+        blockedlistwords=${blockedlistwords%.}
+        sed -i "s|BLOCKEDWORDSLIST|$blockedlistwords|g" "$webadmin_install_dir/blocking_words.html"
+        chown www-data:www-data "$webadmin_install_dir/blocking_words.html"
+    fi
+}
+
+
 # NOTE: deliberately no exit 0
diff --git a/src/freedombone-utils-webadmin b/src/freedombone-utils-webadmin
index d67ee870f..a33cc2ff7 100755
--- a/src/freedombone-utils-webadmin
+++ b/src/freedombone-utils-webadmin
@@ -2123,6 +2123,7 @@ function install_web_admin {
     web_admin_configure_installer_daemon
 
     regenerate_webadmin_blocklist
+    regenerate_webadmin_blocklist_muted_words
 
     regenerate_webadmin_dynamic_dns
 
diff --git a/webadmin/EN/blocking_words_template.html b/webadmin/EN/blocking_words_template.html
new file mode 100644
index 000000000..682e20c18
--- /dev/null
+++ b/webadmin/EN/blocking_words_template.html
@@ -0,0 +1,130 @@
+<!DOCTYPE html>
+<html lang="en">
+  <head>
+    <meta charset="utf-8">
+    <style>
+      body {
+          margin: 0;
+          font-family: Arial;
+          background-color: white;
+          color: black;
+      }
+
+      #headerpic {
+          width: 60%;
+          height: auto;
+          margin-right : auto;
+          margin-left : auto;
+          min-width : 220px;
+      }
+
+      .header {
+          text-align: center;
+          padding: 32px;
+      }
+
+      .card {
+          box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2);
+          max-width: 600px;
+          margin: auto;
+          text-align: center;
+          font-family: arial;
+          clear: both;
+      }
+
+      .card input[type=text] {
+          width: 90%;
+          clear: both;
+          text-align: center;
+          color: black;
+          background-color: lightblue;
+      }
+
+      .appurl {
+          color: grey;
+          font-size: 100%;
+      }
+
+      .welcomeheader {
+          font-size: 200%;
+          font-weight: bold;
+      }
+
+      .descriptiontext {
+          font-size: 90%;
+      }
+
+      .logintext {
+          font-size: 120%;
+          font-weight: bold;
+          color: #981737;
+      }
+
+      button {
+          border: none;
+          outline: 0;
+          display: inline-block;
+          padding: 8px;
+          color: white;
+          background-color: #000;
+          text-align: center;
+          cursor: pointer;
+          width: 100%;
+          font-size: 18px;
+      }
+
+      a {
+          text-decoration: none;
+          color: black;
+      }
+
+      button:hover, a:hover {
+          opacity: 0.7;
+      }
+
+      .chip {
+          display: inline-block;
+          padding: 0 25px;
+          height: 50px;
+          font-size: 70%;
+          line-height: 50px;
+          border-radius: 25px;
+          background-color: #f1f1f1;
+      }
+
+      .chip img {
+          float: left;
+          margin: 0 10px 0 -25px;
+          height: 50px;
+          width: 50px;
+          border-radius: 50%;
+      }
+
+      textarea {
+          width: 90%;
+          color: black;
+          font-weight: bold;
+          background: lightblue;
+          font-size: 120%;
+      }
+    </style>
+  </head>
+  <body>
+    <div class="card">
+      <div class="header">
+        <a href="settings.html" title="Go Back"><img id="headerpic" class="img-responsive" src="images/logo.png" alt="Go Back"></a><br>
+
+        <p class="descriptiontext" translate="yes">Emails, messages or social network posts will be blocked if they contain the following words or phrases</p>
+
+        <form action="blocking.php" method="post">
+          <textarea rows="10" cols="50" name="blockinglistwords" translate="no">BLOCKEDWORDSLIST</textarea>
+          <br><br>
+          <input type="submit" name="submitblockingwordscancel" translate="yes" value="Cancel">
+          <input type="submit" name="submitblockingwordscontinue" translate="yes" value="Continue">
+        </form>
+
+        <br>
+      </div>
+    </div>
+  </body>
+</html>
diff --git a/webadmin/blocking.php b/webadmin/blocking.php
index ef0438e63..9f853a19a 100755
--- a/webadmin/blocking.php
+++ b/webadmin/blocking.php
@@ -4,14 +4,24 @@
 
 $output_filename = "settings.html";
 
+// blocked addresses or domains
 if (isset($_POST['submitblocking'])) {
     $blockinglist = htmlspecialchars($_POST['blockinglist']);
 
-    $blocking_file = fopen(".blocklist.txt", "w") or die("Unable to create setup file");
+    $blocking_file = fopen(".blocklist.txt", "w") or die("Unable to create blocklist file");
     fwrite($blocking_file, $blockinglist);
     fclose($blocking_file);
 }
 
+// muted words
+if (isset($_POST['submitblockingwordscontinue'])) {
+    $blockinglistwords = htmlspecialchars($_POST['blockinglistwords']);
+
+    $blocking_words_file = fopen(".blocklistwords.txt", "w") or die("Unable to create blocklistwords file");
+    fwrite($blocking_words_file, $blockinglistwords);
+    fclose($blocking_words_file);
+}
+
 if (isset($_POST['submitblockingwords'])) {
     $output_filename = "blocking_words.html";
 }
-- 
GitLab