Files
felhom.eu/documentation/audits/night-2026-09-26/tools/e5b.py
T

48 lines
3.0 KiB
Python

import re, time, json, sys
import walk as w, fixtures
OUT = open(f"{w.EV}/E/E5-7-load-delete.txt", "w", buffering=1)
def say(*a):
w.say(*a); OUT.write(" ".join(map(str, a)) + "\n")
HDD = "/mnt/felhom-drives/scratch_hdd"
w.login()
import os
sess = open(f"{w.SC}/sess{os.getpid()}.txt").read().strip(); csrf = open(f"{w.SC}/csrf{os.getpid()}.txt").read().strip()
def form(path, data):
args = ["curl", "-sk", "-D", "-", "-o", "/dev/null", "-H", w.HOSTHDR, "-H", f"Cookie: {sess}", "-X", "POST", "--data-urlencode", f"_csrf={csrf}"]
for k, v in data.items():
args += ["--data-urlencode", f"{k}={v}"]
r = w.sh(args + [f"{w.BASE}{path}"])
loc = re.search(r"(?im)^location:\s*(\S+)", r.stdout or "")
code = (r.stdout or "").split(" ", 2)[1] if r.stdout else "?"
return code, (loc.group(1) if loc else "")
import urllib.parse
def flash(loc):
q = urllib.parse.parse_qs(urllib.parse.urlparse(loc).query)
return {k: v[0] for k, v in q.items()}
items = re.findall(r'name="path" value="([^"]+)"', w.page("/kept-data"))
say("listed paths:", items)
leftover = f"{HDD}/appdata/nextcloud"
dated = [p for p in items if "/kept/nextcloud/" in p]
unitdated = [p for p in dated if w.guest(f"test -d {p}/unit && echo yes").strip() == "yes"][0]
say("the loadable item:", unitdated)
c, loc = form("/kept-data/load", {"path": unitdated}); say(f"LOAD while the leftover occupies the folder -> {c} {flash(loc)}")
c, loc = form("/kept-data/delete", {"path": leftover, "confirm": "Nextclod"}); say(f"DELETE leftover with a WRONG name -> {c} {flash(loc)}")
say("leftover still there:", w.guest(f"test -d {leftover} && echo yes || echo GONE").strip())
c, loc = form("/kept-data/delete", {"path": "/mnt/felhom-drives/scratch_hdd/userdata", "confirm": "userdata"}); say(f"DELETE a path that is not listed (userdata) -> {c} {flash(loc)}")
c, loc = form("/kept-data/delete", {"path": leftover, "confirm": "Nextcloud"}); say(f"DELETE leftover with the right name -> {c} {flash(loc)}")
say("leftover now:", w.guest(f"test -d {leftover} && echo STILL || echo gone").strip())
since = w.guest("date -u +%Y-%m-%dT%H:%M:%SZ").strip()
c, loc = form("/kept-data/load", {"path": unitdated}); say(f"LOAD the dated item with its backup -> {c} {flash(loc)}")
t0 = time.time()
while time.time() - t0 < 900:
st = w.stack("nextcloud")
if st.get("deployed") and st.get("state") == "running" and "after_load" in w.guest(f"docker logs --since {since} felhom-controller 2>&1 | grep -c after_load"):
break
time.sleep(10)
time.sleep(20)
say("controller lines:\n" + w.guest(f"docker logs --since {since} felhom-controller 2>&1 | grep -iE 'kept|after_load|Restore-from-unit' | grep -v DEBUG | cut -c1-260 | head -12"))
toks = json.load(open(w.SC + "/seed-tokens.json"))
say("account reads back:", fixtures.FIXTURES["nextcloud"].verify(w, "c-nc", toks["nextcloud"], say))
items2 = re.findall(r'name="path" value="([^"]+)"', w.page("/kept-data"))
say("the loaded item left the list:", unitdated not in items2, "| list now:", items2)