summaryrefslogtreecommitdiffstats
path: root/src/com/android/email/mail/transport
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/email/mail/transport')
-rw-r--r--src/com/android/email/mail/transport/DiscourseLogger.java119
-rw-r--r--src/com/android/email/mail/transport/MailTransport.java320
2 files changed, 0 insertions, 439 deletions
diff --git a/src/com/android/email/mail/transport/DiscourseLogger.java b/src/com/android/email/mail/transport/DiscourseLogger.java
deleted file mode 100644
index 67f4e115b..000000000
--- a/src/com/android/email/mail/transport/DiscourseLogger.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.email.mail.transport;
-
-import com.android.emailcommon.Logging;
-import com.android.mail.utils.LogUtils;
-
-import java.util.ArrayList;
-
-/**
- * A class to keep last N of lines sent to the server and responses received from the server.
- * They are sent to logcat when {@link #logLastDiscourse} is called.
- *
- * <p>This class is used to log the recent network activities when a response parser crashes.
- */
-public class DiscourseLogger {
- private final int mBufferSize;
- private String[] mBuffer;
- private int mPos;
- private final StringBuilder mReceivingLine = new StringBuilder(100);
-
- public DiscourseLogger(int bufferSize) {
- mBufferSize = bufferSize;
- initBuffer();
- }
-
- private void initBuffer() {
- mBuffer = new String[mBufferSize];
- }
-
- /** Add a single line to {@link #mBuffer}. */
- private void addLine(String s) {
- mBuffer[mPos] = s;
- mPos++;
- if (mPos >= mBufferSize) {
- mPos = 0;
- }
- }
-
- private void addReceivingLineToBuffer() {
- if (mReceivingLine.length() > 0) {
- addLine(mReceivingLine.toString());
- mReceivingLine.delete(0, Integer.MAX_VALUE);
- }
- }
-
- /**
- * Store a single byte received from the server in {@link #mReceivingLine}. When LF is
- * received, the content of {@link #mReceivingLine} is added to {@link #mBuffer}.
- */
- public void addReceivedByte(int b) {
- if (0x20 <= b && b <= 0x7e) { // Append only printable ASCII chars.
- mReceivingLine.append((char) b);
- } else if (b == '\n') { // LF
- addReceivingLineToBuffer();
- } else if (b == '\r') { // CR
- } else {
- final String hex = "00" + Integer.toHexString(b);
- mReceivingLine.append("\\x" + hex.substring(hex.length() - 2, hex.length()));
- }
- }
-
- /** Add a line sent to the server to {@link #mBuffer}. */
- public void addSentCommand(String command) {
- addLine(command);
- }
-
- /** @return the contents of {@link #mBuffer} as a String array. */
- /* package for testing */ String[] getLines() {
- addReceivingLineToBuffer();
-
- ArrayList<String> list = new ArrayList<String>();
-
- final int start = mPos;
- int pos = mPos;
- do {
- String s = mBuffer[pos];
- if (s != null) {
- list.add(s);
- }
- pos = (pos + 1) % mBufferSize;
- } while (pos != start);
-
- String[] ret = new String[list.size()];
- list.toArray(ret);
- return ret;
- }
-
- /**
- * Log the contents of the {@link mBuffer}, and clears it out. (So it's okay to call this
- * method successively more than once. There will be no duplicate log.)
- */
- public void logLastDiscourse() {
- String[] lines = getLines();
- if (lines.length == 0) {
- return;
- }
-
- LogUtils.w(Logging.LOG_TAG, "Last network activities:");
- for (String r : getLines()) {
- LogUtils.w(Logging.LOG_TAG, "%s", r);
- }
- initBuffer();
- }
-}
diff --git a/src/com/android/email/mail/transport/MailTransport.java b/src/com/android/email/mail/transport/MailTransport.java
deleted file mode 100644
index 213fbfc99..000000000
--- a/src/com/android/email/mail/transport/MailTransport.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.email.mail.transport;
-
-import android.content.Context;
-
-import com.android.email.DebugUtils;
-import com.android.emailcommon.Logging;
-import com.android.emailcommon.mail.CertificateValidationException;
-import com.android.emailcommon.mail.MessagingException;
-import com.android.emailcommon.provider.HostAuth;
-import com.android.emailcommon.utility.SSLUtils;
-import com.android.mail.utils.LogUtils;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.net.Socket;
-import java.net.SocketAddress;
-import java.net.SocketException;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLPeerUnverifiedException;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLSocket;
-
-public class MailTransport {
-
- // TODO protected eventually
- /*protected*/ public static final int SOCKET_CONNECT_TIMEOUT = 10000;
- /*protected*/ public static final int SOCKET_READ_TIMEOUT = 60000;
-
- private static final HostnameVerifier HOSTNAME_VERIFIER =
- HttpsURLConnection.getDefaultHostnameVerifier();
-
- private final String mDebugLabel;
- private final Context mContext;
- protected final HostAuth mHostAuth;
-
- private Socket mSocket;
- private InputStream mIn;
- private OutputStream mOut;
-
- public MailTransport(Context context, String debugLabel, HostAuth hostAuth) {
- super();
- mContext = context;
- mDebugLabel = debugLabel;
- mHostAuth = hostAuth;
- }
-
- /**
- * Returns a new transport, using the current transport as a model. The new transport is
- * configured identically (as if {@link #setSecurity(int, boolean)}, {@link #setPort(int)}
- * and {@link #setHost(String)} were invoked), but not opened or connected in any way.
- */
- @Override
- public MailTransport clone() {
- return new MailTransport(mContext, mDebugLabel, mHostAuth);
- }
-
- public String getHost() {
- return mHostAuth.mAddress;
- }
-
- public int getPort() {
- return mHostAuth.mPort;
- }
-
- public boolean canTrySslSecurity() {
- return (mHostAuth.mFlags & HostAuth.FLAG_SSL) != 0;
- }
-
- public boolean canTryTlsSecurity() {
- return (mHostAuth.mFlags & HostAuth.FLAG_TLS) != 0;
- }
-
- public boolean canTrustAllCertificates() {
- return (mHostAuth.mFlags & HostAuth.FLAG_TRUST_ALL) != 0;
- }
-
- /**
- * Attempts to open a connection using the Uri supplied for connection parameters. Will attempt
- * an SSL connection if indicated.
- */
- public void open() throws MessagingException, CertificateValidationException {
- if (DebugUtils.DEBUG) {
- LogUtils.d(Logging.LOG_TAG, "*** " + mDebugLabel + " open " +
- getHost() + ":" + String.valueOf(getPort()));
- }
-
- try {
- SocketAddress socketAddress = new InetSocketAddress(getHost(), getPort());
- if (canTrySslSecurity()) {
- mSocket = SSLUtils.getSSLSocketFactory(
- mContext, mHostAuth, canTrustAllCertificates()).createSocket();
- } else {
- mSocket = new Socket();
- }
- mSocket.connect(socketAddress, SOCKET_CONNECT_TIMEOUT);
- // After the socket connects to an SSL server, confirm that the hostname is as expected
- if (canTrySslSecurity() && !canTrustAllCertificates()) {
- verifyHostname(mSocket, getHost());
- }
- mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);
- mOut = new BufferedOutputStream(mSocket.getOutputStream(), 512);
- mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
- } catch (SSLException e) {
- if (DebugUtils.DEBUG) {
- LogUtils.d(Logging.LOG_TAG, e.toString());
- }
- throw new CertificateValidationException(e.getMessage(), e);
- } catch (IOException ioe) {
- if (DebugUtils.DEBUG) {
- LogUtils.d(Logging.LOG_TAG, ioe.toString());
- }
- throw new MessagingException(MessagingException.IOERROR, ioe.toString());
- } catch (IllegalArgumentException iae) {
- if (DebugUtils.DEBUG) {
- LogUtils.d(Logging.LOG_TAG, iae.toString());
- }
- throw new MessagingException(MessagingException.UNSPECIFIED_EXCEPTION, iae.toString());
- }
- }
-
- /**
- * Attempts to reopen a TLS connection using the Uri supplied for connection parameters.
- *
- * NOTE: No explicit hostname verification is required here, because it's handled automatically
- * by the call to createSocket().
- *
- * TODO should we explicitly close the old socket? This seems funky to abandon it.
- */
- public void reopenTls() throws MessagingException {
- try {
- mSocket = SSLUtils.getSSLSocketFactory(mContext, mHostAuth, canTrustAllCertificates())
- .createSocket(mSocket, getHost(), getPort(), true);
- mSocket.setSoTimeout(SOCKET_READ_TIMEOUT);
- mIn = new BufferedInputStream(mSocket.getInputStream(), 1024);
- mOut = new BufferedOutputStream(mSocket.getOutputStream(), 512);
-
- } catch (SSLException e) {
- if (DebugUtils.DEBUG) {
- LogUtils.d(Logging.LOG_TAG, e.toString());
- }
- throw new CertificateValidationException(e.getMessage(), e);
- } catch (IOException ioe) {
- if (DebugUtils.DEBUG) {
- LogUtils.d(Logging.LOG_TAG, ioe.toString());
- }
- throw new MessagingException(MessagingException.IOERROR, ioe.toString());
- }
- }
-
- /**
- * Lightweight version of SSLCertificateSocketFactory.verifyHostname, which provides this
- * service but is not in the public API.
- *
- * Verify the hostname of the certificate used by the other end of a
- * connected socket. You MUST call this if you did not supply a hostname
- * to SSLCertificateSocketFactory.createSocket(). It is harmless to call this method
- * redundantly if the hostname has already been verified.
- *
- * <p>Wildcard certificates are allowed to verify any matching hostname,
- * so "foo.bar.example.com" is verified if the peer has a certificate
- * for "*.example.com".
- *
- * @param socket An SSL socket which has been connected to a server
- * @param hostname The expected hostname of the remote server
- * @throws IOException if something goes wrong handshaking with the server
- * @throws SSLPeerUnverifiedException if the server cannot prove its identity
- */
- private static void verifyHostname(Socket socket, String hostname) throws IOException {
- // The code at the start of OpenSSLSocketImpl.startHandshake()
- // ensures that the call is idempotent, so we can safely call it.
- SSLSocket ssl = (SSLSocket) socket;
- ssl.startHandshake();
-
- SSLSession session = ssl.getSession();
- if (session == null) {
- throw new SSLException("Cannot verify SSL socket without session");
- }
- // TODO: Instead of reporting the name of the server we think we're connecting to,
- // we should be reporting the bad name in the certificate. Unfortunately this is buried
- // in the verifier code and is not available in the verifier API, and extracting the
- // CN & alts is beyond the scope of this patch.
- if (!HOSTNAME_VERIFIER.verify(hostname, session)) {
- throw new SSLPeerUnverifiedException(
- "Certificate hostname not useable for server: " + hostname);
- }
- }
-
- /**
- * Get the socket timeout.
- * @return the read timeout value in milliseconds
- * @throws SocketException
- */
- public int getSoTimeout() throws SocketException {
- return mSocket.getSoTimeout();
- }
-
- /**
- * Set the socket timeout.
- * @param timeoutMilliseconds the read timeout value if greater than {@code 0}, or
- * {@code 0} for an infinite timeout.
- */
- public void setSoTimeout(int timeoutMilliseconds) throws SocketException {
- mSocket.setSoTimeout(timeoutMilliseconds);
- }
-
- public boolean isOpen() {
- return (mIn != null && mOut != null &&
- mSocket != null && mSocket.isConnected() && !mSocket.isClosed());
- }
-
- /**
- * Close the connection. MUST NOT return any exceptions - must be "best effort" and safe.
- */
- public void close() {
- try {
- mIn.close();
- } catch (Exception e) {
- // May fail if the connection is already closed.
- }
- try {
- mOut.close();
- } catch (Exception e) {
- // May fail if the connection is already closed.
- }
- try {
- mSocket.close();
- } catch (Exception e) {
- // May fail if the connection is already closed.
- }
- mIn = null;
- mOut = null;
- mSocket = null;
- }
-
- public InputStream getInputStream() {
- return mIn;
- }
-
- public OutputStream getOutputStream() {
- return mOut;
- }
-
- /**
- * Writes a single line to the server using \r\n termination.
- */
- public void writeLine(String s, String sensitiveReplacement) throws IOException {
- if (DebugUtils.DEBUG) {
- if (sensitiveReplacement != null && !Logging.DEBUG_SENSITIVE) {
- LogUtils.d(Logging.LOG_TAG, ">>> " + sensitiveReplacement);
- } else {
- LogUtils.d(Logging.LOG_TAG, ">>> " + s);
- }
- }
-
- OutputStream out = getOutputStream();
- out.write(s.getBytes());
- out.write('\r');
- out.write('\n');
- out.flush();
- }
-
- /**
- * Reads a single line from the server, using either \r\n or \n as the delimiter. The
- * delimiter char(s) are not included in the result.
- */
- public String readLine(boolean loggable) throws IOException {
- StringBuffer sb = new StringBuffer();
- InputStream in = getInputStream();
- int d;
- while ((d = in.read()) != -1) {
- if (((char)d) == '\r') {
- continue;
- } else if (((char)d) == '\n') {
- break;
- } else {
- sb.append((char)d);
- }
- }
- if (d == -1 && DebugUtils.DEBUG) {
- LogUtils.d(Logging.LOG_TAG, "End of stream reached while trying to read line.");
- }
- String ret = sb.toString();
- if (loggable && DebugUtils.DEBUG) {
- LogUtils.d(Logging.LOG_TAG, "<<< " + ret);
- }
- return ret;
- }
-
- public InetAddress getLocalAddress() {
- if (isOpen()) {
- return mSocket.getLocalAddress();
- } else {
- return null;
- }
- }
-}