Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot connect to Dovecot IMAP server with SSL #3709

Open
sergio91pt opened this issue Jun 13, 2017 · 27 comments
Open

Cannot connect to Dovecot IMAP server with SSL #3709

sergio91pt opened this issue Jun 13, 2017 · 27 comments
Labels
Priority:Important Issues & PRs that are important; broken functions, errors - there are workarounds Type:Bug Bugs within the core SuiteCRM codebase

Comments

@sergio91pt
Copy link
Contributor

sergio91pt commented Jun 13, 2017

Issue

Cannot save a inbound email account, when using a IMAPS Dovecot server, since folder selection is required but SuiteCRM does not properly connect to the server.

Upon further investigation, it was failling because findOptimumSettings (modules/InboundEmail/InboundEmail.php)
was erroneously assuming the credentials were incorrect and stopping the
loop early.

The test failed on the service=imap/ssl/validate-cert/secure test, with error
[CLOSED] IMAP connection broken (server response), but succeeded on the
service=imap/ssl/validate-cert test.

The dovecot server was running with:

  • disable_plaintext_auth = yes
  • auth_mechanisms = plain login
  • ssl = required
  • ssl_protocols = !SSLv2 !SSLv3
  • Using defaults for client_limit, service_count and process_limit of dovecot services
  • Trusted and correctly configured certificate

Expected Behavior

Able to add dovecot imaps server. Clicking on select folder for Trash and Sent works. Test settings button works.

Actual Behavior

Unable to add inbound email account (personal/group/bounce). Test settings and select folder buttons do not work as expected.
In some cases it displayed a generic error, in others (tested in various panels and versions) it showed invalid credentials or similar (credentials were correct).

Possible Fix

Do not use [CLOSED] IMAP connection broken (server response) as invalid credentials, it may lead to false positives.

Steps to Reproduce

  1. Go to profile -> email settings
  2. Add a personal inbound email account using
  3. Try to select the trash folder

Your Environment

  • SuiteCRM Version used: 7.8.4, 7.9.0 and hotfix branch (3acecfe)
  • Browser name and version: Chromium 58
  • Environment name and version: MySQL 5.7, PHP 7.0.18, Nginx 1.10
  • Operating System and version: Ubuntu 16.04

Mail Server Environment

  • Mail Server version: Dovecot 2.2.9
  • Operating System and version: Ubuntu 14.04
@pgorod
Copy link
Contributor

pgorod commented Jun 14, 2017

@sergio91pt I was wondering if this could be in any way related to #2807 ? I don't know if this findOptimumSettings function is being called also when connecting to send emails. It seems to be a different part of the email code, but some of the symptoms look similar...

@sergio91pt
Copy link
Contributor Author

@pgorod I don't think so. When findOptimumSettings runs, the unsuccessful attempts are clearly marked as coming from dovecot and not postfix/smtpd in mail.log.

This loop that failed due to [CLOSED] IMAP connection broken (server response):

---------------STARTING FINDOPTIMUMS LOOP----------------
1: I-E testing string: {redacted.com:993/service=imap/ssl/tls/validate-cert/secure}INBOX
1: I-E failed using [{redacted.com:993/service=imap/ssl/tls/validate-cert/secure}INBOX] - error: Can't open mailbox {redacted.com:993/service=imap/ssl/tls/validate-cert/secure}INBOX: invalid remote specification
1: I-E clearing error and alert stacks.
2: I-E testing string: {redacted.com:993/service=imap/ssl/tls/validate-cert}INBOX
2: I-E failed using [{redacted.com:993/service=imap/ssl/tls/validate-cert}INBOX] - error: Can't open mailbox {redacted.com:993/service=imap/ssl/tls/validate-cert}INBOX: invalid remote specification
2: I-E clearing error and alert stacks.
3: I-E testing string: {redacted.com:993/service=imap/ssl/validate-cert/secure}INBOX
3: I-E failed using [{redacted.com:993/service=imap/ssl/validate-cert/secure}INBOX]
3: I-E ERROR: $ie->findOptimums() failed due to bad user credentials for user login: redacted@redacted.com
Hook called: InboundEmail::after_ui_frame
Creating new instance of hook class hooks without parameters
Creating new instance of hook class AssignGroups without parameters
Hook called: ::after_ui_footer
Creating new instance of hook class AssignGroups without parameters
Hook called: ::server_round_trip
Calling MySQLi::disconnect()

Appears in the mail server as:

dovecot: imap-login: Aborted login (no auth attempts in 0 secs): user=<>, rip=redacted_server_ip, lip=redacted_suitecrm_ip, TLS, session=<3uBvZwNR2gA0MKR+>
dovecot: imap-login: Aborted login (no auth attempts in 0 secs): user=<>, rip=redacted_server_ip, lip=redacted_suitecrm_ip, TLS, session=<tatwZwNR3AA0MKR+>
dovecot: imap-login: Aborted login (no auth attempts in 0 secs): user=<>, rip=redacted_server_ip, lip=redacted_suitecrm_ip, TLS, session=<UndxZwNR3gA0MKR+>

