diff --git a/apps/tesm/pyproject.toml b/apps/tesm/pyproject.toml index 88b8615..300bd98 100644 --- a/apps/tesm/pyproject.toml +++ b/apps/tesm/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "tesm" -version = "2.8.22" +version = "2.8.23" description = "TESM -- Verwaltung und Ueberwachung von PoE-Endgeraeten und Aruba-Switchen" requires-python = ">=3.11" dependencies = [ diff --git a/apps/tesm/src/tesm/templates/tesm/screen.html b/apps/tesm/src/tesm/templates/tesm/screen.html index 85d83a7..55da0bd 100644 --- a/apps/tesm/src/tesm/templates/tesm/screen.html +++ b/apps/tesm/src/tesm/templates/tesm/screen.html @@ -51,7 +51,9 @@ action="{{ url_for('screen.probe', device_id=device.id) }}"> diff --git a/packages/tesm-core/pyproject.toml b/packages/tesm-core/pyproject.toml index ba907d0..d78849c 100644 --- a/packages/tesm-core/pyproject.toml +++ b/packages/tesm-core/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "tesm-core" -version = "2.8.12" +version = "2.8.13" description = "Gemeinsames Anwendungsgeruest (Auth, RBAC, Navigation, Design-System, Migrationen) fuer TESM und TESM-Lizenzserver" requires-python = ">=3.11" dependencies = [ diff --git a/packages/tesm-core/src/tesm_core/static/tesm_core/js/screen.js b/packages/tesm-core/src/tesm_core/static/tesm_core/js/screen.js index 01953c8..235bcff 100644 --- a/packages/tesm-core/src/tesm_core/static/tesm_core/js/screen.js +++ b/packages/tesm-core/src/tesm_core/static/tesm_core/js/screen.js @@ -66,6 +66,24 @@ const HOECHSTENS = 2; //: jedes Ereignis, und die Seite stuende stumm bis zum Seitenwechsel. const AUFBAU_GRENZE = 12000; +//: Verfahren, die im Browser keinen Schluesseltausch kosten. +//: +//: Der Grund steht in der Bibliothek, `core/ra2.js`: fuer RA2ne erzeugt der +//: **Browser** bei jeder Sitzung ein eigenes 2048-Bit-RSA-Schluesselpaar, in +//: JavaScript. Die Primzahlsuche dafuer dauert ein bis drei Minuten -- genau +//: die Zeit, die zwischen Klick und Bild lag. "Ohne Authentifizierung" (1) +//: kostet davon nichts. +//: +//: Deshalb kommt es zuerst, **wenn der Server es anbietet** und wir nicht +//: ohnehin schon wissen, was hier traegt. Das ist nicht dieselbe Vorauswahl +//: wie in 2.8.14: die war geraten, diese steht auf einer Messung. Traegt sie +//: nicht, nimmt der zweite Anlauf die Reihenfolge des Servers -- dann dauert +//: es eben. +const OHNE_SCHLUESSELTAUSCH = new Set([1]); + +//: RA2ne. Wird es ausgehandelt, ist die Wartezeit erklaerbar und kein Fehler. +const RA2NE = 6; + //: Tastenkombinationen, die der Arbeitsplatz selbst abfaengt und die deshalb //: einen Knopf brauchen. X11-Keysyms. const ALT_LINKS = 0xffe9; @@ -196,6 +214,17 @@ export function starteSitzung(wurzel, quelle) { versuche += 1; window.clearTimeout(aufbauUhr); aufbauUhr = window.setTimeout(() => { + // Ein ausgehandeltes RA2ne ist kein Fehler, sondern Rechenzeit: der + // Browser erzeugt dafuer gerade einen 2048-Bit-Schluessel. Das zu + // melden ist das Gegenteil einer Warnung -- es nimmt die Sorge. + if (rfb && rfb._rfbAuthScheme === RA2NE) { + melden( + "Der Server verlangt RA2ne (RSA-AES). Dafür erzeugt der Browser ein " + + "2048-Bit-Schlüsselpaar – das dauert ein bis drei Minuten. Bitte warten.", + "warnung", + ); + return; + } melden("Es kommt keine Antwort. Wird geprüft, woran es liegt …", "warnung"); streckeTesten().then((steht) => { melden( @@ -212,18 +241,28 @@ export function starteSitzung(wurzel, quelle) { }); }, AUFBAU_GRENZE); - // Zwei Regeln, beide aus Erfahrung und keine aus Vermutung: + // Drei Regeln, alle aus Messung und keine aus Vermutung: // - // 1. Was schon einmal getragen hat, kommt zuerst -- aber nur beim ersten - // Anlauf. Ohne das faengt jede Sitzung wieder mit der ersten Wahl des - // Servers an, die hier schon abgerissen ist, und ein sperrender - // RealVNC Server laesst sich mit der Absage Minuten Zeit. - // 2. Was abgerissen ist, wird nicht noch einmal gewaehlt. + // 1. Was schon einmal getragen hat, kommt zuerst. + // 2. Sonst das Verfahren ohne Schluesseltausch -- aber nur, wenn der + // Server es nachweislich anbietet (sonst faende noVNC gar keines und + // scheiterte sofort). RA2ne kostet sonst ein bis drei Minuten + // Rechenzeit im Browser, jedes Mal. + // 3. Was abgerissen ist, wird nicht noch einmal gewaehlt. + // + // Beides gilt nur fuer den **ersten** Anlauf; danach zaehlt die + // Reihenfolge des Servers, abzueglich dessen, was schon abgerissen ist. const bewaehrt = daten.bewaehrt || 0; - const zuerst = versuche === 1 && bewaehrt > 0 && !gescheitert.has(bewaehrt); + const angeboten = daten.verfahren || []; + const schnell = angeboten.filter((typ) => OHNE_SCHLUESSELTAUSCH.has(typ)); + let bevorzugt = 0; + if (versuche === 1) { + if (bewaehrt > 0 && !gescheitert.has(bewaehrt)) bevorzugt = bewaehrt; + else if (schnell.length && !gescheitert.has(schnell[0])) bevorzugt = schnell[0]; + } RFB.prototype._isSupportedSecurityType = function (typ) { if (gescheitert.has(typ)) return false; - if (zuerst) return typ === bewaehrt; + if (bevorzugt) return typ === bevorzugt; return istUnterstuetzt.call(this, typ); };