Beat: Perl Net::Smtp Auth Login Verfahren

Hallo.

Dies ist eine Lösungsbeschreibung für ein Problem, das mich die letzten zwei Tage beschäftigt hat.

Tags: SMTP, AUTH LOGIN, PASSWORD, USERNAME, FORMMAILER, NET::SMTP

Problembeschreibung:

Der MailClient, in diesem Fall Perls Net::Smtp befindet sich auf dem localen PC.
Der Smtp-Server befindet sich jedoch auf einem fernen Server.
Viele Mailprovider akzeptieren den Versand von Mails nur, wenn der Mailclient sich beim Server authentifiziert.

Das Problem jedoch ist, wie hat das zu geschehen?
Eine Anwendung der Methode
smtp->auth( 'USERNAME', 'PASSWORD' )
wird unter Umständen scheitern.
Keine Dokumentation im Netz beschreibt dies.
Auf dieser Seite jedoch
http://www.go4expert.com/forums/showthread.php?t=2556
wurde ich auf die Lösung aufmerksam. (mein Dank an den dortigen Poster)

In meinem Fall hat es ebenfalls geholfen, USERNAME und PASSWORD vorher base64 zu encoden.
Der Trick besteht darin, nicht smtp->auth zu verwenden, sondern in drei Schritten die Information AUTH LOGIN, USERNAME, PASSWORD zu übermitteln.

Hier folgen relevante Scriptauszüge sowie die zugehörige Debugging Info, erzeugt durch Net::Smtp.
Möge es anderen helfen.

  
use warnings;  
use strict;  
use MIME::Base64;  
use Net::SMTP;  
  
#....  
  
my $smtp = Net::SMTP->new(  
	Host => 'smtp.server.domain',  
	Hello => 'sender@mail.domain',  
	Timeout => 10,  
		Debug =>1,  
) or die "Keine Connetion";  
  
# Hier der Trick. Kein smtp->auth() sondern:  
  
$smtp->datasend("AUTH LOGIN\n") or die 'auth login';  
$smtp->response();  
  
$smtp->datasend( encode_base64('USERNAME') ) or die 'username';  
$smtp->response();  
  
$smtp->datasend(encode_base64('PASSWORD') ) or die 'password';  
$smtp->response();  
  
# Hier geht es wie gewohnt weiter.  
  
$smtp->mail( 'sender@mail.domain' ) or die '$smtp->mail';  
$smtp->to( 'recipient@mail.domain' ) or die '$smtp->to';  
$smtp->data();  
$smtp->datasend( $mail );  
$smtp->datasend("\n");  
$smtp->dataend();  
$smtp->quit;  