@pgorod
Copy link
Contributor

pgorod commented Jun 14, 2017

Ok, thanks. To be frank I don't really understand these configurations and protocols so I was just hoping there might be a connection, so we could make some progress on that other issue, which is creating problems for a lot of people and still doesn't have a full diagnosis. Thanks!

@chris001
Copy link
Contributor

@sergio91pt

  • What's the CN name on the imap server certificate.
  • What's the server name you provide in the imap settings.

@sergio91pt
Copy link
Contributor Author

@chris001 This should answer your questions.

# Executed on the crm server.
# Reverse ip lookup points to the same domain presented by the server
$ openssl s_client -CApath /etc/ssl/certs/ -connect redacted.com:465
CONNECTED(00000003)
depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify return:1
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL, CN = redacted.com
verify return:1
---
Certificate chain
 0 s:/OU=Domain Control Validated/OU=PositiveSSL/CN=redacted.com
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
 1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
 2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
   i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
---
Server certificate
-----BEGIN CERTIFICATE-----
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/OU=PositiveSSL/CN=redacted.com
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 4825 bytes and written 431 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: DBCD15DC4EF4E07060177ECD89FCE5E4006721ADDC7E674C77103E543EDD77FD
    Session-ID-ctx: 
    Master-Key: C755EC455A35797605920CB3B443658CB1EFCC63F0784E82C9189542EDB3D26B18531E892010660B58344587BF3B825E
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1497445091
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
220 redacted.com ESMTP Postfix (Ubuntu)
EHLO crmserver
250-redacted.com
250-PIPELINING
250-SIZE 100000000
250-ETRN
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN
QUIT
DONE

findOptimumSettings runs this tests in order:

        $ssl = array(
            'ssl-both-on-secure' => '/ssl/tls/validate-cert/secure',
            'ssl-both-on' => '/ssl/tls/validate-cert',
            'ssl-cert-secure' => '/ssl/validate-cert/secure',
            'ssl-cert' => '/ssl/validate-cert',
            'ssl-tls-secure' => '/ssl/tls/secure',
            'ssl-tls' => '/ssl/tls',
            'ssl-both-off-secure' => '/ssl/notls/novalidate-cert/secure',
            'ssl-both-off' => '/ssl/notls/novalidate-cert',
            'ssl-nocert-secure' => '/ssl/novalidate-cert/secure',
            'ssl-nocert' => '/ssl/novalidate-cert',
            'ssl-notls-secure' => '/ssl/notls/secure',
            'ssl-notls' => '/ssl/notls',
            'ssl-secure' => '/ssl/secure',
            'ssl-none' => '/ssl',
        );

While I don't know the difference between /ssl/validate-cert/secure and /ssl/validate-cert, the fact that it passes /ssl/validate-cert means SuiteCRM/PHPMailer has no problem validating the certificate.

@sergio91pt
Copy link
Contributor Author

@chris001 Sorry, only realized I sent you the SMTP connection test instead of IMAP.

I don't think dovecot has a server name configured (thats why I without thinking did a SMTP test).
The certificate is for a single domain, not wildcard. It also has the www subdomain, in the alt names.

$ openssl s_client -CApath /etc/ssl/certs/ -connect redacted.com:993
CONNECTED(00000003)
depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify return:1
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL, CN = redacted.com
verify return:1
---
Certificate chain
 0 s:/OU=Domain Control Validated/OU=PositiveSSL/CN=redacted.com
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
 1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
 2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
   i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
---
Server certificate
-----BEGIN CERTIFICATE-----

-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/OU=PositiveSSL/CN=redacted.com
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-384, 384 bits
---
SSL handshake has read 5004 bytes and written 463 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: E14C60CAB29281BDB075E0A6CBAE7F7920575AE2F1DB14AE1A43C47B70FC8362
    Session-ID-ctx: 
    Master-Key: 1902F00DCF10473C1D22DE048D33E3064A6665032FB6E449BDD8274BDCD8A3F26017DEF1688F027BCFC1DFE65049507A
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - de 43 8b 7f 73 b0 af 27-12 3f e3 05 24 2b e3 2e   .C..s..'.?..$+..
    0010 - fd 38 fe f2 05 c7 50 81-b0 1f b7 00 e6 45 58 36   .8....P......EX6
    0020 - df 1e f5 f1 33 a9 a3 bc-f3 31 08 88 14 6d f1 89   ....3....1...m..
    0030 - 45 02 9c 3f 8d f6 a3 11-a3 2b 87 f2 20 71 8e 84   E..?.....+.. q..
    0040 - de 23 57 fd 19 92 8a 03-c4 52 66 3a 99 f0 61 31   .#W......Rf:..a1
    0050 - b0 7b f4 3e 9a 54 f1 8d-52 86 ec 90 07 af b8 56   .{.>.T..R......V
    0060 - dc ee 49 c5 d2 21 11 b0-44 08 e1 01 d8 34 30 de   ..I..!..D....40.
    0070 - f0 e5 76 68 bd 89 6f 11-fa 4e 10 4b 40 a9 b0 e4   ..vh..o..N.K@...
    0080 - 9b 69 f4 15 7c 5d a8 db-dc 6d ac b3 e6 6d 7e 7a   .i..|]...m...m~z
    0090 - 69 9f 02 92 64 46 40 b0-4c 34 ec c7 04 48 22 ec   i...dF@.L4...H".

    Start Time: 1497445758
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN] Dovecot (Ubuntu) ready.
closed

