Telopt STARTTLS: weitere Ausgaben unterbinden.
Die Pruefung auf eine aktive Verhandlung in logon2()
ging irgendwann verloren und wurde wieder ergaenzt.
Ausserdem an zwei Stellen im Telnegshandler pruefen, ob
eine Verhandlung laeuft.
Change-Id: I15333d719c7f53c187f52e4fdc28b04fbce8d8e9
diff --git a/secure/login.c b/secure/login.c
index bd8726e..d51402a 100644
--- a/secure/login.c
+++ b/secure/login.c
@@ -169,26 +169,6 @@
tls_init_connection(this_object(), #'tls_init_callback);
}
-// Wenn der Client via STARTTLS eine TLS negotiation angestossen hat und
-// die noch laeuft, darf keine Ausgabe erfolgen. In diesem Fall wird das
-// Loginverfahren ausgesetzt, bis die TLS-Verhandlung abgeschlossen ist.
-// Danach wird es fortgesetzt bzw. neugestartet. Dies gilt auch fuer Fall,
-// dass STARTTLS verhandelt wurde, aber die TLS-Verhandlung noch nicht
-// laeuft. (Bemerkung: beides pruefen ist nicht ueberfluessig. Den Zustand
-// der Telnet-Option muss man pruefen, weil der Client evtl. seine
-// Verhandlung noch nicht signalisiert hat (FOLLOWS vom Client) und die
-// efun muss man pruefen, weil nach Empfang von FOLLOWS vom Client der
-// Status der Telnet-Optiosn resettet wurde - standardkonform.)
-private int check_tls_negotiation()
-{
- struct telopt_s s_tls = query_telnet_neg()[TELOPT_STARTTLS];
- if (tls_query_connection_state(this_object()) < 0
- || (structp(s_tls) && s_tls->state->remoteside) )
- return 1;
-
- return 0;
-}
-
/*
* This is the function that gets called by /secure/master for every user
*/
@@ -348,6 +328,10 @@
int i, arg;
mixed txt;
+ // ggf. muss TLS (initiiert durch STARTTLS) noch ausverhandelt werden.
+ if (check_tls_negotiation())
+ return;
+
if ( !str || str == "" ){
write( "Abbruch!\n" );
destruct( this_object() );
diff --git a/secure/telnetneg.c b/secure/telnetneg.c
index 1b175a5..f6f254b 100644
--- a/secure/telnetneg.c
+++ b/secure/telnetneg.c
@@ -138,7 +138,8 @@
return efun::binary_message(arr, bm_flags);
}
-protected varargs int send_telnet_neg_str(bytes str, int bm_flags) {
+protected varargs int send_telnet_neg_str(bytes str, int bm_flags)
+{
#ifdef __DEBUG__
// Debugausgaben zur Zeit nur fuer arraybasierte Variante
return send_telnet_neg(to_array(str), bm_flags);
@@ -171,6 +172,28 @@
#endif // __DEBUG__
}
+// Wenn der Client via STARTTLS eine TLS negotiation angestossen hat und
+// die noch laeuft, darf keine Ausgabe erfolgen. In diesem Fall wird das
+// Loginverfahren ausgesetzt, bis die TLS-Verhandlung abgeschlossen ist.
+// Danach wird es fortgesetzt bzw. neugestartet. Dies gilt auch fuer Fall,
+// dass STARTTLS verhandelt wurde, aber die TLS-Verhandlung noch nicht
+// laeuft. (Bemerkung: beides pruefen ist nicht ueberfluessig. Den Zustand
+// der Telnet-Option muss man pruefen, weil der Client evtl. seine
+// Verhandlung noch nicht signalisiert hat (FOLLOWS vom Client) und die
+// efun muss man pruefen, weil nach Empfang von FOLLOWS vom Client der
+// Status der Telnet-Optiosn resettet wurde - standardkonform.)
+protected int check_tls_negotiation()
+{
+ struct telopt_s s_tls = TN[TELOPT_STARTTLS];
+ if (tls_query_connection_state(this_object()) < 0
+ || (structp(s_tls) && s_tls->state->remoteside) )
+ {
+ debug_message("In TLS negotiation.\n");
+ return 1;
+ }
+ return 0;
+}
+
// Startet eine Verhandlung, um den Status einer Option zu aendern.
// Wenn bereits eine Verhandlung laeuft, wird nichts gemacht und -1
// zurueckgeben.
@@ -182,6 +205,12 @@
// DO : Option soll auf der anderen Seite eingeschaltet werden.
// DONT: Option soll auf der anderen Seite ausgeschaltet werden.
protected int do_telnet_neg(int option, int action) {
+
+ // ggf. muss TLS (initiiert durch STARTTLS) noch ausverhandelt werden. In
+ // dem Fall nix verhandeln/senden, was nicht STARTTLS ist.
+ if (option != TELOPT_STARTTLS && check_tls_negotiation())
+ return 0;
+
struct telopt_s opt = TN[option];
if (!structp(opt))
{
@@ -735,6 +764,11 @@
{
DTN("recv_tn: ", ({IAC, command, option}) + (optargs||({})));
+ // ggf. muss TLS (initiiert durch STARTTLS) noch ausverhandelt werden. In
+ // dem Fall muessen wir alles ignorieren, was nicht STARTTLS ist.
+ if (option != TELOPT_STARTTLS && check_tls_negotiation())
+ return;
+
struct telopt_s opt = TN[option];
if (!structp(opt))
{