Autor Beitrag
tif
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46
Erhaltene Danke: 1

Winxxx
TP, BP, Delphi 1 - 2009
BeitragVerfasst: Mi 08.12.10 09:48 
Hallo und sorry, ich muß nochmal nerven.

Ich versuche seit geraumer Zeit, per TidSMTP eine Email über einen Exchange - Server zu versenden.
Ich trage einmal zusammen, was ich schon habe:

Auf dem Server ist SMTP aktiviert, z.B. per Outlook klappt der Mailversand.
Der SMTP - Server meldet sich wie folgt:

Zitat:

Stat Connected.
Recv 08.12.2010 06:58:03: 220 *server*.*domain* Microsoft ESMTP MAIL Service ready at Wed, 8 Dec 2010 06:57:56 +0100<EOL>
Sent 08.12.2010 06:58:03: EHLO getec_2_vm<EOL>
Recv 08.12.2010 06:58:03: 250-*server*.*domain* Hello [192.168.0.94]<EOL>250-SIZE<EOL>250-PIPELINING<EOL>250-DSN<EOL>250-ENHANCEDSTATUSCODES<EOL>250-STARTTLS<EOL>250-X-ANONYMOUSTLS<EOL>250-AUTH NTLM<EOL>250-X-EXPS GSSAPI NTLM<EOL>250-8BITMIME<EOL>250-BINARYMIME<EOL>250-CHUNKING<EOL>250-XEXCH50<EOL>250-XRDST<EOL>250 XSHADOW<EOL>
Sent 08.12.2010 06:58:06: STARTTLS<EOL>
Recv 08.12.2010 06:58:06: 220 2.0.0 SMTP server ready<EOL>
Sent 08.12.2010 06:58:11: QUIT<EOL>


Ich nehme daraus, dass die Autorisierung per NTLM erfolgen sollte.
Basiserend auf diesem Code habe ich folgendes:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
procedure TForm2.SendNow2;
var MsgSend:TIdMessage;
   SMTP:TIdSMTP;
   SASLNTLM : TIdSASLNTLM;
   UserPassProv:TIdUserPassProvider;
   textPart:TIdText;
   Logfile:TIdLogFile;
   sentOK:Boolean;
begin
  logfile:=NIL;
  MsgSend:=TIdMessage.Create;  //create the message
  with MsgSend do
     begin
        Body.Text:='Test';
        From.Text := 'willy@mydomain.de';
        Recipients.EMailAddresses := 'tino@homedomain.de';
        Subject := 'Test';     // set the subject
        Priority := mpNormal;  // set the priority (note that you could add to
                               // Destination to support different priorities)
     end;
  try
    SMTP:=TIdSMTP.Create;     //create the SMTP object
    try
//*************
     with TIdSSLContext.Create do
      Free;   //try to create a SSL context (immediately disposes of it)
