How to send mail using indy component in delphi xe2? [duplicate] - delphi

This question already has answers here:
Using Gmails Outgoing SMTP from DELPHI(Indy) using TLS
(3 answers)
SendEmail with Indy components
(2 answers)
Closed 9 years ago.
First i have this code and i tried with Gmail Smtp server but i have the result with error exception : Socket °10060 !!!!
it a delay socket error , please if any one tried this before and it work for him just share the idea with me thanks !!!!
VAR SMTP : TIdSMTP; VAR MSG : TIdMSG;
MSG:=TIdMSG.Create(NIL);
TRY
WITH MSG.Recipients.Add DO BEGIN
Name:='<Name of recipient>';
Address:='<Email address of recipient>'
END;
MSG.BccList.Add.Address:='<Email address of Blind Copy recipient>';
MSG.From.Name:='<Name of sender>';
MSG.From.Address:='<Email address of sender>';
MSG.Body.Text:='<Message Body>';
MSG.Subject:='<Subject of message>';
SMTP:=TIdSMTP.Create(NIL);
TRY
SMTP.Host:='x.x.x.x'; // IP Address of SMTP server
SMTP.Port:=25; // Port address of SMTP service (usually 25)
SMTP.Connect;
TRY
SMTP.Send(MSG)
FINALLY
SMTP.Disconnect
END
FINALLY
SMTP.Free
END
FINALLY
MSG.Free
END;

Related

Indy TIdSocksServer not forwarding traffic

