Compare commits

..
1 Commits
Author SHA1 Message Date
alientimandClaude Sonnet 5 a193b9d6e9 licensing.py: optionales report-Feld fuer Sub-Lizenzserver-Meldungen
Rein synchronisierende Aenderung (harte Invariante: licensing.py bleibt
byte-identisch in beiden Repos). build_client_request() akzeptiert
jetzt einen optionalen report-Parameter, der bei Heartbeats einer
role='license_server'-Lizenz den eigenen Kunden-/Ticket-/Lizenzstand
signiert mitschickt -- Kern des neuen Sub-Lizenzserver-Reportings auf
dem Lizenzserver (siehe dortiges Release). Bestehende Aufrufer (TESM-
Client-Heartbeats, activate/deactivate) uebergeben report nie -- das
Feld fehlt dann wie bisher komplett in der Payload, keine
Verhaltensaenderung.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-23 22:43:17 +02:00
2 changed files with 18 additions and 3 deletions
+1 -1
View File
@@ -1 +1 @@
1.2.7 1.2.8
+17 -2
View File
@@ -275,11 +275,24 @@ def system_fingerprint():
# gebunden ist, siehe Plan-Abschnitt "Warum das die Doppelnutzung wirksam # gebunden ist, siehe Plan-Abschnitt "Warum das die Doppelnutzung wirksam
# verhindert". # verhindert".
def build_client_request(action, license_file, nonce=None) -> dict: def build_client_request(action, license_file, nonce=None, report=None) -> dict:
"""Vom CLIENT aufgerufen: erzeugt eine signierte Anfrage (action: """Vom CLIENT aufgerufen: erzeugt eine signierte Anfrage (action:
"activate"/"deactivate"/"heartbeat"). Das Ergebnis ist unverändert für "activate"/"deactivate"/"heartbeat"). Das Ergebnis ist unverändert für
einen Online-API-Aufruf nutzbar; für den Offline-Fall wird es einen Online-API-Aufruf nutzbar; für den Offline-Fall wird es
zusätzlich mit encode_code() in einen kopierbaren Code umgewandelt.""" zusätzlich mit encode_code() in einen kopierbaren Code umgewandelt.
report: NUR für Heartbeats einer role="license_server"-Lizenz gedacht
(siehe Lizenzserver-app.py _build_own_issuance_report()) -- ein
optionaler Schnappschuss der eigenen Kunden/Tickets/Lizenzen dieses
Sub-Lizenzservers, den der Master beim Empfang in seine
reported_sub_*-Tabellen übernimmt, um einen Gesamtüberblick zu haben.
Bewusst Teil DIESER generischen, gemeinsam genutzten Funktion (nicht
ein eigenes Protokoll-Feature) -- ein normaler TESM-Client/eine
"customer"-Lizenz übergibt hier einfach nie einen Wert, das Feld fehlt
dann in der Payload wie bisher (keine Verhaltensänderung für alle
bestehenden Aufrufer). Wie jedes andere Feld wird auch report
mitsigniert -- ein Angreifer ohne den privaten Lizenzschlüssel kann
keine gefälschten Berichte unterschieben."""
if action not in ("activate", "deactivate", "heartbeat"): if action not in ("activate", "deactivate", "heartbeat"):
raise ValueError(f"Unbekannte Aktion: {action!r}") raise ValueError(f"Unbekannte Aktion: {action!r}")
payload = { payload = {
@@ -296,6 +309,8 @@ def build_client_request(action, license_file, nonce=None) -> dict:
"nonce": nonce or uuid.uuid4().hex, "nonce": nonce or uuid.uuid4().hex,
"timestamp": _iso(time.time()), "timestamp": _iso(time.time()),
} }
if report is not None:
payload["report"] = report
signature = sign_payload(payload, license_file["license_privkey"]) signature = sign_payload(payload, license_file["license_privkey"])
return {**payload, "signature": signature} return {**payload, "signature": signature}