//*************
             //- need OpenSSL to support this, if it fails, it will fall into the exception
      smtp.IOHandler := TIdSSLIOHandlerSocketOpenSSL.Create(smtp);     //if we succeed, then we can create a SSL socket handler and assign it to the IOHandler
      smtp.UseTLS := utUseExplicitTLS;                                 //and we can mark the we can use tls
    except
      smtp.IOHandler := TIdIOHandler.MakeDefaultIOHandler(smtp);       //the SSL failed to create, so make the default IO handler
      smtp.UseTLS := utNoTLSSupport;                                   //mark that we have no TLS support
   end;
   smtp.ManagedIOHandler := True;    //either way, we now have a ManagedIOHandler

    if cb_dbg.Checked then   //if we marked that we wanted debugging, we need to do some setup
       begin
       logFile := TidLogFile.Create(nil);          //create the log file
       logFile.FileName:='Log.txt';                //set the default log file name - NOTE: you could get fancy with this, but I normally don't use it
       logFile.Active:=true;                       //activate the log file (creates the file and intializes everything)
       smtp.IOHandler.Intercept := logFile;        //set the logFile to the intercept of the IOHandler to capture the events
       smtp.IOHandler.OnStatus  := smtp.OnStatus;  // - not sure why we do this, copied code -
       end;

    try
      SMTP.AuthType := satSASL;
      SMTP.UserName := le_user.text;        // User Input
      SMTP.Password := le_password.Text;    // User Input

      userPassProv:=TIdUserPassProvider.Create;  //create the user/pass provider - this handles the login functions for SASL
      userPassProv.UserName:=SMTP.UserName;      // setup user name
      userPassProv.Password:=SMTP.Password;      // & password

      if SMTP.AuthType=satSASL then //if we are going to use SASL - basically, SASL just encrypts the login, everything else is still clear text
        begin
         SASLNTLM := TIdSASLNTLM.Create;
         SASLNTLM.UserPassProvider:=userPassProv;
         SMTP.SASLMechanisms.Clear;
         SMTP.SASLMechanisms.Add.SASL:=SASLNTLM;
        end;
      {General setup}
      SMTP.Host := le_server.text;             //setup the server name
      SMTP.Port := StrToInt(le_smtpport.Text); //setup the server port

      {now we send the message}
      SMTP.ConnectTimeout := 1000;
      SMTP.Connect;
      if not SMTP.Authenticate then                                    //authenticate with the server - this will automatically use SASL if configured and supported
      begin
        MessageDlg('An error occurred attempting to send your e-mail. The error was : Unable to authenticate.', mtError, [mbOK], 0);
        exit;
      end;
      try
         try
           ShowMessage('Before Send');
           SMTP.Send(MsgSend);  //send the message
           ShowMessage('After Send');
           SentOk:=true;        //indicate success
         finally
            SMTP.Disconnect;                                           //disconnect from the server
         end;
      except on E :Exception do                                        //if we had a failure, say so
         begin
         MessageDlg('An error occurred attempting to send your e-mail. The error was : '+E.Message, mtError, [mbOK], 0);
         SentOk:=false;                                                //set failure
         end;
      end;
    finally
    SMTP.Free;                                                         //free the memory
    end;
  finally
     if logFile<>nil then                                              //if we had a log file, free that
        logFile.Free;
     MsgSend.Free;                                                     //free the message
  end;
end;


Ich habe auch schon herausgefunden, dass ich hierfür die SSL - DLLs benötige:
libeay32.dll,
ssleay32.dll,
vsinit.dll

die jetzt auch verfügbar sind.

Aber ich bekomme es trotzdem einfach nicht hin, die Mail zu versenden.

Wenn ich die Zeilen zwischen /********** , also die Prüfung auf Verfügbarkeit der SSL - Komponenten, drin habe, dann bringt Indy bereits beim Authentifizieren den Fehler "The specified SASL handlers are not ready".
Die Prüfung selbst klappt aber noch.

Kommentiere ich diese Zeilen aus, dann läuft das Programm bis zum SMTP.Send() durch und geht dann fest. Keine Reaktion mehr, kein weiterer Eintrag im Fehlerprotokoll.

Unterschwellig habe ich das Gefühl, dass das mit einem mehrfachen Laden der SSL - Dlls in Zusammenhang steht. Komischerweise wird IdSSLOpenSSL.LoadOpenSSLLibrary bei jeder Gelegenheit, die korrespondierende UNLoadOpenSSLLibrary aber nie bzw. erst zum Programmende bei finalization aufgerufen. Es sieht so aus, als klappt das mehrfache Laden der DLLs nicht so recht.

Vielleicht bin ich aber auch auf dem falschen Dampfer.

Also, hat jemand von Euch schon mal erfolgreich per Indy Mails über einen Exchange-SMTP - Server mit NTLM Autorisierung versendet?

Vielen Dank vom ratlosen
Tino
tif Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 46
Erhaltene Danke: 1

Winxxx
TP, BP, Delphi 1 - 2009
BeitragVerfasst: Di 04.01.11 20:32 
Hallo again im neuen Jahr!

Freudig erregt kann ich berichten, dass der SMTP - Mailversand jetzt über den Exchange - Server gelungen ist!

Der gepostete Code ist vollkommen korrekt, auch NTLM passt.

Durch den Tipp eines sehr netten Mitlesers bin ich darauf gekommen, doch einmal verschiedene OpenSSL - Versionen auszuprobieren. U.a. bin ich hierbei auch auf diese Downloadquelle gestoßen ftp://indy.fulgan.com/SSL/

Und was soll ich sagen: Mit der OpenSSL - Version 1.0.0c klappte es auf Anhieb (Indy Development Snapshot 10_4525).

Danke für die Unterstützung, jetzt rockt es!

Viele Grüße
Tino

Siehe auch Thread im Entwicklerforum

Für diesen Beitrag haben gedankt: LuMa86