()
| 7650 | <td class="px-2 py-1 text-gray-400">${finding}</td> |
| 7651 | </tr>`; |
| 7652 | }).join('') + '</tbody></table>'; |
| 7653 | } |
| 7654 | if (d.advisories && d.advisories.length) { |
| 7655 | html += '<ul class="text-xs text-cyan-400/80 mt-2 list-disc pl-5">' + |
| 7656 | d.advisories.map(a => '<li>' + escapeHtml(a) + '</li>').join('') + '</ul>'; |
| 7657 | } |
| 7658 | out.innerHTML = html; |
| 7659 | } catch (e) { |
| 7660 | out.innerHTML = '<p class="text-sm text-red-400">Failed: ' + escapeHtml(e.message) + '</p>'; |
| 7661 | } finally { |
| 7662 | _ndBusy(btn, false); |
| 7663 | } |
| 7664 | } |
| 7665 | async function certTrustBaseline() { |
| 7666 | try { |
| 7667 | await postAPI('/api/net/cert-baseline', { action: 'reset' }); |
| 7668 | addConsoleMessage('TLS cert-fingerprint baseline reset — re-learning on the next scan', 'info'); |
| 7669 | await runCertWatch(); |
| 7670 | } catch (e) { |
| 7671 | addConsoleMessage('Failed to reset TLS baseline: ' + e.message, 'error'); |
| 7672 | } |
| 7673 | } |
| 7674 | |
| 7675 | // ---- OSPF Security Scanner (passive) --------------------------------------- |
| 7676 | const _OSPF_VERDICT_STYLE = { |
| 7677 | clean: ['bg-green-950/40 border-green-900 text-green-400', '✓ No OSPF anomalies detected'], |
| 7678 | weak_auth: ['bg-amber-950/50 border-amber-800 text-amber-300', '⚠ Weak / no OSPF authentication — exposed to LSA injection'], |
| 7679 | anomaly: ['bg-amber-950/50 border-amber-800 text-amber-300', '⚠ OSPF anomaly — rogue router / Router-ID conflict / mismatch'], |
| 7680 | injection: ['bg-red-950/60 border-red-800 text-red-300', '🛑 OSPF LSA injection / route poisoning detected'], |
| 7681 | storm: ['bg-red-950/60 border-red-800 text-red-300', '🛑 OSPF flooding storm detected'], |
| 7682 | unknown: ['bg-slate-800 border-slate-700 text-slate-400', '— Could not determine'], |
| 7683 | }; |
| 7684 | const _OSPF_AUTH_NAME = { 0: 'none (0)', 1: 'plaintext (1)', 2: 'cryptographic (2)' }; |
| 7685 | function _ospfFillIfaces() { |
| 7686 | const sel = document.getElementById('ospf-iface'); |
| 7687 | if (!sel || sel.dataset.filled === '1') return Promise.resolve(); |
| 7688 | return fetchAPI('/api/net/interfaces').then(x => { |
| 7689 | (x.interfaces || []).forEach(i => { |
nothing calls this directly
no test coverage detected