Better parsing of ESMTP extensions.

This commit is contained in:
Vincent Richard 2007-03-28 08:28:12 +00:00
parent a88d21a336
commit a5de2571e3
3 changed files with 41 additions and 39 deletions

View File

@ -2,6 +2,10 @@
VERSION 0.8.2cvs VERSION 0.8.2cvs
================ ================
2007-03-28 Vincent Richard <vincent@vincent-richard.net>
* SMTPTransport.cpp: better parsing of ESMTP extensions.
2007-03-02 Vincent Richard <vincent@vincent-richard.net> 2007-03-02 Vincent Richard <vincent@vincent-richard.net>
* Maildir: added support for "Courier" Maildir. * Maildir: added support for "Courier" Maildir.

View File

@ -191,7 +191,9 @@ void SMTPTransport::helo()
// //
// eg: C: EHLO thismachine.ourdomain.com // eg: C: EHLO thismachine.ourdomain.com
// S: 250-smtp.theserver.com // S: 250-smtp.theserver.com
// S: 250 AUTH CRAM-MD5 DIGEST-MD5 // S: 250-AUTH CRAM-MD5 DIGEST-MD5
// S: 250-PIPELINING
// S: 250 SIZE 2555555555
sendRequest("EHLO " + platform::getHandler()->getHostName()); sendRequest("EHLO " + platform::getHandler()->getHostName());
@ -213,12 +215,39 @@ void SMTPTransport::helo()
} }
m_extendedSMTP = false; m_extendedSMTP = false;
m_extendedSMTPResponse.clear(); m_extensions.clear();
} }
else else
{ {
m_extendedSMTP = true; m_extendedSMTP = true;
m_extendedSMTPResponse = resp->getText(); m_extensions.clear();
// Get supported extensions from SMTP response
for (int i = 1, n = resp->getLineCount() ; i < n ; ++i)
{
const string line = resp->getLineAt(i).getText();
std::istringstream iss(line);
string ext;
iss >> ext;
// Special case: some servers send "AUTH=LOGIN"
if (ext.length() == 10 && utility::stringUtils::toUpper(ext) == "AUTH=LOGIN")
{
m_extensions["AUTH"].push_back("LOGIN");
}
// Default case: EXT PARAM1 PARAM2...
else
{
std::vector <string> params;
string param;
while (iss >> param)
params.push_back(utility::stringUtils::toUpper(param));
m_extensions[ext] = params;
}
}
} }
} }
@ -277,41 +306,10 @@ void SMTPTransport::authenticateSASL()
if (!getAuthenticator().dynamicCast <security::sasl::SASLAuthenticator>()) if (!getAuthenticator().dynamicCast <security::sasl::SASLAuthenticator>())
throw exceptions::authentication_error("No SASL authenticator available."); throw exceptions::authentication_error("No SASL authenticator available.");
// Obtain SASL mechanisms supported by server from EHLO response // Obtain SASL mechanisms supported by server from ESMTP extensions
std::vector <string> saslMechs; const std::vector <string> saslMechs =
std::istringstream iss(m_extendedSMTPResponse); (m_extensions.find("AUTH") != m_extensions.end())
? m_extensions["AUTH"] : std::vector <string>();
while (!iss.eof())
{
string line;
std::getline(iss, line);
std::istringstream liss(line);
string word;
bool inAuth = false;
while (liss >> word)
{
if (word.length() == 4 &&
(word[0] == 'A' || word[0] == 'a') &&
(word[1] == 'U' || word[1] == 'u') &&
(word[2] == 'T' || word[2] == 't') &&
(word[3] == 'H' || word[3] == 'h'))
{
inAuth = true;
}
else if (inAuth)
{
saslMechs.push_back(word);
}
// Some servers send "AUTH=LOGIN"
else if (word.length() == 10 && utility::stringUtils::toUpper(word) == "AUTH=LOGIN")
{
saslMechs.push_back("LOGIN");
}
}
}
if (saslMechs.empty()) if (saslMechs.empty())
throw exceptions::authentication_error("No SASL mechanism available."); throw exceptions::authentication_error("No SASL mechanism available.");

View File

@ -89,7 +89,7 @@ private:
bool m_authentified; bool m_authentified;
bool m_extendedSMTP; bool m_extendedSMTP;
string m_extendedSMTPResponse; std::map <string, std::vector <string> > m_extensions;
ref <timeoutHandler> m_timeoutHandler; ref <timeoutHandler> m_timeoutHandler;