1
0
mirror of https://github.com/moparisthebest/k-9 synced 2024-12-18 22:02:19 -05:00
k-9/src/com/fsck/k9/mail/Authentication.java
Joe Steele 26491676fa Retrict use of AuthenticationFailedException
In AccountSetupCheckSettings.onCreate(Bundle), the account settings are
checked.

If an AuthenticationFailedException occurs, A dialog saying "Username or
password incorrect." pops up.  We don't want to say this if the cause is
not related to an incorrect user name or password.  Instead we want to say
the more generic "Cannot connect to server" which pops up for other
exception types.

This commit attempts to eliminate the use of AuthenticationFailedException
in instances where it could not be due to "Username or password
incorrect."
2014-02-25 15:22:30 -05:00

86 lines
2.9 KiB
Java

package com.fsck.k9.mail;
import java.security.MessageDigest;
import com.fsck.k9.mail.filter.Base64;
import com.fsck.k9.mail.filter.Hex;
public class Authentication {
private static final String US_ASCII = "US-ASCII";
/**
* Computes the response for CRAM-MD5 authentication mechanism given the user credentials and
* the server-provided nonce.
*
* @param username The username.
* @param password The password.
* @param b64Nonce The nonce as base64-encoded string.
* @return The CRAM-MD5 response.
*
* @throws MessagingException If something went wrong.
*
* @see Authentication#computeCramMd5Bytes(String, String, byte[])
*/
public static String computeCramMd5(String username, String password, String b64Nonce)
throws MessagingException {
try {
byte[] b64NonceBytes = b64Nonce.getBytes(US_ASCII);
byte[] b64CRAM = computeCramMd5Bytes(username, password, b64NonceBytes);
return new String(b64CRAM, US_ASCII);
} catch (MessagingException e) {
throw e;
} catch (Exception e) {
throw new MessagingException("This shouldn't happen", e);
}
}
/**
* Computes the response for CRAM-MD5 authentication mechanism given the user credentials and
* the server-provided nonce.
*
* @param username The username.
* @param password The password.
* @param b64Nonce The nonce as base64-encoded byte array.
* @return The CRAM-MD5 response as byte array.
*
* @throws MessagingException If something went wrong.
*
* @see <a href="https://tools.ietf.org/html/rfc2195">RFC 2195</a>
*/
public static byte[] computeCramMd5Bytes(String username, String password, byte[] b64Nonce)
throws MessagingException {
try {
byte[] nonce = Base64.decodeBase64(b64Nonce);
byte[] secretBytes = password.getBytes();
MessageDigest md = MessageDigest.getInstance("MD5");
if (secretBytes.length > 64) {
secretBytes = md.digest(secretBytes);
}
byte[] ipad = new byte[64];
byte[] opad = new byte[64];
System.arraycopy(secretBytes, 0, ipad, 0, secretBytes.length);
System.arraycopy(secretBytes, 0, opad, 0, secretBytes.length);
for (int i = 0; i < ipad.length; i++) ipad[i] ^= 0x36;
for (int i = 0; i < opad.length; i++) opad[i] ^= 0x5c;
md.update(ipad);
byte[] firstPass = md.digest(nonce);
md.update(opad);
byte[] result = md.digest(firstPass);
String plainCRAM = username + " " + new String(Hex.encodeHex(result));
byte[] b64CRAM = Base64.encodeBase64(plainCRAM.getBytes());
return b64CRAM;
} catch (Exception e) {
throw new MessagingException("Something went wrong during CRAM-MD5 computation", e);
}
}
}