mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-24 02:12:15 -05:00
Implement SMTP AUTH EXTERNAL
Also, simplify by using Utility.base64Encode(String) in lieu of new String(Base64.encodeBase64(String.getBytes())
This commit is contained in:
parent
c0be0eea12
commit
b557ba008c
@ -1107,6 +1107,8 @@ Please submit bug reports, contribute new features and ask questions at
|
|||||||
<string name="fetching_attachment_dialog_title_save">Saving draft</string>
|
<string name="fetching_attachment_dialog_title_save">Saving draft</string>
|
||||||
<string name="fetching_attachment_dialog_message">Fetching attachment…</string>
|
<string name="fetching_attachment_dialog_message">Fetching attachment…</string>
|
||||||
|
|
||||||
|
<string name="auth_external_error">Unable to authenticate. The server does not advertise the SASL EXTERNAL capability. This could be due to a problem with the client certificate (expired, unknown certificate authority) or some other configuration problem.</string>
|
||||||
|
|
||||||
<!-- === OpenPGP specific ================================================================== -->
|
<!-- === OpenPGP specific ================================================================== -->
|
||||||
<string name="openpgp_decrypting_verifying">Decrypting/Verifying…</string>
|
<string name="openpgp_decrypting_verifying">Decrypting/Verifying…</string>
|
||||||
<string name="openpgp_successful_decryption">Successful decryption</string>
|
<string name="openpgp_successful_decryption">Successful decryption</string>
|
||||||
|
@ -5,9 +5,10 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.fsck.k9.Account;
|
import com.fsck.k9.Account;
|
||||||
import com.fsck.k9.K9;
|
import com.fsck.k9.K9;
|
||||||
|
import com.fsck.k9.R;
|
||||||
|
import com.fsck.k9.helper.Utility;
|
||||||
import com.fsck.k9.mail.*;
|
import com.fsck.k9.mail.*;
|
||||||
import com.fsck.k9.mail.Message.RecipientType;
|
import com.fsck.k9.mail.Message.RecipientType;
|
||||||
import com.fsck.k9.mail.filter.Base64;
|
|
||||||
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
|
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
|
||||||
import com.fsck.k9.mail.filter.LineWrapOutputStream;
|
import com.fsck.k9.mail.filter.LineWrapOutputStream;
|
||||||
import com.fsck.k9.mail.filter.PeekableInputStream;
|
import com.fsck.k9.mail.filter.PeekableInputStream;
|
||||||
@ -307,11 +308,13 @@ public class SmtpTransport extends Transport {
|
|||||||
boolean authLoginSupported = false;
|
boolean authLoginSupported = false;
|
||||||
boolean authPlainSupported = false;
|
boolean authPlainSupported = false;
|
||||||
boolean authCramMD5Supported = false;
|
boolean authCramMD5Supported = false;
|
||||||
|
boolean authExternalSupported = false;
|
||||||
if (extensions.containsKey("AUTH")) {
|
if (extensions.containsKey("AUTH")) {
|
||||||
List<String> saslMech = Arrays.asList(extensions.get("AUTH").split(" "));
|
List<String> saslMech = Arrays.asList(extensions.get("AUTH").split(" "));
|
||||||
authLoginSupported = saslMech.contains("LOGIN");
|
authLoginSupported = saslMech.contains("LOGIN");
|
||||||
authPlainSupported = saslMech.contains("PLAIN");
|
authPlainSupported = saslMech.contains("PLAIN");
|
||||||
authCramMD5Supported = saslMech.contains("CRAM-MD5");
|
authCramMD5Supported = saslMech.contains("CRAM-MD5");
|
||||||
|
authExternalSupported = saslMech.contains("EXTERNAL");
|
||||||
}
|
}
|
||||||
if (extensions.containsKey("SIZE")) {
|
if (extensions.containsKey("SIZE")) {
|
||||||
try {
|
try {
|
||||||
@ -323,8 +326,10 @@ public class SmtpTransport extends Transport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mUsername != null && mUsername.length() > 0 &&
|
if (mUsername != null
|
||||||
mPassword != null && mPassword.length() > 0) {
|
&& mUsername.length() > 0
|
||||||
|
&& (mPassword != null && mPassword.length() > 0 || AuthType.EXTERNAL
|
||||||
|
.equals(mAuthType))) {
|
||||||
|
|
||||||
switch (mAuthType) {
|
switch (mAuthType) {
|
||||||
|
|
||||||
@ -353,6 +358,24 @@ public class SmtpTransport extends Transport {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case EXTERNAL:
|
||||||
|
if (authExternalSupported) {
|
||||||
|
saslAuthExternal(mUsername);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Some SMTP servers are known to provide no error
|
||||||
|
* indication when a client certificate fails to
|
||||||
|
* validate, other than to not offer the AUTH EXTERNAL
|
||||||
|
* capability.
|
||||||
|
*
|
||||||
|
* So, we treat it is an error to not offer AUTH
|
||||||
|
* EXTERNAL when using client certificates. That way, the
|
||||||
|
* user can be notified of a problem during account setup.
|
||||||
|
*/
|
||||||
|
throw new MessagingException(K9.app.getString(R.string.auth_external_error));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* AUTOMATIC is an obsolete option which is unavailable to users,
|
* AUTOMATIC is an obsolete option which is unavailable to users,
|
||||||
* but it still may exist in a user's settings from a previous
|
* but it still may exist in a user's settings from a previous
|
||||||
@ -688,8 +711,8 @@ public class SmtpTransport extends Transport {
|
|||||||
AuthenticationFailedException, IOException {
|
AuthenticationFailedException, IOException {
|
||||||
try {
|
try {
|
||||||
executeSimpleCommand("AUTH LOGIN");
|
executeSimpleCommand("AUTH LOGIN");
|
||||||
executeSimpleCommand(new String(Base64.encodeBase64(username.getBytes())), true);
|
executeSimpleCommand(Utility.base64Encode(username), true);
|
||||||
executeSimpleCommand(new String(Base64.encodeBase64(password.getBytes())), true);
|
executeSimpleCommand(Utility.base64Encode(password), true);
|
||||||
} catch (MessagingException me) {
|
} catch (MessagingException me) {
|
||||||
if (me.getMessage().length() > 1 && me.getMessage().charAt(1) == '3') {
|
if (me.getMessage().length() > 1 && me.getMessage().charAt(1) == '3') {
|
||||||
throw new AuthenticationFailedException("AUTH LOGIN failed (" + me.getMessage()
|
throw new AuthenticationFailedException("AUTH LOGIN failed (" + me.getMessage()
|
||||||
@ -701,10 +724,9 @@ public class SmtpTransport extends Transport {
|
|||||||
|
|
||||||
private void saslAuthPlain(String username, String password) throws MessagingException,
|
private void saslAuthPlain(String username, String password) throws MessagingException,
|
||||||
AuthenticationFailedException, IOException {
|
AuthenticationFailedException, IOException {
|
||||||
byte[] data = ("\000" + username + "\000" + password).getBytes();
|
String data = Utility.base64Encode("\000" + username + "\000" + password);
|
||||||
data = new Base64().encode(data);
|
|
||||||
try {
|
try {
|
||||||
executeSimpleCommand("AUTH PLAIN " + new String(data), true);
|
executeSimpleCommand("AUTH PLAIN " + data, true);
|
||||||
} catch (MessagingException me) {
|
} catch (MessagingException me) {
|
||||||
if (me.getMessage().length() > 1 && me.getMessage().charAt(1) == '3') {
|
if (me.getMessage().length() > 1 && me.getMessage().charAt(1) == '3') {
|
||||||
throw new AuthenticationFailedException("AUTH PLAIN failed (" + me.getMessage()
|
throw new AuthenticationFailedException("AUTH PLAIN failed (" + me.getMessage()
|
||||||
@ -732,6 +754,12 @@ public class SmtpTransport extends Transport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void saslAuthExternal(String username) throws MessagingException, IOException {
|
||||||
|
executeSimpleCommand(
|
||||||
|
String.format("AUTH EXTERNAL %s",
|
||||||
|
Utility.base64Encode(username)), false);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exception that is thrown when the server sends a negative reply (reply codes 4xx or 5xx).
|
* Exception that is thrown when the server sends a negative reply (reply codes 4xx or 5xx).
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user