Forum: PC-Programmierung TCP/IP Authentication Problem


von Jürgen W. (lovos)


Lesenswert?

Hallo,
ich habe ein Problem:
Ich poste zu einem Embedded Webserver eine 1MB-Datei.
Dieser Webserver funktioniert schon seit einigen Jahren sehr gut und 
stabil, es ist aber möglich, dass er noch ein paar Probleme hat.
Bevor man zu der Uploadseite kommt, muss man sich einloggen und bei dem 
Post werden die Credentials dann mitgeschickt (digest).
Der Safari-Webbrowser macht das nicht. Er probiert immer einen Zugriff 
ohne Authentifizierung und schickt sie erst nach einem 401 Error.
Genau da ist das Problem: Der Safari fängt an zu posten und nach ein 
paar Kb schickt der Embedded Webserver eine 401-Meldung.
Irgendwie versteht das der Safari diese nicht und ich bin beim Suchen 
woran das liegt.
(Ich würde erwarten, dass der Safari nach der 401-Botschaft den Post 
wiederholt mit den Credentials im Header, so wie es bei allen anderen 
geschützten Websiten auch macht)

Müsste der Embedded Webserver abwarten, bis der komplette Upload fertig 
ist, bevor er die 401-Meldung schickt?
Muss der Webserver das PSH-, FIN- oder RST-Flag setzen, wenn er schon 
den POST des Client abbricht?

