secubox-deb/packages/secubox-toolbox/conf/splash.html.j2
CyberMind-FR 13e48c93c6 feat(secubox-toolbox): splash R3 detection — dedicated badge + hides useless R0/R1/R2 switch (ref #496)
User feedback : 'niveau splash incoherent wireguard r3 undetected and
switch r0 r1 r2 available but useless'.

When a request to / comes from 10.99.1.0/24 (WG peer subnet), the splash
handler now :
  - looks up the peer pubkey → wg_hash → R3 mac_hash
  - sets is_wg_r3=True in the template context
  - sets current_level='r3' (was defaulting to None/r1)

Splash template :
  - Top of page : large gradient banner '🌐 Mode R3 — Tunnel WireGuard ACTIF'
    with client IP, links to /report?mh=, PDF download, /wg/r3-install
  - The captive R0/R1/R2/R3 form is HIDDEN entirely for is_wg_r3 (was
    useless : R3 client is by construction max-analysis, can't downgrade
    to captive level)

Validated mode chip now also handles current_level=='r3'.
2026-06-05 14:44:07 +02:00

272 lines
15 KiB
Django/Jinja

{# SPDX-License-Identifier: LicenseRef-CMSD-1.0 #}
{# Copyright (c) 2026 CyberMind — Gérald Kerma <devel@cybermind.fr> #}
<!DOCTYPE html>
<html lang="fr"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>{{ ssid }} — Cabine numérique Gondwana</title>
<style>
:root{--bg:#0a0a0f;--phos:#00dd44;--phos-hot:#00ff55;--dim:#006622;--text:#e8e6d9;--red:#ff4466;--amber:#ffb347}
*{box-sizing:border-box;margin:0;padding:0}
body{font-family:'Courier New',monospace;background:var(--bg);color:var(--text);min-height:100vh;display:flex;align-items:center;justify-content:center;padding:1.2rem}
.card{max-width:540px;width:100%;border:1px solid var(--dim);padding:1.5rem;box-shadow:0 0 20px rgba(0,221,68,0.3)}
h1{font-size:1.6rem;color:var(--phos-hot);text-shadow:0 0 6px var(--phos);margin-bottom:0.3rem;letter-spacing:0.08em}
.subtitle{color:var(--dim);font-size:0.85rem;margin-bottom:1rem;letter-spacing:0.05em}
.info{background:rgba(0,221,68,0.05);border-left:2px solid var(--phos);padding:0.7rem 0.9rem;margin-bottom:1rem;font-size:0.82rem;line-height:1.5}
.info b{color:var(--phos);text-shadow:0 0 4px var(--phos)}
.choose-label{font-size:0.95rem;color:var(--phos-hot);margin-bottom:0.6rem;text-shadow:0 0 4px var(--phos);text-align:center;letter-spacing:0.05em}
button.lvl-btn{width:100%;font-family:inherit;text-align:left;padding:0.8rem 0.9rem;background:transparent;border:1px solid;cursor:pointer;font-size:0.95rem;line-height:1.35;transition:all 0.15s;display:block}
button.lvl-btn:hover{background:rgba(255,255,255,0.04);transform:translateX(2px)}
button.lvl-r0{border-color:var(--dim);color:var(--text)}
button.lvl-r1{border-color:var(--phos);color:var(--phos-hot);text-shadow:0 0 4px var(--phos);box-shadow:inset 0 0 12px rgba(0,221,68,0.15)}
button.lvl-r2{border-color:var(--amber);color:#ffd6a0}
.badge{display:inline-block;font-size:0.65rem;padding:0.1rem 0.4rem;background:var(--phos);color:#0a0a0f;border-radius:99px;margin-left:0.3rem;font-weight:bold;letter-spacing:0.03em;vertical-align:middle}
.sub-desc{display:block;font-size:0.72rem;opacity:0.75;margin-top:0.2rem;letter-spacing:0}
.r2-warn{margin-top:0.8rem;padding:0.7rem 0.9rem;background:rgba(255,179,71,0.08);border-left:2px solid var(--amber);font-size:0.75rem;line-height:1.45;color:#ffd6a0}
.r2-warn strong{color:var(--amber);text-shadow:0 0 4px var(--amber)}
.r2-warn a{color:var(--amber);text-decoration:underline}
.terms{font-size:0.72rem;color:var(--dim);margin-top:1rem;line-height:1.45;border-top:1px solid var(--dim);padding-top:0.7rem}
.terms a{color:var(--phos);text-decoration:underline}
.footer{text-align:center;margin-top:1rem;font-size:0.65rem;color:var(--dim);letter-spacing:0.08em}
.footer a{color:var(--dim);text-decoration:none}
</style></head><body>
<div class="card">
<h1>📡 {{ ssid }}</h1>
<p class="subtitle">// Cabine numérique Gondwana</p>
<div class="info">
🌐 Tu es connecté au réseau de la borne.
{% if mac_hash and mac_hash != '??' %}<br>Ton appareil (anonymisé) : <b>{{ mac_hash }}</b>{% endif %}
</div>
{# Phase 6.I (#496) : R3 WG client detected — show special banner, hide R0/R1/R2 switcher #}
{% if is_wg_r3 %}
<div class="info" style="margin-top:0.5rem;background:linear-gradient(135deg,rgba(158,118,255,0.15),rgba(158,118,255,0.05));border-left:4px solid var(--purple);padding:0.9rem 1rem">
<p style="font-size:1.05rem;font-weight:bold;color:#cbb6ff;margin-bottom:0.4rem">
🌐 <b>Mode R3 — Tunnel WireGuard ACTIF</b>
</p>
<p style="font-size:0.82rem;line-height:1.55;opacity:0.92">
Tu es connecté depuis l'extérieur via le tunnel R3 ({{ client_ip }}).<br>
Le bandeau s'injecte sur les pages HTTPS, Signal/WhatsApp/banques en passthrough.
</p>
<p style="margin-top:0.7rem;display:flex;flex-wrap:wrap;gap:0.5rem">
<a href="/report/me/html?mh={{ mac_hash }}"
style="background:var(--purple);color:#0a0a0f;padding:0.5rem 0.9rem;border-radius:4px;text-decoration:none;font-weight:bold;font-size:0.85rem">
📊 Mon rapport live
</a>
<a href="/report/me?mh={{ mac_hash }}"
style="background:transparent;color:var(--purple);border:1px solid var(--purple);padding:0.5rem 0.9rem;border-radius:4px;text-decoration:none;font-weight:bold;font-size:0.85rem">
⬇ PDF
</a>
<a href="/wg/r3-install"
style="background:transparent;color:#cbb6ff;border:1px solid #555;padding:0.5rem 0.9rem;border-radius:4px;text-decoration:none;font-size:0.82rem">
🔧 Réinstaller R3
</a>
</p>
<p style="font-size:0.7rem;opacity:0.6;margin-top:0.5rem">
💡 R0/R1/R2 sont les niveaux de la cabine captive (WiFi local). En R3 tu es par
construction au niveau maximum d'analyse.
</p>
</div>
{% elif already_validated %}
<div class="info" style="margin-top:0.5rem;background:rgba(0,221,68,0.08);border-left-color:var(--phos)">
✅ <b>Tu es déjà validé en mode
{% if current_level == 'r0' %}🌐 R0 (bypass complet)
{% elif current_level == 'r2' %}🔍 R2 (analyse + bandeau)
{% elif current_level == 'r3' %}🌐 R3 (WireGuard tunnel)
{% else %}🛡 R1 (analyse passive){% endif %}</b>
· <a href="/report/me/html" style="color:var(--phos-hot);text-decoration:underline">📊 Voir mon rapport live</a>
<span style="font-size:0.72rem;opacity:0.7;display:block;margin-top:0.3rem">
Tu peux installer/réinstaller les composants ci-dessous ou changer de niveau.
</span>
</div>
{% endif %}
{# Phase 3 (#492) : 📦 Composants à installer — quick-up menu emoji #}
<div class="info" style="margin-top:0.5rem;background:rgba(110,64,201,0.08);border-left-color:#9e76ff">
<p style="font-size:0.9rem;color:#cbb6ff;margin-bottom:0.6rem;font-weight:bold">
📦 Quick install — composants ToolBoX
</p>
<div style="display:grid;grid-template-columns:repeat(2,1fr);gap:0.5rem;margin-bottom:0.6rem">
<a href="/ca/mobileconfig" class="qbtn qbtn-primary">
🔐 Certificat iPhone
<span class="qbtn-sub">.mobileconfig pour iOS</span>
</a>
<a href="/ca/android.crt" class="qbtn qbtn-outline">
🤖 Certificat Android/PC
<span class="qbtn-sub">.crt à installer manuellement</span>
</a>
<a href="/ca/webclip-cabine.mobileconfig" class="qbtn qbtn-primary-alt">
📱 Icône Home iPhone
<span class="qbtn-sub">1-tap accès rapport</span>
</a>
<a href="/ca/install-help" class="qbtn qbtn-outline">
📜 Guide pas-à-pas
<span class="qbtn-sub">comment installer</span>
</a>
</div>
<button type="button" id="test-cert-btn" class="qbtn qbtn-test">
🧪 Tester le certificat maintenant
</button>
<div id="cert-status" style="font-size:0.8rem;padding:0.55rem;background:rgba(0,0,0,0.3);border-radius:3px;text-align:center;margin-top:0.5rem">
<span id="cert-emoji">⏳</span>
<span id="cert-text">Auto-test en cours...</span>
</div>
{# Phase 3.x (#497) : 3 QR codes définitifs synchronisés avec le poster #}
<p style="font-size:0.78rem;color:#cbb6ff;margin-top:0.8rem;text-align:center;border-top:1px solid rgba(158,118,255,0.3);padding-top:0.5rem">
📲 <b>QR codes</b> — scanne depuis un autre appareil
</p>
<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:0.5rem;margin-top:0.4rem">
<div style="text-align:center;background:rgba(255,255,255,0.95);padding:0.4rem;border-radius:4px">
<img src="/qr/splash.png" alt="QR splash" style="width:100%;max-width:120px;display:block;margin:auto"/>
<p style="font-size:0.62rem;color:#0a0a0f;margin-top:0.2rem;font-weight:bold">① SPLASH</p>
</div>
<div style="text-align:center;background:rgba(255,255,255,0.95);padding:0.4rem;border-radius:4px">
<img src="/qr/cert.png" alt="QR cert" style="width:100%;max-width:120px;display:block;margin:auto"/>
<p style="font-size:0.62rem;color:#0a0a0f;margin-top:0.2rem;font-weight:bold">② CERT iPHONE</p>
</div>
<div style="text-align:center;background:rgba(255,255,255,0.95);padding:0.4rem;border-radius:4px">
<img src="/qr/webclip.png" alt="QR webclip" style="width:100%;max-width:120px;display:block;margin:auto"/>
<p style="font-size:0.62rem;color:#0a0a0f;margin-top:0.2rem;font-weight:bold">③ WEBCLIP HOME</p>
</div>
</div>
<p style="font-size:0.7rem;opacity:0.85;margin-top:0.6rem;line-height:1.5">
⚠ L'auto-test est <b>best-effort</b> (probe HTTPS). Pour <b>certifier</b>
que le CA est bien installé + activé sur iPhone :
</p>
<ol style="font-size:0.7rem;padding-left:1.2rem;line-height:1.55;color:#cbb6ff">
<li>Réglages → Général → <b>VPN et gestion d'appareils</b></li>
<li>Profil <b>Gondwana ToolBoX CA</b> doit apparaître → tap → installer</li>
<li>Réglages → Général → Information → <b>Réglages de confiance des certificats</b></li>
<li>Activer le toggle pour <b>Gondwana ToolBoX CA</b> 🟢</li>
</ol>
<p style="font-size:0.7rem;opacity:0.9;margin-top:0.5rem;border-top:1px solid rgba(158,118,255,0.3);padding-top:0.4rem">
Vérifie cette empreinte dans Réglages :
</p>
<p style="font-family:monospace;font-size:0.78rem;word-break:break-all;color:#cbb6ff;background:rgba(0,0,0,0.4);padding:0.5rem;border-radius:3px;margin-top:0.3rem">
🔑 <code id="cert-fp"></code>
</p>
</div>
<style>
.qbtn{display:block;padding:0.7rem 0.6rem;text-decoration:none;text-align:center;
font-family:inherit;font-size:0.82rem;font-weight:bold;border-radius:4px;
transition:transform 0.1s,box-shadow 0.1s;line-height:1.25}
.qbtn:hover{transform:translateY(-1px);box-shadow:0 2px 6px rgba(0,0,0,0.4)}
.qbtn-sub{display:block;font-size:0.65rem;font-weight:normal;opacity:0.75;margin-top:0.2rem}
.qbtn-primary{background:#9e76ff;color:#0a0a0f}
.qbtn-primary-alt{background:#6e40c9;color:#fff}
.qbtn-outline{background:transparent;color:#cbb6ff;border:1px solid #9e76ff}
.qbtn-test{width:100%;background:transparent;color:var(--phos-hot);border:1px solid var(--phos);
padding:0.55rem;cursor:pointer;font-family:inherit;font-size:0.85rem}
.qbtn-test:hover{background:rgba(0,221,68,0.1)}
</style>
<script>
(function(){
var fpEl = document.getElementById('cert-fp');
var emEl = document.getElementById('cert-emoji');
var txEl = document.getElementById('cert-text');
var btnEl = document.getElementById('test-cert-btn');
var statusEl = document.getElementById('cert-status');
fetch('/ca/fingerprint').then(function(r){return r.json();}).then(function(d){
fpEl.textContent = (d.sha1 || d.sha256 || '?');
}).catch(function(){fpEl.textContent = '?';});
function runProbe() {
emEl.textContent = '⏳';
txEl.textContent = 'Test en cours...';
statusEl.style.background = 'rgba(0,0,0,0.3)';
// The probe is HEURISTIC : iOS has special handling for many domains
// (captive.apple.com cert-pinned, etc.) so auto-test is best-effort.
// We probe example.com which is :
// - NOT cert-pinned by iOS
// - simple, low-latency HTTPS
// - if user is in R1/R2 (MITM enabled), mitm generates a leaf cert
// signed by our CA -> success only if our CA is installed.
// - if user is NOT yet in MITM set (pre-validation), the cert chain
// is example.com's real chain -> always succeeds regardless of our CA.
// So pre-validation : auto-test ALWAYS passes (informative only).
// Post-R1/R2 acceptance : auto-test is reliable.
var probe = new Image();
var done = false;
probe.onload = function(){
if (done) return; done = true;
emEl.textContent = '🟢';
txEl.innerHTML = '<b>HTTPS OK</b> — si tu es déjà en R1/R2, ton CA est installé. Vérifie quand même les étapes manuelles ci-dessous.';
statusEl.style.background = 'rgba(0,221,68,0.15)';
};
probe.onerror = function(){
if (done) return; done = true;
emEl.textContent = '🔴';
txEl.innerHTML = '<b>HTTPS échoue</b> — soit pas de réseau, soit en R1/R2 SANS le CA installé. Suis les étapes manuelles ci-dessous.';
statusEl.style.background = 'rgba(255,68,102,0.15)';
};
probe.src = 'https://example.com/favicon.ico?t=' + Date.now();
setTimeout(function(){
if (done) return; done = true;
emEl.textContent = '❔';
txEl.innerHTML = 'Timeout — relance le test ou vérifie manuellement ci-dessous';
statusEl.style.background = 'rgba(255,179,71,0.15)';
}, 4000);
}
btnEl.addEventListener('click', runProbe);
setTimeout(runProbe, 600);
})();
</script>
{# Phase 6.I : R3 clients skip the captive R0/R1/R2 chooser entirely #}
{% if not is_wg_r3 %}
<p class="choose-label">👇 Choisis ton niveau d'analyse :</p>
<form method="POST" action="/accept" style="display:flex;flex-direction:column;gap:0.6rem">
<button type="submit" name="level" value="r0" class="lvl-btn lvl-r0">
🌐 <b>R0 — Bypass complet</b>
<span class="sub-desc">Réseau seul, ZÉRO analyse. La cabine se comporte comme un AP normal.</span>
</button>
<button type="submit" name="level" value="r1" class="lvl-btn lvl-r1">
🛡 <b>R1 — Analyse passive</b><span class="badge">✓ DÉFAUT RECOMMANDÉ</span>
<span class="sub-desc">Rapport détaillé sur ta session, <b>aucun impact</b> sur ta navigation. Apps natives + iCloud + Push fonctionnent normalement.</span>
</button>
{% if r2_enabled %}
<button type="submit" name="level" value="r2" class="lvl-btn lvl-r2">
🔍 <b>R2 — Analyse + bandeau Safari</b>
<span class="sub-desc">Déchiffrement TLS + bandeau visible sur les pages Safari HTML.</span>
</button>
<div class="r2-warn">
<strong>⚠ Si tu choisis R2 :</strong> il te faut <a href="/ca/install-help">installer le certificat racine ToolBoX</a> sur ton iPhone, sinon les sites HTTPS échouent. Le bandeau n'apparaît que sur les pages HTML servies en TCP (la plupart des apps iPhone utilisent QUIC et ne montreront pas le bandeau). Tu peux revenir en R1 depuis le rapport à tout moment.
</div>
{% endif %}
{# Phase 6 (#496) : R3 WireGuard portable mode #}
{% if wg_enabled|default(false) %}
<a href="/wg/r3-install" class="lvl-btn lvl-r3"
style="display:block;text-align:left;padding:0.8rem 0.9rem;border:1px solid #9e76ff;color:#cbb6ff;background:rgba(110,64,201,0.08);text-decoration:none;font-size:0.95rem;line-height:1.35">
🌐 <b>R3 — WireGuard portable (NOUVEAU)</b>
<span style="display:block;font-size:0.72rem;opacity:0.85;margin-top:0.2rem">VPN tunnel mitm. Bandeau sur TOUT (HTTPS + QUIC). Marche hors VILLAGE3B (4G/5G, autre WiFi). Profile install 1 tap.</span>
</a>
{% endif %}
</form>
{% endif %} {# /not is_wg_r3 #}
<p class="terms">
<b>Conformité :</b> CSPN R2 — consentement explicite par MAC ; LCEN — anonymisation par hash quotidien rotatif. Dispositif défensif (rapport sur TON appareil, jamais sur les tiers).
Après validation, <a href="/report/me/html">accède à ton rapport live</a> ou <a href="/report/me">télécharge le PDF</a> pendant 24h.
</p>
<p class="footer">
SecuBox-Deb · CyberMind · <a href="https://github.com/CyberMind-FR/secubox-deb">Source LicenseRef-CMSD-1.0</a>
</p>
</div>
</body></html>