@chris001
Copy link
Contributor

@salesagility Another perfect example of poor/nonexistent/obscured error reporting by this app!
@sergio91pt
Change line 2864 of InboundEmail.php:
https://github.com/salesagility/SuiteCRM/blob/master/modules/InboundEmail/InboundEmail.php#L2864

$GLOBALS['log']->debug($l . ': I-E failed using [' . $serviceTest . ']');

to add this one line after it, as shown:

$GLOBALS['log']->debug($l . ': I-E failed using [' . $serviceTest . ']');
$GLOBALS['log']->debug($l . ': I-E exact error message: [' . $errors . ']');

and run your test again.

@sergio91pt
Copy link
Contributor Author

@chris001 I should have mentioned that I used a debugger to inspect the $errors variable, so that's how I knew which error was the culprit.

I reverted my fix (PR #3710) and added that log (still on hotfix - so not the same line):

Module:InboundEmail using file: ShowInboundFoldersList
---------------STARTING FINDOPTIMUMS LOOP----------------
1: I-E testing string: {redacted.com:993/service=imap/ssl/tls/validate-cert/secure}INBOX
1: I-E failed using [{redacted.com:993/service=imap/ssl/tls/validate-cert/secure}INBOX] - error: Can't open mailbox {redacted.com:993/service=imap/ssl/tls/validate-cert/secure}INBOX: invalid remote specification
1: I-E clearing error and alert stacks.
2: I-E testing string: {redacted.com:993/service=imap/ssl/tls/validate-cert}INBOX
2: I-E failed using [{redacted.com:993/service=imap/ssl/tls/validate-cert}INBOX] - error: Can't open mailbox {redacted.com:993/service=imap/ssl/tls/validate-cert}INBOX: invalid remote specification
2: I-E clearing error and alert stacks.
3: I-E testing string: {redacted.com:993/service=imap/ssl/validate-cert/secure}INBOX
3: I-E failed using [{redacted.com:993/service=imap/ssl/validate-cert/secure}INBOX]
3: I-E exact error message: [[CLOSED] IMAP connection broken (server response)]
3: I-E ERROR: $ie->findOptimums() failed due to bad user credentials for user login: redacted@redacted.com
Hook called: InboundEmail::after_ui_frame
Creating new instance of hook class hooks without parameters
Creating new instance of hook class AssignGroups without parameters
Hook called: ::after_ui_footer
Creating new instance of hook class AssignGroups without parameters
Hook called: ::server_round_trip
Calling MySQLi::disconnect()

On the mail server: (lip is actually the interface internal ip - no point in redacting that)

dovecot: imap-login: Aborted login (no auth attempts in 0 secs): user=<>, rip=redacted, lip=172.31.12.174, TLS, session=<DY/FnO1RNwC8+5I3>
dovecot: imap-login: Aborted login (no auth attempts in 0 secs): user=<>, rip=redacted, lip=172.31.12.174, TLS, session=<nWbNnO1RUQC8+5I3>
dovecot: imap-login: Aborted login (no auth attempts in 0 secs): user=<>, rip=redacted, lip=172.31.12.174, TLS, session=<jOLUnO1RlwC8+5I3>

@chris001
Copy link
Contributor

@sergio91pt
Can you try port 143 instead of 993.

@sergio91pt
Copy link
Contributor Author

sergio91pt commented Jun 15, 2017

@chris001
Port 143 is STARTTLS and also fails on this method. Looking at the imap-open documentation, it is clear that the $ssl tests will never succeed with a STARTTLS connection upgrade: no server offers STARTTLS if the connection is already protected by SSL/TLS and /ssl/notls is redundant and the same as /ssl, same thing for /notls/novalidate-cert and /notls in the $nonSsl array.

I can see various issues now:

  1. Impossible and redundant params in $nonSsl, $ssl make extra unnecessary connection tests
  2. HCI issue: When you select SSL in the UI, it changes the port to 993, which implies that non SSL is STARTTLS, but it favors plaintext connections and non validated certificates
  3. nonSSL should try opportunistic STARTTLS first, preferring validated certificates
  4. Decide weather or not STARTTLS connection upgrades belong in the $ssl tests
  5. Basically this issue. The use of /secure (disallow LOGIN and PLAIN auth mechanisms) in SSL/TLS protected connections (upgraded or not) results in [CLOSED] IMAP connection broken (server response) which is mistaken as invalid credentials.

Maybe we should split some of them into seperate issues?

Tests for reference

$nonSsl = array(
    'both-secure' => '/notls/novalidate-cert/secure',
    'both' => '/notls/novalidate-cert',
    'nocert-secure' => '/novalidate-cert/secure',
    'nocert' => '/novalidate-cert',
    'notls-secure' => '/notls/secure',
    'secure' => '/secure', // for POP3 servers that force CRAM-MD5
    'notls' => '/notls',
    'none' => '', // try default nothing
);
$ssl = array(
    'ssl-both-on-secure' => '/ssl/tls/validate-cert/secure',
    'ssl-both-on' => '/ssl/tls/validate-cert',
    'ssl-cert-secure' => '/ssl/validate-cert/secure',
    'ssl-cert' => '/ssl/validate-cert',
    'ssl-tls-secure' => '/ssl/tls/secure',
    'ssl-tls' => '/ssl/tls',
    'ssl-both-off-secure' => '/ssl/notls/novalidate-cert/secure',
    'ssl-both-off' => '/ssl/notls/novalidate-cert',
    'ssl-nocert-secure' => '/ssl/novalidate-cert/secure',
    'ssl-nocert' => '/ssl/novalidate-cert',
    'ssl-notls-secure' => '/ssl/notls/secure',
    'ssl-notls' => '/ssl/notls',
    'ssl-secure' => '/ssl/secure',
    'ssl-none' => '/ssl',
);

Port 143 (STARTTLS only), SSL not selected

---------------STARTING FINDOPTIMUMS LOOP----------------
1: I-E testing string: {redacted.com:143/service=imap/notls/novalidate-cert/secure}INBOX
1: I-E failed using [{redacted.com:143/service=imap/notls/novalidate-cert/secure}INBOX] - error: Can't do secure authentication with this server
1: I-E clearing error and alert stacks.
2: I-E testing string: {redacted.com:143/service=imap/notls/novalidate-cert}INBOX
2: I-E failed using [{redacted.com:143/service=imap/notls/novalidate-cert}INBOX] - error: Server disables LOGIN, no recognized SASL authenticator
2: I-E clearing error and alert stacks.
3: I-E testing string: {redacted.com:143/service=imap/novalidate-cert/secure}INBOX
3: I-E failed using [{redacted.com:143/service=imap/novalidate-cert/secure}INBOX]
3: I-E exact error message: [[CLOSED] IMAP connection broken (server response)]
3: I-E ERROR: $ie->findOptimums() failed due to bad user credentials for user login: redacted@redacted.com
Hook called: InboundEmail::after_ui_frame
Creating new instance of hook class hooks without parameters
Creating new instance of hook class AssignGroups without parameters
Hook called: ::after_ui_footer
Creating new instance of hook class AssignGroups without parameters
Hook called: ::server_round_trip
Calling MySQLi::disconnect()

Port 143 (STARTTLS only), SSL selected on UI

---------------STARTING FINDOPTIMUMS LOOP----------------
1: I-E testing string: {redacted.com:143/service=imap/ssl/tls/validate-cert/secure}INBOX
1: I-E failed using [{redacted.com:143/service=imap/ssl/tls/validate-cert/secure}INBOX] - error: Can't open mailbox {redacted.com:143/service=imap/ssl/tls/validate-cert/secure}INBOX: invalid remote specification
1: I-E clearing error and alert stacks.
2: I-E testing string: {redacted.com:143/service=imap/ssl/tls/validate-cert}INBOX
2: I-E failed using [{redacted.com:143/service=imap/ssl/tls/validate-cert}INBOX] - error: Can't open mailbox {redacted.com:143/service=imap/ssl/tls/validate-cert}INBOX: invalid remote specification
2: I-E clearing error and alert stacks.
3: I-E testing string: {redacted.com:143/service=imap/ssl/validate-cert/secure}INBOX
3: I-E failed using [{redacted.com:143/service=imap/ssl/validate-cert/secure}INBOX] - error: TLS/SSL failure for redacted.com: SSL negotiation failed
3: I-E clearing error and alert stacks.
4: I-E testing string: {redacted.com:143/service=imap/ssl/validate-cert}INBOX
4: I-E failed using [{redacted.com:143/service=imap/ssl/validate-cert}INBOX] - error: TLS/SSL failure for redacted.com: SSL negotiation failed
4: I-E clearing error and alert stacks.
5: I-E testing string: {redacted.com:143/service=imap/ssl/tls/secure}INBOX
5: I-E failed using [{redacted.com:143/service=imap/ssl/tls/secure}INBOX] - error: Can't open mailbox {redacted.com:143/service=imap/ssl/tls/secure}INBOX: invalid remote specification
5: I-E clearing error and alert stacks.
6: I-E testing string: {redacted.com:143/service=imap/ssl/tls}INBOX
6: I-E failed using [{redacted.com:143/service=imap/ssl/tls}INBOX] - error: Can't open mailbox {redacted.com:143/service=imap/ssl/tls}INBOX: invalid remote specification
6: I-E clearing error and alert stacks.
7: I-E testing string: {redacted.com:143/service=imap/ssl/notls/novalidate-cert/secure}INBOX
7: I-E failed using [{redacted.com:143/service=imap/ssl/notls/novalidate-cert/secure}INBOX] - error: TLS/SSL failure for redacted.com: SSL negotiation failed
7: I-E clearing error and alert stacks.
8: I-E testing string: {redacted.com:143/service=imap/ssl/notls/novalidate-cert}INBOX
8: I-E failed using [{redacted.com:143/service=imap/ssl/notls/novalidate-cert}INBOX] - error: TLS/SSL failure for redacted.com: SSL negotiation failed
8: I-E clearing error and alert stacks.
9: I-E testing string: {redacted.com:143/service=imap/ssl/novalidate-cert/secure}INBOX
9: I-E failed using [{redacted.com:143/service=imap/ssl/novalidate-cert/secure}INBOX] - error: TLS/SSL failure for redacted.com: SSL negotiation failed
9: I-E clearing error and alert stacks.
10: I-E testing string: {redacted.com:143/service=imap/ssl/novalidate-cert}INBOX
10: I-E failed using [{redacted.com:143/service=imap/ssl/novalidate-cert}INBOX] - error: TLS/SSL failure for redacted.com: SSL negotiation failed
10: I-E clearing error and alert stacks.
11: I-E testing string: {redacted.com:143/service=imap/ssl/notls/secure}INBOX
11: I-E failed using [{redacted.com:143/service=imap/ssl/notls/secure}INBOX] - error: TLS/SSL failure for redacted.com: SSL negotiation failed
11: I-E clearing error and alert stacks.
12: I-E testing string: {redacted.com:143/service=imap/ssl/notls}INBOX
12: I-E failed using [{redacted.com:143/service=imap/ssl/notls}INBOX] - error: TLS/SSL failure for redacted.com: SSL negotiation failed
12: I-E clearing error and alert stacks.
13: I-E testing string: {redacted.com:143/service=imap/ssl/secure}INBOX
13: I-E failed using [{redacted.com:143/service=imap/ssl/secure}INBOX] - error: TLS/SSL failure for redacted.com: SSL negotiation failed
13: I-E clearing error and alert stacks.
14: I-E testing string: {redacted.com:143/service=imap/ssl}INBOX
14: I-E failed using [{redacted.com:143/service=imap/ssl}INBOX] - error: TLS/SSL failure for redacted.com: SSL negotiation failed
14: I-E clearing error and alert stacks.
---------------end FINDOPTIMUMS LOOP----------------
Hook called: InboundEmail::after_ui_frame
Creating new instance of hook class hooks without parameters
Creating new instance of hook class AssignGroups without parameters
Hook called: ::after_ui_footer
Creating new instance of hook class AssignGroups without parameters
Hook called: ::server_round_trip
Calling MySQLi::disconnect()

Port 143 connection tests

Telnet connection

$ telnet redacted.com 143
Trying XXX.XXX.XXX.XXX...
Connected to redacted.com.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE STARTTLS LOGINDISABLED] Dovecot (Ubuntu) ready.
A01 LOGOUT
* BYE Logging out
A01 OK Logout completed.
Connection closed by foreign host.

