1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-11-05 17:15:05 -05:00

Ignore case for SMTP extension keywords

The server is permitted to use mixed case keywords.
This converts them to upper case on receipt.
This commit is contained in:
Joe Steele 2014-02-03 16:30:10 -05:00
parent 64fd04ece2
commit f24ac67e4d

View File

@ -288,14 +288,14 @@ public class SmtpTransport extends Transport {
} }
} }
List<String> results = sendHello(localHost); HashMap<String,String> extensions = sendHello(localHost);
m8bitEncodingAllowed = results.contains("8BITMIME"); m8bitEncodingAllowed = extensions.containsKey("8BITMIME");
if (mConnectionSecurity == CONNECTION_SECURITY_TLS_OPTIONAL if (mConnectionSecurity == CONNECTION_SECURITY_TLS_OPTIONAL
|| mConnectionSecurity == CONNECTION_SECURITY_TLS_REQUIRED) { || mConnectionSecurity == CONNECTION_SECURITY_TLS_REQUIRED) {
if (results.contains("STARTTLS")) { if (extensions.containsKey("STARTTLS")) {
executeSimpleCommand("STARTTLS"); executeSimpleCommand("STARTTLS");
SSLContext sslContext = SSLContext.getInstance("TLS"); SSLContext sslContext = SSLContext.getInstance("TLS");
@ -312,7 +312,7 @@ public class SmtpTransport extends Transport {
* Now resend the EHLO. Required by RFC2487 Sec. 5.2, and more specifically, * Now resend the EHLO. Required by RFC2487 Sec. 5.2, and more specifically,
* Exim. * Exim.
*/ */
results = sendHello(localHost); extensions = sendHello(localHost);
} else if (mConnectionSecurity == CONNECTION_SECURITY_TLS_REQUIRED) { } else if (mConnectionSecurity == CONNECTION_SECURITY_TLS_REQUIRED) {
throw new MessagingException("TLS not supported but required"); throw new MessagingException("TLS not supported but required");
} }
@ -328,23 +328,18 @@ public class SmtpTransport extends Transport {
boolean authLoginSupported = false; boolean authLoginSupported = false;
boolean authPlainSupported = false; boolean authPlainSupported = false;
boolean authCramMD5Supported = false; boolean authCramMD5Supported = false;
for (String result : results) { if (extensions.containsKey("AUTH")) {
if (result.matches(".*AUTH.*LOGIN.*$")) { List<String> saslMech = Arrays.asList(extensions.get("AUTH").split(" "));
authLoginSupported = true; authLoginSupported = saslMech.contains("LOGIN");
authPlainSupported = saslMech.contains("PLAIN");
authCramMD5Supported = saslMech.contains("CRAM-MD5");
} }
if (result.matches(".*AUTH.*PLAIN.*$")) { if (extensions.containsKey("SIZE")) {
authPlainSupported = true;
}
if (result.matches(".*AUTH.*CRAM-MD5.*$")) {
authCramMD5Supported = true;
}
if (result.matches(".*SIZE \\d*$")) {
try { try {
mLargestAcceptableMessage = Integer.parseInt(result.substring(result.lastIndexOf(' ') + 1)); mLargestAcceptableMessage = Integer.parseInt(extensions.get("SIZE"));
} catch (Exception e) { } catch (Exception e) {
if (K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) { if (K9.DEBUG && K9.DEBUG_PROTOCOL_SMTP) {
Log.d(K9.LOG_TAG, "Tried to parse " + result + " and get an int out of the last word", e); Log.d(K9.LOG_TAG, "Tried to parse " + extensions.get("SIZE") + " and get an int", e);
}
} }
} }
} }
@ -410,19 +405,24 @@ public class SmtpTransport extends Transport {
* @param host * @param host
* The EHLO/HELO parameter as defined by the RFC. * The EHLO/HELO parameter as defined by the RFC.
* *
* @return The list of capabilities as returned by the EHLO command or an empty list. * @return A (possibly empty) {@code HashMap<String,String>} of extensions (upper case) and
* their parameters (possibly 0 length) as returned by the EHLO command
* *
* @throws IOException * @throws IOException
* In case of a network error. * In case of a network error.
* @throws MessagingException * @throws MessagingException
* In case of a malformed response. * In case of a malformed response.
*/ */
private List<String> sendHello(String host) throws IOException, MessagingException { private HashMap<String,String> sendHello(String host) throws IOException, MessagingException {
HashMap<String, String> extensions = new HashMap<String, String>();
try { try {
//TODO: We currently assume the extension keywords returned by the server are always List<String> results = executeSimpleCommand("EHLO " + host);
// uppercased. But the RFC allows mixed-case keywords! // Remove the EHLO greeting response
results.remove(0);
return executeSimpleCommand("EHLO " + host); for (String result : results) {
String[] pair = result.split(" ", 2);
extensions.put(pair[0].toUpperCase(), pair.length == 1 ? "" : pair[1]);
}
} catch (NegativeSmtpReplyException e) { } catch (NegativeSmtpReplyException e) {
if (K9.DEBUG) { if (K9.DEBUG) {
Log.v(K9.LOG_TAG, "Server doesn't support the EHLO command. Trying HELO..."); Log.v(K9.LOG_TAG, "Server doesn't support the EHLO command. Trying HELO...");
@ -434,8 +434,7 @@ public class SmtpTransport extends Transport {
Log.w(K9.LOG_TAG, "Server doesn't support the HELO command. Continuing anyway."); Log.w(K9.LOG_TAG, "Server doesn't support the HELO command. Continuing anyway.");
} }
} }
return extensions;
return new ArrayList<String>(0);
} }
@Override @Override