Somewhere along the way squirrelmail stopped working with my dovecot imap server, which runs only on the secure port (imaps). I only ever use webmail as a last resort, so the problem may be left over from years ago. The problem is that I’m getting a connect failure but an error code of zero and no error message. This is what it actually shows
Error connecting to IMAP server "localhost:993".Server error: (0)
Which is very helpful. Everything else works with imaps on this system, so why not squirrelmail?
The answer, it seems, is buried deep inside php. Long ago, when php first started using openssl, it pretty much did no peer verification. Nowadays it does. I know I ran into this a long time ago, so the self signed certificate my version of dovecot is using is present in the /etc/ssl/certs directory where php looks for authoritative certificates. Digging into the sources of squirrelmail, it turns out this php statement (with the variables substituted) is the failing one
$imap_stream = @fsockopen('tls://localhost', 993, $errno, $errstr, 15);
It’s failing because $imap_stream is empty, but, as squirrelmail claims, it’s actually failing with a zero error code. After several hours of casting about with the fairly useless php documentation, it turns out that php has an interactive mode where it will actually give you all the errors. executing this
echo 'fsockopen("tls://localhost",993,$errno,$errmsg,15);'|php -a
Finally tells me what’s wrong
Interactive mode enabled PHP Warning: fsockopen(): Peer certificate CN=`bedivere.hansenpartnership.com' did not match expected CN=`localhost' in php shell code on line 1 PHP Warning: fsockopen(): Failed to enable crypto in php shell code on line 1 PHP Warning: fsockopen(): unable to connect to tls://localhost:993 (Unknown error) in php shell code on line 1
So that’s it: php has tightened up the certificate verification not only to validate the certificate itself, but also to check that the CN matches the requested service. In this case, because I’m connecting over the loopback device (localhost) instead of the internet to the DNS name, that CN check has failed and lead to the results I’m seeing. Simply fixing squirrelmail to connect to imaps over the fully qualified hostname instead of localhost gets everything working again.
If you’re connecting over localhost, why bother with imaps, what added security does it buy you?
It’s simple best practises: never run an insecure service from your systems. Squirrelmail connects to the external mail ports. If there’s no insecure one, it has to use a secure connection.
I had the same problem connecting to dovecot from squirrelmail on a different host after an upgrade to version 5.6.7 of php from version 5.4.4. Only in my case I could never see the error messages. I configured php to display all errors of any type…nothing. I tried the interactive mode you mentioned … nothing.
But when I reconfigured squirrelmail to use the fully qualified domain name as it existed within the certificate, everything worked just fine.
Thanks for the post.
I am using proxmox. One OpenVZ container for the www server and another for the mail server.
Squirrelmail runs on the www server. And now it fails, because I have to connect to the localnet ip (192.168.xx.xx). If I try the full domain I get connection refused :/
Any suggestions?
Pingback: Apple MacOS Server and iOS don’t like StartCom Certificates – Äppeltexte
You are a life saver. I spent 2 hours digging through configurations of dovecot, apache2, php etc. before finding your solution. Thank you
I have the same issue with php 5.6 on Debian Jessie 8, but the problem is not solved by providing fully qualitiad domain name.
Any idea what else might it be?
Regards,
Georgi