STARTTLS connection upgrade

# Note: credentials have also been redacted
# AHJlZGFjdGVkQHJlZGFjdGVkLmNvbQByZWRhY3RlZA== is base64_encode("\0redacted@redacted.com\0redacted")

$ openssl s_client -CApath /etc/ssl/certs/ -starttls imap -connect redacted.com:143
CONNECTED(00000003)
depth=3 C = SE, O = AddTrust AB, OU = AddTrust External TTP Network, CN = AddTrust External CA Root
verify return:1
depth=2 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Certification Authority
verify return:1
depth=1 C = GB, ST = Greater Manchester, L = Salford, O = COMODO CA Limited, CN = COMODO RSA Domain Validation Secure Server CA
verify return:1
depth=0 OU = Domain Control Validated, OU = PositiveSSL, CN = redacted.com
verify return:1
---
Certificate chain
 0 s:/OU=Domain Control Validated/OU=PositiveSSL/CN=redacted.com
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
 1 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
   i:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
 2 s:/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Certification Authority
   i:/C=SE/O=AddTrust AB/OU=AddTrust External TTP Network/CN=AddTrust External CA Root
---
Server certificate
-----BEGIN CERTIFICATE-----
REDACTED
-----END CERTIFICATE-----
subject=/OU=Domain Control Validated/OU=PositiveSSL/CN=redacted.com
issuer=/C=GB/ST=Greater Manchester/L=Salford/O=COMODO CA Limited/CN=COMODO RSA Domain Validation Secure Server CA
---
No client certificate CA names sent
Peer signing digest: SHA512
Server Temp Key: ECDH, P-384, 384 bits
---
SSL handshake has read 5328 bytes and written 489 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: E93B5845B525928D74DB9B9820F84A03A8303201B311AD845577548CD9538478
    Session-ID-ctx: 
    Master-Key: DE48207CCD7B3B5ED6F94156CCA90C21F01AC7B2B5F4D3824C2DC046CCF66C9DA11C953BAFE968311B79E828366ABA03
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - aa d9 56 48 6b 6f 25 74-6b 90 9d ef 3f b9 0e 76   ..VHko%tk...?..v
    0010 - 88 28 ec bc 7c 18 6b 8b-b8 7a 06 e3 db 79 ef 00   .(..|.k..z...y..
    0020 - c4 aa 3c 6c 58 72 6d 59-1e 4b 00 4e 7e 18 c2 12   ..<lXrmY.K.N~...
    0030 - d4 2b e4 24 48 3c b4 01-c3 04 26 c1 0c 6e dc 85   .+.$H<....&..n..
    0040 - c9 0f d1 dd 4a 30 91 6b-de 9a c3 78 06 46 01 21   ....J0.k...x.F.!
    0050 - 2c dc 4e 0d 98 27 54 2e-f7 c2 26 af 70 7d 46 ad   ,.N..'T...&.p}F.
    0060 - 69 57 49 5f 19 81 c2 c8-4b fe bb bb 56 1c a1 0d   iWI_....K...V...
    0070 - 44 49 6d 4f ef b3 8c 68-84 65 eb 9e 65 87 0b 59   DImO...h.e..e..Y
    0080 - 99 cf 2b 3f 0f b3 32 4e-92 7e aa f1 17 4a 9b e3   ..+?..2N.~...J..
    0090 - bb 97 80 1d 64 20 6b af-61 00 09 ce 88 bc ce 1f   ....d k.a.......

    Start Time: 1497527649
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)
---
. OK Pre-login capabilities listed, post-login capabilities have more.
A01 CAPABILITY
* CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE AUTH=PLAIN AUTH=LOGIN
A01 OK Pre-login capabilities listed, post-login capabilities have more.
A02 AUTHENTICATE PLAIN AHJlZGFjdGVkQHJlZGFjdGVkLmNvbQByZWRhY3RlZA==
* CAPABILITY IMAP4rev1 LITERAL+ SASL-IR LOGIN-REFERRALS ID ENABLE IDLE SORT SORT=DISPLAY THREAD=REFERENCES THREAD=REFS THREAD=ORDEREDSUBJECT MULTIAPPEND URL-PARTIAL CATENATE UNSELECT CHILDREN NAMESPACE UIDPLUS LIST-EXTENDED I18NLEVEL=1 CONDSTORE QRESYNC ESEARCH ESORT SEARCHRES WITHIN CONTEXT=SEARCH LIST-STATUS SPECIAL-USE BINARY MOVE QUOTA
A02 OK Logged in
A03 LOGOUT
* BYE Logging out
A03 OK Logout completed.
closed

