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.