Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: obscure service process #16

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions IDEAS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ IDEAS
* (core) Increase the obligatory break time at late hours (like do nothing for 2 minutes webpage)
* (core) An option to start a task inside the overlay plugin. So the task can be completed with it opened.
* (core) A **meta** task that exists along the usual task, it would allow to define time for a big task your working towards, and parallely use the little tasks for small well defined activities that work towards that goal.
* (core) Limit the internet bandwidth, allow a certain amount of data to be transfered at full speed per hour, when that limit is reach set the bandwidth very low (e.g 50kb/s).


* (overlay) (terminals) Button to reset terminal
Expand Down Expand Up @@ -42,6 +43,7 @@ IDEAS
* (overlay) Dedicate a entire section of the screen to permanently show a section of the overlay. This could be done with X11 virtual screens. And would persist even when running fullscreen apps.
* (overlay) When indicating which action to execute before starting the session, ask, what, how, and why. So that one must fill these fields before continuing.
* (overlay) Allow to set a virtual screen resolution, i.e. Using big black borders around the main window to artificially make it smaller and therefore help in focusing.
* (overlay) An overlay plugin to allow to inforce the task description to be on a specific language, it would only accept well spelled words, but still allowing any other form of text as long as in in ALL CAPS. For example, if set to spanish only it would be: "Leer sobre ENTITY COMPONENT SYSTEM"


* (tray) Add "tomato break" option to tray icon, this option would end the session and enter a tomato break.
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
run:
python -m aboutlife

run-obfuscated:
python -m aboutlife --obfuscated

run-daemon:
python -m aboutlife --daemon

