Ansi-C: SMTP Library?



  • Hallo.

    Ich suche eine Library für Ansi-C (nicht C++), die Mails über SMTP versendet. Ich habe schon den ganzen Morgen gesucht, aber nichts gefunden.

    Meine Konfiguration ist: Linux Debian-Etch STABLE (ich bin an apt-get gebunden), sendmail

    Der Compiler ist GCC

    Das eheste Ergebnis war jwSMTP, das funktioniert aber nicht da
    a) es nicht per apt-get als stable zu erhalten ist
    b) es ein C++ und kein C code ist (ich möchte auf dem C-Standard bleiben)

    Hat jemand eine Idee, wie ich Mails senden kann, ohne unsichere Techniken zu verwenden (z.B. auf die Systemkonstole zuzugreifen)? Vielen Dank.

    Gruß
    blackdrake



  • normalerweise ruft man unter Linux/Unix das man: sendmail-Programm dafür auf. (wird von allen MTAs zu Verfügung gestellt. Nicht nur von sendmail dem MTA).



  • Hallo.

    Meint du mit "aufrufen" etwa soetwas hier system("sendmail | echo ..."); ? Das wäre mir ein bisschen zu riskant, einfach so auf die Konsole zuzugreifen. Eine Library, die eigenständig (und auch Plattformunabhängig) das SMTP-Protokoll beachtet wäre doch angebrachter, oder?

    Ich vermisse soetwas wie die mail() Funktion bei PHP - diese leitet so weit ich weiß auch an sendmail oder postfix weiter. Wie kann man soetwas in C nachrüsten?

    Gruß
    blackdrake



  • blackdrake schrieb:

    Meint du mit "aufrufen" etwa soetwas hier system("sendmail | echo ...");

    Nein, natürlich nicht per system.

    Hingegen: man: popen und man: sendmail ist eine sehr saubere kanonische Lösung.



  • nman schrieb:

    Hingegen: man: popen und man: sendmail ist eine sehr saubere kanonische Lösung.

    Nebenbei: Das kannst Du natürlich in eine entsprechende Mail-Funktion verpacken, die die lowleveligen Details hübsch wegabstrahiert.



  • blackdrake schrieb:

    Meine Konfiguration ist: Linux Debian-Etch STABLE (ich bin an apt-get gebunden), sendmail

    Etch ist nicht mehr stable sondern schon old-stable. Und Du verwendest doch hoffentlich nicht wirklich sendmail, sondern Postfix oder Exim oä, oder?



  • nman schrieb:

    Etch ist nicht mehr stable sondern schon old-stable. Und Du verwendest doch hoffentlich nicht wirklich sendmail, sondern Postfix oder Exim oä, oder?

    Hallo. Ich habe nochmal bei einer Mail, die mit PHP gesandt wurde, nachgeschaut: Es ist tatsächlich Postfix.

    Meine Frage: Wie steuere den MTA Postfix in meiner C-Anwendung an, ohne system("cat ... | sendmail") zu verwenden? (Diese Lösung mit system()+sendmail funktioniert zwar im Moment, aber sie ist mir zu unsicher wegen fehlender Escapes)

    Meine funktionierende Lösung ist im Moment:

    //********************************************************************************************
    //
    // sendmail
    //
    // Sendet eine E-Mail
    
    const int BFR_SIZE = 2048; // <-- snprintf() braucht eine Begrenzung :-/ ...
    
    static void sendmail (const char *from, const char *from_name, const char *to, const char *betreff, const char *daten)
    {
            char bfr[BFR_SIZE];
            snprintf(bfr, BFR_SIZE, "(cat <<EOF\r\nFrom: %s <%s>\r\nTo: %s\r\nSubject: %s\r\n\r\n%s\r\nEOF\r\n) | /usr/sbin/sendmail -t -i -f %s", from_name, from, to, betreff, daten, from);
            system(bfr);
    }
    

    nman schrieb:

    Nein, natürlich nicht per system.

    Hingegen: man: popen und man: sendmail ist eine sehr saubere kanonische Lösung.

    Wieso soll popen() besser als system() sein? Dort kann ich doch auch eine Command-Line-Injection reinbringen, oder?

    Gruß
    blackdrake



  • blackdrake schrieb:

    Meine Frage: Wie steuere den MTA Postfix in meiner C-Anwendung an, ohne system("cat ... | sendmail") zu verwenden?

    Indem Du man: popen verwendest, um sendmail zu öffnen.

    Wieso soll popen() besser als system() sein? Dort kann ich doch auch eine Command-Line-Injection reinbringen, oder?

    Um Input Sanitation musst Du Dich ohnehin immer kümmern, aber ein dummes "; rm -rf ~" ist damit nicht so einfach möglich.

    Aber system ist einfach böse, weil das wirklich eine komplette frische Shell spawned und dort drin Deinen Befehl ausführt. Mit popen kannst Du einfach direkt ins stdin des Prozesses schreiben. Lies doch einfach mal die Manpage und bemühe Google, da findest Du bestimmt was.



  • Hallo.

    Die Lösung mit popen() erscheint mir ziemlich sauber, nachdem ich gesehen habe, dass ich durch "w" den ganzen (potenziell unsicheren) Eingabecode direkt in den Stream speichern kann, ohne die Befehlszeile, die nun eine Konstante ist, zu berühren!

    Außerdem ist der Code nun übersichtlicher und BFR_SIZE begrenzt nun nicht mehr meinen E-Mail-Körper mail_text.

    Ist folgender Code nun frei von Sichereheitslücken und sauber geschrieben?

    #include <stdio.h>
    #include <stdbool.h>   // bool
    #include <sysexits.h>  // EX_OK
    
    # define BFR_SIZE 2048
    
    //********************************************************************************************
    //
    // sendmail
    //
    // Sendet eine E-Mail
    //
    // Note: At the paramters "from" and "to" you can use following syntax
    // to show a specific name at the user client instead of only the mail address:
    // Your Real Name <your@mail_address.com>
    
    static bool sendmail (const char *from, const char *to, const char *subject, const char *mail_text)
    {
    	FILE *fp = popen("/usr/lib/sendmail -t -i", "w");
    	if (fp) {
    		char bfr[BFR_SIZE];
    
    		snprintf(bfr, BFR_SIZE, "From: %s\r\n", from);
    		fputs(bfr, fp);
    
    		snprintf(bfr, BFR_SIZE, "To: %s\r\n", to);
    		fputs(bfr, fp);
    
    		snprintf(bfr, BFR_SIZE, "Subject: %s\r\n", subject);
    		fputs(bfr, fp);
    
    		fputs("\r\n", fp);
    
    		fputs(mail_text, fp);
    
    		fputs("\r\n", fp);
    
    		fflush(fp);
    
    		return (pclose(fp) == EX_OK);
    	} else {
    		return false;
    	}
    }
    

    ( Ref: http://devboard.viathinksoft.de/viewtopic.php?f=34&t=803 )

    Gruß
    blackdrake



  • Sieht recht brauchbar aus. Abhängig davon, woher Du die Werte empfängst, solltest Du die Werte selbst aber uU. noch überprüfen.


Anmelden zum Antworten