Version 2.8.18: Versionspruefung im Update, zweiter Anlauf beim Bildschirm

This commit is contained in:
alientim committed 2026-09-13 13:23:41 +02:00
1 parent 4041156a19
commit 051d3bc649
6 files changed
+179 -21

No files matched your search

@@ -11,18 +11,33 @@
import RFB from "../vendor/novnc/core/rfb.js";
// Zwei Eingriffe in private Methoden der mitgelieferten Bibliothek -- beide
// nur, um zu *erfahren*, was schiefging; keiner greift in die Verhandlung ein.
// Bewusst hier und nicht in der Bibliothek selbst: eine neue Fassung von noVNC
// laesst sich dann austauschen, ohne eine Aenderung nachzupflegen -- faellt
// eine Methode weg, entfaellt nur die Auskunft, nicht die Sitzung.
// Drei Eingriffe in private Methoden der mitgelieferten Bibliothek. Bewusst
// hier und nicht in der Bibliothek selbst: eine neue Fassung von noVNC laesst
// sich dann austauschen, ohne eine Aenderung nachzupflegen -- faellt eine
// Methode weg, entfaellt nur die Auskunft, nicht die Sitzung.
//
// Es stand hier einmal ein dritter, der die Wahl des Sicherheitsverfahrens
// umbog: ohne hinterlegte Zugangsdaten sollte ein Verfahren ohne Anmeldung
// gewinnen, weil der Server RA2ne zuerst nennt. Gut gemeint und falsch --
// genau dieser Griff hat eine Sitzung, die lief, zum Abbruch gebracht: der
// RealVNC Server bietet "ohne Authentifizierung" zwar an, legt bei dieser Wahl
// aber auf. Die Reihenfolge des Servers ist seine Entscheidung, nicht unsere.
// Zwei davon holen nur Auskunft (_fail, _socketClose). Der dritte greift in
// die Wahl des Sicherheitsverfahrens ein -- aber erst, **nachdem** eines
// nachweislich nicht getragen hat.
//
// Die Vorgeschichte gehoert dazu, damit niemand den Schritt zurueckgeht: hier
// stand einmal eine Vorauswahl, die ohne hinterlegte Zugangsdaten ein
// Verfahren ohne Anmeldung erzwang, weil RealVNC RA2ne zuerst nennt. Das war
// geraten und falsch. Was jetzt hier steht, ist das Gegenteil einer
// Vermutung: der Server nennt seine Reihenfolge, die gilt -- und wenn seine
// erste Wahl die Verbindung abreissen laesst, ist das ein Befund, auf den man
// antworten darf. Gemessen am Geraet: RealVNC bietet 6 (RA2ne) an, waehlt man
// es, legt es auf; daneben liegt 1 (ohne Authentifizierung), und darueber
// laeuft auch der Viewer.
const istUnterstuetzt = RFB.prototype._isSupportedSecurityType;
//: Verfahren, die in dieser Sitzung schon abgerissen sind.
const gescheitert = new Set();
//: Hoechstens ein zweiter Anlauf. Jeder Versuch ist eine Verbindung, und ein
//: RealVNC Server zaehlt abgebrochene Versuche mit -- wer dreimal anklopft,
//: sperrt sich aus.
const HOECHSTENS = 2;
// Den *Grund* eines Fehlschlags kennt nur ``_fail`` -- das Ereignis
// "disconnect" traegt ihn nicht, und der Weg ueber die Protokollausgabe
// funktioniert nicht: die Bibliothek bindet ``console.error`` beim Laden, also
@@ -72,6 +87,9 @@ function starten(wurzel) {
);
let rfb = null;
let versuche = 0;
let stand = false;
let letzterZugang = {};
function melden(text, art = "") {
zeile.textContent = text;
@@ -86,9 +104,35 @@ function starten(wurzel) {
if (rfb && rfb._rfbAuthScheme > 0) {
teile.push(`gewähltes Verfahren: ${rfb._rfbAuthScheme}`);
}
if (gescheitert.size) {
teile.push(`erfolglos: ${[...gescheitert].join(", ")}`);
}
return teile.join(" · ");
}
// Hat das gewählte Verfahren die Verbindung abreissen lassen? Dann ist das
// ein Befund und keine Vermutung -- der naechste Anlauf laesst es aus.
//
// Nur solange nie ein Bild stand: bricht eine **laufende** Sitzung ab, liegt
// es nicht am Anmeldeverfahren, und ein stiller Neuaufbau wuerde die Ursache
// verdecken.
function naechsterVersuch() {
const verfahren = rfb && rfb._rfbAuthScheme > 0 ? rfb._rfbAuthScheme : 0;
if (!verfahren || versuche >= HOECHSTENS || gescheitert.has(verfahren)) {
return false;
}
gescheitert.add(verfahren);
melden(
`Verfahren ${verfahren} hat die Verbindung nicht getragen – nächster Anlauf ` +
"mit dem nächsten, das der Server anbietet …",
"warnung",
);
const zugang = letzterZugang;
rfb = null;
window.setTimeout(() => verbinden(zugang), 400);
return true;
}
// Steht die WebSocket-Strecke zu TESM überhaupt? Zwei sehr verschiedene
// Ursachen sehen von aussen gleich aus: der VNC-Server mag nicht, oder die
// Verbindung kommt nie zustande, weil ein Proxy zwischen Browser und TESM
@@ -115,9 +159,19 @@ function starten(wurzel) {
}
function verbinden(zugang) {
melden("Verbindung wird aufgebaut …");
melden(versuche ? "Nächster Versuch …" : "Verbindung wird aufgebaut …");
letzterGrund = "";
letzterCode = 0;
letzterZugang = zugang;
versuche += 1;
// Was abgerissen ist, wird nicht noch einmal gewaehlt. Sonst faende noVNC
// dasselbe Verfahren wieder zuerst -- und der zweite Anlauf waere eine
// Wiederholung des ersten.
RFB.prototype._isSupportedSecurityType = function (typ) {
if (gescheitert.has(typ)) return false;
return istUnterstuetzt.call(this, typ);
};
rfb = new RFB(leinwand, adresse, {
credentials: zugang,
@@ -131,6 +185,7 @@ function starten(wurzel) {
rfb.focusOnClick = true;
rfb.addEventListener("connect", () => {
stand = true;
melden(`Verbunden mit ${wurzel.dataset.ziel}`, "ok");
abfrage.hidden = true;
leinwand.hidden = false;
@@ -144,6 +199,8 @@ function starten(wurzel) {
knopfStrg.hidden = true;
if (ereignis.detail && ereignis.detail.clean) {
melden("Sitzung beendet.");
} else if (!stand && naechsterVersuch()) {
return;
} else {
const erklaerung = grund();
melden(
@@ -21,14 +21,25 @@ Datei -- mit Grund und Fundstelle, damit ein Wechsel auf eine neuere Fassung
nicht stillschweigend darueberlaeuft.
**Was TESM von aussen umbiegt** (also *nicht* in diesen Dateien steht, sondern
in `js/screen.js`): `RFB.prototype._isSupportedSecurityType` wird ueberschrieben,
solange keine Zugangsdaten vorliegen und der Server ein Verfahren ohne
Anmeldung anbietet. Grund: noVNC nimmt "das erste, das ich kann, in der
Reihenfolge des Servers"; ein RealVNC Server nennt RA2ne vor "ohne
Authentifizierung", und der Browser liefe in eine Passwortabfrage, obwohl
daneben der Weg offensteht, den auch der RealVNC Viewer nimmt. Faellt die
Methode in einer neueren Fassung weg, greift die Vorauswahl nicht mehr -- die
Sitzung laeuft dann wie ohne sie, es bricht nichts.
in `js/screen.js`):
* `RFB.prototype._fail` und `_socketClose` -- nur, um den Grund eines
Abbruchs zu erfahren. noVNC meldet ihn sonst ausschliesslich in die
Entwicklerkonsole, und `console.error` mitzulesen traegt nicht: die
Bibliothek bindet es beim Laden.
* `RFB.prototype._isSupportedSecurityType` -- **erst nachdem** ein Verfahren
die Verbindung nachweislich hat abreissen lassen. Dann wird es fuer den
zweiten Anlauf ausgelassen, damit noVNC nicht wieder dasselbe zuerst findet.
Hoechstens zwei Anlaeufe, denn jeder ist eine Verbindung, und ein RealVNC
Server zaehlt abgebrochene mit.
Hier stand einmal das Gegenteil: eine **Vorauswahl**, die ohne hinterlegte
Zugangsdaten ein Verfahren ohne Anmeldung erzwang. Das war geraten und hat
eine laufende Sitzung gebrochen. Der Unterschied ist nicht der Code, sondern
der Anlass: eine Vermutung vorher gegen einen Befund hinterher.
Faellt eine dieser Methoden in einer neueren Fassung weg, entfaellt nur die
Auskunft bzw. der zweite Anlauf -- die Sitzung laeuft wie ohne sie.
**Was noVNC an Sicherheitsverfahren spricht** (`core/rfb.js`,
`_isSupportedSecurityType`): `1` None, `2` VNC-Passwort, `6` RA2ne (RSA-AES