0 votes

We are trying to get to the bottom of a refusal by Limilabs IMAP client to connect to a dovecot IMAP server running on RHEL6.

The error we're getting is as follows:

Limilabs.Client.ServerException: Tried to read a line. No data received. Please make sure that antivirus and firewall software are disabled or configured correctly. ---> System.Exception: Tried to read a line. No data received.

We are able to successfully connect to this dovecot server using openssl from the machine running the Limilabs client, and we get this as expected:

  • OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN] Dovecot ready.

If we run ssldump on the underlying connection to see the flow of the traffic, we see the following (handshake is successful, and has been removed):

The dovecot IMAP server gives the opening IMAP line to Limilabs:

1 11 0.1113 (0.0557) S>C application_data

Limilabs then responds with a response over two packets:

1 12 0.2587 (0.1474) C>S applicationdata
1 13 0.2587 (0.0000) C>S application
data

Dovecot IMAP server kicks in and responds to Limilabs:

1 14 0.2589 (0.0001) S>C application_data

Limilabs then responds with another response over two packets:

1 15 0.2608 (0.0019) C>S applicationdata
1 16 0.2608 (0.0000) C>S application
data

Dovecot IMAP server responds to the above by gracefully asking SSL to shut down the connection, which duly happens:

1 17 0.2610 (0.0002) S>C Alert
1 0.2610 (0.0000) S>C TCP FIN
1 0.2632 (0.0021) C>S TCP FIN

From the timestamps, this entire exchange is complete inside 263 milliseconds. This doesn’t match the claim in the error message that a timeout has occurred.

On the dovecot server, we see the following logged:

Apr 20 11:50:05 server dovecot: imap-login: Aborted login (no auth attempts): rip=x.x.x.x, lip=y.y.y.y, TLS
Apr 20 11:50:05 server dovecot: imap-login: Warning: SSL alert: where=0x4008, ret=256: warning close notify [x.x.x.x]

Has anyone seen a problem before where Limilabs won't try and log in to the IMAP server? Is there a solution to getting an accurate error message?

by (200 points)
edited by

1 Answer

0 votes

[Edit]

Mail.dll connects to this server without any problems, SSL/TLS channel is also established properly.

Here are the logs:

Connecting to 'gatekeeper.horizonmarine.co.za:993', SSL: True.
S: * OK [CAPABILITY IMAP4rev1 LITERAL+ [...] Dovecot ready.
C: D68C0000 ID ("name" "Mail.dll" "version" [...]
S: * ID NIL
S: D68C0000 OK ID completed.
C: D68C0001 NOOP
S: D68C0001 OK NOOP completed.
C: D68C0002 LOGOUT

Note that the server doesn't send any response to LOGOUT command.

This is the reason why you get this exception.

Consider using:

client.Close(false);

Try forcing TLS 1.2 only:

client.SSLConfiguration.EnabledSslProtocols = SslProtocols.Tls12;

client.ConnectSSL("imap.example.com");
by (301k points)
Unfortunately Limilabs is embedded in third party code that we have no control over, and cannot change the parameters used to connect.

As indicated above, we are successfully connecting via SSL, and a conversation is occurring successfully between dovecot and Limilabs, we just don't know what that conversation is, or why Limilabs is failing to log in.

The error message is telling us the connection timed out, when in reality the dovecot server gracefully terminated the connection.
You only see SSL logs. If SSL negotiation failed - server did not terminate gracefully in terms of IMAP protocol. This is not a timeout error - message says: 'Tried to read a line. No data received.'.

Can you share the server's public address? So we can try to connect?
Try connect to gatekeeper.horizonmarine.co.za:933, with SSL enabled.
Trying to connect to a dovecot IMAP server running on RHEL7 comes up with the same problem. On this server though dovecot is able to log the trace of the conversation, which goes like this:

dovecot says hi:

1524219095.647789 * OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN] Dovecot ready.

Limilabs answers with the IMAP ID command:

1524219096.249356 33b16b431c6f48cc ID ("name" "Mail.dll (Unregistered)" "version" "3.0.14050.1215" "vendor" "www.limilabs.com" "contact" "support@limilabs.com")

dovecot acks the ID:

1524219096.249398 * ID ("name" "Dovecot")
1524219096.249402 33b16b431c6f48cc OK ID completed.

Limilabs waits two seconds for reasons that aren't clear, then sends the LOGOUT command:

1524219096.431073 3407cfd459df4a7b LOGOUT

dovecot responds as follows:

1524219096.431117 * BYE Logging out
1524219096.431128 3407cfd459df4a7b OK Logout completed.
I can connect without problems.

It looks like the problem is  different:

Server doesn't send a response to LOGOUT command and simply closes the connection. That's why you get this error.
I'll add a new answer.
I see that's true that the server doesn't send a response to the LOGOUT command and simply closes the connection, but the question is why would Limilabs send a LOGOUT in this case without trying to LOGIN?

It turns out if I work around this by putting an stunnel in front of the dovecot server, which in turn allows the BYE command to get through, Limilabs *does* log in in this case as expected - but this doesn't explain how something that happens late in the protocol exchange is breaking something that happens early in the protocol exchange.

Does Limilabs have some kind of connection pool functionality where a previous prematurely dropped connection would cause the next connection to fall off the rails?
LOGOUT command is available in any state:
  RFC 3501
    Section 6.1. Client Commands - Any State
      6.1.3. LOGOUT Command

> cause the next connection to fall off the rails
I'm not sure what you mean.
This server problem has nothing to do with previous connections.

There are no problems with Mail.dll connecting/establishing TLS/SSL stream or logging in.

The only problem is that this server doesn't respond to LOGOUT command at all.
To clarify, I'll summarise the problem so far.

Our problem is that the Limilabs client is not making any attempt to log in - instead it waits two seconds and then logs out. Sure, the logout isn't being handled properly by dovecot, but the key problem we're trying to get to the bottom of is why is Limilabs refusing to login in the first place?
Why do you say that Mail.dll is not logging in?
Are you using Imap.Login or Imap.UseBestLogin methods?

You need to use those methods to log-in.

How does your code look like?
As indicated above, we've logged a trace of the conversation, and as you can see there is no attempt by Limilabs to log in - it connects, it runs the ID command, then logs out.

Limilabs is embedded in third party code that we have no control over, we're trying to service the car through the exhaust pipe.

What we have discovered is that a bug in dovecot fixed in 2014 and applied to the dovecot server causes dovecot to close SSL connections properly and Limilabs to start logging in:

https://bugzilla.redhat.com/show_bug.cgi?id=1570017

We have also found that Limilabs when fetching mail from the dovecot IMAP server opens two connections, one of which it opens and closes again, the second of which opens the connection and leaves it open, leaking connections.

Is there anything special that needs to be done in Limilabs to avoid leaking connections after use?
You are greatly mistaken of what Mail.dll does and doesn't.

1.
Mail.dll doesn't open 2 connections by itself.

Code that uses Mail.dll can, however, open as many connections as it wants.

2.
If there is no login attempt, it means that login method (Imap.Login or Imap.UseBestLogin) has not been invoked.

In other words, code that is using Mail.dll hasn't invoke any of the login methods.

3.
Mail.dll does not 'leak' connections.

4.
You should contact 'third party code' owner, not us.

My guess is, that this code ('third party code') tries to establish first, if the connection parameters are correct, and if the server responds properly.

If connection can be established, it connects again, logs in and performs what it was designed to do.

Again, we are not the owner of this 'third party code' so this is just a guess, we can't be responsible of how someone is using Mail.dll.
On "Mail.dll does not 'leak' connections".

When a network component (such as the Limilabs IMAP client) makes a connection to a server, but then never closes that connection to the server, this is termed a "connection leak".

This usually happens when a connection pool is being used. I am assuming from your response that the Limilabs IMAP client does not contain a connection pool, and it is up to the calling application to implement a connection pool itself.

When the Limilabs IMAP client encounters an error, is there a mechanism of some kind (a flag, an exception that is thrown) to indicate that the Limilabs IMAP object is in a broken state and should be destroyed and a new one created?

I am looking for clear instructions on what to do so I can tell the owners of the third party code where they have gone wrong and what they should do to fix it.
Again: Mail.dll does not 'leak' connections.

As with any other .NET component/class that uses unmanaged resources, it's the caller responsibility to call Dispose method when exception is cached/error occurs.

> When the Limilabs IMAP client encounters an error  [...]
Yes, exceptions are being thrown on error server response/connection/network problems.

> I am looking for clear instructions [...]
As you don't know how their code looks like, don't you think it's not possible to tell what they should fix?

Please contact the vendor of the application and describe your problem to them.
>> When the Limilabs IMAP client encounters an error  [...]
> Yes, exceptions are being thrown on error server response/connection/network problems.

Alas, this doesn't answer the question I asked, I'll rephrase it. If an error occurs, is there some flag of some kind that a connection pool could use to detect that the connection in this object is in a broken state, and therefore this connection should not be returned to the pool?

> As you don't know how their code looks like, don't you think it's not possible to tell what they should fix?

In my experience it is very possible to tell them what to fix. Once I get answers to the questions I've asked, I'll know exactly what they've done wrong, and exactly what to do to fix it. Given this is archived by Google, it will also help future developers who encounter the same problem.
No, there is no such property. In most cases, on exception (especially exception different than ImapResponseException), client instance should be disposed.

I don't think this 3rd party code uses a connection pool.
> on exception (especially exception different than
> ImapResponseException), client instance should be disposed.

Thanks for confirming this - I can now clarify with the vendor how to fix their code.
...