/**
   * Authenticate to the IMAP server by sending the AUTHENTICATE command with the selected
   * mechanism, using the given username and the given password.
   *
   * <p>
   *
   * @return True if successfully completed, false if not.
   * @exception IOException If an I/O error occurs while either sending a command to the server or
   *     receiving a reply from the server.
   * @exception NoSuchAlgorithmException If the CRAM hash algorithm cannot be instantiated by the
   *     Java runtime system.
   * @exception InvalidKeyException If the CRAM hash algorithm failed to use the given password.
   * @exception InvalidKeySpecException If the CRAM hash algorithm failed to use the given password.
   */
  public boolean auth(AuthenticatingIMAPClient.AUTH_METHOD method, String username, String password)
      throws IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException {
    if (!IMAPReply.isContinuation(sendCommand(IMAPCommand.AUTHENTICATE, method.getAuthName()))) {
      return false;
    }

    switch (method) {
      case PLAIN:
        {
          // the server sends an empty response ("+ "), so we don't have to read it.
          int result =
              sendData(
                  new String(
                      Base64.encodeBase64(("\000" + username + "\000" + password).getBytes())));
          if (result == IMAPReply.OK) {
            setState(IMAP.IMAPState.AUTH_STATE);
          }
          return result == IMAPReply.OK;
        }
      case CRAM_MD5:
        {
          // get the CRAM challenge (after "+ ")
          byte[] serverChallenge = Base64.decodeBase64(getReplyString().substring(2).trim());
          // get the Mac instance
          Mac hmac_md5 = Mac.getInstance("HmacMD5");
          hmac_md5.init(new SecretKeySpec(password.getBytes(), "HmacMD5"));
          // compute the result:
          byte[] hmacResult = _convertToHexString(hmac_md5.doFinal(serverChallenge)).getBytes();
          // join the byte arrays to form the reply
          byte[] usernameBytes = username.getBytes();
          byte[] toEncode = new byte[usernameBytes.length + 1 /* the space */ + hmacResult.length];
          System.arraycopy(usernameBytes, 0, toEncode, 0, usernameBytes.length);
          toEncode[usernameBytes.length] = ' ';
          System.arraycopy(hmacResult, 0, toEncode, usernameBytes.length + 1, hmacResult.length);
          // send the reply and read the server code:
          int result = sendData(new String(Base64.encodeBase64(toEncode)));
          if (result == IMAPReply.OK) {
            setState(IMAP.IMAPState.AUTH_STATE);
          }
          return result == IMAPReply.OK;
        }
      case LOGIN:
        {
          // the server sends fixed responses (base64("Username") and
          // base64("Password")), so we don't have to read them.
          if (sendData(new String(Base64.encodeBase64(username.getBytes()))) != IMAPReply.CONT) {
            return false;
          }
          int result = sendData(new String(Base64.encodeBase64(password.getBytes())));
          if (result == IMAPReply.OK) {
            setState(IMAP.IMAPState.AUTH_STATE);
          }
          return result == IMAPReply.OK;
        }
    }
    return false; // safety check
  }
Esempio n. 2
0
 /**
  * Encode a password as a base64-encoded char[] array.
  *
  * @param password as a byte array.
  * @return password as a char array.
  */
 static char[] encodePassword(byte[] password) {
   return new String(Base64.encodeBase64(password)).toCharArray();
 }
Esempio n. 3
0
 /**
  * Encode a byte[] identifier as a Base64-encoded string.
  *
  * @param identifier identifier to encode
  * @return Base64-encoded string
  */
 static String encodeIdentifier(byte[] identifier) {
   return new String(Base64.encodeBase64(identifier));
 }
Esempio n. 4
0
 /**
  * Encode a byte[] identifier as a Base64-encoded string.
  *
  * @param identifier identifier to encode
  * @return Base64-encoded string
  */
 static String encodeIdentifier(byte[] identifier) {
   return new String(Base64.encodeBase64(identifier), Charset.defaultCharset());
 }