Pārlūkot izejas kodu

Add files via upload

netico 4 gadi atpakaļ
vecāks
revīzija
9e71bcbfd6
6 mainītis faili ar 827 papildinājumiem un 0 dzēšanām
  1. 36 0
      README
  2. 18 0
      src/Makefile
  3. BIN
      src/anonymizer
  4. 46 0
      src/anonymizer.geany
  5. 273 0
      src/anonymizer.glade
  6. 454 0
      src/anonymizer.vala

+ 36 - 0
README

@@ -0,0 +1,36 @@
+
+# Anonymizer                                                                   #
+# Tor made easy (transparently routing traffic through Tor)                    #
+# ---------------------------------------------------------------------------- #
+
+# BUILD FROM SOURCE                                                            #
+# ---------------------------------------------------------------------------- #
+
+cd src
+make
+make install
+
+# DOCUMENTATION                                                                #
+# ---------------------------------------------------------------------------- #
+
+# ABOUT VALA
+https://wiki.gnome.org/Projects/Vala/
+https://en.wikipedia.org/wiki/Vala_(programming_language)
+
+# TUTORIALS, GUIDES AND REFERENCES
+https://valadoc.org/
+https://wiki.gnome.org/Projects/Vala/Tutorial
+https://developer.gnome.org/gnome-devel-demos/stable/beginner.vala.html.en
+
+# VALA AND GTK+
+https://wiki.gnome.org/Projects/Vala/GTKSample
+https://developer.gnome.org/gnome-devel-demos/stable/toolbar_builder.vala.html.en
+
+# VALA AND UNIX SHELL
+http://www.teejeetech.in/2013/05/vala-7-process-execution.html
+
+# NETFILTER/IPTABLES
+https://www.netfilter.org/
+
+# TOR
+https://www.torproject.org/

+ 18 - 0
src/Makefile

@@ -0,0 +1,18 @@
+#!/bin/bash
+
+
+all:
+	valac --pkg gtk+-3.0 --pkg gmodule-2.0 "anonymizer.vala" -o anonymizer
+
+clean:
+	rm -rf *.o anonymizer
+
+install:
+	mkdir -p /usr/share/anonymizer/
+	cp -f anonymizer.glade /usr/share/anonymizer
+	chmod -R 644 /usr/share/anonymizer/anonymizer.glade
+	cp -f anonymizer /usr/bin
+
+uninstall:
+	rm -f /usr/bin/anonymizer
+	rm -f /usr/share/anonymizer

BIN
src/anonymizer


+ 46 - 0
src/anonymizer.geany

@@ -0,0 +1,46 @@
+[editor]
+line_wrapping=true
+line_break_column=80
+auto_continue_multiline=true
+
+[file_prefs]
+final_new_line=true
+ensure_convert_new_lines=true
+strip_trailing_spaces=true
+replace_tabs=false
+
+[indentation]
+indent_width=4
+indent_type=1
+indent_hard_tab_width=8
+detect_indent=false
+detect_indent_width=false
+indent_mode=2
+
+[project]
+name=Anonymizer
+base_path=/home/netico/Documents/Code/anonymizer-gui
+description=Tor made easy (transparently routing traffic through Tor)                    #
+file_patterns=
+
+[long line marker]
+long_line_behaviour=2
+long_line_column=80
+
+[files]
+current_page=1
+FILE_NAME_0=19;None;0;EUTF-8;1;1;1;%2Fhome%2Fnetico%2FDocuments%2FCode%2Fanonymizer-gui%2FREADME;0;4
+FILE_NAME_1=1408;Vala;0;EUTF-8;1;1;1;%2Fhome%2Fnetico%2FDocuments%2FCode%2Fanonymizer-gui%2Fsrc%2Fanonymizer.vala;0;4
+FILE_NAME_2=263;Sh;0;EUTF-8;1;1;1;%2Fhome%2Fnetico%2FDocuments%2FCode%2Fanonymizer-gui%2Fsrc%2FMakefile;0;4
+
+[VTE]
+last_dir=/home/netico/Documents/Code/anonymizer-gui/src
+
+[build-menu]
+filetypes=Vala;Sh;
+ShFT_02_LB=_Lint
+ShFT_02_CM=shellcheck --format=gcc "%f"
+ShFT_02_WD=
+ValaFT_00_LB=_Compile
+ValaFT_00_CM=valac -c "%f"
+ValaFT_00_WD=

