licence-server/docs/asp-terminia/01-postojece-stanje.md
Nenad Djukic adac321938 Preuzet radni paket ASP-Terminia (licenciranje) iz firmverskog repoa
Paket je nastao u asp-terminia/licence/ ali je sav posao serverski, pa se
seli ovde. Firmverska strana je gotova od FW 0.10.0 i ne dira se.

- docs/asp-terminia/ - 6 dokumenata: postojece stanje servera i FW klijenta,
  tacan API ugovor koji firmware ocekuje, zadaci Z1-Z6 sa kriterijumima
  prihvatanja, pravila rada na produkciji, enforcement pitanja E1-E6
- reference prepravljene: "ASP repo" = https://git.terminia.net/djuka/asp-terminia
  (ranije su pokazivale na lokalnu putanju D:\priv\... koja vise ne postoji)
- CLAUDE.md: sekcija o cetvrtom proizvodu + pokazivac na paket

ASP-Terminia se od ESIR/ARV/LIGHT_TICKET razlikuje po tome sto je
machine_fingerprint MAC cipa (eFuse), a uredjaj radi offline - mrezna
greska ne sme da ga obori.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-24 21:44:20 +02:00

5.0 KiB
Raw Blame History

Postojeće stanje (provereno na serveru 2026-07-24, read-only)

1. Server 151 — pristup i raspored

  • SSH: ssh root@157.180.119.151 (host se javlja kao MCLaud, Ubuntu; ključ ~/.ssh/id_ed25519 sa razvojne mašine; samo root). Hetzner, van LAN-a.
  • Na ISTOM serveru žive i drugi sistemi — ne dirati:
    • terminia SaaS platforma za klubove (portovi 8091/8092) — IME SLIČNO, ali NIJE naš proizvod;
    • Gitea;
    • ESIR backend (fiskalizacija).

2. dal-license-server (naš deo)

  • Kod: /root/projects/dal-license-server — Go, bez frameworka, MySQL.
  • Port: 8090 lokalno; javno preko nginx sajta arv.
  • Javni URL (ovo firmware već koristi): https://157.180.119.151/license/api/v1/
    • HTTPS 443, cert /etc/nginx/ssl/arv.crt, server_name = IP → self-signed (zato firmware koristi setInsecure(); odluku štiti RSA potpis odgovora).
    • Na portu 80 je izložen samo validator API; ostalo redirect na 443.
  • Produkcioni obim: 3 proizvoda (ESIR, ARV, LIGHT_TICKET — seed u migrations/002_seed_products.sql), ~140 licenci, ~19 aktivacija. ŽIVO.

Kripto

  • RSA-2048, potpis RSA-SHA256.
  • Privatni ključ: na serveru (crypto/ + .env konfiguracija) — NE čitati, NE kopirati, NE logovati.
  • Javni ključ: crypto/public.pem — VEĆ ugrađen u firmware (licenca.cpp, LIC_PUBKEY). Ako se ključ ikad rotira, MORA i novi firmware — to je krupna odluka, ne radi se usput.
  • Potpis stiže kao string: "signature": "RSA-SHA256:<base64>" uz license objekat. Potpisuje se serijalizacija license objekta kakvu server pošalje — klijent verifikuje SIROVE bajtove (ne re-serijalizuje). Svaka izmena serijalizacije na serveru lomi sve klijente u polju.

Klijentski API (bez autentikacije, rate-limited)

Ruta Telo zahteva Odgovor
POST /api/v1/activate {license_key, machine_fingerprint, app_version, os, hostname} {license:{... expires_at, grace_days, limits, features, customer ...}, signature}
POST /api/v1/validate {license_key, machine_fingerprint} {valid, expires_at, revoked}
POST /api/v1/deactivate (transfer/oslobađanje)

Greške (JSON error polje): INVALID_KEY, ALREADY_ACTIVATED, KEY_EXPIRED, KEY_REVOKED, PRODUCT_MISMATCH.

Admin API

  • Header X-API-Key (ključ u .env — od vlasnika se traži ključ ili da on sam klikne u dashboardu; agent NE vadi ključ iz .env bez izričite dozvole).
  • Kreira proizvode i licence. Postoji i htmx admin dashboard.

3. Firmware klijent — GOTOV (od FW 0.10.0)

Fajlovi u firmware repou (firmware/10_terminia/):

Šta Gde
Modul licenca.h / licenca.cpp
Ugrađen javni ključ licenca.cppLIC_PUBKEY (PEM)
NVS namespace lic: raw (sirovi license JSON) + sig; ključ/URL u configu: licKey, licUrl (podrazumevano https://157.180.119.151/license/api/v1)
Web API (SPA) /api/license (status), /api/license-save (ključ/URL), /api/license-activate, /api/license-check — sve samo admin
UI SPA → Podešavanja → Uređaj → kartica „Licenca" (status, izdanje, korisnik, važi do, otisak uređaja, unos ključa, Aktiviraj, Proveri na serveru)

Kako klijent radi (bitno za server stranu)

  1. Otisak: machine_fingerprint = "sha256:" + sha256hex(MAC) gde je MAC oblika AA:BB:CC:DD:EE:FF (velika slova, dvotačke). ⚠️ PRETPOSTAVKA — proveriti u Go kodu servera kako računa fingerprint za poređenje; ako se razlikuje, uskladiti NA SERVERU dokumentaciju/verifikaciju za ASP proizvod ILI javiti pa menjamo FW (zadatak Z2).
  2. Aktivacija: POST /activate; iz odgovora isecₐ SIROVE bajtove license objekta (brojanje zagrada, string-safe), verifikuje signature RSASHA256 javnim ključem, čuva sirovo+potpis u NVS.
  3. Svaki start (offline): ponovo verifikuje potpis iz NVS + poredi machine_fingerprint iz licence sa svojim + proverava expires_at (poređenje po datumu YYYY-MM-DD; prazno = trajna; nepouzdan sat → grejs, nikad pad).
  4. Statusi na uređaju: nema / vazi / grejs / los-potpis / drugi-uredjaj / istekla.
  5. ENFORCEMENT NE POSTOJI — uređaj samo prikazuje status. Gašenje funkcija bez licence je odluka vlasnika (zadatak Z4).

Polja koja klijent čita iz license objekta

edition, customer (ili customer_name), expires_at, license_id (ili key), grace_days, machine_fingerprint. Nepoznata dodatna polja ne smetaju (parsira se ciljano). limits/features se JOŠ ne čitaju — planirano uz enforcement.

4. Šta NE postoji (i pripada zadacima)

  • Proizvod „ASP-Terminia" na serveru — ne postoji (zadatak Z1).
  • Nijedan ASP ključ — ne postoji (Z1/Z2).
  • Domen licenca.terminia.net + Let's Encrypt — ne postoji (Z3; domen kupuje vlasnik).
  • Enforcement na uređaju + features/limits semantika za ASP (Z4/Z5).
  • FW potpisivanje .bin + katalog firmvera (Z6; preduslov za auto-OTA, vidi i ASP repo: serviseri/03-provisioning-i-fw-katalog.md).