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:
parent
038637443b
commit
6084afffb5
|
@ -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
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
Loading…
Reference in New Issue