+ 273 - 0
src/anonymizer.glade

@@ -0,0 +1,273 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.20.0 
+
+Copyright (C) 2018 lab61
+
+This file is part of Anonymizer.
+
+Anonymizer is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+Anonymizer is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Anonymizer.  If not, see <http://www.gnu.org/licenses/>.
+
+Author: lab61
+
+-->
+<interface>
+  <requires lib="gtk+" version="3.0"/>
+  <!-- interface-license-type gplv3 -->
+  <!-- interface-name Anonymizer -->
+  <!-- interface-description Transparently routing traffic through Tor -->
+  <!-- interface-copyright 2018 lab61 -->
+  <!-- interface-authors lab61 -->
+  <object class="GtkWindow" id="window">
+    <property name="can_focus">False</property>
+    <property name="title" translatable="yes">Anonymizer</property>
+    <property name="window_position">center</property>
+    <property name="default_width">800</property>
+    <property name="default_height">600</property>
+    <property name="icon_name">dialog-password</property>
+    <property name="has_resize_grip">True</property>
+    <signal name="destroy" handler="gtk_main_quit" swapped="no"/>
+    <child>
+      <object class="GtkBox">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkMenuBar">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkMenuItem">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Anonymizer</property>
+                <property name="use_underline">True</property>
+                <child type="submenu">
+                  <object class="GtkMenu">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <child>
+                      <object class="GtkMenuItem">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Quit</property>
+                        <signal name="activate" handler="on_quit_clicked" swapped="no"/>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkMenuItem">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Tor</property>
+                <property name="use_underline">True</property>
+                <child type="submenu">
+                  <object class="GtkMenu">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <child>
+                      <object class="GtkMenuItem">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Start</property>
+                        <property name="use_underline">True</property>
+                        <signal name="activate" handler="on_start_tor_clicked" object="console" swapped="no"/>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkMenuItem">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Stop</property>
+                        <signal name="activate" handler="on_stop_tor_clicked" object="console" swapped="no"/>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+            <child>
+              <object class="GtkMenuItem">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">Proxy</property>
+                <child type="submenu">
+                  <object class="GtkMenu">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <child>
+                      <object class="GtkMenuItem">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Enable proxy</property>
+                      </object>
+                    </child>
+                    <child>
+                      <object class="GtkMenuItem">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label" translatable="yes">Reset netfilter</property>
+                      </object>
+                    </child>
+                  </object>
+                </child>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkToolbar">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <child>
+              <object class="GtkToolButton" id="start_tor">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="is_important">True</property>
+                <property name="label" translatable="yes">Start</property>
+                <property name="stock_id">gtk-media-play</property>
+                <signal name="clicked" handler="on_start_tor_clicked" object="console" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkToolButton" id="stop_tor">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="is_important">True</property>
+                <property name="label" translatable="yes">Stop</property>
+                <property name="stock_id">gtk-media-stop</property>
+                <signal name="clicked" handler="on_stop_tor_clicked" object="console" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkToolButton" id="enable proxy">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="is_important">True</property>
+                <property name="label" translatable="yes">Enable proxy</property>
+                <property name="stock_id">gtk-connect</property>
+                <signal name="clicked" handler="on_enable_proxy_clicked" object="console" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkToolButton" id="reset_netfilter">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="is_important">True</property>
+                <property name="label" translatable="yes">Reset netfilter</property>
+                <property name="stock_id">gtk-disconnect</property>
+                <signal name="clicked" handler="on_reset_netfilter_clicked" object="console" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkToolButton" id="quit">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="is_important">True</property>
+                <property name="label" translatable="yes">Quit</property>
+                <property name="stock_id">gtk-quit</property>
+                <signal name="clicked" handler="on_quit_clicked" swapped="no"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="homogeneous">True</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkScrolledWindow">
+            <property name="visible">True</property>
+            <property name="can_focus">True</property>
+            <property name="hscrollbar_policy">never</property>
+            <property name="window_placement">bottom-left</property>
+            <child>
+              <object class="GtkTextView" id="console">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="has_focus">True</property>
+                <property name="is_focus">True</property>
+                <property name="hexpand">True</property>
+                <property name="vexpand">True</property>
+                <property name="resize_mode">immediate</property>
+                <property name="pixels_above_lines">4</property>
+                <property name="pixels_below_lines">4</property>
+                <property name="editable">False</property>
+                <property name="wrap_mode">word</property>
+                <property name="left_margin">10</property>
+                <property name="right_margin">10</property>
+                <property name="cursor_visible">False</property>
+                <property name="accepts_tab">False</property>
+                <property name="monospace">True</property>
+              </object>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="position">2</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkStatusbar" id="statusbar">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_left">10</property>
+            <property name="margin_right">10</property>
+            <property name="margin_start">10</property>
+            <property name="margin_end">10</property>
+            <property name="margin_top">6</property>
+            <property name="margin_bottom">6</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">8</property>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">4</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
+</interface>