Debugging Info
Hinweise Daten wurden [ANONYMISIERT]
...
Net::SMTP=GLOB(0x1a6c69c)<<< 220 [SERVICENAME]
Net::SMTP=GLOB(0x1a6c69c)>>> EHLO smtp.server.domain
Net::SMTP=GLOB(0x1a6c69c)<<< 250-service domaine
Net::SMTP=GLOB(0x1a6c69c)<<< 250-PIPELINING
Net::SMTP=GLOB(0x1a6c69c)<<< 250-SIZE 20240000
Net::SMTP=GLOB(0x1a6c69c)<<< 250-ETRN
Net::SMTP=GLOB(0x1a6c69c)<<< 250-AUTH PLAIN LOGIN
Net::SMTP=GLOB(0x1a6c69c)<<< 250-AUTH=PLAIN LOGIN
Net::SMTP=GLOB(0x1a6c69c)<<< 250-ENHANCEDSTATUSCODES
Net::SMTP=GLOB(0x1a6c69c)<<< 250-8BITMIME
Net::SMTP=GLOB(0x1a6c69c)<<< 250 DSN
Net::SMTP=GLOB(0x1a6c69c)>>> AUTH LOGIN
Net::SMTP=GLOB(0x1a6c69c)<<< 334 [Base64String]
Net::SMTP=GLOB(0x1a6c69c)>>> [BASE64EncodedUSERNAM]==
Net::SMTP=GLOB(0x1a6c69c)<<< 334 [Base64String]
Net::SMTP=GLOB(0x1a6c69c)>>> [BASE64EncodedPASSWORD]=
Net::SMTP=GLOB(0x1a6c69c)<<< 235 2.0.0 Authentication successful
Net::SMTP=GLOB(0x1a6c69c)>>> .
Net::SMTP=GLOB(0x1a6c69c)<<< 502 5.5.2 Error: command not recognized
Net::SMTP=GLOB(0x1a6c69c)>>> MAIL FROM:sender@mail.domain
Net::SMTP=GLOB(0x1a6c69c)<<< 250 2.1.0 Ok
Net::SMTP=GLOB(0x1a6c69c)>>> RCPT TO:recipient@mail.domain
Net::SMTP=GLOB(0x1a6c69c)<<< 250 2.1.5 Ok
Net::SMTP=GLOB(0x1a6c69c)>>> DATA
Net::SMTP=GLOB(0x1a6c69c)<<< 354 End data with <CR><LF>.<CR><LF>
Net::SMTP=GLOB(0x1a6c69c)>>> From: sender@mail.domain
Net::SMTP=GLOB(0x1a6c69c)>>> To: recipient@mail.domain
Net::SMTP=GLOB(0x1a6c69c)>>> Subject: Dies ist ein Test
Net::SMTP=GLOB(0x1a6c69c)>>> Content-Type: text/plain; charset=utf-8
Net::SMTP=GLOB(0x1a6c69c)>>>
Net::SMTP=GLOB(0x1a6c69c)>>>
Net::SMTP=GLOB(0x1a6c69c)>>> Dies ist der Mailtext
Net::SMTP=GLOB(0x1a6c69c)>>> .
Net::SMTP=GLOB(0x1a6c69c)<<< 250 2.0.0 Ok: queued as A61BE28123
Net::SMTP=GLOB(0x1a6c69c)>>> QUIT
Net::SMTP=GLOB(0x1a6c69c)<<< 221 2.0.0 Bye

mfg Beat