@sergio91pt
Copy link
Contributor Author

sergio91pt commented Jun 15, 2017

I created a small script to test imap_open "specs". The big difference is that I'm using imap_errors() instead of imap_last_error(), to get all the errors.

Tested it with my PC's php-cli (v5.5.9 - Ubuntu 14.04). Both Ubuntu 14.04 (php 5.5) and 16.04 (php 7.0) use the same IMAP c-Client Version (2007f).

When I intentionally provide the wrong password I get:

ERR: Can not authenticate to IMAP server: [AUTHENTICATIONFAILED] Authentication failed.
ERR: [CLOSED] IMAP connection broken (server response)

Since the server only provides PLAIN and LOGIN authentication, when I use /tls/secure with port 143 or /ssl/secure with port 993, I get:

ERR: Can't do secure authentication with this server
ERR: [CLOSED] IMAP connection broken (server response)

If I do something stupid like use /blah or /ssl/tls as the spec, I get the invalid remote specification and no connection seems to be attempted.

The changelog of the imap c-client library answers some questions:

imap-2006 is a major release. Programs written for imap-2004g should
build with this version with minor or no modification. imap-2005 was not
released except as development snapshots.

(...)

SSL/TLS certificate validation on UNIX now checks the alternative names in the
certificate if the CN does not match.

