Improve login method : detect custom login form and destination url

git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@132 3d1905a2-6b24-0410-a738-b14d5a86fcbd
This commit is contained in:
mguessan 2008-08-24 16:01:03 +00:00
parent 038637443b
commit 6084afffb5
2 changed files with 83 additions and 41 deletions

View File

@ -201,42 +201,69 @@ public class ExchangeSession {
HttpMethod initmethod = new GetMethod(url); HttpMethod initmethod = new GetMethod(url);
wdr.executeHttpRequestMethod(httpClient, wdr.executeHttpRequestMethod(httpClient,
initmethod); initmethod);
// default destination is provided url
String destination = url;
if (!isBasicAuthentication) { if (!isBasicAuthentication) {
LOGGER.debug("Form based authentication detected"); LOGGER.debug("Form based authentication detected");
if (initmethod.getPath().indexOf("exchweb/bin") == -1) { // default logon method path
LOGGER.error("DavMail configuration exception: authentication form not found at " + url + String logonMethodPath = "/exchweb/bin/auth/owaauth.dll";
" and basic authentication not requested");
throw new IOException("DavMail configuration exception: authentication form not found at " + url + // try to parse login form to determine logon url and destination
" and basic authentication not requested"); BufferedReader loginFormReader = null;
} else { try {
PostMethod logonMethod = new PostMethod( loginFormReader = new BufferedReader(new InputStreamReader(initmethod.getResponseBodyAsStream()));
"/exchweb/bin/auth/owaauth.dll?" + String line;
"ForcedBasic=false&Basic=false&Private=true" + // skip to form action
"&Language=No_Value" final String FORM_ACTION = "<FORM action=\"";
); final String DESTINATION_INPUT = "name=\"destination\" value=\"";
logonMethod.addParameter("destination", url); //noinspection StatementWithEmptyBody
logonMethod.addParameter("flags", "4"); while ((line = loginFormReader.readLine()) != null && line.indexOf(FORM_ACTION) == -1) ;
if (line != null) {
int start = line.indexOf(FORM_ACTION) + FORM_ACTION.length();
int end = line.indexOf("\"", start);
logonMethodPath = line.substring(start, end);
//noinspection StatementWithEmptyBody
while ((line = loginFormReader.readLine()) != null && line.indexOf(DESTINATION_INPUT) == -1) ;
if (line != null) {
start = line.indexOf(DESTINATION_INPUT) + DESTINATION_INPUT.length();
end = line.indexOf("\"", start);
destination = line.substring(start, end);
}
}
} catch (IOException e) {
LOGGER.error("Error parsing login form at " + initmethod.getPath());
} finally {
if (loginFormReader != null) {
loginFormReader.close();
}
}
PostMethod logonMethod = new PostMethod(
logonMethodPath + "?ForcedBasic=false&Basic=false&Private=true&Language=No_Value"
);
logonMethod.addParameter("destination", destination);
logonMethod.addParameter("flags", "4");
// logonMethod.addParameter("visusername", userName.substring(userName.lastIndexOf('\\'))); // logonMethod.addParameter("visusername", userName.substring(userName.lastIndexOf('\\')));
logonMethod.addParameter("username", userName); logonMethod.addParameter("username", userName);
logonMethod.addParameter("password", password); logonMethod.addParameter("password", password);
// logonMethod.addParameter("SubmitCreds", "Log On"); // logonMethod.addParameter("SubmitCreds", "Log On");
// logonMethod.addParameter("forcedownlevel", "0"); // logonMethod.addParameter("forcedownlevel", "0");
logonMethod.addParameter("trusted", "4"); logonMethod.addParameter("trusted", "4");
wdr.executeHttpRequestMethod(httpClient, logonMethod); httpClient.executeMethod(logonMethod);
Header locationHeader = logonMethod.getResponseHeader("Location"); Header locationHeader = logonMethod.getResponseHeader("Location");
if (logonMethod.getStatusCode() != HttpURLConnection.HTTP_MOVED_TEMP ||
locationHeader == null ||
!url.equals(locationHeader.getValue())) {
throw new HttpException("Authentication failed");
}
if (logonMethod.getStatusCode() != HttpURLConnection.HTTP_MOVED_TEMP ||
locationHeader == null ||
!destination.equals(locationHeader.getValue())) {
throw new HttpException("Authentication failed");
} }
} }
// User may be authenticated, get various session information // User may be authenticated, get various session information
HttpMethod method = new GetMethod(url); HttpMethod method = new GetMethod(destination);
int status = wdr.executeHttpRequestMethod(httpClient, method); int status = wdr.executeHttpRequestMethod(httpClient, method);
if (status != HttpStatus.SC_OK) { if (status != HttpStatus.SC_OK) {
HttpException ex = new HttpException(); HttpException ex = new HttpException();
@ -244,26 +271,41 @@ public class ExchangeSession {
ex.setReason(method.getStatusText()); ex.setReason(method.getStatusText());
throw ex; throw ex;
} }
// test form based authentication
String queryString = method.getQueryString();
if (queryString != null && queryString.endsWith("reason=2")) {
throw new HttpException("Authentication failed: invalid user or password");
}
// get user mail URL from html body (multi frame) // get user mail URL from html body (multi frame)
String mailboxName = method.getResponseBodyAsString(); BufferedReader mainPageReader = null;
int beginIndex = mailboxName.indexOf(url); try {
if (beginIndex < 0) { mainPageReader = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream()));
throw new HttpException(url + " not found in body"); String line;
// find base url
final String BASE_HREF = "<base href=\"";
//noinspection StatementWithEmptyBody
while ((line = mainPageReader.readLine()) != null && line.toLowerCase().indexOf(BASE_HREF) == -1) ;
if (line != null) {
int start = line.toLowerCase().indexOf(BASE_HREF) + BASE_HREF.length();
int end = line.indexOf("\"", start);
String mailBoxBaseHref = line.substring(start, end);
URL baseURL = new URL(mailBoxBaseHref);
mailPath = baseURL.getPath();
}
} catch (IOException e) {
LOGGER.error("Error parsing main page at " + method.getPath());
} finally {
if (mainPageReader != null) {
mainPageReader.close();
}
} }
mailboxName = mailboxName.substring(beginIndex);
int endIndex = mailboxName.indexOf('"');
if (endIndex < 0) {
throw new HttpException(url + " not found in body");
}
mailboxName = mailboxName.substring(url.length(), endIndex);
// if body is empty : wrong password, not authenticated if (mailPath == null) {
if (mailboxName.length() == 0) { throw new HttpException(destination + " not found in body, authentication failed");
throw new HttpException("Authentication failed");
} }
// got base http mailbox http url // got base http mailbox http url
mailPath = "/exchange/" + mailboxName;
wdr.setPath(mailPath); wdr.setPath(mailPath);
// Retrieve inbox and trash URLs // Retrieve inbox and trash URLs

View File

@ -118,11 +118,11 @@ public class PopConnection extends AbstractConnection {
} catch (Exception e) { } catch (Exception e) {
String message = e.getMessage(); String message = e.getMessage();
if (message == null) { if (message == null) {
message = e.toString(); message = "Authentication failed: "+e.toString();
} }
DavGatewayTray.error(message); DavGatewayTray.error(message);
message = message.replaceAll("\\n", " "); message = message.replaceAll("\\n", " ");
sendERR("authentication failed : " + message); sendERR(message);
} }
} }
} else if ("CAPA".equalsIgnoreCase(command)) { } else if ("CAPA".equalsIgnoreCase(command)) {