Example #1
0
  boolean idle(final ImapRequest req, final boolean begin) throws IOException {
    if (begin == ImapHandler.IDLE_STOP) {
      // check state -- don't want to send DONE if we're somehow not in IDLE
      ImapHandler handler = mHandler;
      if (handler == null) throw new IOException("proxy connection already closed");
      Thread idle = mIdleThread;
      if (idle == null)
        throw new IOException("bad proxy state: no IDLE thread active when attempting DONE");
      // send the DONE, which elicits the tagged response that causes the IDLE thread (below) to
      // exit
      writeRequest(req.toByteArray());
      // make sure that the idle thread actually exits; otherwise we're in a bad place and we must
      // kill the whole session
      mIdleThread = null;
      try {
        idle.join(5 * Constants.MILLIS_PER_SECOND);
      } catch (InterruptedException ie) {
      }
      if (idle.isAlive()) handler.dropConnection(false);
    } else {
      final ImapHandler handler = mHandler;
      final ImapConnection conn = mConnection;
      if (conn == null) throw new IOException("proxy connection already closed");

      ImapConfig config = conn.getImapConfig();
      final int oldTimeout =
          config != null ? config.getReadTimeout() : LC.javamail_imap_timeout.intValue();
      // necessary because of subsequent race condition with req.cleanup()
      final byte[] payload = req.toByteArray();

      mIdleThread =
          new Thread() {
            @Override
            public void run() {
              boolean success = false;
              try {
                // the standard aggressive read timeout is inappropriate for IDLE
                conn.setReadTimeout(mHandler.getConfig().getAuthenticatedMaxIdleSeconds());
                // send the IDLE command; this call waits until the subsequent DONE is acknowledged
                boolean ok = proxyCommand(req.getTag(), payload, true, true);
                // restore the old read timeout
                conn.setReadTimeout(oldTimeout);
                // don't set <code>success</code> until we're past things that can throw
                // IOExceptions
                success = ok;
              } catch (IOException e) {
                ZimbraLog.imap.warn("error encountered during IDLE; dropping connection", e);
              }
              if (!success) handler.dropConnection();
            }
          };
      mIdleThread.setName("Imap-Idle-Proxy-" + Thread.currentThread().getName());
      mIdleThread.start();
    }
    return true;
  }
Example #2
0
  ImapProxy(final ImapHandler handler, final ImapPath path) throws ServiceException {
    mHandler = handler;
    mPath = path;

    Account acct = handler.getCredentials().getAccount();
    Server server = Provisioning.getInstance().getServer(path.getOwnerAccount());
    String host = server.getServiceHostname();
    if (acct == null)
      throw ServiceException.PROXY_ERROR(
          new Exception("no such authenticated user"), path.asImapPath());

    ImapConfig config = new ImapConfig();
    config.setAuthenticationId(acct.getName());
    config.setMechanism(ZimbraAuthenticator.MECHANISM);
    config.setAuthenticatorFactory(sAuthenticatorFactory);
    config.setReadTimeout(LC.javamail_imap_timeout.intValue());
    config.setConnectTimeout(config.getReadTimeout());
    config.setHost(host);
    if (server.isImapServerEnabled()) {
      config.setPort(server.getIntAttr(Provisioning.A_zimbraImapBindPort, ImapConfig.DEFAULT_PORT));
    } else if (server.isImapSSLServerEnabled()) {
      config.setPort(
          server.getIntAttr(Provisioning.A_zimbraImapSSLBindPort, ImapConfig.DEFAULT_SSL_PORT));
      config.setSecurity(MailConfig.Security.SSL);
    } else {
      throw ServiceException.PROXY_ERROR(
          new Exception("no open IMAP port for server " + host), path.asImapPath());
    }

    ZimbraLog.imap.info(
        "opening proxy connection (user="******", host="
            + host
            + ", path="
            + path.getReferent().asImapPath()
            + ')');

    ImapConnection conn = mConnection = new ImapConnection(config);
    try {
      conn.connect();
      conn.authenticate(AuthProvider.getAuthToken(acct).getEncoded());
    } catch (Exception e) {
      dropConnection();
      throw ServiceException.PROXY_ERROR(e, null);
    }
  }