httpS-Request

Alle Fragen zur Netzwerkkommunikation
Benutzeravatar
m.fuchs
Lazarusforum e. V.
Beiträge: 2636
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: httpS-Request

Beitrag von m.fuchs »

Zeig doch mal ein wenig Quellcode. Vielleicht kann man dann mehr dazu sagen.
BTW: Zeigt dir heaptrc irgendwas an?
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: httpS-Request

Beitrag von Christian »

Du hattest nach einer Möglichkeit gefragt den Thread abzubrechen. Darauf habich mit .Free geantwortet.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 394
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: httpS-Request

Beitrag von MitjaStachowiak »

Ok, hier ist etwas Code rund um die Methode. Also StateReport stellt den übergebenen Text in einem Label dar, sodass man im Programm immer sieht, wo der Zweitthread gerade steht. Wenn ich das Programm mit HTTPS laufen lasse, steht da irgendwann nur noch "Upload". Es muss also HTTPGetText sein, das sich aufhängt.

Code: Alles auswählen

   Updating := false;
   Exclude(s);
   if (Protocol <> 'https://') then begin CreateChecksum; DoSeq; end;
 
   Str.Clear;
   StateReport('Upload');
   Success := HttpGetText(Protocol + Adress + '?' + s,Str);
   StateReport('Checksumme prüfen...');
   if (Success) then begin
    if (Str.Count <> 1) then Success := false
    else begin
     s := '';
     for i := 1 to Length(Str[0]) do if (Str[0][i] = '&') then break else s := s + Str[0][i];
     if (s = 'UPLOADED') then begin
 
 
[...]
 
procedure StateReport(const State : AnsiString);
begin
 _ConnState := State;
 Synchronize(@ConnState);
end;
 



Dieses Bug zu finden dürfte anstrengend werden. Mit heaptrc habe ich noch nicht gearbeitet. Außerdem stürzt das Programm ja nicht ab, der Mainthread läuft weiter und schreibt immer weiter Requests in die Warteschleife. Ich denke, die einfachste Lösung ist es, den hängenden Thread neu zu starten. Ich brauche also entweder eine weitere Containerklasse, oder ich mache das per Konvention, also dass man die klasse nicht direkt erzeugt, sondern eine Methode aufruft, die einen Pointer auf einen Pointer auf die Klasse ausspuckt. Dann kann ich einfach den zweiten Pointer neu setzen, wenn ich eine neue Instanz erzeugen muss.

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 394
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: httpS-Request

Beitrag von MitjaStachowiak »

So, im Prinzip habe ich alles Nötige einprogrammiert. Jedoch kannn ich den hängenden Thread eben nicht mit .Free freigeben.

Ich habe testweise folgenden Codezeile im zweiten Thread eingebaut:

Code: Alles auswählen

if (GetTickCount mod 20 = 0) then while (1 = 1) do sleep(100);

Die führt dazu, dass der Thread früher oder später in eine Endlosschleife geht.
Nach einiger Zeit bemerkt das Programm, dass der Thread hängt und ruft .Free auf. Im Destructor steht folgender Code:

Code: Alles auswählen

 
 MessageBox(0,'Destroy 1',nil,0);
 inherited;
 MessageBox(0,'Destroy 2',nil,0);
 

Destroy 1 wird aufgerufen, danach bleibt der Mainthread ebenfalls hängen. :|

Ich brauche wahrscheinlich irgend einen Befehl aus der Windows API um den Thread abzubrechen...

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: httpS-Request

Beitrag von Christian »

Free ruft intern Terminate auf
in deinem Handler (im Execute) sollte regelmässig geschaut werden ob Terminated true ist
dann klappt das auch sauber mit Free.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 394
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: httpS-Request

Beitrag von MitjaStachowiak »

Ja, aber in den Klassen/DLLs zu HTTPS kann ich darauf nicht reagieren.

Ich rufe jetzt einfach TerminateThread vor inherited auf, wenn es sich aufgehängt hat, und gut is'.

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 394
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: httpS-Request

Beitrag von MitjaStachowiak »

Hmmm, jetzt habe ich das Problem, dass wenn TerminateThread einige Male aufgerufen wurde, THTTPSend gar nicht mehr funktioniert. HTTPGetText liefert dann nur noch false...

[Edit] Ach, halt, ich hatte einen Parameter falsch übergeben. Jetzt läuft es :wink:

Maria73
Beiträge: 6
Registriert: Di 4. Feb 2014, 16:32
OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
CPU-Target: xxBit
Wohnort: 8700

