diff options
Diffstat (limited to 'raveos-center/raveos_center/oldalak/rendszer/secureboot.py')
| -rw-r--r-- | raveos-center/raveos_center/oldalak/rendszer/secureboot.py | 256 |
1 files changed, 256 insertions, 0 deletions
diff --git a/raveos-center/raveos_center/oldalak/rendszer/secureboot.py b/raveos-center/raveos_center/oldalak/rendszer/secureboot.py new file mode 100644 index 0000000..00ca444 --- /dev/null +++ b/raveos-center/raveos_center/oldalak/rendszer/secureboot.py @@ -0,0 +1,256 @@ +import shutil +import subprocess + +from PyQt6.QtWidgets import QHBoxLayout, QMessageBox, QPlainTextEdit, QVBoxLayout, QWidget + +from raveos_center import muveletek +from raveos_center.elemek import Kartya, Racs, cimke, gomb +from raveos_center.hatter import ervenytelenit, gyorsitott, tarolt + +AZON = "secureboot" +CIM = "Secure Boot" + +SZKRIPT = "raveos-secureboot-setup" +UJRAINDITAS_KELL = 10 + +LEPESEK_SZOVEG = [ + "telepíti a szükséges eszközöket (sbsigntools, efitools),", + "létrehoz egy saját, csak ehhez a géphez tartozó aláíró kulcsot,", + "aláírja a rendszerbetöltőt, a kernelt és a külső kernelmodulokat (pl. NVIDIA),", + "beírja a firmware-be a RaveOS, a Microsoft és a saját géped kulcsát, így a Windows is tovább indul,", + "beállít egy automatikus aláírást, ami minden kernelfrissítés után újra aláír.", +] + + +def allapot_lekerdez(): + if not shutil.which(SZKRIPT): + return None + kimenet = subprocess.run([SZKRIPT, "--status"], capture_output=True, text=True, timeout=30) + adat = {} + for sor in kimenet.stdout.splitlines(): + if "=" in sor and not sor.startswith("["): + k, _, v = sor.partition("=") + adat[k.strip()] = v.strip() + if not adat and "Nem UEFI" in kimenet.stdout: + adat["uefi"] = "0" + return adat + + +class SecureBoot(QWidget): + def __init__(self, kozpont): + super().__init__() + self.kozpont = kozpont + doboz = QVBoxLayout(self) + doboz.setContentsMargins(0, 20, 0, 0) + doboz.setSpacing(16) + doboz.addWidget( + cimke( + "A Secure Boot csak aláírt rendszerbetöltőt és kernelt enged elindulni. Akkor hasznos, ha a gépen " + "Windows is van, és ott olyan játék vagy program fut, ami bekapcsolt Secure Bootot kér (például egyes " + "csalásvédelmek vagy a Windows 11). A beállítás után a RaveOS és a Windows is elindul.", + "masodlagos", + True, + ) + ) + oszlopok = QHBoxLayout() + oszlopok.setSpacing(24) + bal = QVBoxLayout() + bal.setSpacing(12) + oszlopok.addLayout(bal, 3) + doboz.addLayout(oszlopok, 1) + self.racs = Racs(110, 10) + self.ertekek = {} + for kulcs, nev in ( + ("secureboot", "Secure Boot"), + ("setupmode", "Setup Mode"), + ("keys", "Gépkulcs"), + ("signed", "Aláírások"), + ): + k = Kartya(nev, terkoz=6, margo=14) + ertek = cimke("...", "nagyszam") + k.elrendezes.addWidget(ertek) + self.ertekek[kulcs] = ertek + self.racs.hozzaad(k) + bal.addWidget(self.racs) + self.figyelem = cimke("", "figyelem", True) + self.figyelem.hide() + bal.addWidget(self.figyelem) + bal.addWidget( + cimke( + "FIGYELEM, BITLOCKER: ha a gépen Windows is van BitLockerrel, a beállítás előtt a Windowsban függeszd " + "fel a BitLockert (manage-bde -protectors -disable C: -rebootcount 2), vagy legyen kéznél a 48 jegyű " + "helyreállítási kulcs. Enélkül a Windows a következő indításkor ezt a kulcsot fogja kérni.", + "figyelem", + True, + ) + ) + + leiras = Kartya("A beállítás lépései", terkoz=6) + leiras.elrendezes.addWidget(cimke("A Beállítás gomb egymás után:", "masodlagos")) + for i, szoveg in enumerate(LEPESEK_SZOVEG, 1): + sor = QHBoxLayout() + sor.setSpacing(10) + jel = cimke(f"{i}.", "monozold") + jel.setFixedWidth(22) + sor.addWidget(jel) + sor.addWidget(cimke(szoveg, "masodlagos", True), 1) + leiras.elrendezes.addLayout(sor) + leiras.elrendezes.addSpacing(6) + leiras.elrendezes.addWidget( + cimke( + "Ehhez a firmware-nek Setup Mode-ban kell lennie: a BIOS/UEFI beállításokban töröld a Secure Boot " + "kulcsokat (Clear Secure Boot keys / Reset to Setup Mode). Ha nincs Setup Mode-ban, a Center szól, " + "és újraindítás után a beállítás magától folytatódik.", + "halvany", + True, + ) + ) + + leiras.setMinimumWidth(300) + leiras.setMaximumWidth(420) + jobb = QVBoxLayout() + jobb.addWidget(leiras) + jobb.addStretch(1) + oszlopok.addLayout(jobb, 2) + + gombok = QHBoxLayout() + gombok.setSpacing(8) + self.frissit_gomb = gomb("Állapot frissítése") + self.frissit_gomb.clicked.connect(self.frissit) + self.ujra_gomb = gomb("Újra aláírás") + self.ujra_gomb.setToolTip("Ha a gépkulcs már megvan, csak újra aláírja a rendszerbetöltőt, a kernelt és a modulokat.") + self.ujra_gomb.clicked.connect(lambda: self._futtat("resign", "Újra aláírás")) + self.beallit_gomb = gomb("Beállítás", fo=True) + self.beallit_gomb.clicked.connect(self._beallit) + gombok.addWidget(self.frissit_gomb) + gombok.addStretch(1) + gombok.addWidget(self.ujra_gomb) + gombok.addWidget(self.beallit_gomb) + bal.addLayout(gombok) + + bal.addWidget(cimke("NAPLÓ", "h2")) + self.naplo = QPlainTextEdit() + self.naplo.setObjectName("naplo") + self.naplo.setReadOnly(True) + self.naplo.setMinimumHeight(80) + bal.addWidget(self.naplo, 1) + + self.futtato = muveletek.Futtato(self) + self.futtato.sor.connect(self.naplo.appendPlainText) + self.futtato.kesz.connect(self._kesz) + self.adat = {} + + def megjelenik(self, *_): + self._betolt() + + def frissit(self): + ervenytelenit("secureboot") + self._betolt() + + def _betolt(self): + if tarolt("secureboot") is None: + for e in self.ertekek.values(): + e.setText("...") + gyorsitott( + "secureboot", allapot_lekerdez, kesz=self._allapot, + hiba=lambda u: self._hiba(f"Az állapot nem olvasható: {u}"), kor=60, + ) + + def _hiba(self, szoveg): + self.figyelem.setText(szoveg) + self.figyelem.show() + + def _allapot(self, adat): + self.adat = adat or {} + self.figyelem.hide() + if adat is None: + for e in self.ertekek.values(): + e.setText("-") + self._hiba("A Secure Boot beállító (raveos-secureboot-setup) nincs telepítve.") + self._gombok(False) + return + if adat.get("uefi") == "0": + for e in self.ertekek.values(): + e.setText("-") + self._hiba("Ez a gép nem UEFI módban indult, ezért a Secure Boot nem érhető el.") + self._gombok(False) + return + def ki(ertek, igen, nem): + return igen if ertek == "1" else nem if ertek == "0" else "?" + self._beir("secureboot", ki(adat.get("secureboot"), "BE", "KI"), adat.get("secureboot") == "1") + self._beir("setupmode", ki(adat.get("setupmode"), "IGEN", "NEM"), adat.get("setupmode") == "1") + self._beir("keys", ki(adat.get("keys"), "MEGVAN", "NINCS"), adat.get("keys") == "1") + self._beir("signed", ki(adat.get("signed"), "RENDBEN", "HIÁNYZIK"), adat.get("signed") == "1") + if adat.get("pending") == "1": + self._hiba("A beállítás félbemaradt, és a következő újraindításkor magától folytatódik.") + self._gombok(True) + + def _beir(self, kulcs, szoveg, zold): + e = self.ertekek[kulcs] + e.setText(szoveg) + e.setProperty("zold", zold) + e.style().unpolish(e) + e.style().polish(e) + + def _gombok(self, elerheto): + fut = self.futtato.fut() + helper = muveletek.helper_elerheto() + self.beallit_gomb.setEnabled(elerheto and helper and not fut) + self.ujra_gomb.setEnabled(elerheto and helper and not fut and self.adat.get("keys") == "1") + self.frissit_gomb.setEnabled(not fut) + + def _beallit(self): + valasz = QMessageBox.question( + self, + "Secure Boot beállítása", + "A beállítás kulcsokat ír a firmware-be, és aláírja a rendszerbetöltőt és a kernelt. " + "Ha Windows is van a gépen BitLockerrel, előtte függeszd fel a BitLockert.\n\nFolytatod?", + QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No, + QMessageBox.StandardButton.No, + ) + if valasz == QMessageBox.StandardButton.Yes: + self._futtat("setup", "Secure Boot beállítása") + + def _futtat(self, mod, cimke_szoveg): + self.naplo.clear() + self._gombok(False) + self.futtato.indit([muveletek.Lepes(cimke_szoveg, muveletek.root("secureboot", mod))]) + + def _bios_ujrainditas(self, cim, szoveg): + doboz = QMessageBox(self) + doboz.setWindowTitle(cim) + doboz.setText(szoveg) + most = doboz.addButton("Újraindítás a BIOS-ba", QMessageBox.ButtonRole.AcceptRole) + doboz.addButton("Később", QMessageBox.ButtonRole.RejectRole) + doboz.exec() + if doboz.clickedButton() is most: + muveletek.Futtato(self).indit( + [ + muveletek.Lepes( + "Újraindítás a firmware beállításaiba", + ["bash", "-c", "systemctl reboot --firmware-setup || systemctl reboot"], + ) + ] + ) + + def _kesz(self, rendben, _hibasak): + kod = self.futtato.utolso_kod + if rendben: + self._bios_ujrainditas( + "Secure Boot", + "Az aláírások és a kulcsok készen vannak.\n\nA BIOS-ban állítsd a Secure Bootot Enabled-re, " + "majd mentsd el a beállítást és indítsd újra a gépet.", + ) + elif kod == UJRAINDITAS_KELL: + self._bios_ujrainditas( + "Újraindítás szükséges", + "A firmware nincs Setup Mode-ban.\n\nA BIOS-ban a Secure Boot menüben töröld a kulcsokat " + "(Key Management, Clear Secure Boot keys), így a gép Setup Mode-ba kerül. Mentés után indítsd újra " + "a gépet: a beállítás indítás után magától befejeződik.", + ) + else: + QMessageBox.warning(self, "Secure Boot", "A művelet nem sikerült. A részleteket a napló mutatja.") + self.frissit() + + +FUL = SecureBoot |