Curl Login und Post



  • Hallo,
    ich hab ein Problem mit Curl in C. Ich kann mich einloggen und das Formular, welches ich absenden will, wird mir auch in der Konsole ausgeben, jedoch wird es nicht ausgefüllt/abgeschickt. Der Fehler liegt wohl in meinem Programm, jedoch komme ich mit Curl nicht so ganz zurecht. Es wäre nett wenn ihr mir helfen könnten.

    #include <stdio.h>
    #include <stdlib.h>
    #include <curl.h>
    #include <string.h>
    #include <windows.h>
    
       CURL *curl;
        CURLcode res;
    
        curl = curl_easy_init();
        if(curl) {
            curl_easy_setopt(curl, CURLOPT_URL, "http://blabla/login.php");
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "login=1234&pwd=abc");
            curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
    
            res = curl_easy_perform(curl);
            _sleep(5000);
    
    //Das eigentliche Formular
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "notes=abcdefg&start=1234");
    
            res = curl_easy_perform(curl);
    
            _sleep(1000);
            curl_easy_cleanup(curl);
        }
    
        return EXIT_SUCCESS;
    }
    


  • nur zum verständnis: sind es zwei formulare? sieht so aus.
    das eine ist zum einloggen.
    das zweite ist zum absenden von weiteren daten, oder?

    http ist statuslos. die seite muss nach dem login merken, wer eingeloggt ist. wie arbeitet die seite, wahrscheinlich mit cookies und sessions. den inhalt des cookies musst du bei einem zweiten! request auch mitschicken. (bzw. wenn ohne cookie, die hiddenfelder etc...)



  • Soweit ich das gesehen habe wird die Session ID in der URL übergeben mit dem redirect.

    Es sind zwei Formulare, eines zum einloggen und das zweite zum abschicken, welches nach dem einloggen kommen soll.
    Kenne mich mit php nicht besonders aus, aber alles in ein Formular erscheint mir auch schwierig, weil die abgeschickten Daten dem Benutzer zugeordnert werden müssen. Ich habe zur Seite (Formular) Adminzugang, habe sie jedoch nicht selber erstellt.



  • neo_02 schrieb:

    Soweit ich das gesehen habe wird die Session ID in der URL übergeben mit dem redirect.

    Es sind zwei Formulare, eines zum einloggen und das zweite zum abschicken, welches nach dem einloggen kommen soll.
    Kenne mich mit php nicht besonders aus, aber alles in ein Formular erscheint mir auch schwierig, weil die abgeschickten Daten dem Benutzer zugeordnert werden müssen. Ich habe zur Seite (Formular) Adminzugang, habe sie jedoch nicht selber erstellt.

    die sitzt dann wahrscheinlich im cookie.

    mach also einen zweiten request, hol dir das cookie (beispielsweise speicher es beim ersten request in eine textdatei) und sende es mit

    curl_setopt(curl, CURLOPT_COOKIEFILE, "cookie.txt");
    

    hat nichts mit php zutun, sondern mit dem http protokoll. das statuslose http protokoll muss sich ja irgendwie den nutzer merken, typischerweise über die sessionid. und die liegt meist im cookie, manchmal wird sie auch von der einen seite zur nächsten über eine get oder post variable übergeben. also schau nach, wie das auf deiner seite funktioniert.



  • Okay ich werde das mal probieren. Danke erstmal.

    Das mit dem PHP war darauf bezogen, dass ich auch theoretisch einfach die Seite dahingegen ändern könnte dass es einfacher funktioniert 😉



  • Leider hat dies noch nicht das gewünschte Ergebnis gebracht. Ich denke nicht, dass es an den Cookies liegt.

    Ich logge mich ein auf der Seite (erstes Formular), darauf bekomme ich als Ausgabe in der Konsole die Seite mit dem zweiten Formuluar angezeigt. Will ich das jedoch ausfüllen bekomme ich wieder das zweite Formular in der Konsole angezeigt. Das Übermitteln der Daten hat nicht funktioniert, weil auch in der Datenbank nicht das gewünschte Ergebnis auftaucht.



  • tja, und du gibts zu wenig infos...
    es existiert also kein cookie? wo ist dann die sessionid gespeichert?
    wenn sie weitergereicht wird, musst du wohl oder übel die html seite parsen und dir die sessionid rausfischen und beim zweiten request mitsenden.

    aber ... ist alles nur kristallkugel 😉 vielleicht ist die seite ja ganz anders strukturiert.



  • ich sehe grad, du schreibst, dass die sessionid mit der url übergeben wird...

    sieht also danach aus, dass du sie aus dem html (oder head) fischen kannst.



  • Die Session ID kann ich auslesen, und die korrekte URL aufrufen.
    Das redirect hat auch die korrekte URL übermittelt.
    Jedoch bekomme ich nach wie vor 2x das Formular als Ausgabe. Es wird also nicht abgeschickt wie mir scheint. Der Quellcode für zwei Formulare müsste so aber stimmen oder? Anbei nochmal der aktuelle Quellcode

    #include <stdio.h>
    #include <stdlib.h>
    #include <curl.h>
    #include <string.h>
    #include <windows.h>
    
    int main(int argc, char *argv[]) {
    
        CURL *curl;
        CURLcode res;
    
        curl = curl_easy_init();
        if(curl) {
            curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
            curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5);
    
            curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.0.102/blabla/libcurl_login.php");
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "login=1234&pwd=5678");
    
            res = curl_easy_perform(curl);
            _sleep(1000);
    
            char* info = NULL;
            res =curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &info);
            if((CURLE_OK == res) && info) {
                printf("URL: %s\n",info);
            }
    
            _sleep(1000);
    
            // Auslesen und speichern der SID
            int token=1;
            char *sid;
            char* session;
            char trennzeichen[] = "=";
    
            sid = strtok(info, trennzeichen);
    
            while(sid != NULL) {
    
            printf("SID %d: %s\n",token++, sid);
            sid = strtok(NULL, trennzeichen);
            if (token==2) {
                    session=sid;
            }
    
            }
            printf("Session: %s\n", session);
    
            char formular[]="http://192.168.0.102/blabla/libcurl_main.php?sid=";
            char *urlformular;
    
            urlformular= strcat(formular, session);
            printf("URL fuer das zweite Formular: %s", urlformular);
    
    // zweites Formular
            curl_easy_setopt(curl, CURLOPT_URL, urlformular);
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "notes=test&start_h=01&start_m=10&arrive_h=02&arrive_m=20&duration_h=1&duration_m=10&fl=FL20&fuel=1234");
            res = curl_easy_perform(curl);
    
            curl_easy_cleanup(curl);
        }
    
        return EXIT_SUCCESS;
    }
    


  • erstes rüberschauen: ein segmentation fault...

    strcat (a,b); für a zuwenig speicher reserviert.



  • noch ein hinweis:
    die meisten server heute haben die
    session.use_only_cookies auf on.

    damit geht tatsächlich das übertragen nur mit cookies. in der php.ini zu konfigurieren, wenn man jedoch keinen zugriff auf den server hat, so eben mit cookie auslesen.



  • mal ein skript gebaut auf grundlage von deinem, in dem ein redirect verfolgt wird (weil du das meintest).
    daraufhin wird eine weitere seite angesurft, der dann, jetzt eingeloggt durch die mitgegebene sessionid, daten für weitere aktionen (datenbank ... etc.) geschickt werden können.

    aber vorsicht, funktioniert nur, wenn auf deinem server die erwähnte
    session.use_only_cookies auf off ist.
    ansonsten musst das srkipt um cookie auslesen und selber behandeln erweitert werden.

    (sicher nicht fehlerfrei, aber funktioniert; erstmal nur als diskussionsgrundlage)

    #include <stdio.h>
    #include <stdlib.h>
    #include <curl/curl.h>
    #include <string.h>
    
    int main(int argc, char *argv[]) {
    
        CURL *curl = curl_easy_init();
    
        if (curl) {
            curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
            curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5);
            curl_easy_setopt(curl, CURLOPT_HEADER, 1);
    
            curl_easy_setopt(curl, CURLOPT_URL, "http://localhost/test/session/login.php");
            curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "username=biene&passwort=maja");
    
            CURLcode res = curl_easy_perform(curl);
    
            char* info = NULL;
            res = curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &info);
    
            if((CURLE_OK == res) && info) {
                printf("URL: %s\n",info);
            } else {
                curl_easy_cleanup(curl);
                exit(1);
            }
    
            int token=1;
            char trennzeichen[] = "=";
            char* sid = strtok(info, trennzeichen);
    
            char* session=NULL;
            while(sid != NULL) {
    
                printf("SID %d: %s\n",token++, sid);
                sid = strtok(NULL, trennzeichen);
                if (token==2) {
    				session=sid;
                }
            }
    
            if(session==NULL){
                curl_easy_cleanup(curl);
                exit(1);
            }
    
            printf("Session: %s\n", session);
    
            char formular[100]="http://localhost/test/session/index.php?PHPSESSID=";
            strcat(formular, session);
    
    		// zweites Formular
    		printf("URL Formular: %s", formular);
    
    		curl_easy_setopt(curl, CURLOPT_URL, formular);
    		curl_easy_setopt(curl, CURLOPT_POSTFIELDS, ""); //hier dann postdaten für die Datenbank einlegen
    
    		printf("\nFormular\n");
    
    		CURLcode res1 = curl_easy_perform(curl);
    
    		if(CURLE_OK == res1) {
    			printf("Formular OK\n");
    		}
    
    		curl_easy_cleanup(curl);
        }
    
        return 0;
    }
    


  • Ich teste das ganze auf einem lokalen Server und nicht auf dem tatsächlich im Einsatz befindlichen, von daher habe ich dort Rootzugang. Die PHP.ini wurde geändert. Aber das Formular wird nicht abgesendet... und das verstehe ich einfach nicht.



  • nach dem ändern der php.ini den server neu gestartet? (sonst liest er sie nicht ein...)

    ansonsten: bringe den php code aufs minimalste runter und poste ihn.



  • Ja den neustart habe ich gemacht.
    Das Formular kann ich ja auch im Browser abschicken, das funktioniert bereits alles seit Jahren, deshalb bin ich so verwundert.
    Den vollständingen PHP Code zu posten ist schwierig, aufgrund des Copyrights etc. Reicht dir der <form> Abschnitt?



  • nein..., keinen vollständigen php code, ich habe gesagt, dass DU mal testen sollst, in dem du den code auf eine minimale form bringst. diese wäre dann ev. postbar, da vollständig abgespeckt. aber es ist eher eine hilfe für dich, die relevanten dinge zu sehen.

    erstmal fällt mir nichts mehr ein, da mein beispiel funktioniert.
    du sagst ja, der code arbeitet auch ohne cookies (das hast du ja hoffentlich getestet ;), ansonsten immernoch der hinweis, die cookies mit zu senden). und vermutlich sendest du auch alle relevanten variablen mit.



  • Das habe ich gemacht 😉 Läuft aber irgendwie nicht. Ich denke nicht dass es ein Problem mit den Cookies sein wird, denn die Session kann ich am PC erstellen und mit der ID am Laptop ohne einloggen reinkommen. Ist heutzutage nicht mehr sicher, aber in mittelfristiger Zukunft kommt da etwas neues, soweit ich weiß.
    Außerdem kommt nach dem Absenden des Formulars selbiges als Ausgabe in Curl zurück, was mich eigentlich verwundert. Das Formular funktioniert wunderbar im Webbrowser.

    Das Formular selektiert bereits einige Daten vor. Kann ich mit curl also nur diejenigen übermitteln, die noch nicht aus vorselektiert sind? Denn dann sind es eigentlich nur 2 Felder die ich ausfüllen muss.
    Dass es ein paar mal eine "select"-Auswahl ist sollte ja nichts ausmachen, nehme ich an.

    EDIT:
    Selbst wenn ich nur die Variablen übermittel die ausgefüllt werden müssen und diese ungültig sind, sodass der Server normal eine Fehlermeldung ausgibt, passiert nichts. Da muss doch irgendwo der Wurm drinnen liegen.



  • Ich habe eine Idee.
    Kann es daran liegen, dass das Formular so beginnt:

    <form action="<?echo $PHP_SELF;?>?sid=<?echo $sid;?>&cmd=<?echo $cmd;?>&lang=<?echo $lang;?>" name="reporten" method="post">
    						<input type="hidden" name="action" value="1">
    						<input type="hidden" name="buchid" value="<?echo $buch_vars['BUCH_ID'];?>">
    [...]
    //PHP aus Datenbank
    FNR.: <?echo $buch_arr['FP_NR'];?>
    [...]
    
    //Eigentliches Formular
    <textarea name="notes"><?if(!isset($notes)){echo $buch_arr['FP_DESCR'];}else{echo $notes;}?></textarea>
    [...]
    


  • was als post, get (und cookie) mitgesendet werden muss, damit das ganze klappt, musst du selber herausfinden.



  • Okay, ich habe aber noch eine Frage:
    ich muss die hidden Felder aber explizit mitsenden, oder? Will heißen, die wern wenn ich die nicht im Programm definiere einfach nicht gesendet. Weil im Browser werden die im Hintergrund ausgefüllt und gesendet. Diese sind ziemlich sicher für das Formular, wie mir jetzt auffällt. Vielen Dank schonmal hierfür 🙂

    Die Frage ist jetzt allerdings, wie komme ich an die Daten dran? Die werden von dem PHP Skript erst aus der Datenbank abgerufen, wenn die Seite aufgerufen wird.
    Kann ich die Daten in dem Moment, in dem die Seite mit dem Formular aufgerufen wird, irgendwie in das C Programm bekommen?