Re: httpS-Request

Beitrag von Maria73 »

Hallo, da ich diesen Beitrag hier aufmerksam verfolgt habe, interessiere ich mich nun auch für einen https-Request. Leider habe ich überhaupt keine Ahnung von der Materie und müsste zuerst mal die Vorteile einer S-Verbindung kennen. Wie kann ich dann das OpenSSL einbauen? Vielen Dank schonmal für eure Antworten im Voraus!!

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 394
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: httpS-Request

Beitrag von MitjaStachowiak »

Hallo,

also HTTPS ist mithilfe von SSL-Zertifikaten vollständig verschlüsselt. Wie sicher diese Zertifikate bei normalen Hosting-Angeboten sind, sei mal dahingestellt, aber wer die knacken kann, der kommt früher oder später eh' auf den Server. Das heißt, man bewegt sich mit HTTPS im Bereich der allgemeinen Sicherheitsstufe, mit der der Server geschützt ist. Es sei natürlich angemerkt, dass signierte Zertifikate kostenpflichtig sind. Wählt man eine Vertragslaufzeit von über einem Jahr, ist man bei für ein billiges Zertifikat mit 1-2€/Monat dabei. Bei teureren Hostingangeboten ist in der Regel ein Wildcard-Zertifikat vorhanden, aber da meckert dann meistens der Browser, genau wie bei unsignierten Zertifikaten, weil der genaue Domainname nicht stimmt.

Wie auch immer - die Signierung ist nur wichtig, um die Identität der Gegenstelle zu verifizieren. Wenn du also ein eigenes Programm schreibst, kannst du die Identität anders Prüfen, etwa durch mehrfachen Passwortaustausch, oder einen speziellen Zufallsgenerator, und es wird auch ein unsigniertes Zertifikat reichen; falls du so eins auf deinen Server hochladen kannst. Das geht auch nur bei eigenen Servern oder teuereren Hostingangeboten.

Also es sei mal angenommen, dass bereits ein Zertifikat existiert und der Server über HTTPS erreichbar ist und dass du bereits eine funktionierende Verbindung mit HTTPsend aufgebaut hast. Jetzt brauchst du nur noch ssl_openssl in die Uses-Liste aufzunehmen und die erwähnten DLLs deinem Programm beilegen und schon kannst du https://... als Adresse in HTTPsend verwenden. In den neueren Lazarus-Versionen ist diese Unit dabei, früher musste man die extra runterladen... Hat bei mir damals jedenfalls nicht funktioniert...

Aber jetzt ist HTTPS der einfachste Weg, um eine geschützte Verbindung zum Server aufzubauen. Wenn du nicht einen dauerhaften, sekündlichen HTTPS-Datenverkehr laufen lässt, dürfte das hier diskutierte Aufhänge-Bug auch kein Problem sein. Du kannst natürlich auch verschiedene Bibliotheken zur Verschlüsselung verwenden, aber da auf dem Server meistens eine andere Programmier/Scriptsprache verwendet werden muss, ist das sehr kompliziert. Ich hatte vorher eine eigene Verschlüsselung, basierend auf RSA und einigen selbst ausgedachten Zufallsgeneratoren, aber die dürfte nicht sehr sicher gewesen sein :mrgreen:



Davon mal abgesehen - prüft ssl_openssl eigentlich die Identität der Seite? Also wird die Gültigkeit des Zertifikates von einer Validierungsstelle bestätigt? Ich habe gelesen, dass viele Bibliotheken diesen Schritt auslassen und alle Zertifikate akzeptieren...

.

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: httpS-Request

Beitrag von Christian »

SSL ist mit einem Schlüssel verschlüsselt, der bei jedem verbindungsaufbau (teilweise auch zwischendrin ??) verhandelt wird. Das Zertifikat sagt nur etwas über das gegenüber aus nämlich das die Verbindung wirklich zu jemandem hergestellt wird mit dem man auch ne verbindung herstellen will.

Jeder kann sich selbst einfach kostenlos Zertifikate erstellen.
Die Kostenpflichtigen Zertifikate sind nur von einer CA unterschrieben undalle Browser vertrauen der CA ohne Meldung. Das ist der Unterschied.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 394
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: httpS-Request

Beitrag von MitjaStachowiak »

Ja, aber wenn das Zertifikat nicht signiert ist, hat man doch keine Garantie, dass das Gegenüber auch der richtige Server ist, und nicht jemand den Datenverkehr manipuliert, oder?