--
><o(((°>           ><o(((°>
   <°)))o><                     ><o(((°>o
Der Valigator leibt diese Fische
  1. Moin!

    Dies ist eine Lösungsbeschreibung für ein Problem, das mich die letzten zwei Tage beschäftigt hat.

    Nun gut, du hast jetzt eine Lösung, aber die Frage ist doch: Wo ist das eigentliche Problem? Und ist deine Lösung schön[TM].

    Eine Anwendung der Methode
    smtp->auth( 'USERNAME', 'PASSWORD' )
    wird unter Umständen scheitern.

    Das liegt dann sehr wahrscheinlich daran, dass Net::SMTP einen Fehler bei der Ermittlung des gewünschten Authentifizierungsmechanismus macht, bzw. dass das Resultat der Serverauskunft, das Net::SMTP heranzieht, dem Server wieder nicht gefällt.

    Der Fehler steckt also entweder in Net::SMTP oder im benutzten Mailserver.

    Im ersten Fall wäre die bessere Vorgehensweise, den Fehler in Net::SMTP zu melden, evtl. gar zu beheben.

    Im zweiten Fall wird man sich wünschen, das der Mailserver sich doch bitte standardgemäß verhielte, also entweder korrekt konfiguriert wird (vielleicht hat er ein Problem mit dem von Net::SMTP gewählten Authentifizierungs-Schema, weil er das zwar laut SMTP anbietet, aber nicht versteht), oder der Fehler wird gepatcht. Problem dabei ist natürlich, dass fremde Mailserver sich diesen Wünschen gerne widersetzen.

    Hier der Trick. Kein smtp->auth() sondern:

    $smtp->datasend("AUTH LOGIN\n") or die 'auth login';
    $smtp->response();

    $smtp->datasend( encode_base64('USERNAME') ) or die 'username';
    $smtp->response();

    $smtp->datasend(encode_base64('PASSWORD') ) or die 'password';
    $smtp->response();

    Ich halte es für problematisch, ohne weitere Checks auf die Verträglichkeit der Methode einfach die Authorisationsmethode LOGIN anzuwenden, und diese auch ohne weitere Checks auf den Erfolg durchzuführen. Fehlerbehandlung sieht leicht anders aus. :)

    Spannend wäre, wie erwähnt, die Antwort auf die Frage, was denn im Normalfall so auf der Leitung passiert, wenn smtp->auth() benutzt wird.

    - Sven Rautenberg

    1. Ich halte es für problematisch, ohne weitere Checks auf die Verträglichkeit der Methode einfach die Authorisationsmethode LOGIN anzuwenden, und diese auch ohne weitere Checks auf den Erfolg durchzuführen. Fehlerbehandlung sieht leicht anders aus. :)

      Richtig wäre es, die möglichen Methoden aus dem banner zu lesen.
      In diesem Fall wird AUTH LOGIN nicht aufgeführt, wird aber vom mailserver, wie eben demonstriert, behandelt.
      Das ist in der Tat eine Fehlkonfiguration des Servers (welche ich nicht beeinflussen kann)

      Spannend wäre, wie erwähnt, die Antwort auf die Frage, was denn im Normalfall so auf der Leitung passiert, wenn smtp->auth() benutzt wird.

      Auch das habe ich gestern, allerdings ohne Base64 Codierte Daten, versucht.
      In dem Falle geschieht das.

      smtp->auth('Username','Password');
      Der Server gibt keine Antwort. darauf, sprich, es wird gar nicht versucht.
      smtp->mail('senderaddress');
      Der Server sendet ein OK. Der User existiert.
      smtp->To('recipient');
      Der Server mokiert, keine Berechtigung.
      An diesem Punkt hätte ich abzubrechen.

      mfg Beat

      --
      ><o(((°>           ><o(((°>
         <°)))o><                     ><o(((°>o
      Der Valigator leibt diese Fische
      1. Moin!

        Richtig wäre es, die möglichen Methoden aus dem banner zu lesen.
        In diesem Fall wird AUTH LOGIN nicht aufgeführt, wird aber vom mailserver, wie eben demonstriert, behandelt.

        Doch, wird aufgeführt. Zumindest laut deinem Testlog.

        Das ist in der Tat eine Fehlkonfiguration des Servers (welche ich nicht beeinflussen kann)

        Was für ein Server ist das denn?

        Spannend wäre, wie erwähnt, die Antwort auf die Frage, was denn im Normalfall so auf der Leitung passiert, wenn smtp->auth() benutzt wird.

        Auch das habe ich gestern, allerdings ohne Base64 Codierte Daten, versucht.
        In dem Falle geschieht das.

        Debug-Log?

        smtp->auth('Username','Password');
        Der Server gibt keine Antwort. darauf, sprich, es wird gar nicht versucht.

        Das würde ich nicht unbedingt so sehen. Die Frage ist: Was wird versucht?

        smtp->mail('senderaddress');
        Der Server sendet ein OK. Der User existiert.

        Nein, das OK hat an dieser Stelle noch nichts zu sagen.

        smtp->To('recipient');
        Der Server mokiert, keine Berechtigung.

        Wenn dem Server die Gesamtheit aus HELO, Sender und Empfänger nicht gefällt, ist dies der beste Zeitpunkt, das kundzutun.

        An diesem Punkt hätte ich abzubrechen.

        Logisch, weil weitere Daten zu dieser Mail nicht erfolgreich akzeptiert würden.

        - Sven Rautenberg

        1. Richtig wäre es, die möglichen Methoden aus dem banner zu lesen.
          In diesem Fall wird AUTH LOGIN nicht aufgeführt, wird aber vom mailserver, wie eben demonstriert, behandelt.

          Doch, wird aufgeführt. Zumindest laut deinem Testlog.

          AUTH LOGIN PLAIN ist doch nicht etwa dasselbe?

          Das ist in der Tat eine Fehlkonfiguration des Servers (welche ich nicht beeinflussen kann)

          Was für ein Server ist das denn?

          Die Software müsste ich anfragen
          Ich kann ihn als meinen eigenen ansprechen:
          smtp.elcappuccino.ch
          Er begrüsst mich als smtp-04.vtx.ch

          Spannend wäre, wie erwähnt, die Antwort auf die Frage, was denn im Normalfall so auf der Leitung passiert, wenn smtp->auth() benutzt wird.

          Auch das habe ich gestern, allerdings ohne Base64 Codierte Daten, versucht.
          In dem Falle geschieht das.

          Debug-Log?

          Die Log sah exakt gleich aus wie ein Aufruf ohne smtp->auth()
          Ich habe sie in einem anderen Post gestern gepostet:
          https://forum.selfhtml.org/?t=190124&m=1269172

          mfg Beat

          --
          ><o(((°>           ><o(((°>
             <°)))o><                     ><o(((°>o
          Der Valigator leibt diese Fische
          1. Moin!

            Richtig wäre es, die möglichen Methoden aus dem banner zu lesen.
            In diesem Fall wird AUTH LOGIN nicht aufgeführt, wird aber vom mailserver, wie eben demonstriert, behandelt.

            Doch, wird aufgeführt. Zumindest laut deinem Testlog.

            AUTH LOGIN PLAIN ist doch nicht etwa dasselbe?

            Doch, exakt. Nach dem AUTH kommt eine Liste mit unterstützen Methoden, hier LOGIN und PLAIN.

            Die Doppelzeile mit AUTH= ist für dumme Exchange-Server oder Outlook-Clients, IIRC.

            Das ist in der Tat eine Fehlkonfiguration des Servers (welche ich nicht beeinflussen kann)

            Was für ein Server ist das denn?

            Die Software müsste ich anfragen

            So rein vom Gefühl her könnte ich auf Postfix tippen - die Abbruchmeldung aus deinem anderen Log ist relativ einschlägig.

            Ich kann ihn als meinen eigenen ansprechen:
            smtp.elcappuccino.ch
            Er begrüsst mich als smtp-04.vtx.ch

            Ich verstehe nicht, warum ein Mailserver keine Mail akzeptiert mit dem Zieladressat seiner Domain. Aber wahrscheinlich liegt das daran, dass ihm die Absenderadresse nicht gefällt: Seine eigene Domain.

            Spannend wäre, wie erwähnt, die Antwort auf die Frage, was denn im Normalfall so auf der Leitung passiert, wenn smtp->auth() benutzt wird.

            Auch das habe ich gestern, allerdings ohne Base64 Codierte Daten, versucht.
            In dem Falle geschieht das.

            Debug-Log?

            Die Log sah exakt gleich aus wie ein Aufruf ohne smtp->auth()

            Mit anderen Worten: Authentifizierung mit smtp->auth() hatte keinerlei Wirkung? Interessant. Da würde ich an dieser Stelle tatsächlich mal Net::SMTP einer genaueren Betrachtung unterziehen, denn dass da einfach NICHTS passiert, wenn man sich authentifizieren will, ist doch sehr ungewöhnlich.

            Auf der anderen Seite: Will man Login-Daten unverschlüsselt durch das Internet schicken? Doch eher nicht. SSL wäre angebracht, TLS von deinem Server leider nicht offeriert (STARTTLS fehlt in der Auflistung nach dem EHLO).

            Ich habe sie in einem anderen Post gestern gepostet:
            http://forum.de.selfhtml.org/my/?t=190124&m=1269172

            - Sven Rautenberg

        2. Richtig wäre es, die möglichen Methoden aus dem banner zu lesen.
          In diesem Fall wird AUTH LOGIN nicht aufgeführt, wird aber vom mailserver, wie eben demonstriert, behandelt.

          Doch, wird aufgeführt. Zumindest laut deinem Testlog.

          Scheint so zu sein, wenn man die Zeile zu interpretieren versteht.
          AUTH LOGIN PLAIN
          ID   METHODE METHODE

          Hier noch eine interessante Lektüre
          http://www.huschi.net/11_108_de-esmtp-dialog-smtp-auth.html

          Problem ist, dass smtp->auth() selbst keinen Fehler produziert.

          Aus den Tiefen von SMTP.pm

          sub auth {
              my ($self, $username, $password) = @_;

          eval {
          require MIME::Base64;
          require Authen::SASL;
              } or $self->set_status(500,["Need MIME::Base64 and Authen::SASL todo auth"]), return 0;

          Das ist natürlich jetzt klar.
          Das Modul ist nicht in meiner ActiveState enthalten.
          damit fällt smtp->auth() als eine Methode für ein öffentliches Formmailer-Script dahin.

          Mein Workaround erweist sich somit als sicher, sofern man ohne SASL leben kann.
          Im praktischen Fall wird ja ein CGI-Formmailerscrpt nicht über das Internet auf einen fernen Server zugreifen.

          mfg Beat

          --
          ><o(((°>           ><o(((°>
             <°)))o><                     ><o(((°>o
          Der Valigator leibt diese Fische
          1. Moin!

            Hier noch eine interessante Lektüre
            http://www.huschi.net/11_108_de-esmtp-dialog-smtp-auth.html

            Die hat so ihre Detailfehlerchen. Denn der dargestellte Server unterstützt kein CRAM-MD5 laut seiner Liste.

            Problem ist, dass smtp->auth() selbst keinen Fehler produziert.

            Offenbar hast du versäumt, den Status von Net::SMTP abzufragen, wenn ich mir den Code der auth-Methode so ansehe.

            Aus den Tiefen von SMTP.pm

            sub auth {
                my ($self, $username, $password) = @_;

            eval {
            require MIME::Base64;
            require Authen::SASL;
                } or $self->set_status(500,["Need MIME::Base64 and Authen::SASL todo auth"]), return 0;

            Das ist natürlich jetzt klar.
            Das Modul ist nicht in meiner ActiveState enthalten.

            Welches Modul? Da werden zwei eingebunden.

            damit fällt smtp->auth() als eine Methode für ein öffentliches Formmailer-Script dahin.

            Mein Workaround erweist sich somit als sicher, sofern man ohne SASL leben kann.

            Wenn deine Äußerungen sich auf das hier im Forum mal angesprochene Projekt "Formmailer neumachen" beziehen, dann ist die von mir geäußerte Kritik, dass dein Skript sich nicht um offerierte Auth-Methoden kümmert und die Authentisierung ohne Prüfung des Erfolgs durchführt, als schwerwiegend einzustufen.

            Im praktischen Fall wird ja ein CGI-Formmailerscrpt nicht über das Internet auf einen fernen Server zugreifen.

            Doch, genau das wird getan werden. Denn wenn das nicht notwendig wäre, würde man die schlichte Sendmail-Methode wählen, und alles wäre deutlich einfacher. Oder würde keine SMTP-Authentifizierung erfordern.

            Das Szenario, welches du gerade bearbeitest, tritt sozusagen NUR dann auf, wenn ein Webserver selbst keinen direkten, unauthentifizierten Zugang zu einem Mailserver hat, und deshalb den Zugriff via Internet auf einen existierenden, aber gegen unautorisierte Fremdbenutzung abgesicherten Mailserver erfolgen muss. Gerade in so einem Szenario sollte die Sicherheit an allererster Stelle stehen - und das bedeutet für mich:

            • Einsatz von SSL, sofern der Mailserver auf einem alternativen Port via SMTPS erreichbar ist.
            • Einsatz von STARTTLS, sofern vom Mailserver angeboten.
            • Warnung des Users, dass seine Mailzugangsdaten potentiell öffentlich lesbar über das Netz übertragen werden.
            • Einsatz von verschleiernden Authentifizierungen wie CRAM-MD5.
            • Wenn nichts anderes mehr geht: LOGIN oder PLAIN. Im Prinzip komplett ungeeignet, zumindest aber für alles, was das heimatliche Netzsegment des Webservers verlässt.

            Die schlaue Lösung wäre, zu recherchieren, wo die fehlenden Module herzukriegen sind, damit smtp->auth() korrekt funktioniert.

            - Sven Rautenberg

            1. Die schlaue Lösung wäre, zu recherchieren, wo die fehlenden Module herzukriegen sind, damit smtp->auth() korrekt funktioniert.

              Das Modul Authen:SASL erhalte ich via ppm angeboten. Das ist nicht das Problem, dass ich es nicht einsetzten könnte.
              Ich darf es nur jetzt nicht installieren, um den worst Case eben zu erfassen.

              Mein aktuelles Problem:
              Wie gelange ich an die Fähigkeiten des smtp-Servers um auf CRAM MD5 reagieren zu können.
              print $smtp->banner()
              oder dergleichen gibt mir nur die Firmenzeile aus.
              $smtp->help() wird nicht unterstützt.

              mfg Beat

              --
              ><o(((°>           ><o(((°>
                 <°)))o><                     ><o(((°>o
              Der Valigator leibt diese Fische
              1. Moin!

                Die schlaue Lösung wäre, zu recherchieren, wo die fehlenden Module herzukriegen sind, damit smtp->auth() korrekt funktioniert.

                Das Modul Authen:SASL erhalte ich via ppm angeboten. Das ist nicht das Problem, dass ich es nicht einsetzten könnte.
                Ich darf es nur jetzt nicht installieren, um den worst Case eben zu erfassen.

                Mein aktuelles Problem:
                Wie gelange ich an die Fähigkeiten des smtp-Servers um auf CRAM MD5 reagieren zu können.
                print $smtp->banner()
                oder dergleichen gibt mir nur die Firmenzeile aus.
                $smtp->help() wird nicht unterstützt.

                Tja, da kann ich leider nicht wirklich hilfreich werden. Perl ist nicht mein Fachgebiet, ich kenne mich nur mit SMTP aus. :-|

                - Sven Rautenberg

                1. Tja, da kann ich leider nicht wirklich hilfreich werden. Perl ist nicht mein Fachgebiet, ich kenne mich nur mit SMTP aus. :-|

                  Mein nächster Versuch

                  print "AL1:", $smtp->datasend("AUTH LOGIN\n"); # Ausgabe 1 (also true???)
                  print "AL2:", $smtp->response(), NL; # Ausgabe 3 (also true???)

                  oder wenn

                  print "AL1:", $smtp->datasend("AUTH CRAM-MD5\n"); # Ausgabe 1 (also true???)
                  print "AL2:", $smtp->response(), NL; # Ausgabe 5 (also true???)

                  Was soll ich mit diesen Rückgabewerten machen?

                  mfg Beat

                  --
                  ><o(((°>           ><o(((°>
                     <°)))o><                     ><o(((°>o
                  Der Valigator leibt diese Fische
                  1. Tja, da kann ich leider nicht wirklich hilfreich werden. Perl ist nicht mein Fachgebiet, ich kenne mich nur mit SMTP aus. :-|

                    Ich warte auf den nächsten Kenner der Materie.

                    Problem
                    smtp->auth liefert immer Null
                    ich kann also nicht sagen
                    smtp->auth or
                      do {  }

                    Das zweite Problem:
                    smtp->auth, wenn AUTHEN::SASL installiert ist, bringt keine verschlüsselte Passwortübertragung, wenn das der Server nicht unterstützt.

                    In einem praktischen Test hat smtp->auth gerade mal die identisch Base64 kodierung angewendet, de ich in meinem Eingangsposting erwähnte.

                    Zwischenfazit:
                    Net::Smtp ist frustrierend. Man bekommt nicht einmal informative true Werte zurück.

                    mfg Beat

                    --
                    ><o(((°>           ><o(((°>
                       <°)))o><                     ><o(((°>o
                    Der Valigator leibt diese Fische
                    1. Moin!

                      Das zweite Problem:
                      smtp->auth, wenn AUTHEN::SASL installiert ist, bringt keine verschlüsselte Passwortübertragung, wenn das der Server nicht unterstützt.

                      Naja, wie willst du das auch umgehen? Technisch unmöglich, selbst mit Perl. :)

                      In einem praktischen Test hat smtp->auth gerade mal die identisch Base64 kodierung angewendet, de ich in meinem Eingangsposting erwähnte.

                      Was auf rein technischer Ebene ja wohl korrekt ist.

                      Zwischenfazit:
                      Net::Smtp ist frustrierend. Man bekommt nicht einmal informative true Werte zurück.

                      Net::Smtp ist im Prinzip ein sehr dünner Wrapper, der das Herstellen und Befeuern einer TCP-Verbindung zum Mailserver etwas erleichtert. Man muss für die korrekte aber genaue Kenntnis vom SMTP-Protokoll haben, und kann nicht einfach so die Methoden für z.B. Mailempfänger und Absender in beliebiger Reihenfolge verwenden. Bzw: Können kann man es natürlich schon, die Frage ist, ob das laut SMTP-Standard auch erlaubt ist. Unendliche Beliebigkeit ist sicher nicht möglich.

                      Und auch das eigentliche Versenden des Mailtextes ist eher als rudimentär anzusehen. Net::Smtp gibt keine Hilfestellung, um beispielsweise die bereits einmal an das Modul übergebenen Mailadressen für Sender und Empfänger an dieser Stelle simpel zu wiederholen. Ebenso ist die korrekte Kodierung von Mailadressen bzw. weiteren Mail-Header-Zeilen in keinster Weise hilfreich unterstützt.

                      Die Verwendung dieses Moduls bedeutet also im Prinzip nur eine sehr geringe Erleichterung im Vergleich zum direkten Öffnen eines rohen TCP-Kanals.

                      Allerdings ist das Wrappen ggf. nicht ganz so schlecht, denn Net::Smtp baut auf Net::Cmd auf, und das hat ein paar Methoden, um die Serverantwort auszuwerten. Beispielsweise message(), code() und ok().

                      Wenn ich mir im Vergleich dazu Mailklassen für PHP anschaue, sehe ich durchweg deutlich angenehmere Funktionalität integriert. Alle Bestandteile einer Mail werden von der Klasse in der Regel erst einmal vollständig gesammelt und können deshalb in beliebiger Reihenfolge hinzugefügt werden. Erst der Befehl zum Absenden der Daten sorgt dann für die Verbindungsaufnahme mit dem Mailziel - was je nach Klasse und/oder Konfiguration dann die lokale Installation des Sendmail-Befehls sein kann, oder ein SMTP-Mailserver, oder ggf. ein noch exotischeres Ziel.

                      - Sven Rautenberg

                      1. Allerdings ist das Wrappen ggf. nicht ganz so schlecht, denn Net::Smtp baut auf Net::Cmd auf, und das hat ein paar Methoden, um die Serverantwort auszuwerten. Beispielsweise message(), code() und ok().

                        Ich habe mittlerweile auch festgestellt, dass Net:Cmd eigentlich die Basis ist. So ist es mir mit status() möglich, auf einen Error zu reagieren.

                        Wenn ich mir im Vergleich dazu Mailklassen für PHP anschaue, sehe ich durchweg deutlich angenehmere Funktionalität integriert. Alle Bestandteile einer Mail werden von der Klasse in der Regel erst einmal vollständig gesammelt und können deshalb in beliebiger Reihenfolge hinzugefügt werden. Erst der Befehl zum Absenden der Daten sorgt dann für die Verbindungsaufnahme mit dem Mailziel - was je nach Klasse und/oder Konfiguration dann die lokale Installation des Sendmail-Befehls sein kann, oder ein SMTP-Mailserver, oder ggf. ein noch exotischeres Ziel.

                        Das ist wohl die Folge davon, dass Perl nicht hauptsächlich eine CGI Sprache ist. PHP hier aber eigentlich viel mehr die Motivation hat, alles mit Bequemlichkeit abzudecken.
                        Bei Perl steht jener Webadmin im Regen, der keine Mudlule installieren darf.
                        Bei Php ist dieser Bedarf für die gleiche Funktionalität weit weniger gegeben.

                        Das ist halt die Herausforderung: Ein Mdoul zu schreiben, das alles kann und nichts verlangt. und das Ganze für eine im Grunde immer kleiner werdende Community.
                        Ich werde später meine Lösung (sendmail oder smtp) hier nochmals posten.

                        mfg Beat

                        --
                        ><o(((°>           ><o(((°>
                           <°)))o><                     ><o(((°>o
                        Der Valigator leibt diese Fische
                      2. Moin Moin!

                        Net::Smtp ist im Prinzip ein sehr dünner Wrapper, der das Herstellen und Befeuern einer TCP-Verbindung zum Mailserver etwas erleichtert. Man muss für die korrekte aber genaue Kenntnis vom SMTP-Protokoll haben, und kann nicht einfach so die Methoden für z.B. Mailempfänger und Absender in beliebiger Reihenfolge verwenden. Bzw: Können kann man es natürlich schon, die Frage ist, ob das laut SMTP-Standard auch erlaubt ist. Unendliche Beliebigkeit ist sicher nicht möglich.

                        [...]

                        Wenn ich mir im Vergleich dazu Mailklassen für PHP anschaue, sehe ich durchweg deutlich angenehmere Funktionalität integriert. Alle Bestandteile einer Mail werden von der Klasse in der Regel erst einmal vollständig gesammelt und können deshalb in beliebiger Reihenfolge hinzugefügt werden. Erst der Befehl zum Absenden der Daten sorgt dann für die Verbindungsaufnahme mit dem Mailziel - was je nach Klasse und/oder Konfiguration dann die lokale Installation des Sendmail-Befehls sein kann, oder ein SMTP-Mailserver, oder ggf. ein noch exotischeres Ziel.

                        Die Net::*-Module kümmern sich nur um die diversen (IP-)Protokolle. Anwendungen können darauf aufsetzen, in der Regel über eine weitere Schicht wie z.B. MIME::Lite. Daher halte ich den Vergleich von Mail-Klassen einer anderen Sprache wie PHP mit einer reinen Protokollklasse in Perl für mehr als unfair.

                        Wenn Du Mail-Klassen vergleichen möchtest, fang mit diesen an:

                        MIME::Lite kann alles, was man für Mail-Versand braucht, wahlweise über Net::SMTP oder über sendmail. Einfache OOP-API. Alte Versionen waren fürchterlich zickig bis hin zur Totalverweigerung, wenn kein sendmail-Executable gefunden wurde. Der größte Design-Fehler ist, dass MIME::Lite standardmäßig sendmail verwenden will. Mein Standard für E-Mail-sendende Programme, in aller Regel als Klasse, von der eine meiner Klassen erbt, um das Handling noch etwas zu vereinfachen oder z.B. um Templates benutzen zu können.

                        Mail::Sender kann ähnliches, hat aber eine etwas komplexere API.

                        Mail::SendEasy ist sehr einfach, eine Mail aus Text und/oder HTML, dazu wahlweise Attachments. Speicherfresser.

                        Mail::Builder::Simple verpackt Mail::Builder und Email::Send in eine handliche API, inklusive UTF-8, Attachments, Templates, SSL und was man sich noch so alles wünschen kann.

                        Alexander

                        --
                        Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so".
  2. hi,

    Keine Dokumentation im Netz beschreibt dies.

    War meine Site weg heut morgen?

    Hotte