What do the SMTP Indy component security and authentication properties do? - delphi

I am using the indy components to implement emails in a delphi application. I am specifically using the TidSMTP component. I need to effectively support all major email servers. I use Mozilla Thunderbird as my email client and am comparing the smtp properties with those in the TidSMTP component. I have attempted to find documentation that describes the relationship between the TidSMTP properties, but have not been able to figure it out.
Can someone explain how these compare and what they do:
In Thunderbird:Connection Security: (None, STARTTLS, SSL/TLS).
In TidSMTP.UseTLS (utNoTLSSupport, utUseImplicitTLS, utUseRequireTLS, utUseExplicitTLS)
In Thunderbird:Authentication method: (No Authentication, Normal Password, Encrypted Password, Kerberos/GSSAPI, NTLM)
In TidSMTP (username, password, with useAuthentication method)
I also see other TidSMTP properties: UseEhlo, UseVerp, UseNagle. Do I need to be using these? What do they do?

When using STARTTLS, the server's listening port is initially unencrypted upon connecting. When a client connects, it can send an optional STARTTLS command to the server, if the server supports it, to dynamically perform the SSL/TLS handshake at that time. This allows legacy non-SSL/TLS clients to continue connecting to that same port, while allowing newer SSL/TLS-enabled clients to use SSL/TLS if available on the server. This corresponds to UseTLS=utUseExplicitTLS in Indy. You need to set UseEHLO to True in order to use UseTLS=utUseExplicitTLS, as the EHLO command is how TIdSMTP discovers whether the server supports the STARTTLS command or not.
When using SSL/TLS instead of STARTTLS, the server's listening port is always using encryption and the client must initiate the SSL/TLS handshake immediately upon connecting before any other data can be exchanged. This corresponds to UseTLS=utUseImplicitTLS in Indy. There is no STARTTLS command used.
For authentication, TIdSMTP has two options - the old (and unsecure) AUTH LOGIN command that is defined by the original SMTP spec, and SMTP extensions for SASL-based hashing/encryption algorithms (Kerberos, GSSAPI, NTLM, etc are implemented as SASL algorithms).
To use SASL, set TIdSMTP.AuthType to satSASL and then fill in the TIdSMTP.SASLMechanisms collection to point at separate TIdSASL-derived components for the algorithms you want to support in your app. Indy has native SASL components for DIGEST-MD5, CRAM-MD5, CRAM-SHA1, NTLM (experimental), ANONYMOUS, EXTERNAL, OTP, PLAIN, SKEY, and LOGIN (SASL wrapper for AUTH LOGIN). If you need another algorithm (Kerberos or GSSAPI, for instance), you will have to write your own TIdSASL-derived component. For algorithms that use Username/Password, the values must be assigned to a separate TIdUserPassProvider component that is then assigned to the SASL components (the TIdSMTP.UserName and TIdSMTP.Password properties are not used with SASL). The more SASL algorithms you support, the wider the number of servers you will be able to support.
For servers that still support AUTH LOGIN, it can be used either by setting TIdSMTP.AuthType to satDefault (and optionally setting TIdSMTP.ValidateAuthLoginCapability to False if the server supports AUTH LOGIN but does not report it in response to the EHLO command) and then filling in the TIdSMTP.UserName and TIdSMTP.Password properties, or by including the TIdSASLLogin component in the TIdSMTP.SASLMechanisms collection.
UseVerp and UseNagle have nothing to do with security. VERP is an SMTP extension for detecting bouncing emails due to undeliverable errors. Nagle is a networking algorithm for optimizing network data packets.

Related

Chilkat Rest - How authorized with certificate