(...)

The silly mailbox flag combination /ssl/tls is now rejected as an invalid
remote specification. Previous versions tried to negotiate TLS over an SSL
session; even if the server permitted such a thing it couldn't work.

IMAP connection test script

<?php

if (PHP_SAPI !== 'cli') {
    die('cli only');
}
if ($argc < 5 || $argc > 6) {
    die("USAGE: php $argv[0] HOST PORT USERNAME PASSWORD [SPEC]\n");
}
$host = $argv[1];
$port = intval($argv[2]);
$username = $argv[3];
$password = $argv[4];
$spec = isset($argv[5]) ? $argv[5] : (($port === 993) ? '/ssl' : '/tls');
$params = array('DISABLE_AUTHENTICATOR' => '');
$mailbox = "{{$host}:{$port}{$spec}}INBOX";
$options = 0;

function printArray($array, $prefix)
{
    if (is_array($array)) {
        foreach ($array as $entry) {
            print "$prefix: $entry\n";
        }
    }
    else {
        print "$prefix: None\n";
    }
}

$connection = imap_open($mailbox, $username, $password, $options, 0, $params);

printArray(imap_errors(), "ERR");
printArray(imap_alerts(), "Alert");

if ($connection !== FALSE) {
    imap_close($connection);
}

@samus-aran
Copy link
Contributor