Bei Wireshark/Analyze/Follow TCP Stream sieht das so aus:
1
POST update.html HTTP/1.1
2
Host: 192.168.1.1
3
Origin: http://192.168.1.1
4
Content-Length: 800723
5
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_5_8) Version/5.0.6 Safari/533.22.3
6
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryFOqmS9nBVqEBbKLF
7
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
8
Referer: http://192.168.1.1/update.html
9
Accept-Language: de-de
10
Accept-Encoding: gzip, deflate
11
Connection: keep-alive
12
13
------WebKitFormBoundaryFOqmS9nBVqEBbKLF
14
Content-Disposition: form-data; name="dateiupdate"; filename="file.gz"
15
Content-Type: application/x-gzip
16
17
....B..L..yyyzzz.elf.S19..}Y..*.....{a.>.....^.......y3.....0f.B.B.......w...
18
.....~kiHTTP/1.0 401 Unauthorized
19
Server: embeddedServer
20
Connection: close 
21
Content-Type: text/html 
22
WWW-Authenticate: Digest realm="xxxxx", nonce=xxxx, qop="xxxx"
23
24
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"><html><head>
25
<meta name="generator" content="HTML Tidy for Windows (vers 1st April 2002), see www.w3.org">
26
<title>401 Unauthorized</title></head><body>



Das erste Paket zu der 401-Botschaft hat FIN gesetzt, vorher wurden ganz 
normal die Pakete des Client mit ACKs bestätigt.
1
Header length: 20 bytes
2
Flags: 0x11 (FIN, ACK)

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Also du wirfst hier einiges durcheinander. HTTP spielt sich oberhalb von 
TCP ab.
Zum POST request gehören natürlich auch die Daten dazu, die kannst du 
natürlich ignorieren aber nicht mittendrin die (TCP) Verbindung canceln.

Wie sich einzelne Operationen verhalten sollen steht in der zugehörigen 
RFC für HTTP (http://tools.ietf.org/html/rfc2616), das alles darf aber 
keinesfalls Auswirkungen auf die Transportschicht (TCP/IP) haben!


Jürgen G. schrieb:
> Müsste der Embedded Webserver abwarten, bis der komplette Upload fertig
> ist, bevor er die 401-Meldung schickt?
Die Antwort darf er vorher senden, nur lesen sollte er den Request auf 
jedenfall zu ende!

> Connection: close
ist bei HTTP 1.0 nicht definiert wenn ich mich recht erinnere. Auch 
müßte man mal schauen ob ein HTTP 1.0 Server bei einer HTTP 1.1 
Anfrage nicht mit dem Status "505 HTTP Version Not Supported" antworten 
sollte. (edit: Das ist so okay, der Client sagt nur die höchste Version 
welche er versteht, der Server darf "downgraden")

Mal interessehalber: Warum forderst du nicht schon beim GET eine 
Autorisation?

von Εrnst B. (ernst)


Lesenswert?

Dafür gabs doch eigentlich die "Expect: 100-continue" header, mit der 
der Browser mitteilt dass er erst wissen will ob der Server den 
Datenwust überhaupt haben will, bevor der Upload losläuft.

Dummerweise muss der Client das initiieren, der Server hat da keinen 
direkten Einfluss drauf.

Pragmatische Lösung:
Pack in die Upload-Form noch hidden-input-felder mit Session-ID oder 
Username/passwort.
Akzeptier die anstelle des Digest-Auth beim Fileupload.
Unsicherer wird es dadurch nicht.

von Jürgen W. (lovos)


Lesenswert?

Läubi .. schrieb:
> Mal interessehalber: Warum forderst du nicht schon beim GET eine
> Autorisation?

Tue ich ja. Aber der Safari schickt dann trotzdem den Post ohne 
Autorisation weg.
Dieses Problem habe ich NUR mit Safari-Browser. Alle anderen 
funktionieren.



Ich habe das ganze unter Apache ausprobiert. D.h. ich schicke vom Safari 
eine grosse Datei zum Apache-PC. Die Upload-Seite ist Digest gesichert.

Zunächst mal musste ich in der Apache-Konfiguration
1
KeepAlive Off
stellen, da mit KeepAlive Connections der Safari sich wie Firefox 
verhält, d.h. Credentials werden automatisch mitgeliefert.


Der Firefox liest den gesamten Post, bevor er 401 schickt, auch bei ganz 
grossen Dateien (30MB).


>natürlich ignorieren aber nicht mittendrin die (TCP) Verbindung canceln.

Naja, ich dachte vielleicht hat TCP da eine Back-door.

von Nico S. (nico22)


Lesenswert?

Jürgen G. schrieb:
> d.h. Credentials werden automatisch mitgeliefert.

Und daran ist was das Problem?

von Jürgen W. (lovos)


Lesenswert?

Nico Sch. schrieb:
> Jürgen G. schrieb:
>> d.h. Credentials werden automatisch mitgeliefert.
>
> Und daran ist was das Problem?


Mit der Apache-Umgebung will ich nur wissen, wie sich ein Webserver 
korrekt zu verhalten hat, wenn er einen Post wegen fehlender 
Authorization abweisen muss.
Da der Apache default KeepAlive Connections verwendet, hat sich der 
Safari anders verhalten, insofern, dass er die Authorization schon bei 
allen Anfrage beim ersten Mal mitgeliefert hat.

Das musste ich ändern, da ich wollte, dass sich der Safari dem Apache 
gegenüber GENAUSO verhält, wie dem Embedded Webserver gegengüber.
Deshalb habe ich beim Apache KeepAlive abgeschaltet.

Ich beobachtete, dass der Apache den gesamten (nicht authorisierten) 
Datenwust eingelesen hat, bevor er 401-Antwort schickte.

Mein Problem ist jetzt, dass ich den Embedded-Server auch ändern muss, 
dass er auch alles einliest bis er 401 schickt (was nicht einfach sein 
wird, Code von Vorgängern),
oder eine andere Lösung wie ernst mit Hidden Fields angedeutet hat.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Gibt es eigentlich einen Grund weswegen der Embedded Server kein 
keep-alive implementiert? Ansonsten ist das natürlich ein nicht so 
schönes Verhalten vom Safari...

Außerdem solltest du wenn möglich den Embedded-Server http/1.1 Konform 
machen:
http://www8.org/w8-papers/5c-protocols/key/key.html
Dann dürftest du nämlich auch "Expect and 100 (Continue)" nutzen, was 
genau für solche Fälle gedacht ist.
Dafür benötigt man aber meine ich eine keep-alive Verbindung, und das 
wird auch der Unterschied sein weswegen es ohne keep-alive nicht 
wirklich rund läuft.

von Jürgen W. (lovos)


Lesenswert?

Läubi .. schrieb:
> Gibt es eigentlich einen Grund weswegen der Embedded Server kein
> keep-alive implementiert?

Er soll warscheinlich kurz und kompakt sein.
Mich wúrde interessieren, wie das andere Embedded Server handeln, z.B. 
lwip (Lightweight IP). Weiß das jemand?

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Jürgen G. schrieb:
> Mich wúrde interessieren, wie das andere Embedded Server handeln

Einfach mal bei denen nachschauen? ;)

Jürgen G. schrieb:
> Er soll warscheinlich kurz und kompakt sein.

Dann muss man das aber auch bis zum ende durchziehen! Das Implementierte 
Verfahren funktioniert zumindest nur mit HTTP/1.1 ggf. wird keep-alive 
benötigt (zumindest scheint der Safari das zu benötigen).

Jürgen G. schrieb:
> Mein Problem ist jetzt, dass ich den Embedded-Server auch ändern muss

Was ist das den für ein Gerät? Es ist ja nicht so, dass es nicht schon 
fertige Webserver gäbe, in dem Bereich was "richtiges" zu bauen ist 
schwer weil der Teufel oft im Detail steckt wie du schon festgestellt 
hast.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.