I am attempting to create a SOCKS 4/5 server, and I would like to use the Indy TIdSocksServer component as the foundation. It seems straight forward enough and simple to use, but I must be missing something.
I dropped a TIdSocksServer onto a new Form and configured the following:
Active: True
AllowSocks4: True
AllowSocks5: True
Bindings: 0.0.0.0:43334
Default Port: 80
Intercept: null
IOHandler: null
I added code to display 'connect' in a TMemo upon connection:
procedure TForm1.IdSocksServer1Connect(AContext: TIdContext);
begin
Memo1.Lines.Add('connect');
end;
I configured ProxyChains on a Linux host:
/etc/proxychains.conf
...
socks5 10.0.0.56 43334
When I execute the App and try to connect using ProxyChains, I get the following error:
kelly#ubuntu:~/home$ proxychains curl www.google.com
ProxyChains-3.1 (http://proxychains.sf.net)
|DNS-request| www.google.com
|S-chain|-<>-10.0.0.56:43334-<><>-4.2.2.2:53-<--timeout
|DNS-response|: www.google.com does not exist
curl: (6) Could not resolve host: www.google.com
I can confirm that the connection is established, because the text 'connect' gets added to the Memo. I also used Wireshark and observed the three-way handshake and teardown between my Ubuntu host and the Windows host.
It seems the issue is that the traffic is reaching the SOCKS server, but not getting forwarded. I acknowledge that this is absolute minimum code, but I am under the impression that the TIdSocksServer component would take care of forwarding the traffic, and I would add in supporting functions such as validating credentials for SOCKS5, etc.
Remy identified the issue with my code. In order to verify that the server was receiving connections I added a procedure which wrote to a TMemo component, which was causing a deadlock. To fix the error all I had to do was remove the procedure which was updating the TMemo component. Works as expected.

How to make TidFTPServer working with SSL

I m looking for example but can't find one working. How can i make TidFTPServer accepting SSL connection (password and data encrypted) ? I understand that i need to use IdServerIOHandlerSSLOpenSSL but I can't make it working
This is the code i did :
fIdServerIOHandlerSSLOpenSSL := TIdServerIOHandlerSSLOpenSSL.Create(nil);
fIdServerIOHandlerSSLOpenSSL.SSLOptions.SSLVersions := [TIdSSLVersion.sslvSSLv2, TIdSSLVersion.sslvSSLv23, TIdSSLVersion.sslvSSLv3, TIdSSLVersion.sslvTLSv1, TIdSSLVersion.sslvTLSv1_1, TIdSSLVersion.sslvTLSv1_2];
fFTPServer.IOHandler := fIdServerIOHandlerSSLOpenSSL;
I have the error in the ftp server:
TIDFtpServer: Exception class EIdOSSLUnderlyingCryptoError with
message 'Error accepting connection with SSL. error:1408A0C1:SSL
routines:ssl3_get_client_hello:no shared cipher

Indy SMTP and Exchange Server

I'm having a very strange problem sending emails via indy through two different mechanisms in my program. This problem is similar to [this one][1], but not exactly the same. I'm using Indy 10.5 with the latest OpenSSL libraries and Delphi XE3.
The first code snippet, which works, is a simple SMTP client I wrote. Here's an example of how I set it up. This isn't the exact code but it should give you an idea.
FIndySMTP.Intercept := FIndyLogFile;
FIndySMTP.IOHandler := FIndySSLHandler;
FIndyMessage.From.Address := FEmailAddress;
FIndySSLHandler.Destination := FSMTPAddress + ':' + IntToStr(FSMTPPort);
FIndySSLHandler.Host := FSMTPAddress;
FIndySSLHandler.Port := FSMTPPort;
FIndySMTP.Host := FSMTPAddress;
FIndySMTP.Port := FSMTPPort;
FIndySMTP.Username := FAccountName;
FIndySMTP.Password := FAccountPass;
FIndySMTP.AuthType := satDefault;
FIndySMTP.UseEhlo := True;
FIndySMTP.UseTLS := utUseExplicitTLS
FIndySMTP.Connect;
try
if FIndySMTP.Connected = True then
FIndySMTP.Send(FIndyMessage);
finally
FIndySMTP.Disconnect;
end;
This generates a successful email with the log:
Recv 10/9/2015 10:41:02 AM: 220 server.server1.local Microsoft ESMTP MAIL Service ready at Fri, 9 Oct 2015 13:41:01 -0400<EOL>
Sent 10/9/2015 10:41:02 AM: EHLO DEIMOS<EOL>
Recv 10/9/2015 10:41:02 AM: 250-server.server1.local Hello [68.14.239.173]<EOL>250-SIZE 36700160<EOL>250-PIPELINING<EOL>250-DSN<EOL>250-ENHANCEDSTATUSCODES<EOL>250-AUTH<EOL>250-8BITMIME<EOL>250-BINARYMIME<EOL>250 CHUNKING<EOL>
Sent 10/9/2015 10:41:02 AM: RSET<EOL>
Recv 10/9/2015 10:41:02 AM: 250 2.0.0 Resetting<EOL>
....(The rest snipped)
Now the second method, which uses Report Builder built in Email components to send a Report via email (again, some code is snipped for brevity, the real clue is in the logs):
lIOHandler.Destination := Host + ':' + IntToStr(Port);
lIOHandler.Host := Host;
lIOHandler.Port := Port;
TheReport.EmailSettings.HostAddress := Host;
TheReport.EmailSettings.UserName := UserName;
TheReport.EmailSettings.Password := Password;
lEmail.SMTP.OnEmailError := FMain.EmailErrorEvent;
TppSMTPIndy(lEmail.SMTP).IndySMTP.OnFailedRecipient := FMain.idSMTPFailedRecipient;
TppSMTPIndy(lEmail.SMTP).IndySMTP.Intercept := FMain.IdLogFile1;
TppSMTPIndy(lEmail.SMTP).IndySMTP.Port := Port;
TppSMTPIndy(lEmail.SMTP).IndySMTP.IOHandler := lIOHandler;
TppSMTPIndy(lEmail.SMTP).IndySMTP.UseTLS := utUseExplicitTLS;
TppSMTPIndy(lEmail.SMTP).IndySMTP.AuthType := satDefault;
TppSMTPIndy(lEmail.SMTP).IndySMTP.UseEhlo := True;
TheReport.SendMail;
You can see that with the exception of using the Report Builder TppSMTPIndy, every setting is the same. Yet the email does not get sent, and the log looks like this:
Stat Connected.
Recv 10/9/2015 10:44:31 AM: 220 server.server1.local Microsoft ESMTP MAIL Service ready at Fri, 9 Oct 2015 13:44:28 -0400<EOL>
Sent 10/9/2015 10:44:31 AM: EHLO DEIMOS<EOL>
Recv 10/9/2015 10:44:31 AM: 250-server.server1.local Hello [68.14.239.173]<EOL>250-SIZE 36700160<EOL>250-PIPELINING<EOL>250-DSN<EOL>250-ENHANCEDSTATUSCODES<EOL>250-AUTH<EOL>250-8BITMIME<EOL>250-BINARYMIME<EOL>250 CHUNKING<EOL>
Sent 10/9/2015 10:44:31 AM: QUIT<EOL>
Recv 10/9/2015 10:44:31 AM: 221 2.0.0 Service closing transmission channel<EOL>
Stat Disconnected.
You can see that a QUIT is sent immediately after receiving HELLO. This is why my question is different than the link above. That person was at least receiving a STARTTLS request.
What could be causing Indy to send a QUIT immediately after receiving a HELLO? I am not getting any errors. It just silently fails and the program moves on.
Now here's a kicker hint. If I set the AuthType to satNone in the Report Builder example it works. While in my first example I can set the AuthType to satNone and satDefault and both work.
Any ideas?
Thanks a lot for your time.
What could be causing Indy to send a QUIT immediately after receiving a HELLO?
The only time QUIT is sent is when TIdSMTP.Disconnect() is called.
The only times that TIdSMTP itself calls Disconnect() are when:
an exception is raised inside of TIdSMTP.Connect(), such as if the server's greeting has an error code, or there is a unexpected problem parsing the server's greeting or EHLO response.
an exception is raised inside of TIdSMTP.StartTLS(), which is called by TIdSMTP.Authenticate() (which is called by TIdSMTP.Send() if not already called beforehand). However, since you have set UseTLS=utUseExplicitTLS and the server's EHLO response does not advertise support for STARTTLS, TIdSMTP.StartTLS() is effectively a no-op on this server.
I am not getting any errors. It just silently fails and the program moves on.
Unless Report Builder is catching exceptions internally and not passing them into your code, then the most likely scenario is that Report Builder itself is calling TIdSMTP.Disconnect() without calling TIdSMTP.Send() first. The RSET command shown in your log is sent by TIdSMTP.Send() at the beginning of the email (BTW, more recent versions of Indy no longer send RSET unless the email fails with an SMTP error code). Report Builder is likely just skipping Send(), and I can think of one possible reason why it might do that.
AuthType=satDefault uses the AUTH LOGIN command (which is not a secure command), but your server's EHLO response is not advertising support for LOGIN authentication (in fact, it is not advertising support for any authentications at all). As such, TIdSMTP.Authenticate() will skip authentication on this server by default and return False, and also set the TIdSMTP.DidAuthenticate property to False. Maybe Report Builder is calling TIdSMTP.Authenticate() directly and checking the result before calling TIdSMTP.Send(). Your non-ReportBuilder example does not do that validation. Setting AuthType=satNone will cause TIdSMTP.Authenticate() to return True and set the TIdSMTP.DidAuthenticate property to True.
If the server happens to support LOGIN authentication (some servers do support it without advertising it), you can set the TIdSMTP.ValidateAuthLoginCapability property to False (it is True by default) to make satDefault attempt authentication as long as the TIdSMTP.Username property has been assigned a non-blank string.

Indy HTTP: Cannot change Host header [duplicate]

This question already has an answer here:
Delphi Indy https request with custom DNS resolving
(1 answer)
Closed 3 years ago.
I'm trying to change Host header before sending get request to a website. I do that using this code:
IdHTTP1.Request.HOST := 'example.com';
memo1.Text := IdHTTP1.Get('http://stackoverflow.com');
showmessage(IdHTTP1.Request.Host); // Expected to be example.com but it's stackoverflow.com
I've got a big problem here. Even though I change Host header before getting URL, Host header will change to stackoverflow.com again. What am I doing wrong? I want to change request header to example.com.
Thanks
Unfortunately, there is no option to specify a custom Host header that specifies a different hostname than the one specified in the URL. The URL has priority. Any hostname you specify in the Request.Host or even the Request.CustomHeaders is overwritten by the hostname in the URL.
If the hostname in the URL is not registered with DNS, you will not be able to reach it with any web browser, or most HTTP libraries including TIdHTTP. While the HTTP protocol itself defines how the Host header works, current web browser technology uses the hostname from the URL, and so does TIdHTTP. So it does not make sense to have a website that uses a hostname that is not registered with DNS in the first place, as most modern client systems would not be able to retrieve it. DNS is required to convert the URL's hostname into an IP address, and then the same hostname is put into the Host header.
As Remy Lebeau said, it seems there is no way to specify a custom Host header. So I decided to modify IdHTTP codes just a little bit.
First I copied IdHTTP.pas (C:\Program Files (x86)\Embarcadero\Studio\XX.0\source\Indy10\Protocols\IdHTTP.pas) to my project directory and added it to my project. Then in TIdCustomHTTP.PrepareRequestmethod (Line 1792) I changed the code like this:
if (TextIsSame(FURI.Protocol, 'http') and (FURI.Port = IntToStr(IdPORT_HTTP))) or {do not localize}
(TextIsSame(FURI.Protocol, 'https') and (FURI.Port = IntToStr(IdPORT_https))) then {do not localize}
begin
if FURI.Host = 'stackoverflow.com' then
ARequest.Host := 'example.com'
else
ARequest.Host := FURI.Host;
end else begin
if FURI.Host = 'stackoverflow.com' then
ARequest.Host := 'example.com' + ':' + FURI.Port {do not localize}
else
ARequest.Host := FURI.Host + ':' + FURI.Port; {do not localize}
end;
I know it's not the best way and modifying libraries is not a good idea but it worked for me.
So if I change the examples above, stackoverflow.com to myblog.wordpress.com and example.com to anotherblog.wordpress.com, By IdHTTP1.Get('http://myblog.wordpress.com') we will get anotherblog.wordpress.com content.

Indy Mail server

Following is my code for the smtp client for sending email
VAR SMTP : TIdSMTP;
MSG : TIdmessage;
begin
MSG:=TIdmessage.Create(NIL);
TRY
WITH MSG.Recipients.Add DO BEGIN
Name:='me025';
Address:='me025#gmail.com'
END;
MSG.BccList.Add.Address:='me025#yahoo.com';
MSG.From.Name:='self025';
MSG.From.Address:='self025#127.0.1.1';
MSG.Body.Text:='<Message Body>';
MSG.Subject:='<Subject of message>';
SMTP:=TIdSMTP.Create(NIL);
TRY
SMTP.Host:='127.0.1.1'; // IP Address of SMTP server
// 127.0.1.1
SMTP.Port:=25; // Port address of SMTP service (usually 25)
SMTP.Connect;
TRY
SMTP.Send(MSG)
FINALLY
SMTP.Disconnect
END
FINALLY
SMTP.Free
END
FINALLY
MSG.Free
END;
end;
which will use a SMTPserver in same pc
the smtp server is a working indy 10 unofficial sample
http://indy.fulgan.com/ZIP/Indy10demo.zip
whenever i connect to the server "Socket error # 11001 Host not found " error occers
but smtp server is receiving all the parameters correctly and showing correctly on the GUI
Has your PC an address of 127.0.1.1 or are you trying to use localhost (127.0.0.1)? People should get used to DNS names... as soon as IPv6 will become mainstream at least people won't be able any longer to remember IP numbers easily :)

Resources