Expand Down
4 changes: 2 additions & 2 deletions aboutlife-webext/main.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// config vars
var PORT = "8080";
var PORT = "13005";
var HELP_SITE = "";
var ENDPOINT_QUERY = `http://localhost:${PORT}/state`;
var ENDPOINT_RESET = `http://localhost:${PORT}/close_tabs_reset`;
Expand Down Expand Up @@ -172,7 +172,7 @@ async function loop() {
console.log("I: Background script started");
try {
result = await browser.storage.local.get({
port: "8080",
port: PORT,
help_page_url: "",
});
if (result.port != "") {
Expand Down
2 changes: 1 addition & 1 deletion aboutlife-webext/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"manifest_version": 2,
"name": "Aboutlife Webext",
"version": "1.4.0",
"version": "1.5.0",
"description": "Communicates with the local Aboutlife instance",
"icons": {
"48": "icons/border-48.png"
Expand Down
2 changes: 1 addition & 1 deletion aboutlife-webext/options.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ <h2>Aboutlife Web Extension Settings</h2>
<label id="lbl_info">Connection status: Loading</label>
<p></p>
<label for="tbx_port">API port:</label>
<input type="text" id="tbx_port" name="port" placeholder="8080" />
<input type="text" id="tbx_port" name="port" placeholder="13005" />
<p></p>
<label for="tbx_help_page_url">Help page URL:</label>
<input type="text" id="tbx_help_page_url" name="help_page_url" />
Expand Down
4 changes: 2 additions & 2 deletions aboutlife-webext/options.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
var PORT = "8080";
var PORT = "13005";

document.addEventListener("DOMContentLoaded", function () {
// load
browser.storage.local
.get({
port: "8080",
port: PORT,
help_page_url: "",
})
.then((result) => {
Expand Down
25 changes: 20 additions & 5 deletions aboutlife/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,46 @@
sys.path.append(str(root))

import argparse
from aboutlife.overlay import overlay
from aboutlife.sticky import sticky
from aboutlife import daemon


def main():
print("I: Booting")
parser = argparse.ArgumentParser(description="Aboutlife")
parser.add_argument("--daemon", action="store_true", help="Run server only")
parser.add_argument(
"--obfuscated", action="store_true", help="Launch main deamon obfuscated"
)
parser.add_argument("--daemononly", action="store_true", help="Run server only")
parser.add_argument("--overlay", action="store_true", help="Launch overlay plugin")
parser.add_argument("--sticky", action="store_true", help="Launch sticky plugin")
args = parser.parse_args()

if args.overlay:
from aboutlife.overlay import overlay

print("I: Launching overlay")
overlay.main()

elif args.sticky:
from aboutlife.sticky import sticky

print("I: Launching sticky")
sticky.main()

elif args.daemon:
elif args.daemononly:
from aboutlife import daemon

print("I: Launching daemon server only")
daemon.main(False)

elif args.obfuscated:
from aboutlife.launcher import launcher

print("I: Launching daemon obfuscated")
launcher.main()

else:
from aboutlife import daemon

print("I: Launching aboutlife")
daemon.main()

Expand Down
20 changes: 20 additions & 0 deletions aboutlife/common/obscure_process.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import random
import psutil
import setproctitle


def get_random_process_name() -> str:
processes = [
proc.info["cmdline"]
for proc in psutil.process_iter(attrs=["cmdline"])
if proc.info["cmdline"] != None
and len(proc.info["cmdline"]) > 0
and "[" not in " ".join(proc.info["cmdline"])
]

new_name = " ".join(random.choice(processes))
return new_name


def obscure_process_name():
setproctitle.setproctitle(get_random_process_name())
8 changes: 6 additions & 2 deletions aboutlife/daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
from typing import List
from aboutlife.plugin import Plugin
from aboutlife.tray.tray import TrayPlugin
from aboutlife.rest.rest import RestPlugin
from aboutlife.rest.rest import RestPlugin, DEFAULT_PORT
from aboutlife.overlay.watcher import OverlayWatcherPlugin
from aboutlife.sticky.watcher import StickyWatcherPlugin
from aboutlife.networkmanager.watcher import NetworkManagerPlugin
from aboutlife.context import Context, STATE
from aboutlife.common import obscure_process

plugins: List[Plugin] = []
plugins_args: List = []
Expand Down Expand Up @@ -36,6 +37,9 @@ def process_loop():
def main(start_plugins: bool = True):
Context().get_singleton().reset()

# obscure main daemon process
obscure_process.obscure_process_name()

# setup plugins
if start_plugins:
plugins.append(TrayPlugin())
Expand Down Expand Up @@ -65,4 +69,4 @@ def main(start_plugins: bool = True):
thread.start()

rest = RestPlugin()
rest.setup(8080)
rest.setup(DEFAULT_PORT)
Empty file added aboutlife/launcher/__init__.py
Empty file.
36 changes: 36 additions & 0 deletions aboutlife/launcher/launcher.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import time
import subprocess
import time
import sys
from aboutlife.overlay import client


POLLING_DELAY = 3 # seconds
bin_path = sys.argv[0]


def main():
while True:
# handle requests

print("I: Launcher: Polling for _daemon_")
time.sleep(POLLING_DELAY)

# spawn new daemon if time expires

if client.get_state() == None:
process_cmd = [
# systemd cgroup disowning spawn
# extracted from https://stackoverflow.com/a/57041270
"systemd-run",
"--user",
"--scope",
"--slice=slice",
# process disowning spawn
"bash",
"-c",
f"( nohup sh -c '{bin_path} &' >/dev/null 2>&1 ) & ",
# f"{bin_path} & pid=$! ; echo \"pid $pid\"", # DEBUG
]
process = subprocess.Popen(process_cmd)
process.wait()
21 changes: 17 additions & 4 deletions aboutlife/networkmanager/watcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,23 @@ def setup(self):
if ctx.state != STATE.WORKING:
active = True

if active:
process = subprocess.Popen(["nmcli", "n", "on"])
else:
process = subprocess.Popen(["nmcli", "n", "off"])
command = [
"bash",
"-c",
"( (nmcli n on &) ) &",
]

if not active:
command = [
"bash",
"-c",
"( (nmcli n off &) ) &",
]

# TODO: Reduce spawn frequency

process = subprocess.Popen(command)
process.wait()

def process(self):
pass
Expand Down
3 changes: 2 additions & 1 deletion aboutlife/overlay/client.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from aboutlife.context import STATE
from aboutlife.rest.endpoints import ENDPOINT
from dataclasses import dataclass
from aboutlife.rest.rest import DEFAULT_PORT
import http.client
import json

HOST = "localhost:8080"
HOST = f"localhost:{DEFAULT_PORT}"


@dataclass
Expand Down
2 changes: 1 addition & 1 deletion aboutlife/overlay/feed/quotes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ Never stop learning. If you learn one new thing everyday, you will overcome 99%
It's a funny thing about life; if you refuse to accept anything but the best, you often get it.
Believe in yourself and you will be unstoppable.
No man ever became great without many and great mistakes.
n the long run, we only hit what we aim at.
In the long run, we only hit what we aim at.
Success seems to be connected with action. Successful men keep moving; they make mistakes, but they do not quit.
Destiny is not a matter of chance; it's a matter of choice. It is not a thing to be waited for; it is a thing to be achieved.
All or our dreams can come true if we have the courage to pursue them.
Expand Down
6 changes: 3 additions & 3 deletions aboutlife/overlay/watcher.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import time
import subprocess
import sys
from aboutlife.plugin import Plugin
from aboutlife.context import Context, STATE

PID_PATH = "/tmp/aboutlife_overlay.pid"


class OverlayWatcherPlugin(Plugin):
def setup(self):
Expand All @@ -17,8 +18,7 @@ def setup(self):
active = ctx.state != STATE.WORKING

if active:
process = subprocess.Popen([bin_path, "--overlay"])
process.wait()
self.spawn_if_pid_is_dead(PID_PATH, f"{bin_path} --overlay")

def process(self):
pass
Expand Down
47 changes: 47 additions & 0 deletions aboutlife/plugin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import os
import subprocess
from abc import ABC, abstractmethod


class Plugin(ABC):
must_read_pid = False
current_instance_pid = -1

def setup(self):
pass

Expand All @@ -14,3 +19,45 @@ def process(self):
@abstractmethod
def cleanup():
pass

# spawns new process if pid is not alive
def spawn_if_pid_is_dead(self, pid_path: str, command: str):
try:
# read pid

if self.must_read_pid:
pid = -1
with open(pid_path, "r") as f:
pid = int(f.read().strip())
self.must_read_pid = False
self.current_instance_pid = pid

if is_pid_alive(self.current_instance_pid):
return

# spawn instance, then save and read pid to keep track of it

process_cmd = [
"bash",
"-c",
f'( ({command} & pid=$! ; echo "$pid" > {pid_path} ) ) & ',
]
process = subprocess.Popen(process_cmd)
process.wait()
self.must_read_pid = True

except Exception as e:
self.must_read_pid = False
self.current_instance_pid = -1
raise e


def is_pid_alive(pid):
if pid < 0:
return False
try:
# doesn't kill it, just checks
os.kill(pid, 0)
except OSError:
return False
return True
7 changes: 5 additions & 2 deletions aboutlife/rest/rest.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@
from aboutlife.rest.handler import Handler


DEFAULT_PORT = 13005


class RestPlugin(Plugin):
def __init__(self):
self.server = None
self.port: int = 80

def setup(self, port: int):
self.port = port
self.server = HTTPServer(("0.0.0.0", port), Handler)
self.server = HTTPServer(("127.0.0.1", port), Handler)
self.server.running = True
print("D: serving rest")

Expand Down Expand Up @@ -46,4 +49,4 @@ def thread_helper(plugin):
thread = threading.Thread(target=thread_helper, args=(plugin,))
thread.daemon = True
thread.start()
plugin.setup(8080)
plugin.setup(DEFAULT_PORT)
10 changes: 6 additions & 4 deletions aboutlife/sticky/watcher.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
import time
import subprocess
import sys
from aboutlife.plugin import Plugin
from aboutlife.context import Context, STATE


PID_PATH = "/tmp/aboutlife_sticky.pid"


class StickyWatcherPlugin(Plugin):
def setup(self):
bin_path = sys.argv[0]
active = False

while True:
time.sleep(1)
time.sleep(2)

with Context.get_mutex():
ctx = Context.get_singleton()
active = ctx.state == STATE.WORKING

if active:
process = subprocess.Popen([bin_path, "--sticky"])
process.wait()
self.spawn_if_pid_is_dead(PID_PATH, f"{bin_path} --sticky")

def process(self):
pass
Expand Down
Loading