Valentin Mihov's Blog

Random pieces of wisdom about technology

SMTPs и POP3s с JavaMail

Тези дни ми се наложи да се боря с JavaMail и поддръжката му на SSL/TLS за вързване към мейл сървърите. На пръв поглед от документацията се вижда, че това се поддържа от API-то и не би трябвало да има проблеми с интеграцията. На втори поглед, както винаги, се разбира че всъщност нещата не стоят толкова просто.

  • Първото нещо, което прави впечатление след като вече имаме конфигурирани сървъри и приложение, което се вързва към тях е, че ако използваме тестови сертификати, които не са подписани от достоверно certificate authority приложението ни ще гърми с грешка от сорта на:

    sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

    Това се получава, защото JVM не може да вярва на сертификата отсреща. За целта има един файл, които съдържа всички сертификати, на които Java вярва и той се намира в %JAVA_HOME%\jre\lib\security\cacerts. Защитен е с парола, която по подразбиране е “changeit”. За да преодолеем горния проблем трябва да направил следното:

    cd “C:\Program Files\Java\jdk1.5.0_09\jre\lib\security” ....\bin\keytool.exe -import -trustcacerts -storepass changeit -alias \ mykey -keystore cacerts -file E:\pop3d.pem

    Това ще “вкара” сертификата в trusted сертификатите под името mykey. Ако това име вече съществува не е проблем да се ползва произволно.

  • Нагласяне на версиите на SSL/TLS.

    Нещо, което почти ме накара да се хвърля от прозореца (спря ме само това, че е прекалено ниско ;-)). Като цяло в Java 1.5 и нагоре има поддръжка на SSLv3 и TLS 1.0 (инфо). Обаче ако някой сървър настоява за SSLv2, това ще накара Java да хвърли грешка. Интересното е, че използвайки OpenSSL 0.9.8g със SSLv3 нещата не работят, тъй като сървъра се оплаква, че не може да декриптира пакетите от клиента. Това е интересна тема за разследване.

  • Конфигуриране на postfix и courier

В postfix има една опция с която може да си поиграе човек: smtpd_tls_mandatory_ciphers. Там може да се зададе какъв точно протокол да се ползва. Аз специално не успях да го подкарам със SSLv3 и съм оставил стойността по подразбиране.

В courier има няколко опции, които са доста важни. Едната е TLS_PROTOCOL, която оказва какъв протокол да се ползва. Интересното, че единствения начин, по които аз успях да го подкарам е като задам SSL23, което е НЕДОКУМЕНТИРАНА СТОЙНОСТ! Всякаква друга стойност там прецаква нещата. Другата е POP3_TLS_REQUIRED. Това е дали да се изисква STARTTLS (държа да отбележа, че това е за pop3 сървъра), което за съжаление е неподдържана функционалност от JavaMail и трябва да е изключено.

Ако имам време ще разуча още малко нещата. Иска ми се да направя клиент, който може да се свързва към сървъри със всякакви конфигурации.

Edit: Една много полезна статия, която обяснява нещата на разбираем език: http://sial.org/howto/openssl/tls-name/