[PATCH] - HttpUtils - Support von HTTP Digest Authentifizierung

Begonnen von Markus Bloch, 26 Oktober 2015, 21:06:30

Vorheriges Thema - Nächstes Thema

Markus Bloch

Hallo Rudi,

in http://forum.fhem.de/index.php/topic,48112.msg397788.html#msg397788 und http://forum.fhem.de/index.php/topic,46627.msg383571.html#msg383571 zeigt sich, dass die Funktion md5_hex() nicht verfügbar ist.

Dazu muss in HttpUtils.pm die Zeile 9 geändert werden in:

use Digest::MD5 qw(md5_hex);

Kannst du das bitte ändern?

Vielen Dank

Gruß
Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

rudolfkoenig

Habs gemacht.
Kannst du bitte erklaeren, warum das so besser ist?
Ich habe nur eine wage Theorie, und keine Zeit es zu verifizieren.

Markus Bloch

Wenn man bei use ... nicht angibt, welche Funktionen man in den aktuellen Namespace importieren möchte, stehen die Funktionen nur im ursprünglichen Namespace zur Verfügung (in dem Falle Digest::MD5::md5_hex(..) ).

Bei mir tritt dieser Fehler nicht auf, da ein Import auf den Namespace "main" bereits durch andere Module, die bei mir geladen sind, vollzogen wurde.

Gruß
Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

Loredo

Wie genau muss ich denn Digest Auth jetzt anwenden?
Wenn ich es richtig verstehe, dann kann ich einfach wie bei BasicAuth die URL http://user:pass@server/path verwenden und in der Annahme, dass der Server in seiner Antwort dann Digest Auth fordert, wird die selbe Anfrage dann einfach nochmal als DigestAuth geschickt? Auch wenn das "teuer" ist, wäre das zunächst einmal ein Ansatz. Wie würde ich denn direkt ohne Umwege eine Digest Auth Anfrage senden? Und: Wie sollte ich das Session Handling machen? Kann ich dazu einfach etwas aus der ersten Antwort im Device Hash merken und beim nächsten Mal wieder mit übergeben?


Ich werde aus all dem leider nicht so ganz schlau bisher... :-/
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

Markus Bloch

Hallo Loredo,

Digest kann man nicht proaktiv von vornherein "einfordern" vom Server aufgrund der Art und Weise wie Digest funktioniert. Der Client ruft eine Seite auf und der Server fordert vom Client ein sich zu authentifizieren. Der Server teilt in diesem Zuge mit, dass das Verfahren "Digest" zu nutzen ist samt dem Nonce den der Client für die Berechnung der Challenge-Response benötigt. Der Client ist bei der initialen Authentifizierung auf die Antwort des Servers angewiesen um die Challenge-Response zu generieren und kann nicht bereits proaktiv eine Digest Authentifizierung vorab durchführen ohne den Nonce zu kennen.

Sobald der Client sich einmalig authentifiziert hat ist es vom Standard her vorgesehen alle weiteren Anfragen direkt mit Digest zu authorisieren. Dabei muss je nach Quality-Of-Protection ("qop") der Digest bei jedem folgenden Request neu berechnet werden, da ein Nonce-Count bei jedem Request um 1 erhöht wird, welcher in die Berechnung der Antwort mit einfließt. Dadurch können alle weiteren Anfragen an den Server direkt authentifiziert werden, da die jeweiligen Nonce (server-, als auch clientseitig) bekannt sind.

HttpUtils.pm geht hierbei etwas anders vor. Sobald man einen HTTP-Request mit Authentifizierung durchführt wird immer proaktiv eine Basic-Authentifizierung durchgeführt. Sollte der Server auf Digest bestehen, würde in der Antwort (401 Authentication Required) ein entsprechender WWW-Authenticate-Header enthalten sein, der eine Digest-Authentifizierung einleitet. HttpUtils wird darauf dann eine entsprechende Challenge-Response generieren und den Request erneut durchführen.

Die aktuelle Implementierung erlaubt es aktuell nicht, die Authentifizierung im Rahmen von Keep-Alive aufrecht zu erhalten. Dazu müssten entsprechende Daten im Parameter-Hash gespeichert werden, wodurch HttpUtils.pm bei allen folgenden Requests entsprechend der bekannten Nonce-Daten immer einen neuen Digest-Header erzeugt um alle weiteren Requests zu authentifizieren.

Viele Grüße

Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

Loredo

Hallo Markus,


danke für die Erläuterung.


Ich weiß leider nicht, welche Abwandlung genau vom Gerät verwendet wird, da ich es auch selbst nicht besitze.
Ich habe in 70_PHTV lediglich die Möglichkeit eingebaut Username+Passwort mit zu hinterlegen, welches sich die User zuvor beim Pairing separat erstellt haben. Aber offenbar funktioniert die Abfrage mit diesen dann hinterher nicht.


Mal sehen, vielleicht liefert ja einer der User noch ein Logfile nach...




Gruß
Julian
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

Loredo

Hi Markus,

wir sind nun soweit, dass wir das Pairing soweit im Griff haben und nun eigentlich mit gültigen Zugangsdaten authentifizieren würden.
Allerdings scheint das nicht zu funktionieren.

Ich habe daraufhin in HttpUtils einmal die request und response Header beim Zugriff auf einen HTTP Digest Auth Beispielserver mitgeloggt:


2017.02.20 10:03:22.187 4: HttpUtils url=https://user:passwd@httpbin.org:443/digest-auth/auth/user/passwd
2017.02.20 10:03:22.557 4: https://user:passwd@httpbin.org:443/digest-auth/auth/user/passwd: HTTP request header:
GET /digest-auth/auth/user/passwd HTTP/1.1
Host: httpbin.org
User-Agent: fhem
Connection: Close
Authorization: Basic dXNlcjpwYXNzd2Q=
Content-Type: application/json

2017.02.20 10:03:22.671 4: https://user:passwd@httpbin.org:443/digest-auth/auth/user/passwd: HTTP response header:
HTTP/1.1 401 UNAUTHORIZED
Server: nginx
Date: Mon, 20 Feb 2017 09:03:22 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: close
WWW-Authenticate: Digest nonce="65bb11ffe99d63178408c558c26699e0", opaque="099659c62506db1df8051a741085637f", realm="me@kennethreitz.com", qop=auth
Set-Cookie: fake=fake_value
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
2017.02.20 10:03:22.672 4: https://user:passwd@httpbin.org:443/digest-auth/auth/user/passwd: HTTP response code 401
2017.02.20 10:03:22.672 4: HttpUtils url=https://user:passwd@httpbin.org:443/digest-auth/auth/user/passwd
2017.02.20 10:03:23.059 4: https://user:passwd@httpbin.org:443/digest-auth/auth/user/passwd: HTTP request header:
GET /digest-auth/auth/user/passwd HTTP/1.1
Host: httpbin.org
User-Agent: fhem
Connection: Close
Content-Type: application/json
Authorization: Digest nonce="65bb11ffe99d63178408c558c26699e0", response="ce9327f84102be913f67f7615b46822a", uri="/digest-auth/auth/user/passwd", realm="me@kennethreitz.com", nc=00000001, opaque="099659c62506db1df8051a741085637f", cnonce="37d7694490628422aec92a9819f37b08", username="user", qop="auth"

2017.02.20 10:03:23.264 4: https://user:passwd@httpbin.org:443/digest-auth/auth/user/passwd: HTTP response header:
HTTP/1.1 401 UNAUTHORIZED
Server: nginx
Date: Mon, 20 Feb 2017 09:03:23 GMT
Content-Type: text/html; charset=utf-8
Content-Length: 0
Connection: close
WWW-Authenticate: Digest nonce="d34a64f81d3894e41f57baf9ef86ac36", opaque="b4fdc941e867d9037097bb220abdff62", realm="me@kennethreitz.com", qop=auth
Set-Cookie: fake=fake_value
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
2017.02.20 10:03:23.264 4: https://user:passwd@httpbin.org:443/digest-auth/auth/user/passwd: HTTP response code 401


Es scheint so, als wenn auch hier die Authentifizierung nicht funktionieren würde. Im Browser funktioniert es allerdings.
Hast du eine Idee, was hier fehlt?


Gruß
Julian
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

Markus Bloch

Bei httpbin.org funktioniert dies explizit nicht, weil das gesetzte Cookie bei der Authentifizierung nicht durch FHEM mitgeschickt wird. Hier muss man explizit das Cookie mitsenden, damit der Request authorisiert wird.

Gruß
Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

Loredo

Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

Loredo

Hi Markus,


also der Server schickt wohl auf eine Basic-Auth Anfrage keinen 401 Fehler, sondern einen permanenten 403 Fehler (siehe hier). Soweit ich das verstehe ist das eigentlich kein RFC konformes Verhalten, ist aber wohl nunmal so...


Ich werde einmal schauen diesen Teil so zu erweitern, man im Hash angeben kann, ob bei der ersten Anfrage Basic-Auth verwendet werden soll oder nicht. Ich gehe davon aus, dass dann jeder Webserver dann auch korrekt einen 401 zurückschickt und der Rest dann wie gehabt funktionieren kann.




Gruß
Julian
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

Loredo

Hallo Rudi,


anbei ein klitzekleiner Patch, damit man als Modulautor explizit sagen kann, dass HTTP Digest Auth verwendet werden soll.
Es wäre prima, wenn du den Patch übernehmen könntest.




Danke & Gruß
Julian
Hat meine Arbeit dir geholfen? ⟹ https://paypal.me/pools/c/8gDLrIWrG9

Maintainer:
FHEM-Docker Image, https://github.com/fhem, Astro(Co-Maintainer), ENIGMA2, GEOFANCY, GUEST, HP1000, Installer, LaMetric2, MSG, msgConfig, npmjs, PET, PHTV, Pushover, RESIDENTS, ROOMMATE, search, THINKINGCLEANER

rudolfkoenig


Markus Bloch

Hallo Rudi,

im Rahmen von https://forum.fhem.de/index.php/topic,74872.0.html wurde ein Problem mit der Digest-Implementierung in HttpUtils.pm gefunden. Anbei ein Patch zur Behebung mit der Bitte um Änderung.

Index: FHEM/HttpUtils.pm
===================================================================
--- FHEM/HttpUtils.pm   (revision 14892)
+++ FHEM/HttpUtils.pm   (working copy)
@@ -545,7 +545,7 @@
   my ($hash, $header) = @_;
   my %digdata;

-  while($header =~ /(\w+)="?([^"]+?)"?(?:,\s+|$)/gc) {
+  while($header =~ /(\w+)="?([^"]+?)"?(?:\s*,\s*|$)/gc) {
     $digdata{$1} = $2;
   }


Viele Grüße

Markus
Developer für Module: YAMAHA_AVR, YAMAHA_BD, FB_CALLMONITOR, FB_CALLLIST, PRESENCE, Pushsafer, LGTV_IP12, version

aktives Mitglied des FHEM e.V. (Technik)

rudolfkoenig