when I try to query a test, freely available, environment, the command below will return the required answer...
lnSuccess = loRest.Connect("https://api.test.....com", 443, 1, 1)
But how to ask the production environment where certificate verification is required?
Many thanks
J.B.
You would use the Chilkat Socket object to connect, then use Rest.UseConnection. See https://www.example-code.com/foxpro/rest_useSocketObject.asp
The reason Chilkat did it this way is to avoid needing to add all of the TLS connection related properties to Rest. Instead, you can use the full flexibility of the Socket object to make the connection, then just tell Rest to use the already-established connection.
To make the TLS connection with certificate verification, call Socket.SetSslClientCert, SetSslClientCertPem, or SetSslClientCertPfx (see https://www.example-code.com/foxpro/socket_tlsClientCert.asp) prior to connecting.

creating idhttpserver with ssl encryption

I am not good with delphi yet, but based on some examples I have managed to create simple http server with no more than 10 users.
There are 2 main problems I don't know how to solve yet.
proper way to authenticate, manage users - sessions
main problem, connection must be secure, so SSL encryption is needed, how to implement it?
Any example I found in relation with idhttpserver and openssl, was not quite complete or with older version of Indy.
I am currently working with Delphi XE2 with Indy 10 components.
proper way to authenticate, manage users - sessions
TIdHTTPServer manages HTTP sessions for you if you set the TIdHTTPServer.SessionState property is true (it is false by default). TIdHTTPServer uses cookies for session management, so your clients need to have cookies enabled.
Authentication has to be performed manually, but how you do that depends on whether your clients are using HTTP-based or HTML-based authentication.
For HTTP authentication, there are ARequestInfo.UserName and ARequestInfo.Password properties available. If not valid, send an appropriate 401 response back to the client (if you set the AResponseInfo.AuthRealm property to a non-blank string, TIdHTTPServer will send a 401 response for you). By default, TIdHTTPServer only supports BASIC authentication. If you want to support other authentication schemes, you will have to use the TIdHTTPServer.OnParseAuthentication event, and send the 401 reply manually so you can send back appropriate WWW-Authenticate headers. Either way, if the client is validated, you can use HTTP sessions to keep the client logged in between requests. The AResponseInfo.Session and AResponseInfo.Session properties point at the current session. If TIdHTTPServer.AutoStartSession is true (it is false by default), TIdHTTPServer creates new sessions automatically. Otherwise, you can call TIdHTTPServer.CreateSession() yourself when needed. TIdHTTPSession has a Content property that you can store session-specific data in. Or you can derive a new class from TIdHTTPSession and then use the TIdHTTPServer.OnCreateSession event to create instances of that class.
For HTML authentication, you have two choices, depending on how you configure your HTML:
if your HTML <form> tag does not have an enctype attribute, or it is set to application/x-www-webform-urlencoded, TIdHTTPServer will store the raw webform data in the ARequestInfo.FormParams property, and if TIdHTTPServer.ParseParams is true (which it is by default), the data will also be parsed into the ARequestInfo.Params property for you.
if your HTML <form> tag has an enctype attribute set to multipart/form-data, you will have to parse the content of the ARequestInfo.PostStream manually, as TIdHTTPServer does not yet parse that data for you (examples have been posted many times before on many different forums on how to parse that data manually using Indy's TIdMessageDecoderMIME class). By default, ARequestInfo.PostStream points at a TMemoryStream object. You can use the TIdHTTPServer.OnCreatePostStream event to create an instance of a different TStream-derived class, if desired.
main problem, connection must be secure, so SSL encryption is needed, how to implement it?
Before activating the server:
assign a TIdServerIOHandlerSSLBase-derived component, such as TIdServerIOHandlerSSLOpenSSL, to the TIdHTTPServer.IOHandler property and configure it as needed (certificate, peer validation, SSL version(s), etc). In the case of OpenSSL, you will have to deploy the 2 OpenSSL library binaries libeay32.dll and ssleay32.dll (or non-Windows platform equivalents) with your app if they are not already pre-installed on the target OS, or if you want to ensure your app uses a specific version of OpenSSL. At this time, OpenSSL is the only encryption that Indy supports natively, but there are third-party solutions available that are compatible with Indy, such as EldoS SecureBlackbox.
fill in the TIdHTTPServer.Binding property with a binding for your desired HTTPS port (443 is the default HTTPS port). Typically you should create 2 bindings, one for HTTP port 80 and one for HTTPS port 443. Inside your OnCommand... handlers, if you receive a request that requires SSL/TLS encryption, you can check the port that the request was made on (AContext.Binding.Port) and if not HTTPS then redirect (AResponseInfo.Redirect()) the client to retry the request on the HTTPS port.
assign a handler to the TIdHTTPServer.OnQuerySSLPort event and have it set its VUseSSL parameter to True when its APort parameter matches your HTTPS port. UPDATE starting with SVN rev 5461, an OnQuerySSLPort handler is no longer needed if your only HTTPS port is 443.

Delphi Redirect SSL tcp data to other port no ssl

I am working with D5 ( thats a fact ). I have Indy9 installed.
I'm trying to receive data of IdMappedPortTCP on port 8041 (SSL) and redirect the data to a Tserversocket on port 8040. So I will have support of SSL over Tserversocket.
I use the following code:
var
masterdir:String;
begin
masterdir:=Extractfilepath(paramstr(0));
IdMappedPortTCP1.Active:=false;
datamodule2.IdMappedPortTCP1.MappedHost:='192.168.0.3';
datamodule2.IdMappedPortTCP1.MappedPort:=8041;
datamodule2.IdMappedPortTCP1.DefaultPort:=8040;
IdServerIOHandlerSSL1.SSLOptions.RootCertFile:=masterdir+'mycert.pem';
IdServerIOHandlerSSL1.SSLOptions.CertFile:=masterdir+'mycert.pem';
IdServerIOHandlerSSL1.SSLOptions.KeyFile:=masterdir+'key.pem';
IdMappedPortTCP1.IOHandler:=IdServerIOHandlerSSL1;
IdMappedPortTCP1.Active:=true;
end;
If I don't use SSL everything is fine. But when I use SSL teh request never comes to the port 8040 encrypted and I need it not encrypted so I can proccess it.
It is not clear from your description whether TServerSocket is using SSL on port 8040 or not. It makes a big difference in how you set up TIdMappedPortTCP. However, from your description, you have the MappedPort and DefaultPort property assignments backwards, at least. DefaultPort is the port that TIdMappedPortTCP listens on, so it should be 8041. MappedPort is the port that TIdMappedPortTCP connects to, so it should be 8040.
It is not common to have unencrypted and encrypted connections on the same port. Most protocols use separate ports. Is that the case here? Is port 8040 unencrypted, and port 8041 encrypted?
If you want TIdMappedPortTCP to accept encrypted and unencrypted clients on separate ports, you need to add 2 entries to the TIdMappedPortTCP.Bindings collection, one for each port, and not use the DefaultPort property at all. In the TIdMappedPortTCP.OnConnect event, you can detect which port the client connected to, and then configure the AThread.OutboundClient accordingly before it connects to TServerSocket.
It is not wise to have unencrypted and encrypted clients connect to the same port. In that scenario, you have to sniff the first few bytes to know if the client is sending an SSL handshake or not, and then act accordingly. It is easier to just use separate ports instead. However, some protocols do allow a client to connect to an unencrypted port and then send a command to activate encryption when needed. In that scenario, you would only need 1 port in TIdMappedPortTCP, so you can either define 1 Binding or use DefaultPort.
TIdMappedPortTCP is primarily intended to be a straight passthrough of raw bytes back and forth between the client and the target server. If TServerSocket is using SSL and you want the client to talk to TServerSocket using SSL properly, you should not be using TIdServerIOHandlerSSL at all. Let TIdMappedPortTCP pass the client's raw encrypted data as-is to TServerSocket, and vice versa. They should establish a secure session with each other, not with you. This is especially important if either one of them performs peer identity validation.
If you need to process encrypted data that is being exchanged between the client and TServerSocket, you have to decrypt and re-encrypt the data as it passes through TIdMappedPortTCP (which means you are acting as a man-in-the-middle attacker, which peer validation is meant to prevent). To do that, you have to establish separate SSL sessions between the client and TIdMappedPortTCP, and between TIdMappedPortTCP and TServerSocket. Assigning a TIdServerIOHandlerSSL to TIdMappedPortTCP only facilitates the session with the client. You have to manually setup a session with TServerSocket. To do that, you have to manually assign a new TIdSSLIOHandlerSocket object to the AThread.OutboundClient.IOHandler property in the OnConnect event. TIdMappedPortTCP will not handle that for you.
If, however, TServerSocket is not using SSL, and you are using TIdMappedPortTCP as an SSL gateway into TServerSocket, then you can skip the OutboundClient.IOHandler assignment, since you would only need 1 SSL session, between TIdMappedPortTCP and the client.
Now, with that said, there are some problems in Indy 9. The TIdSSLIOHandlerOpenSSL.PassThrough property is False by default (thus assuming encryption is initially active), and TIdServerIOHandlerSSL assumes that every accepted client connection is using SSL, even if it really is not. If an unencrypted client connects to TIdMappedPortTCP with TIdServerIOHandlerSSL assigned, the client will not be handled correctly. These issues were fixed in Indy 10. But in Indy 9, you will not be able to handle encrypted and unencrypted clients in the same TIdMappedPortTCP component. If you are only dealing with encrypted clients though, you won't run into a problem. Otherwise, create 2 TIdMappedPortTCP components, one listening on an unencrypted port, the other listening on an encrypted port. They can share the same event handlers. If needed, you can use the AThread.Connection.Socket.Binding.Port property to know which port the client is connected to.

Delphi Indy - How to get SSL certificates for a SSL-TCP Client/Server link with Indy 10

I'm completely new to SSL and these ciphering stuff but I need to make communicate client and server Delphi XE6 apps running on mobile devices. The TCP communication has to be safely ciphered.
To start, I simply wrote the Delphi/Indy TIdTCPServer/TIdTCPClient based Win32 client and server exchanging strings. (Issued from the indy10clieservr demos found on SourceForge: svn://svn.code.sf.net/p/indy10clieservr/code/1_sample Simple String Exchange)
I tried to modify them to cipher the communication by adding a TIdServerIOHandlerSSLOpenSSL component on the Server, and a TIdSSLIOHandlerSocketOpenSSL on the Client, attaching them respectively to the TIdTCPServer and TIdTCPClient.
I set their following properties on both sides:
- SSLOptions.Method = sslvSSSv23
- SSLOptions.Mode = sslmServer / sslmClient (respectively)
- SSLOptions.VerifyDepth = 2
And I added an OnGetPassword Event handler setting the Password parameter to 'password' on both sides too.
(What is the role of this password ? Is it critical for the privacy of the communication ? What if it is found by analysing/reverse enginering the binary file ?)
Finaly, in the server's OnConnect event handler I set the TIdSSLIOHandlerSocketBase(AContext.Connection.IOHandler).PassThrough property to false.
But what about the 3 SSLOptions certificate properties ??
- CertFile
- KeyFile
- RootCertFile
How to generate and deploy them on my target devices to make run my SSL layer on the client and server ?
Moreover, is there something special to do or to take into acount if I intend to deploy later my server and/or clients on IOS or Android mobile device.
I'm aware that I have few knowledge on this SSL topic. Sorry if I ask something trivial. Any basic documentation explaining all of this tricky stuff to a newbie would be greatly appreciated.
As I told you in my answer to your same question on the Embarcadero forums, certificates are optional. They are used to allow peers to validate each other's identities, not for encryption. Certificates help avoid man-in-the-middle attacks, by allowing a client to verify it is connected to the correct server it is expecting to be connected to, and vice versa. It is not common for a client to have a certificate, except maybe when making a proprietary system where only authorized clients are allowed to connect. But it is pretty common for servers to have certificates, at least. Certificates can be password-protected, so if you do use them, you have to provide the correct password for the certificate(s) that you are actually using. A certificate's password can't be retrieved from the certificate itself, but if an attacker gains access to your certificate files then you have bigger issues to deal with.
As for SSLv23, it is a wildcard that allows dynamic version negotiation in cases where
client and server support different SSL/TLS versions. SSLv23 allows them
to figure out and use the highest version common to both parties. If a server
needs to support a wide range of clients, it makes sense to use SSLv23 on
the server side. Not so much on the client side. Since you control both
client and server, you should use use a specific version instead, preferrably
TLSv1 or higher.

Methods of transferring data securely between an iPhone app and an Arduino server

I'm trying to make a secure protocol between an iPhone app and an Arduino server. The goal is that the iPhone app makes a request to an Arduino server and the server only processes it if it has the proper credentials of one form or another. I'm not really sure how to approach this problem. Any suggestions are much appreciated!
Unfortunately there are no truly secure communication options available on Arduino. The basic problem is that SSL libraries have not been ported to this platform, partly owing to the fact that the 8-bit processors the platform is built around are not very powerful. Having said that there are some things you can do, but you'll have to do them yourself:
Basic access authentication is a very insecure method of controlling access to HTTP pages so it isn't recommended. Digest access authentication, on the other hand, employs one-way cryptographic encoding (hashing). It only requires MD5 library, which, is actually available for Arduino. What you'll need to do is modify the source code for the Web Server class to support digest access authentication: AFAIK it does not support it out of the box.
If this seems to difficult, you could implement something fairly basic (and not very secure, but better than nothing) yourself. It might look like this:
The first GET request comes in from a client
The server responds with "not authorized" response, embedding in the response a token which is related to (perhaps a hash of) the requesting IP address. You could make the original timeframe part of the hash as well, and give such tokens a limited lifetime.
If the next request from the same IP address includes a hash based on some secret code + the token sent, the next request is honored.
Now this will not protect you from IP address spoofing, and many other things I probably haven't thought of. However, it will give you a modicum of security (and a tiny bit of security through obscurity, if you believe in this sort of a thing). You could ask for (slightly) more elaborate schemes on superuser
You might be able to just use authenticated messages built on shared secrets. The message will contain [at minimum] a message type, message body, timestamp, and message digest. You create the digest by HMACing the other stuff with a shared secret. (Type HMAC Arduino into Google for libaries and code.) The message is sent over TCP or UDP (i prefer it). The Arduino computes digest of message, checks it, validates data, and then acts on message.
One thing I like to do is implement port-knocking or something at the network layer in front of the application server. This prevents unwanted traffic from reaching the custom (and possibly vulnerable) command server. This can be done stealthily (see Silent Knock) or obviously. The network protections can also be implemented by a dedicated device that does the heavily lifting and disqualifies much rogue traffic before it reaches the Arduino.

Resources