mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-24 10:22:15 -05:00
Remove coupling between ImapStore and ImapConnection by adding an settings indirection interface. Purpose: use the IMAP connection code to validate credentials without having an actual ImapStore instance.
This commit is contained in:
parent
a1e059e871
commit
47762a9baa
@ -1,41 +1,21 @@
|
|||||||
|
|
||||||
package com.fsck.k9.mail.store;
|
package com.fsck.k9.mail.store;
|
||||||
|
|
||||||
import android.content.Context;
|
import java.io.BufferedInputStream;
|
||||||
import android.net.ConnectivityManager;
|
import java.io.BufferedOutputStream;
|
||||||
import android.net.NetworkInfo;
|
import java.io.ByteArrayInputStream;
|
||||||
import android.os.PowerManager;
|
import java.io.IOException;
|
||||||
import android.util.Log;
|
import java.io.InputStream;
|
||||||
import com.fsck.k9.Account;
|
import java.io.OutputStream;
|
||||||
import com.fsck.k9.K9;
|
import java.io.UnsupportedEncodingException;
|
||||||
import com.fsck.k9.R;
|
import java.net.ConnectException;
|
||||||
import com.fsck.k9.controller.MessageRetrievalListener;
|
import java.net.InetSocketAddress;
|
||||||
import com.fsck.k9.helper.Utility;
|
import java.net.Socket;
|
||||||
import com.fsck.k9.helper.power.TracingPowerManager;
|
import java.net.SocketAddress;
|
||||||
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
|
import java.net.SocketException;
|
||||||
import com.fsck.k9.mail.*;
|
import java.net.URI;
|
||||||
import com.fsck.k9.mail.filter.CountingOutputStream;
|
import java.net.URISyntaxException;
|
||||||
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
|
import java.net.URLDecoder;
|
||||||
import com.fsck.k9.mail.filter.FixedLengthInputStream;
|
|
||||||
import com.fsck.k9.mail.filter.PeekableInputStream;
|
|
||||||
import com.fsck.k9.mail.internet.*;
|
|
||||||
import com.fsck.k9.mail.store.ImapResponseParser.ImapList;
|
|
||||||
import com.fsck.k9.mail.store.ImapResponseParser.ImapResponse;
|
|
||||||
import com.jcraft.jzlib.JZlib;
|
|
||||||
import com.jcraft.jzlib.ZInputStream;
|
|
||||||
import com.jcraft.jzlib.ZOutputStream;
|
|
||||||
import com.beetstra.jutf7.CharsetProvider;
|
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
|
||||||
import javax.net.ssl.SSLException;
|
|
||||||
import javax.net.ssl.TrustManager;
|
|
||||||
|
|
||||||
|
|
||||||
import org.apache.commons.codec.binary.Base64;
|
|
||||||
import org.apache.commons.codec.binary.Hex;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.net.*;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.CharBuffer;
|
import java.nio.CharBuffer;
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
@ -45,11 +25,73 @@ import java.security.NoSuchAlgorithmException;
|
|||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.Security;
|
import java.security.Security;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLException;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.apache.commons.codec.binary.Hex;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
|
import android.os.PowerManager;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.beetstra.jutf7.CharsetProvider;
|
||||||
|
import com.fsck.k9.Account;
|
||||||
|
import com.fsck.k9.K9;
|
||||||
|
import com.fsck.k9.R;
|
||||||
|
import com.fsck.k9.controller.MessageRetrievalListener;
|
||||||
|
import com.fsck.k9.helper.Utility;
|
||||||
|
import com.fsck.k9.helper.power.TracingPowerManager;
|
||||||
|
import com.fsck.k9.helper.power.TracingPowerManager.TracingWakeLock;
|
||||||
|
import com.fsck.k9.mail.AuthenticationFailedException;
|
||||||
|
import com.fsck.k9.mail.Body;
|
||||||
|
import com.fsck.k9.mail.CertificateValidationException;
|
||||||
|
import com.fsck.k9.mail.FetchProfile;
|
||||||
|
import com.fsck.k9.mail.Flag;
|
||||||
|
import com.fsck.k9.mail.Folder;
|
||||||
|
import com.fsck.k9.mail.Message;
|
||||||
|
import com.fsck.k9.mail.MessagingException;
|
||||||
|
import com.fsck.k9.mail.Part;
|
||||||
|
import com.fsck.k9.mail.PushReceiver;
|
||||||
|
import com.fsck.k9.mail.Pusher;
|
||||||
|
import com.fsck.k9.mail.Store;
|
||||||
|
import com.fsck.k9.mail.filter.CountingOutputStream;
|
||||||
|
import com.fsck.k9.mail.filter.EOLConvertingOutputStream;
|
||||||
|
import com.fsck.k9.mail.filter.FixedLengthInputStream;
|
||||||
|
import com.fsck.k9.mail.filter.PeekableInputStream;
|
||||||
|
import com.fsck.k9.mail.internet.MimeBodyPart;
|
||||||
|
import com.fsck.k9.mail.internet.MimeHeader;
|
||||||
|
import com.fsck.k9.mail.internet.MimeMessage;
|
||||||
|
import com.fsck.k9.mail.internet.MimeMultipart;
|
||||||
|
import com.fsck.k9.mail.internet.MimeUtility;
|
||||||
|
import com.fsck.k9.mail.store.ImapResponseParser.ImapList;
|
||||||
|
import com.fsck.k9.mail.store.ImapResponseParser.ImapResponse;
|
||||||
|
import com.fsck.k9.mail.transport.imap.ImapSettings;
|
||||||
|
import com.jcraft.jzlib.JZlib;
|
||||||
|
import com.jcraft.jzlib.ZInputStream;
|
||||||
|
import com.jcraft.jzlib.ZOutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
* TODO Need to start keeping track of UIDVALIDITY
|
* TODO Need to start keeping track of UIDVALIDITY
|
||||||
@ -64,7 +106,7 @@ public class ImapStore extends Store
|
|||||||
public static final int CONNECTION_SECURITY_SSL_REQUIRED = 3;
|
public static final int CONNECTION_SECURITY_SSL_REQUIRED = 3;
|
||||||
public static final int CONNECTION_SECURITY_SSL_OPTIONAL = 4;
|
public static final int CONNECTION_SECURITY_SSL_OPTIONAL = 4;
|
||||||
|
|
||||||
private enum AuthType { PLAIN, CRAM_MD5 }
|
public enum AuthType { PLAIN, CRAM_MD5 }
|
||||||
|
|
||||||
private static final int IDLE_READ_TIMEOUT_INCREMENT = 5 * 60 * 1000;
|
private static final int IDLE_READ_TIMEOUT_INCREMENT = 5 * 60 * 1000;
|
||||||
private static final int IDLE_FAILURE_COUNT_LIMIT = 10;
|
private static final int IDLE_FAILURE_COUNT_LIMIT = 10;
|
||||||
@ -100,6 +142,89 @@ public class ImapStore extends Store
|
|||||||
private volatile String mCombinedPrefix = null;
|
private volatile String mCombinedPrefix = null;
|
||||||
private volatile String mPathDelimeter = null;
|
private volatile String mPathDelimeter = null;
|
||||||
|
|
||||||
|
public class StoreImapSettings implements ImapSettings
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHost()
|
||||||
|
{
|
||||||
|
return mHost;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPort()
|
||||||
|
{
|
||||||
|
return mPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getConnectionSecurity()
|
||||||
|
{
|
||||||
|
return mConnectionSecurity;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AuthType getAuthType()
|
||||||
|
{
|
||||||
|
return mAuthType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getUsername()
|
||||||
|
{
|
||||||
|
return mUsername;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPassword()
|
||||||
|
{
|
||||||
|
return mPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useCompression(final int type)
|
||||||
|
{
|
||||||
|
return mAccount.useCompression(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPathPrefix()
|
||||||
|
{
|
||||||
|
return mPathPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPathPrefix(String prefix)
|
||||||
|
{
|
||||||
|
mPathPrefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPathDelimeter()
|
||||||
|
{
|
||||||
|
return mPathDelimeter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPathDelimeter(String delimeter)
|
||||||
|
{
|
||||||
|
mPathDelimeter = delimeter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCombinedPrefix()
|
||||||
|
{
|
||||||
|
return mCombinedPrefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCombinedPrefix(String prefix)
|
||||||
|
{
|
||||||
|
mCombinedPrefix = prefix;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private static final SimpleDateFormat RFC3501_DATE = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);
|
private static final SimpleDateFormat RFC3501_DATE = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);
|
||||||
|
|
||||||
private LinkedList<ImapConnection> mConnections =
|
private LinkedList<ImapConnection> mConnections =
|
||||||
@ -375,7 +500,7 @@ public class ImapStore extends Store
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ImapConnection connection = new ImapConnection();
|
ImapConnection connection = new ImapConnection(new StoreImapSettings());
|
||||||
connection.open();
|
connection.open();
|
||||||
connection.close();
|
connection.close();
|
||||||
}
|
}
|
||||||
@ -408,7 +533,7 @@ public class ImapStore extends Store
|
|||||||
}
|
}
|
||||||
if (connection == null)
|
if (connection == null)
|
||||||
{
|
{
|
||||||
connection = new ImapConnection();
|
connection = new ImapConnection(new StoreImapSettings());
|
||||||
}
|
}
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
@ -2061,16 +2186,23 @@ public class ImapStore extends Store
|
|||||||
/**
|
/**
|
||||||
* A cacheable class that stores the details for a single IMAP connection.
|
* A cacheable class that stores the details for a single IMAP connection.
|
||||||
*/
|
*/
|
||||||
class ImapConnection
|
public static class ImapConnection
|
||||||
{
|
{
|
||||||
private Socket mSocket;
|
protected Socket mSocket;
|
||||||
private PeekableInputStream mIn;
|
protected PeekableInputStream mIn;
|
||||||
private OutputStream mOut;
|
protected OutputStream mOut;
|
||||||
private ImapResponseParser mParser;
|
protected ImapResponseParser mParser;
|
||||||
private int mNextCommandTag;
|
protected int mNextCommandTag;
|
||||||
protected Set<String> capabilities = new HashSet<String>();
|
protected Set<String> capabilities = new HashSet<String>();
|
||||||
|
|
||||||
private String getLogId()
|
private ImapSettings mSettings;
|
||||||
|
|
||||||
|
public ImapConnection(final ImapSettings settings)
|
||||||
|
{
|
||||||
|
this.mSettings = settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getLogId()
|
||||||
{
|
{
|
||||||
return "conn" + hashCode();
|
return "conn" + hashCode();
|
||||||
}
|
}
|
||||||
@ -2126,7 +2258,6 @@ public class ImapStore extends Store
|
|||||||
return responses;
|
return responses;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void open() throws IOException, MessagingException
|
public void open() throws IOException, MessagingException
|
||||||
{
|
{
|
||||||
if (isOpen())
|
if (isOpen())
|
||||||
@ -2161,19 +2292,19 @@ public class ImapStore extends Store
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
||||||
SocketAddress socketAddress = new InetSocketAddress(mHost, mPort);
|
SocketAddress socketAddress = new InetSocketAddress(mSettings.getHost(), mSettings.getPort());
|
||||||
|
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.i(K9.LOG_TAG, "Connection " + getLogId() + " connecting to " + mHost + " @ IP addr " + socketAddress);
|
Log.i(K9.LOG_TAG, "Connection " + getLogId() + " connecting to " + mSettings.getHost() + " @ IP addr " + socketAddress);
|
||||||
|
|
||||||
if (mConnectionSecurity == CONNECTION_SECURITY_SSL_REQUIRED ||
|
if (mSettings.getConnectionSecurity() == CONNECTION_SECURITY_SSL_REQUIRED ||
|
||||||
mConnectionSecurity == CONNECTION_SECURITY_SSL_OPTIONAL)
|
mSettings.getConnectionSecurity() == CONNECTION_SECURITY_SSL_OPTIONAL)
|
||||||
{
|
{
|
||||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||||
final boolean secure = mConnectionSecurity == CONNECTION_SECURITY_SSL_REQUIRED;
|
final boolean secure = mSettings.getConnectionSecurity() == CONNECTION_SECURITY_SSL_REQUIRED;
|
||||||
sslContext.init(null, new TrustManager[]
|
sslContext.init(null, new TrustManager[]
|
||||||
{
|
{
|
||||||
TrustManagerFactory.get(mHost, secure)
|
TrustManagerFactory.get(mSettings.getHost(), secure)
|
||||||
}, new SecureRandom());
|
}, new SecureRandom());
|
||||||
mSocket = sslContext.getSocketFactory().createSocket();
|
mSocket = sslContext.getSocketFactory().createSocket();
|
||||||
mSocket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT);
|
mSocket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT);
|
||||||
@ -2211,8 +2342,8 @@ public class ImapStore extends Store
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mConnectionSecurity == CONNECTION_SECURITY_TLS_OPTIONAL
|
if (mSettings.getConnectionSecurity() == CONNECTION_SECURITY_TLS_OPTIONAL
|
||||||
|| mConnectionSecurity == CONNECTION_SECURITY_TLS_REQUIRED)
|
|| mSettings.getConnectionSecurity() == CONNECTION_SECURITY_TLS_REQUIRED)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (hasCapability("STARTTLS"))
|
if (hasCapability("STARTTLS"))
|
||||||
@ -2221,12 +2352,12 @@ public class ImapStore extends Store
|
|||||||
executeSimpleCommand("STARTTLS");
|
executeSimpleCommand("STARTTLS");
|
||||||
|
|
||||||
SSLContext sslContext = SSLContext.getInstance("TLS");
|
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||||
boolean secure = mConnectionSecurity == CONNECTION_SECURITY_TLS_REQUIRED;
|
boolean secure = mSettings.getConnectionSecurity() == CONNECTION_SECURITY_TLS_REQUIRED;
|
||||||
sslContext.init(null, new TrustManager[]
|
sslContext.init(null, new TrustManager[]
|
||||||
{
|
{
|
||||||
TrustManagerFactory.get(mHost, secure)
|
TrustManagerFactory.get(mSettings.getHost(), secure)
|
||||||
}, new SecureRandom());
|
}, new SecureRandom());
|
||||||
mSocket = sslContext.getSocketFactory().createSocket(mSocket, mHost, mPort,
|
mSocket = sslContext.getSocketFactory().createSocket(mSocket, mSettings.getHost(), mSettings.getPort(),
|
||||||
true);
|
true);
|
||||||
mSocket.setSoTimeout(Store.SOCKET_READ_TIMEOUT);
|
mSocket.setSoTimeout(Store.SOCKET_READ_TIMEOUT);
|
||||||
mIn = new PeekableInputStream(new BufferedInputStream(mSocket
|
mIn = new PeekableInputStream(new BufferedInputStream(mSocket
|
||||||
@ -2234,7 +2365,7 @@ public class ImapStore extends Store
|
|||||||
mParser = new ImapResponseParser(mIn);
|
mParser = new ImapResponseParser(mIn);
|
||||||
mOut = mSocket.getOutputStream();
|
mOut = mSocket.getOutputStream();
|
||||||
}
|
}
|
||||||
else if (mConnectionSecurity == CONNECTION_SECURITY_TLS_REQUIRED)
|
else if (mSettings.getConnectionSecurity() == CONNECTION_SECURITY_TLS_REQUIRED)
|
||||||
{
|
{
|
||||||
throw new MessagingException("TLS not supported but required");
|
throw new MessagingException("TLS not supported but required");
|
||||||
}
|
}
|
||||||
@ -2245,13 +2376,13 @@ public class ImapStore extends Store
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Yahoo! requires a custom IMAP command to work right over a non-3G network
|
// Yahoo! requires a custom IMAP command to work right over a non-3G network
|
||||||
if (mHost.endsWith("yahoo.com"))
|
if (mSettings.getHost().endsWith("yahoo.com"))
|
||||||
{
|
{
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.v(K9.LOG_TAG, "Found Yahoo! account. Sending proprietary commands.");
|
Log.v(K9.LOG_TAG, "Found Yahoo! account. Sending proprietary commands.");
|
||||||
executeSimpleCommand("ID (\"GUID\" \"1\")");
|
executeSimpleCommand("ID (\"GUID\" \"1\")");
|
||||||
}
|
}
|
||||||
if (mAuthType == AuthType.CRAM_MD5)
|
if (mSettings.getAuthType() == AuthType.CRAM_MD5)
|
||||||
{
|
{
|
||||||
authCramMD5();
|
authCramMD5();
|
||||||
// The authCramMD5 method called on the previous line does not allow for handling updated capabilities
|
// The authCramMD5 method called on the previous line does not allow for handling updated capabilities
|
||||||
@ -2266,9 +2397,9 @@ public class ImapStore extends Store
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (mAuthType == AuthType.PLAIN)
|
else if (mSettings.getAuthType() == AuthType.PLAIN)
|
||||||
{
|
{
|
||||||
receiveCapabilities(executeSimpleCommand("LOGIN \"" + escapeString(mUsername) + "\" \"" + escapeString(mPassword) + "\"", true));
|
receiveCapabilities(executeSimpleCommand("LOGIN \"" + escapeString(mSettings.getUsername()) + "\" \"" + escapeString(mSettings.getPassword()) + "\"", true));
|
||||||
}
|
}
|
||||||
authSuccess = true;
|
authSuccess = true;
|
||||||
}
|
}
|
||||||
@ -2296,7 +2427,7 @@ public class ImapStore extends Store
|
|||||||
int type = netInfo.getType();
|
int type = netInfo.getType();
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.d(K9.LOG_TAG, "On network type " + type);
|
Log.d(K9.LOG_TAG, "On network type " + type);
|
||||||
useCompression = mAccount.useCompression(type);
|
useCompression = mSettings.useCompression(type);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
@ -2328,9 +2459,9 @@ public class ImapStore extends Store
|
|||||||
|
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.d(K9.LOG_TAG, "NAMESPACE = " + hasCapability(CAPABILITY_NAMESPACE)
|
Log.d(K9.LOG_TAG, "NAMESPACE = " + hasCapability(CAPABILITY_NAMESPACE)
|
||||||
+ ", mPathPrefix = " + mPathPrefix);
|
+ ", mPathPrefix = " + mSettings.getPathPrefix());
|
||||||
|
|
||||||
if (mPathPrefix == null)
|
if (mSettings.getPathPrefix() == null)
|
||||||
{
|
{
|
||||||
if (hasCapability(CAPABILITY_NAMESPACE))
|
if (hasCapability(CAPABILITY_NAMESPACE))
|
||||||
{
|
{
|
||||||
@ -2357,11 +2488,11 @@ public class ImapStore extends Store
|
|||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.d(K9.LOG_TAG, "Got first personal namespaces: " + firstNamespace);
|
Log.d(K9.LOG_TAG, "Got first personal namespaces: " + firstNamespace);
|
||||||
bracketed = (ImapList)firstNamespace;
|
bracketed = (ImapList)firstNamespace;
|
||||||
mPathPrefix = bracketed.getString(0);
|
mSettings.setPathPrefix(bracketed.getString(0));
|
||||||
mPathDelimeter = bracketed.getString(1);
|
mSettings.setPathDelimeter(bracketed.getString(1));
|
||||||
mCombinedPrefix = null;
|
mSettings.setCombinedPrefix(null);
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.d(K9.LOG_TAG, "Got path '" + mPathPrefix + "' and separator '" + mPathDelimeter + "'");
|
Log.d(K9.LOG_TAG, "Got path '" + mSettings.getPathPrefix() + "' and separator '" + mSettings.getPathDelimeter() + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2371,10 +2502,10 @@ public class ImapStore extends Store
|
|||||||
{
|
{
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.i(K9.LOG_TAG, "mPathPrefix is unset but server does not have NAMESPACE capability");
|
Log.i(K9.LOG_TAG, "mPathPrefix is unset but server does not have NAMESPACE capability");
|
||||||
mPathPrefix = "";
|
mSettings.setPathPrefix("");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mPathDelimeter == null)
|
if (mSettings.getPathDelimeter() == null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -2384,10 +2515,10 @@ public class ImapStore extends Store
|
|||||||
{
|
{
|
||||||
if (ImapResponseParser.equalsIgnoreCase(response.get(0), "LIST"))
|
if (ImapResponseParser.equalsIgnoreCase(response.get(0), "LIST"))
|
||||||
{
|
{
|
||||||
mPathDelimeter = response.getString(2);
|
mSettings.setPathDelimeter(response.getString(2));
|
||||||
mCombinedPrefix = null;
|
mSettings.setCombinedPrefix(null);
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
Log.d(K9.LOG_TAG, "Got path delimeter '" + mPathDelimeter + "' for " + getLogId());
|
Log.d(K9.LOG_TAG, "Got path delimeter '" + mSettings.getPathDelimeter() + "' for " + getLogId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2463,7 +2594,7 @@ public class ImapStore extends Store
|
|||||||
|
|
||||||
byte[] ipad = new byte[64];
|
byte[] ipad = new byte[64];
|
||||||
byte[] opad = new byte[64];
|
byte[] opad = new byte[64];
|
||||||
byte[] secretBytes = mPassword.getBytes("US-ASCII");
|
byte[] secretBytes = mSettings.getPassword().getBytes("US-ASCII");
|
||||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||||
if (secretBytes.length > 64)
|
if (secretBytes.length > 64)
|
||||||
{
|
{
|
||||||
@ -2477,11 +2608,11 @@ public class ImapStore extends Store
|
|||||||
byte[] firstPass = md.digest(nonce);
|
byte[] firstPass = md.digest(nonce);
|
||||||
md.update(opad);
|
md.update(opad);
|
||||||
byte[] result = md.digest(firstPass);
|
byte[] result = md.digest(firstPass);
|
||||||
String plainCRAM = mUsername + " " + new String(Hex.encodeHex(result));
|
String plainCRAM = mSettings.getUsername() + " " + new String(Hex.encodeHex(result));
|
||||||
byte[] b64CRAM = Base64.encodeBase64(plainCRAM.getBytes("US-ASCII"));
|
byte[] b64CRAM = Base64.encodeBase64(plainCRAM.getBytes("US-ASCII"));
|
||||||
if (K9.DEBUG)
|
if (K9.DEBUG)
|
||||||
{
|
{
|
||||||
Log.d(K9.LOG_TAG, "Username == " + mUsername);
|
Log.d(K9.LOG_TAG, "Username == " + mSettings.getUsername());
|
||||||
Log.d(K9.LOG_TAG, "plainCRAM: " + plainCRAM);
|
Log.d(K9.LOG_TAG, "plainCRAM: " + plainCRAM);
|
||||||
Log.d(K9.LOG_TAG, "b64CRAM: " + new String(b64CRAM, "US-ASCII"));
|
Log.d(K9.LOG_TAG, "b64CRAM: " + new String(b64CRAM, "US-ASCII"));
|
||||||
}
|
}
|
||||||
@ -2538,12 +2669,12 @@ public class ImapStore extends Store
|
|||||||
return capabilities.contains(capability.toUpperCase());
|
return capabilities.contains(capability.toUpperCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isOpen()
|
public boolean isOpen()
|
||||||
{
|
{
|
||||||
return (mIn != null && mOut != null && mSocket != null && mSocket.isConnected() && !mSocket.isClosed());
|
return (mIn != null && mOut != null && mSocket != null && mSocket.isConnected() && !mSocket.isClosed());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void close()
|
public void close()
|
||||||
{
|
{
|
||||||
// if (isOpen()) {
|
// if (isOpen()) {
|
||||||
// try {
|
// try {
|
||||||
@ -2581,12 +2712,12 @@ public class ImapStore extends Store
|
|||||||
mSocket = null;
|
mSocket = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImapResponse readResponse() throws IOException, MessagingException
|
public ImapResponse readResponse() throws IOException, MessagingException
|
||||||
{
|
{
|
||||||
return readResponse(null);
|
return readResponse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImapResponse readResponse(ImapResponseParser.IImapResponseCallback callback) throws IOException
|
public ImapResponse readResponse(ImapResponseParser.IImapResponseCallback callback) throws IOException
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -2614,7 +2745,7 @@ public class ImapStore extends Store
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendContinuation(String continuation) throws IOException
|
public void sendContinuation(String continuation) throws IOException
|
||||||
{
|
{
|
||||||
mOut.write(continuation.getBytes());
|
mOut.write(continuation.getBytes());
|
||||||
mOut.write('\r');
|
mOut.write('\r');
|
||||||
@ -2683,7 +2814,7 @@ public class ImapStore extends Store
|
|||||||
return executeSimpleCommand(command, sensitive, null);
|
return executeSimpleCommand(command, sensitive, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ImapResponse> executeSimpleCommand(String command, boolean sensitive, UntaggedHandler untaggedHandler)
|
public List<ImapResponse> executeSimpleCommand(String command, boolean sensitive, UntaggedHandler untaggedHandler)
|
||||||
throws IOException, ImapException, MessagingException
|
throws IOException, ImapException, MessagingException
|
||||||
{
|
{
|
||||||
String commandToLog = command;
|
String commandToLog = command;
|
||||||
|
38
src/com/fsck/k9/mail/transport/imap/ImapSettings.java
Normal file
38
src/com/fsck/k9/mail/transport/imap/ImapSettings.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package com.fsck.k9.mail.transport.imap;
|
||||||
|
|
||||||
|
import com.fsck.k9.mail.store.ImapStore;
|
||||||
|
import com.fsck.k9.mail.store.ImapStore.AuthType;
|
||||||
|
import com.fsck.k9.mail.store.ImapStore.ImapConnection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Settings source for IMAP. Implemented in order to remove coupling between {@link ImapStore} and {@link ImapConnection}.
|
||||||
|
*/
|
||||||
|
public interface ImapSettings
|
||||||
|
{
|
||||||
|
String getHost();
|
||||||
|
|
||||||
|
int getPort();
|
||||||
|
|
||||||
|
int getConnectionSecurity();
|
||||||
|
|
||||||
|
AuthType getAuthType();
|
||||||
|
|
||||||
|
String getUsername();
|
||||||
|
|
||||||
|
String getPassword();
|
||||||
|
|
||||||
|
boolean useCompression(int type);
|
||||||
|
|
||||||
|
String getPathPrefix();
|
||||||
|
|
||||||
|
void setPathPrefix(String prefix);
|
||||||
|
|
||||||
|
String getPathDelimeter();
|
||||||
|
|
||||||
|
void setPathDelimeter(String delimeter);
|
||||||
|
|
||||||
|
String getCombinedPrefix();
|
||||||
|
|
||||||
|
void setCombinedPrefix(String prefix);
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user