- abendkontrolle.py: --quelle und --quelle-ibkr (Vorgabe wsl wie bisher, dockerhost liest das Ergebnis des Hosts ueber SSH), fahre_dockerhost - abendkontrolle_wsl.py: --ibkr-python fuer ibkr_pruefen.py im Container - abendkontrolle_einrichten.ps1: -Quelle und -QuelleIbkr, 23:15 sobald ein Teil vom Host kommt - neue Angriffstreiber abendkontrolle_dockerhost_angriffe.py und abendkontrolle_ibkr_python_angriffe.py - Abdichtung gegen echte WSL- und SSH-Wege in den Treibern, auch in abendkontrolle_angriffe.py und rueckweg_aapl_angriffe.py (nach dem ntfy-Vorfall eines Mutanten am 2026-09-26) - LIESMICH: Abschnitt Paket DH - .claude/workflows/plankritik.js: LF statt CRLF (das CR war die Ursache von "script contains control characters"), meta gekuerzt, Einzelheiten im Kommentar Co-Authored-By: Claude Opus 5.5 <[email protected]>
96 lines
3.5 KiB
Python
96 lines
3.5 KiB
Python
"""Angriffsfaelle fuer --ibkr-python von abendkontrolle_wsl.py (Nachtrag zu Paket DH, IB2), in WSL, ohne Netz.
|
|
|
|
Koordinator-Werkzeug, nicht fuers Repo. Auf dem Docker-Host laeuft der Teil ibkr im Abbild; dort
|
|
gibt es das Venv aus WSL nicht, und ibkr_pruefen.py lesen laeuft mit dem python des Containers
|
|
(abendkontrolle-host.sh: --ibkr-python python). Die Faelle pruefen den Schalter, die Vorgabe, den
|
|
Aufruf mit dem genannten Interpreter gegen ein Ersatzskript in einem Wegwerf-Ordner und die
|
|
Weitergabe im Ablauf. Das Ersatzskript druckt den Interpreter, der es startet; so faellt ein
|
|
Aufruf mit dem festen Venv-Pfad auf, auch wenn es den Pfad gibt.
|
|
Aufruf (WSL, Venv): python abendkontrolle_ibkr_python_angriffe.py
|
|
Exit 0 ohne Abweichung, 2 mit Abweichung.
|
|
"""
|
|
|
|
import importlib.util
|
|
import sys
|
|
import tempfile
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
HIER = Path(__file__).resolve().parent
|
|
ERSATZ = (
|
|
"import sys\n"
|
|
"print('Interpreter: ' + sys.executable)\n"
|
|
"print('Positionen: 0')\n"
|
|
"print('Offene Orders: 0')\n"
|
|
)
|
|
|
|
FAELLE = []
|
|
|
|
|
|
def fall(funktion):
|
|
FAELLE.append(funktion)
|
|
return funktion
|
|
|
|
|
|
def lade():
|
|
spec = importlib.util.spec_from_file_location("abendkontrolle_wsl_unter_angriff", HIER / "abendkontrolle_wsl.py")
|
|
modul = importlib.util.module_from_spec(spec)
|
|
spec.loader.exec_module(modul)
|
|
# Zweite Sperre (Pruefung DH-Nachtrag, 2026-09-26): Die Faelle geben den Ordner mit dem
|
|
# Ersatzskript ausdruecklich mit. Nimmt ein Mutant stattdessen die Vorgabe, zeigt sie ins Leere
|
|
# und nicht auf den Betriebsordner mit dem echten ibkr_pruefen.py.
|
|
modul.IBKR_ORDNER = "/nicht-vorhanden/trading-ibkr-betrieb"
|
|
return modul
|
|
|
|
|
|
@fall
|
|
def der_schalter_nennt_den_interpreter():
|
|
argumente = lade().parse_args(["--tag", "2026-10-05", "--teil", "ibkr", "--ibkr-python", "/usr/local/bin/python"])
|
|
assert argumente.ibkr_python == "/usr/local/bin/python", argumente
|
|
|
|
|
|
@fall
|
|
def ohne_schalter_bleibt_das_venv_aus_wsl():
|
|
modul = lade()
|
|
argumente = modul.parse_args(["--tag", "2026-10-05", "--teil", "ibkr"])
|
|
assert argumente.ibkr_python == modul.IBKR_PY, argumente
|
|
assert modul.IBKR_PY == "/home/claude/venvs/trading-ibkr/bin/python", modul.IBKR_PY
|
|
|
|
|
|
@fall
|
|
def lesen_laeuft_mit_dem_genannten_interpreter():
|
|
modul = lade()
|
|
with tempfile.TemporaryDirectory() as ordner:
|
|
wurzel = Path(ordner)
|
|
(wurzel / "scripts").mkdir()
|
|
(wurzel / "scripts" / "ibkr_pruefen.py").write_text(ERSATZ, encoding="utf-8")
|
|
code, text = modul.lies_konto_ibkr(wurzel, None, sys.executable)
|
|
assert code == 0, (code, text)
|
|
assert f"Interpreter: {sys.executable}" in text, text
|
|
assert "Positionen: 0" in text and "Offene Orders: 0" in text, text
|
|
|
|
|
|
@fall
|
|
def der_ablauf_gibt_den_schalter_weiter():
|
|
quelle = (HIER / "abendkontrolle_wsl.py").read_text(encoding="utf-8")
|
|
assert "lies_konto_ibkr, ordner, argumente.ibkr_konto, argumente.ibkr_python)" in quelle
|
|
assert '[python, "scripts/ibkr_pruefen.py", "lesen"], cwd=ordner,' in quelle
|
|
|
|
|
|
def main() -> int:
|
|
abweichungen = 0
|
|
for funktion in FAELLE:
|
|
try:
|
|
funktion()
|
|
except (Exception, SystemExit) as ausnahme:
|
|
abweichungen += 1
|
|
print(f"ABWEICHUNG {funktion.__name__}: {type(ausnahme).__name__}: {ausnahme}")
|
|
else:
|
|
print(f"OK {funktion.__name__}")
|
|
print(f"{len(FAELLE)} Faelle, {abweichungen} Abweichung(en) ({datetime.now():%Y-%m-%d %H:%M})")
|
|
return 2 if abweichungen else 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|