Ist die openSSL-Library für Lazarus eigentlich auch von der Sicherheitslücke betroffen, von der man seit einigen Tagen hört? Ich meine muss man neue Header herunterladen und sein Programm neu kompilieren, oder nur die DLLs auswechseln?

Übrigens hat sich, was mein Problem betrifft, gezeigt, dass das Neustarten des hängenden Threads nicht immer funktioniert. Manchmal stürzt danach der komplette Prozess ab :-/
Ich muss also doch noch einen Wächer-Prozess schreiben, der das Programm neustarten kann. Aber das ist gar nicht so einfach, wie es klingt.

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 394
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: httpS-Request

Beitrag von MitjaStachowiak »

Boah, wie mich die WindowsAPI schon wieder nervt :evil:

Ich versuche jetzt schon den ganzen Vormittag, zu überprüfen, ob das Programm läuft. Wenn ich selbiges mit CreateProcess starte, bekomme ich ein MainThread-Handle und mit GetThreadTimes --> ExitTime kann ich prüfen, ob dieser Prozess noch läuft. Gut. Aber wenn das Hauptprogramm zuerst startet, müsste dieses sein eigenes Thread-Handle ermitteln und dem Wächer-Programm übergeben. Klingt einfach, jedoch liefert GetCurrentThread ein vollkommen anderes Handle, dessen ExitTime nie Null wird. Und das benötigte Mainthread-Handle lässt sich einfach nicht finden. Die Prozess-ID ist zwar die gleiche, aber man kann nicht prüfen [Edit] Doch, siehe unten [/Edit], ob ein Prozess noch ausgeführt wird und man kommt auch so gut wie gar nicht vom Prozess-Handle zu den Threads zurück. Also nix mit EnumThreads.

[Edit] So, für alle, die das hier zufällig lesen: Es gibt noch GetProcessTimes. Damit tritt zunächst das gleiche Problem auf. Das Handle, das man mit GetCurrentProcess bekommt, funktioniert nicht. Stattdessen gebe ich die ID, also GetCurrentProcessID an das Wächter-Programm weiter. Dort muss ich openProcess mit den richtigen Parametern aufrufen, um ein Handle zu bekommen, das funktioniert. Für Prozesse gibt es spezielle Parameter, die es für Threads nicht gibt. Also keine Ahnung, ob das mit openThread auch geklappt hätte, aber processHandle := Windows.OpenProcess($1000, false, processID); liefert mir jetzt endlich das richtige Handle 8)

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: httpS-Request

Beitrag von Christian »

Ja, aber wenn das Zertifikat nicht signiert ist, hat man doch keine Garantie, dass das Gegenüber auch der richtige Server ist, und nicht jemand den Datenverkehr manipuliert, oder?

Doch, es ist eher mit CA unsicherer, da sich CAś schon mehrfach als unseriös rausgestellt haben.
Wenn ich beim ersten benutzen ein Zertifikat prüfe und bestätige, bekomm ich bei ner Zertifikatsänderung (z.b. Man in the Middle) ne Fehlermeldung.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Socke
Lazarusforum e. V.
Beiträge: 3158
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: httpS-Request

Beitrag von Socke »

Christian hat geschrieben:
Ja, aber wenn das Zertifikat nicht signiert ist, hat man doch keine Garantie, dass das Gegenüber auch der richtige Server ist, und nicht jemand den Datenverkehr manipuliert, oder?

Doch, es ist eher mit CA unsicherer, da sich CAś schon mehrfach als unseriös rausgestellt haben.
Wenn ich beim ersten benutzen ein Zertifikat prüfe und bestätige, bekomm ich bei ner Zertifikatsänderung (z.b. Man in the Middle) ne Fehlermeldung.

Das Verfahren nennt man dann "Certificate Pinning". Man gibt dem Programm vor, welches Zertifikat es vom Server zu erwarten hat (Fingerabdruck). Falls ein anderes Zertifikat vom Server kommt, lehnt man dieses immer ab. In diesem Fall ist es egal, ob man ein selbst signiertes Zertifikat oder ein Zertifikat eines CAs nutzt -- solange man den privaten Schlüssel selbst generiert hat.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

MitjaStachowiak
Lazarusforum e. V.
Beiträge: 394
Registriert: Sa 15. Mai 2010, 13:46
CPU-Target: 64 bit
Kontaktdaten:

Re: httpS-Request

Beitrag von MitjaStachowiak »

Genau. Und wie stellt man das in openssl ein, dass nur ein bestimmtes CA zulässig ist?

Antworten