@sergio91pt - Sorry just to confirm where did you guys get to with debugging this?

@chris001
Copy link
Contributor

  • Workarounds for common imap mail servers (Gmail, exchange 2010, localhost, Dovecot, detecting blocked ports, etc), posted in the comments of the PHP documentation mentioned above:
    http://php.net/manual/en/function.imap-open.php
    These IMAP servers have come into existence after this Sugar code was written.
  • As part of the automated phpunit codeception tests Feature codeception #3600 , you must add a live connection test to real email accounts hosted on each type of supported IMAP server. The automated test must try to connect, and fail when the connect fails.

@sergio91pt
Copy link
Contributor Author

sergio91pt commented Jun 16, 2017

@samus-aran We've identified 5 issues related to the findOptimumSettings method:

Issue 1 (this issue)

Unable to connect to IMAP servers that only allow PLAIN and/or LOGIN authentication (and/or unsupported authentication methods like XOAUTH - probably).
Erroneously fails with a bad credentials error. On Dovecot, only affects SSL and STARTTLS connections.

Proposed solution:

  1. IMAP connection broken doesn't mean there is an authentication failure
  2. Use imap_errors() instead of imap_last_error()

Issue 2

Security issue: For Non SSL servers, plaintext connections are preferred over opportunistic STARTTLS

Proposed solution:

  1. Change order of tests
  2. Somehow invalidate the connection string of possible affected accounts and force a re-test on the next connection. This is not trivial. The "string" is saved in $_SESSION and in the service column of the inbound_email table (using different syntax).

Issue 3

findOptimumSettings has some impossible and redundant tests.

Proposed solution:

  1. Remove impossible and redundant tests

Issue 4

Each failed test attempts 3 connections in getImapConnection (disables authenticators for compatibility, I guess).

Proposed solution:

  1. Save somewhere if the connection requires an authenticator to be disabled. On the database, we could use the stored options column.

Issue 5

findOptimumSettings and getImapConnection should skip tests/connections depending on the errors of previous attempts.

For example, attempting a SSL connection test to a non-SSL server results in 30 TCP connections, it only needs 1 or 2 to return "invalid" (depending on the error message when connection to a server that presents a invalid certificate).

This issue may trigger the dovecot filter of fail2ban prior to v0.9.0.
Doesn't trigger on Ubuntu 14.04, because the sessions identifiers broke the fail regex that shipped with the distro package (fixed before 0.9.0 - it seems).

@pgorod
Copy link
Contributor

pgorod commented Jun 16, 2017

@sergio91pt here's a first-place medal for your diagnostic work 🥇

And... you know we're gonna need your help fixing this, don't you? :-)

@chris001
Copy link
Contributor

chris001 commented Jun 17, 2017

@sergio91pt

  1. To fix this bug once and for all. First, improve the unit test for the findOptimumSettings method.
    https://github.com/salesagility/SuiteCRM/blob/master/tests/tests/modules/InboundEmail/InboundEmailTest.php#L1180
    How to improve this unit test method - Have it connect, one by one, to REAL email accounts created for testing purposes: Gmail, Exchange, Yahoo, and the top 10 Linux mail servers.
  2. Then, adjust parameters in findOptimumSettings, until all mail server types connect without error.
    https://github.com/salesagility/SuiteCRM/blob/master/modules/InboundEmail/InboundEmail.php#L2783
    How to know all mail server types connect without error - Run this command:
    ./vendor/bin/codecept run tests/unit/modules/InboundEmail | grep optimum
    and it no longer shows F InboundEmailTest: Testfind Optimum Settings.

