예제 #1
0
  /**
   * Builds a URI scheme name given the parameters for a {@code HostAuth}. If a {@code clientAlias}
   * is provided, this indicates that a secure connection must be used.
   */
  public static String getSchemeString(String protocol, int flags, String clientAlias) {
    String security = "";
    switch (flags & USER_CONFIG_MASK) {
      case FLAG_SSL:
        security = "+ssl+";
        break;
      case FLAG_SSL | FLAG_TRUST_ALL:
        security = "+ssl+trustallcerts";
        break;
      case FLAG_TLS:
        security = "+tls+";
        break;
      case FLAG_TLS | FLAG_TRUST_ALL:
        security = "+tls+trustallcerts";
        break;
    }

    if (!TextUtils.isEmpty(clientAlias)) {
      if (TextUtils.isEmpty(security)) {
        throw new IllegalArgumentException(
            "Can't specify a certificate alias for a non-secure connection");
      }
      if (!security.endsWith("+")) {
        security += "+";
      }
      security += SSLUtils.escapeForSchemeName(clientAlias);
    }

    return protocol + security;
  }
  /**
   * 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 (MailActivityEmail.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 (MailActivityEmail.DEBUG) {
        LogUtils.d(Logging.LOG_TAG, e.toString());
      }
      throw new CertificateValidationException(e.getMessage(), e);
    } catch (IOException ioe) {
      if (MailActivityEmail.DEBUG) {
        LogUtils.d(Logging.LOG_TAG, ioe.toString());
      }
      throw new MessagingException(MessagingException.IOERROR, ioe.toString());
    } catch (IllegalArgumentException iae) {
      if (MailActivityEmail.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.
   *
   * <p>NOTE: No explicit hostname verification is required here, because it's handled automatically
   * by the call to createSocket().
   *
   * <p>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 (MailActivityEmail.DEBUG) {
        LogUtils.d(Logging.LOG_TAG, e.toString());
      }
      throw new CertificateValidationException(e.getMessage(), e);
    } catch (IOException ioe) {
      if (MailActivityEmail.DEBUG) {
        LogUtils.d(Logging.LOG_TAG, ioe.toString());
      }
      throw new MessagingException(MessagingException.IOERROR, ioe.toString());
    }
  }