HttpUtils: "Can't connect to foo:bar: " ohne Fehlermeldung $@

Begonnen von Dr. Boris Neubert, 02 Oktober 2014, 22:22:47

Vorheriges Thema - Nächstes Thema

Dr. Boris Neubert

Hallo,

im Thread http://forum.fhem.de/index.php?topic=27524 hat eine Anwenderin das Problem, dass eine ical-Datei nicht von www.google.com:443 heruntergeladen werden kann. Die Meldung lautet

2014.10.02 21:12:29 1: Calendar Kalender_Haus: Could not retrieve file at URL. <hidden>: Can't connect to https://www.google.com:443:

Hinter dem letzten Doppelpunkt fehlt die Fehlermeldung. Die Meldung wird in HttpUtils.pm in Zeile 172 generiert. Offenbar wird $@ nicht gesetzt oder ist bereits gelöscht oder überschrieben.

Die Vermutung liegt nahe, dass die Ursache ein Problem bei der SSL-Verbindung mit IO::Socket:SSL ist. Das Perl-Modul ist vorhanden und aktuell.

Wenn es ein Ladeproblem wäre, stünde aufgrund Zeile 162 etwas im Log (der Aufruf kommt aus Calendar ohne explizites Loglevel; es greift der Default 4; verbose steht auf 5). Das ist nicht der Fall. Ich glaube, dass wir eine Fehlerbedingung in start_SSL in Zeile 166 nicht sehen, weil wir $SSL_ERROR (siehe http://search.cpan.org/~sullr/IO-Socket-SSL-1.998/lib/IO/Socket/SSL.pod#DESCRIPTION) nicht auswerten. Bevor ich die Anwenderin mit weiteren Codeänderungen traktiere, möchte ich mir erstmal hier eine Zweitmeinung einholen.

Off-topic: mir ist auch aufgefallen, dass die HttpUtils-Routinen zum Abholen im Fehlerfall als zweites Argument nicht durchgängig undef zurückliefern, wenn nichts abgeholt werden konnte, sondern überwiegend aber nicht immer "". M.E. sollte "" nur zurückgeliefert werden, wenn ein leeres Ergebnis empfangen wurde.

Viele Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

rudolfkoenig

Danke fuer den Hinweis. Jetzt wird SSL_ERR zurueckgeliefert, falls @_ leer ist, und https gesetzt ist.

Das die Routinen in Fehlerfall nicht durchgaengig undef fuer die Daten zurueckliefern ist zwar nicht schoen, aber ich bin nicht 100% sicher, dass ich keine Nebeneffekte erzeuge, falls ich es umstelle. Meiner Ansicht nach sollte man nur dann auf die Daten zugreifen, falls $err nicht gesetzt ist.

Auch off-topic: CustomGetFileFromURL setzt ab sofort loglevel auch auf 4, falls es nicht spezifiziert wurde.

Dr. Boris Neubert

Danke.

Calendar umgebaut, erkennt jetzt einen Fehler, wenn der Rückgabewert undefiniert oder "" ist oder wenn die Fehlermeldung nicht "" ist.

Viele Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

Dr. Boris Neubert

Hallo,

die Anwenderin bekommt immer noch keine Fehlermeldung hinter dem Doppelpunkt.

Ich habe mir daraufhin HttpUtils genauer angesehen:

  • In Zeile 172 ist die Connection nicht gesetzt.
  • Aus Zeile 161ff kommt kein Fehler.
  • Vermutung: wir gehen schon ohne gesetzte Connection in HttpUtils_Connect2() hinein.
  • Der Aufruf von HttpUtils_Connect2() muss wohl aus Zeile 153 kommen, da wir ein BlockingGet (kein Callback) haben.
  • Zuvor wird der else-Zweig aufgerufen, Zeile 150, und der geht möglicherweise schief, ohne dass wir davon erfahren, weil es keine Fehlermeldung aus Zeile 151 gibt.

Ich möchte die Anwenderin bitten, nach Zeile 151 eine Logmeldung einzubauen.

Woher bekomme ich die Fehlermeldung, die IO::Socket::INET->new() vermutlich erzeugt?


Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

rudolfkoenig

ZitatIch möchte die Anwenderin bitten, nach Zeile 151 eine Logmeldung einzubauen.

Erledigt.
Ich vermute dass die SSL Routine einen Systemcall absetzt, der die globale Variable errno loescht, aber SSL_ERR nicht setzt. Wenn das stimmt, dann waere die richtige Loesung, genau wie von dir vorgeschlagen, die Fehlermeldung in der Zeile 151 zu generieren.


ZitatWoher bekomme ich die Fehlermeldung, die IO::Socket::INET->new() vermutlich erzeugt?

Wenn mein Patch nicht hilft, dann faellt mir nur strace ein.

betateilchen

Zitat von: Dr. Boris Neubert am 04 Oktober 2014, 18:34:52
Woher bekomme ich die Fehlermeldung, die IO::Socket::INET->new() vermutlich erzeugt?

Meinst  Du sowas?


$socket = new IO::Socket::INET (
LocalHost => '127.0.0.1',
LocalPort => '5000',
Proto => 'tcp',
Listen => 5,
Reuse => 1
) or die "ERROR in Socket Creation : $!\n";


Sollte sich vielleicht über ein eval abfangen lassen?
-----------------------
Formuliere die Aufgabe möglichst einfach und
setze die Lösung richtig um - dann wird es auch funktionieren.
-----------------------
Lesen gefährdet die Unwissenheit!

Dr. Boris Neubert

Hallo,

Ariane hat, nachdem $SSL_ERR nicht gesetzt wurde, selbst Hand angelegt und herausgefunden, wie man doch noch eine Fehlermeldung herauskitzeln kann:

    IO::Socket::SSL::errstr()

Genaueres hat Sie nicht geschrieben. Aber vielleicht magst Du, Rudi, das noch an geeigneten Stellen einbauen.

Viele Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

rudolfkoenig

SSL_ERR war vermutlich nicht gesetzt, da die Variable laut Doku SSL_ERROR heisst.
Ich gebe jetzt in SSL-Fall entweder SSL_ERROR, oder falls nicht gesetzt, dann IO::Socket::SSL::errstr() zusaetzlich zum $@ aus.

Dr. Boris Neubert

Hallo,

hier: http://forum.fhem.de/index.php/topic,27524.msg220921.html#msg220921 gibt es noch einen wichtigen Hinweis, warum die SSL-Utils auf manchen Systemen nicht funktionieren. Offenbar wird SSLv2 angefordert und von der Gegenseite nicht unterstützt - zu Recht, da SSLv2 wegen Sicherheitslücken nicht mehr eingesetzt werden sollte.

Mögliche Lösung (dort vorgeschlagen, von mir ungetestet):

IO::Socket::SSL->start_SSL($hash->{conn}, SSL_version =>'SSLv3', Timeout=>$hash->{timeout})

Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

rudolfkoenig

Ich haette gerne ein Tipp, ob ich die Aenderung unkonditional oder abschaltbar einbauen soll.
Koennen alle gegenstellen SSLv3? Kann jede FHEM-Installation SSLv3? Und wenn abschaltbar: wie?

Dr. Boris Neubert

Hallo,

ich habe von dem Thema keinen Plan. Aber ich habe jetzt mal die Doku zu IO::Socket::SSL gelesen und meine Hypothese widerlegt, dass SSLv2 angefordert würde aber abgelehnt wird. Die Doku trifft nämlich die für mich etwas verwirrende Aussage:

ZitatThe default SSL_version is 'SSLv23:!SSLv3:!SSLv2' which means, that the handshake format is compatible to SSL2.0 and higher, but that the successful handshake is limited to TLS1.0 and higher, that is no SSL2.0 or SSL3.0 because both of these versions have serious security issues and should not be used anymore. You can also use !TLSv1_1 and !TLSv1_2 to disable TLS versions 1.1 and 1.2 while still allowing TLS version 1.0.

Der User aus dem Board nebenan hat also SSLv3 explizit zugelassen, weil sein System offensichtlich TLS1.0 und höher nicht kann. Dazu sagt die Doku:

ZitatSupport for 'TLSv1_1' and 'TLSv1_2' requires recent versions of Net::SSLeay and openssl.

Möglicherweise fehlt das dem User auf seinem Cubietruck3.

So not our problem?

Ich lasse das erstmal den User ausprobieren, bevor wir hier rummachen.

Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

Dr. Boris Neubert

Hallo,

also der User hat alle benötigte Software da.

Wenn er keine Vorgaben zur SSL-Version macht, geht es nicht. Wenn er den vorgeblichen Default per

SSL_version =>'SSLv23:!SSLv3:!SSLv2'

explizit angibt, funktioniert es. Er hat Debian 7.7 mit Perl 5.14.2 auf Cubietruck. Ich habe Debian 7.6 mit Perl 5.14.2 auf Raspberry und ich brauche die Angabe der SSL_version nicht.

Ich schlage vor, die Version explizit mit aufzunehmen. Wenn die obige Version der Default ist, sollte das nicht schaden.

Viele Grüße
Boris


Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

rudolfkoenig


Dr. Boris Neubert

Hallo Rudi,

ich habe den Commit in HttpUtils.pm nicht gefunden. Ich glaube, Du hast eine neue Variable SSL_version in TcpServerUtils.pm eingebaut und in HttpUtils.pm nicht genutzt.

Viele Grüße
Boris
Globaler Moderator, Developer, aktives Mitglied des FHEM e.V. (Marketing, Verwaltung)
Bitte keine unaufgeforderten privaten Nachrichten!

rudolfkoenig

In der Tat. Habs in HttpUtils nachgezogen, kurz getestet und eingecheckt.