@pgorod
Copy link
Contributor

pgorod commented Jun 17, 2017

I like the idea of getting real email accounts, even though it sounds like a lot of work... but getting even just one email account to be actionable during our tests would greatly decrease risks when touching email code. I'm thinking of all the bugs of the past two weeks here...

And getting a nice array of accounts like @chris001 suggests would be perfect for this particular Issue, and add a lot of extra security to the rest of our email challenges.

For Gmail, Outlook, etc. , it's just a matter of opening the accounts, I guess. But for the "top 10 Linux mail servers" I don't know where we could go. We'd have to know of free public services that use specific types of mail software...

@sergio91pt
Copy link
Contributor Author

@pgorod Thanks. I do intend to help although time might be a problem. I still don't have my own instance in production and I should already be working on a different project

@chris001 I haven't run the tests yet, only looked around. Does it already use a live account?
I see multiple tests using $inboundEmail->id = 1, but I'm not sure if those tests are assuming a functioning mailbox and if said mailbox is setup by the test runner or manually.

@chris001
Copy link
Contributor

@sergio91pt The test isn't using a live account right now, it never has! Someone should sign up for a free email account on gmail, yahoo, microsoft live. Once you have the mail account credentials, I'll show you how to safely add them to the tests.

@Dillon-Brown Dillon-Brown added Type:Bug Bugs within the core SuiteCRM codebase Priority:Important Issues & PRs that are important; broken functions, errors - there are workarounds labels Jul 19, 2017
@dspaan
Copy link

dspaan commented Aug 18, 2017

It's amazing to me that the inbound e-mail setup in SuiteCRM has a link to prefill the default setup information for a Gmail account but it's not working? I spent hours on this. I also lost time on setting up an inbound e-mail account with Koozali SME server (which uses Dovecot). And this while i don't even need inbound e-mail but i'm forced to configure one otherwise i can't send outbound e-mails (issue #3741). I finally got my setup working by configuring an IMAP account from a different provider. This should be high priority if you ask me.

@dspaan
Copy link

dspaan commented Jan 1, 2018

Is this isssue on a roadmap to fixed? I wanted to created an e-mail campaign but it seems i can't because the related domain email is on a server that SuiteCRM does not support.

@rajohn96
Copy link

ALCON,

Any updates on this issue; it is confounding me too. I'll settle for a workaround/one-off, and will commit to working the real fix in exchange.

Thanks!

Alan

@rajohn96
Copy link

BTW, I can connect just fine with a gmail server, its only the Dovecot that's not working (which unfortunately is the one I need to talk to!!)

@rajohn96
Copy link

rajohn96 commented Jun 1, 2018

so I have had a small amount of success, which may be worth something. For my needs I've removed all of the ssl connection options (/ssl/verify-cert, /ssl/noverify-cert, etc) save the one I want, and I've adjusted the imap_open retry count from 0 to 1 and it seems to work for me. What still doesn't work is the selection of folders (which is really not a bit deal to me, but definitely needs to be addressed in the "real" PR). Anyone, does this help at all?

@rajohn96
Copy link

rajohn96 commented Jun 1, 2018

oh, and i updated to the 7.10.5 version; that fixed a different permissions problem I was having elsewhere.

@lintech-admin
Copy link

Good day to all!

There is Postfix + Dovecot mail server. Authorization by IMAP for login and password. Email clients connect and work.
When I configure the connection in SuiteCRM I get the error "Invalid login or password".
The SMTP connection is configured and running.
In the server logs such messages:

Jun 26 15:42:29 server dovecot: imap-login: Aborted login (client did not finish SASL auth, waited 0 secs): user = <>, method = GSSAPI, rip = YYYY, lip = XXXX, session = < 7 / 7K1Ipv / ADAqAAz>
Jun 26 15:42:29 server dovecot: imap-login: aborted login (no auth attempts in 0 secs): user = <>, rip = Y.Y.Y.Y, lip = X.X.X.X, session = <90bL1Ipv / gDAqAAz>
Jun 26 15:42:29 server dovecot: imap-login: aborted login (no auth attempts in 0 secs): user = <>, rip = Y.Y.Y.Y, lip = X.X.X.X, session =

Tell me, please, how to change the authentication method in SuiteCRM !!!

@Jorilx
Copy link
Contributor

Jorilx commented Aug 24, 2018

It looks like the problem with Dovecot happens when SuiteCRM tries to login using an encrypted password ("/secure") to a server that supports only PLAIN passwords, maybe it would be easier to add a "encrypt password" checkbox and only try with "/secure" if requested by the user?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority:Important Issues & PRs that are important; broken functions, errors - there are workarounds Type:Bug Bugs within the core SuiteCRM codebase
Projects
None yet
Development

No branches or pull requests

9 participants