Skip to content

Commit

Permalink
JAMES-1930 Refactor Auth plain parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
chibenwa authored and aduprat committed Feb 14, 2017
1 parent 200460c commit 0175e31
Showing 1 changed file with 54 additions and 13 deletions.
Expand Up @@ -37,6 +37,8 @@
import org.apache.james.imap.message.response.AuthenticateResponse;
import org.apache.james.mailbox.MailboxManager;

import com.google.common.base.Optional;

/**
* Processor which handles the AUTHENTICATE command. Only authtype of PLAIN is supported ATM.
*
Expand Down Expand Up @@ -101,16 +103,21 @@ public void onLine(ImapSession session, byte[] data) {
* @param responder
*/
protected void doPlainAuth(String initialClientResponse, ImapSession session, String tag, ImapCommand command, Responder responder) {
String pass = null;
String user = null;
AuthPlainAttempt authPlainAttempt = parseDelegationAttempt(initialClientResponse);
// Authenticate user
doAuth(authPlainAttempt.getAuthenticationId(), authPlainAttempt.getPassword(), session, tag, command, responder, HumanReadableText.AUTHENTICATION_FAILED);
}

private AuthPlainAttempt parseDelegationAttempt(String initialClientResponse) {
String token2;
try {

String userpass = new String(Base64.decodeBase64(initialClientResponse));
StringTokenizer authTokenizer = new StringTokenizer(userpass, "\0");
String authorize_id = authTokenizer.nextToken(); // Authorization Identity
user = authTokenizer.nextToken(); // Authentication Identity
String token1 = authTokenizer.nextToken(); // Authorization Identity
token2 = authTokenizer.nextToken(); // Authentication Identity
try {
pass = authTokenizer.nextToken(); // Password
return delegation(token1, token2, authTokenizer.nextToken());
} catch (java.util.NoSuchElementException _) {
// If we got here, this is what happened. RFC 2595
// says that "the client may leave the authorization
Expand All @@ -127,19 +134,17 @@ protected void doPlainAuth(String initialClientResponse, ImapSession session, St
// elements, leading to the exception we just
// caught. So we need to move the user to the
// password, and the authorize_id to the user.
pass = user;
user = authorize_id;
}

authTokenizer = null;
return noDelegation(token1, token2);
} finally {
authTokenizer = null;
}
} catch (Exception e) {
// Ignored - this exception in parsing will be dealt
// with in the if clause below
return noDelegation(null, null);
}
// Authenticate user
doAuth(user, pass, session, tag, command, responder, HumanReadableText.AUTHENTICATION_FAILED);
}

/**
* @see org.apache.james.imap.processor.CapabilityImplementingProcessor
* #getImplementedCapabilities(org.apache.james.imap.api.process.ImapSession)
Expand All @@ -156,4 +161,40 @@ public List<String> getImplementedCapabilities(ImapSession session) {
return Collections.unmodifiableList(caps);
}

private static AuthPlainAttempt delegation(String authorizeId, String authenticationId, String password) {
return new AuthPlainAttempt(Optional.of(authorizeId), authenticationId, password);
}

private static AuthPlainAttempt noDelegation(String authenticationId, String password) {
return new AuthPlainAttempt(Optional.<String>absent(), authenticationId, password);
}

private static class AuthPlainAttempt {
private final Optional<String> authorizeId;
private final String authenticationId;
private final String password;

private AuthPlainAttempt(Optional<String> authorizeId, String authenticationId, String password) {
this.authorizeId = authorizeId;
this.authenticationId = authenticationId;
this.password = password;
}

public boolean isDelegation() {
return authorizeId.isPresent();
}

public Optional<String> getAuthorizeId() {
return authorizeId;
}

public String getAuthenticationId() {
return authenticationId;
}

public String getPassword() {
return password;
}
}

}

0 comments on commit 0175e31

Please sign in to comment.