+ 454 - 0
src/anonymizer.vala

@@ -0,0 +1,454 @@
+/* main.vala
+ *
+ * Copyright (C) 2018 netico@riseup.net
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+using Gtk;
+
+// Setup                                                                      //
+// -------------------------------------------------------------------------- //
+const string NIC = "wlan0";
+const int TOR_UID = 121;
+const string TOR_USER = "debian-tor";
+
+const int TOR_PORT = 56662;
+const int TOR_DNS_PORT = 56663;
+const string VIRTUAL_ADDRESS = "10.192.0.0/10";
+const string IPTABLES_BIN = "/sbin/iptables";
+
+// Buttons                                                                    //
+// -------------------------------------------------------------------------- //
+
+// Quit
+public void on_quit_clicked (Button source)
+{
+	Gtk.main_quit ();
+    Process.exit (0);
+
+    // TODO - Drop /tmp/start_tor.sh
+}
+// Start Tor
+public void on_start_tor_clicked (Button source, TextView console_view)
+{
+	try {
+
+		int tor_pid_int = -1;
+		string tor_pid = shell_sync ("pidof tor");
+		tor_pid.scanf ("%d", &tor_pid_int);
+
+		if (tor_pid_int > 0)
+		{
+			console_view.buffer.text = "Tor is already running";
+			return;
+		}
+
+		var file = File.new_for_path ("/tmp/anonymizer.log");
+		if (file.query_exists ())
+		{
+			file.delete ();
+		}
+		var file_stream = file.create (FileCreateFlags.NONE);
+		var data_stream = new DataOutputStream (file_stream);
+        data_stream.put_string
+        (
+			"Tor made easy "
+			+ "(transparently routing traffic through Tor)"
+			+ "\n"
+		);
+
+		string torrc = "SOCKSPort 127.0.0.1:56661\n"
+		+ "TransPort 127.0.0.1:56662 IsolateClientAddr IsolateClientProtocol "
+		+ "IsolateDestAddr IsolateDestPort\n"
+		+ "DNSPort 127.0.0.1:56663\n"
+		+ "VirtualAddrNetworkIPv4 10.192.0.0/10\n"
+		+ "AutomapHostsOnResolve 1\n"
+		+ "Log notice file /tmp/anonymizer.log\n";
+
+		string config = "/tmp/anonymizer.cnf";
+        file = File.new_for_path (config);
+        if (file.query_exists ())
+        {
+            file.delete ();
+        }
+        var dos = new DataOutputStream
+        (
+			file.create (FileCreateFlags.REPLACE_DESTINATION)
+		);
+        string text = torrc;
+        uint8[] data = text.data;
+        long written = 0;
+        while (written < data.length)
+        {
+            written += dos.write (data[written:data.length]);
+        }
+		string permissions;
+		permissions = shell_sync ("chmod -R 666 /tmp/anonymizer.log"); // FIXME
+		shell_run_as_async
+		(
+			"/usr/bin/tor --quiet -f /tmp/anonymizer.cnf",
+			TOR_USER,
+			"/tmp",
+			"start-tor.sh"
+		);
+		log_file_monitor (console_view, "/tmp/anonymizer.log");
+	}
+	catch (Error e)
+	{
+		console_view.buffer.text = e.message;
+	}
+}
+// Stop Tor
+public void on_stop_tor_clicked (Button source, TextView console_view)
+{
+
+	int tor_pid_int = -1;
+	string tor_pid = shell_sync ("pidof tor");
+	tor_pid.scanf ("%d", &tor_pid_int);
+
+	if (tor_pid_int > 0)
+	{
+		string shell_command = "kill " + tor_pid_int.to_string ();
+		string pkexec;
+		pkexec = shell_run_as
+		(
+			shell_command,
+			"root",
+			"/tmp",
+			"stop_tor.sh"
+		);
+		console_view.buffer.text = "Tor has stopped working";
+	}
+	else
+	{
+		console_view.buffer.text = "Tor is not running";
+	}
+}
+
+// Enable proxy
+public void on_enable_proxy_clicked (Button source, TextView console_view)
+{
+	//on_reset_netfilter_clicked (source, console_view);
+	//on_restart_tor_clicked (source, console_view);
+
+	//string resolv_conf =
+	var file = File.new_for_path ("/etc/resolv.conf");
+
+    try {
+        var dis = new DataInputStream (file.read ());
+        string line;
+        var resolv_conf = new StringBuilder ();
+        while ((line = dis.read_line (null)) != null)
+        {
+			if ("nameserver" in line)
+			{
+				if (line.contains ("127.0.0.1") == false)
+				{
+					resolv_conf.append (line + "\n");
+				}
+			}
+        }
+		string resolv_conf_new = resolv_conf.str + "nameserver 127.0.0.1\n";
+
+		string shell_command = "echo \"" + resolv_conf_new
+		+ "\"> /etc/resolv.conf;\n"
+		+ IPTABLES_BIN
+		+ " -v -t nat -A OUTPUT -d " + VIRTUAL_ADDRESS.to_string()
+		+ " -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j REDIRECT "
+		+ "--to-ports " + TOR_PORT.to_string() + ";\n"
+		+ IPTABLES_BIN + " -v -t nat -A OUTPUT -d 127.0.0.1/32 -p udp -m udp "
+		+ "--dport 53 -j REDIRECT --to-ports " + TOR_DNS_PORT.to_string() + ";\n"
+		+ IPTABLES_BIN + " -v -t nat -A OUTPUT -m owner --uid-owner "
+		+ TOR_UID.to_string() + " -j RETURN;\n"
+		+ IPTABLES_BIN + " -v -t nat -A OUTPUT -o lo -j RETURN;\n"
+		+ IPTABLES_BIN + " -v -t nat -A OUTPUT -p tcp -m tcp "
+		+ " --tcp-flags FIN,SYN,RST,ACK SYN "
+		+ " -j REDIRECT --to-ports " + TOR_PORT.to_string() + ";\n"
+		+ IPTABLES_BIN + " -v -A INPUT -m state --state ESTABLISHED -j ACCEPT;\n"
+		+ IPTABLES_BIN + " -v -A INPUT -i lo -j ACCEPT;\n"
+		+ IPTABLES_BIN + " -v -A INPUT -j DROP;\n"
+		+ IPTABLES_BIN + " -v -A FORWARD -j DROP;\n"
+		+ IPTABLES_BIN + " -v -A OUTPUT -m state --state INVALID -j DROP;\n"
+		+ IPTABLES_BIN + " -v -A OUTPUT -m state --state ESTABLISHED -j ACCEPT;\n"
+		+ IPTABLES_BIN + " -v -A OUTPUT -o " + NIC + " -m owner "
+		+ " --uid-owner " + TOR_UID.to_string()
+		+ " -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m state "
+		+ " --state NEW -j ACCEPT;\n"
+		+ IPTABLES_BIN + " -v -A OUTPUT -d 127.0.0.1/32 -o lo -j ACCEPT;\n"
+		+ IPTABLES_BIN + " -v -A OUTPUT -d 127.0.0.1/32 -p tcp -m tcp "
+		+ " --dport " + TOR_PORT.to_string()
+		+ " --tcp-flags FIN,SYN,RST,ACK SYN -j ACCEPT;\n"
+		+ IPTABLES_BIN + " -v -A OUTPUT -j DROP;\n"
+		+ IPTABLES_BIN + " -v -P INPUT DROP;\n"
+		+ IPTABLES_BIN + " -v -P FORWARD DROP;\n"
+		+ IPTABLES_BIN + " -v -P OUTPUT DROP;\n";
+
+		string pkexec;
+		pkexec = shell_run_as
+		(
+			shell_command,
+			"root",
+			"/tmp",
+			"enable_proxy.sh"
+		);
+		console_view.buffer.text = "Rules:\n" + pkexec;
+
+    } catch (Error e) {
+        console_view.buffer.text = e.message;
+    }
+
+
+}
+// Reset netfilter
+public void on_reset_netfilter_clicked (Button source, TextView console_view)
+{
+	string shell_command = IPTABLES_BIN
+	+ " -v -P INPUT ACCEPT;\n"
+	+ IPTABLES_BIN + " -P FORWARD ACCEPT;\n"
+	+ IPTABLES_BIN + " -P OUTPUT ACCEPT;\n"
+	+ IPTABLES_BIN + " -t nat -P PREROUTING ACCEPT;\n"
+	+ IPTABLES_BIN + " -t nat -P POSTROUTING ACCEPT;\n"
+	+ IPTABLES_BIN + " -t nat -P OUTPUT ACCEPT;\n"
+	+ IPTABLES_BIN + " -t mangle -P PREROUTING ACCEPT;\n"
+	+ IPTABLES_BIN + " -t mangle -P OUTPUT ACCEPT;\n"
+	+ IPTABLES_BIN + " -F;\n"
+	+ IPTABLES_BIN + " -X;\n"
+	+ IPTABLES_BIN + " -t nat -F;\n"
+	+ IPTABLES_BIN + " -t nat -X;\n"
+	+ IPTABLES_BIN + " -t mangle -F;\n"
+	+ IPTABLES_BIN + " -t mangle -X;\n";
+
+	string pkexec;
+	pkexec = shell_run_as
+	(
+		shell_command,
+		"root",
+		"/tmp",
+		"reset_netfilter.sh"
+	);
+	console_view.buffer.text = "All rules are deleted";
+}
+
+// Shell                                                                      //
+// -------------------------------------------------------------------------- //
+
+// Sync method
+private string shell_sync (string cmd)
+{
+    try {
+        int exit_code;
+        string std_out;
+        Process.spawn_command_line_sync (cmd, out std_out, null, out exit_code);
+        return std_out;
+    }
+    catch (Error e)
+    {
+        return (e.message);
+    }
+}
+// Async method
+private bool shell_async (string[] args)
+{
+    try {
+        Process.spawn_async
+        (
+			null, args, null, SpawnFlags.SEARCH_PATH, null, null
+		);
+        return true;
+    }
+    catch (Error e)
+    {
+        stderr.printf (e.message);
+        return false;
+    }
+}
+// pkexec sync
+private string shell_run_as (string cmd, string user, string dir, string script)
+{
+	try
+	{
+		string program = dir + "/" + script;
+        var file = File.new_for_path (program);
+        if (file.query_exists ())
+        {
+            file.delete ();
+        }
+        var dos = new DataOutputStream
+        (
+			file.create (FileCreateFlags.REPLACE_DESTINATION)
+		);
+        string text = cmd;
+        uint8[] data = text.data;
+        long written = 0;
+        while (written < data.length)
+        {
+            written += dos.write (data[written:data.length]);
+        }
+        string pkexec;
+		pkexec = shell_sync ("pkexec --user " + user + " /bin/sh " + program);
+		if (file.query_exists ())
+        {
+            file.delete ();
+        }
+        return pkexec;
+    }
+    catch (Error e)
+    {
+        return (e.message);
+    }
+}
+
+// pkexec sync
+private void shell_run_as_async (string cmd, string user, string dir, string script)
+{
+	try
+	{
+		string program = dir + "/" + script;
+        var file = File.new_for_path (program);
+        if (file.query_exists ())
+        {
+            file.delete ();
+        }
+        var dos = new DataOutputStream
+        (
+			file.create (FileCreateFlags.REPLACE_DESTINATION)
+		);
+        string text = cmd;
+        uint8[] data = text.data;
+        long written = 0;
+        while (written < data.length)
+        {
+            written += dos.write (data[written:data.length]);
+        }
+        shell_async
+		({
+			"pkexec",
+			"--user",
+			user,
+			"/bin/sh",
+			program
+		});
+    }
+    catch (Error e)
+    {
+        stderr.printf (e.message);
+    }
+}
+
+// Log                                                                        //
+// -------------------------------------------------------------------------- //
+
+private void log_file_monitor (TextView console_view, string log_file)
+{
+	// Reference to log file
+    var log = File.new_for_path (log_file);
+	try
+	{
+		FileMonitor monitor = log.monitor (FileMonitorFlags.NONE, null);
+		MainLoop loop = new MainLoop ();
+		monitor.changed.connect ((src, dest, event) =>
+		{
+			string event_string = event.to_string ();
+			if (event_string == "G_FILE_MONITOR_EVENT_DELETED")
+			{
+				loop.quit ();
+			}
+			if (event_string == "G_FILE_MONITOR_EVENT_CHANGED")
+			{
+				try
+				{
+					var dis = new DataInputStream (log.read ());
+					string line;
+					var log_console = new StringBuilder ();
+
+					// Read lines until end of file (null) is reached
+					while ((line = dis.read_line (null)) != null)
+					{
+						log_console.append (line + "\n");
+					}
+					console_view.buffer.text = log_console.str;
+				}
+				catch (Error e)
+				{
+					console_view.buffer.text = (e.message);
+				}
+			}
+		});
+		loop.run ();
+    }
+    catch (Error e)
+    {
+        console_view.buffer.text = e.message;
+    }
+}
+
+// Main                                                                       //
+// -------------------------------------------------------------------------- //
+
+int main (string[] args)
+{
+	Gtk.init (ref args);
+
+	try
+	{
+		var b = new Builder ();
+		b.add_from_file ("/usr/share/anonymizer/anonymizer.glade");
+		b.connect_signals (null);
+
+		var window = b.get_object ("window") as Window;
+		window.show_all ();
+
+		// Console
+		var console_view = b.get_object ("console") as TextView;
+		console_view.buffer.text = "This program helps you setup network " +
+		"interface to use Tor as transparent proxy." +
+		"\nThis software is very experimental and you should only use this if "
+		+ "you know what you are doing. \n\nEnjoy! \n\nAnd RTFM.";
+
+		// Statusbar
+		var regex = new Regex ("[a-zA-Z]| ");
+		// Linux version
+		string linux_v_a = shell_sync("uname -r");
+		string linux_v_b = "Linux " + linux_v_a;
+		// iptables version
+		string iptables_v_a = shell_sync(IPTABLES_BIN + " -V");
+        string iptables_v_b = regex.replace (iptables_v_a, -1, 0, "");
+        string iptables_v_c = "iptables " + iptables_v_b;
+		// Tor version
+		string tor_v_a = shell_sync("/usr/bin/tor --version");
+		string tor_v_b = tor_v_a.substring (0, 21);
+		string tor_v_c = regex.replace (tor_v_b, -1, 0, "");
+		string tor_v_d = "Tor " + tor_v_c;
+		// pkexec version
+		string pkexec_v_a = shell_sync("pkexec --version");
+		string pkexec_v_b = regex.replace (pkexec_v_a, -1, 0, "");
+		string pkexec_v_c = " pkexec " + pkexec_v_b;
+		string sysinfo = linux_v_b + iptables_v_c + tor_v_d + pkexec_v_c;
+		var alphanum = new Regex ("[^a-zA-Z0-9-.| ]");
+		string sbar_text = alphanum.replace (sysinfo, -1, 0, " ");
+		var statusbar = b.get_object ("statusbar") as Statusbar;
+		var context_id = statusbar.get_context_id ("statusbar");
+		statusbar.push (context_id, sbar_text);
+
+		Gtk.main ();
+
+	}
+	catch (Error e)
+	{
+		stderr.printf (e.message);
+		return 1;
+	}
+	return 0;
+}