From d4942165b4fa12c73b10b688b3db780ca902cc53 Mon Sep 17 00:00:00 2001 From: mguessan Date: Mon, 28 Feb 2011 22:31:42 +0000 Subject: [PATCH] Implement Microsoft Forefront Unified Access Gateway logon form compatibility git-svn-id: http://svn.code.sf.net/p/davmail/code/trunk@1633 3d1905a2-6b24-0410-a738-b14d5a86fcbd --- .../davmail/exchange/ExchangeSession.java | 39 ++++++++++++------- .../exchange/ews/EwsExchangeSession.java | 37 +++++++++++------- 2 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/java/davmail/exchange/ExchangeSession.java b/src/java/davmail/exchange/ExchangeSession.java index 2e6d5151..67bd8c13 100644 --- a/src/java/davmail/exchange/ExchangeSession.java +++ b/src/java/davmail/exchange/ExchangeSession.java @@ -34,6 +34,7 @@ import org.apache.commons.httpclient.params.HttpClientParams; import org.apache.commons.httpclient.util.URIUtil; import org.apache.log4j.Logger; import org.htmlcleaner.CommentToken; +import org.htmlcleaner.ContentToken; import org.htmlcleaner.HtmlCleaner; import org.htmlcleaner.TagNode; @@ -69,6 +70,7 @@ public abstract class ExchangeSession { USER_NAME_FIELDS.add("txtUserName"); USER_NAME_FIELDS.add("userid"); USER_NAME_FIELDS.add("SafeWordUser"); + USER_NAME_FIELDS.add("user_name"); } protected static final Set PASSWORD_FIELDS = new HashSet(); @@ -190,8 +192,8 @@ public abstract class ExchangeSession { } } - // avoid 401 roundtrips, only if NTLM is disabled - if (!DavGatewayHttpClientFacade.hasNTLM(httpClient)) { + // avoid 401 roundtrips, only if NTLM is disabled and basic authentication enabled + if (isBasicAuthentication && !DavGatewayHttpClientFacade.hasNTLM(httpClient)) { httpClient.getParams().setParameter(HttpClientParams.PREEMPTIVE_AUTHENTICATION, true); } @@ -350,9 +352,9 @@ public abstract class ExchangeSession { * @return logon method * @throws IOException on error */ - protected PostMethod buildLogonMethod(HttpClient httpClient, HttpMethod initmethod) throws IOException { + protected HttpMethod buildLogonMethod(HttpClient httpClient, HttpMethod initmethod) throws IOException { - PostMethod logonMethod = null; + HttpMethod logonMethod = null; // create an instance of HtmlCleaner HtmlCleaner cleaner = new HtmlCleaner(); @@ -376,13 +378,15 @@ public abstract class ExchangeSession { logonMethod = new PostMethod(getAbsoluteUri(initmethod, logonMethodPath)); - List inputList = logonForm.getElementListByName("input", true); + // retrieve lost inputs attached to body + List inputList = node.getElementListByName("input", true); + for (Object input : inputList) { String type = ((TagNode) input).getAttributeByName("type"); String name = ((TagNode) input).getAttributeByName("name"); String value = ((TagNode) input).getAttributeByName("value"); if ("hidden".equalsIgnoreCase(type) && name != null && value != null) { - logonMethod.addParameter(name, value); + ((PostMethod) logonMethod).addParameter(name, value); } // custom login form if (USER_NAME_FIELDS.contains(name)) { @@ -395,7 +399,7 @@ public abstract class ExchangeSession { logonMethod = buildLogonMethod(httpClient, newInitMethod); } else if (TOKEN_FIELDS.contains(name)) { // one time password, ask user - logonMethod.addParameter(name, DavGatewayOTPPrompt.getOneTimePassword()); + ((PostMethod) logonMethod).addParameter(name, DavGatewayOTPPrompt.getOneTimePassword()); } } } else { @@ -427,6 +431,15 @@ public abstract class ExchangeSession { HttpMethod newInitMethod = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, src); logonMethod = buildLogonMethod(httpClient, newInitMethod); } + + } else if (content instanceof ContentToken) { + // Microsoft Forefront Unified Access Gateway redirect + String scriptValue = ((ContentToken) content).getContent(); + String location = StringUtil.getToken(scriptValue, "window.location.replace(\"", "\""); + if (location != null) { + LOGGER.debug("Post logon redirect to: " + location); + logonMethod = DavGatewayHttpClientFacade.executeFollowRedirects(httpClient, location); + } } } } @@ -2488,11 +2501,11 @@ public abstract class ExchangeSession { Condition condition; if (caldavDisableTasks) { condition = or(isEqualTo("instancetype", 1), - and(isEqualTo("instancetype", 0), dateCondition)); + and(isEqualTo("instancetype", 0), dateCondition)); } else { condition = or(isNull("instancetype"), - isEqualTo("instancetype", 1), - and(isEqualTo("instancetype", 0), dateCondition)); + isEqualTo("instancetype", 1), + and(isEqualTo("instancetype", 0), dateCondition)); } return searchEvents(folderPath, condition); @@ -2529,11 +2542,11 @@ public abstract class ExchangeSession { Condition condition; if (caldavDisableTasks) { condition = or(isEqualTo("instancetype", 1), - and(isEqualTo("instancetype", 0), dateCondition)); + and(isEqualTo("instancetype", 0), dateCondition)); } else { condition = or(isNull("instancetype"), - isEqualTo("instancetype", 1), - and(isEqualTo("instancetype", 0), dateCondition)); + isEqualTo("instancetype", 1), + and(isEqualTo("instancetype", 0), dateCondition)); } return searchEvents(folderPath, condition); diff --git a/src/java/davmail/exchange/ews/EwsExchangeSession.java b/src/java/davmail/exchange/ews/EwsExchangeSession.java index e298cb91..62613049 100644 --- a/src/java/davmail/exchange/ews/EwsExchangeSession.java +++ b/src/java/davmail/exchange/ews/EwsExchangeSession.java @@ -55,6 +55,7 @@ public class EwsExchangeSession extends ExchangeSession { /** * Message types. + * * @see http://msdn.microsoft.com/en-us/library/aa565652%28v=EXCHG.140%29.aspx */ protected static final Set MESSAGE_TYPES = new HashSet(); @@ -153,9 +154,6 @@ public class EwsExchangeSession extends ExchangeSession { if (locationHeader == null || !"/ews/services.wsdl".equalsIgnoreCase(locationHeader.getValue())) { throw new IOException("Ews endpoint not available at " + getMethod.getURI().toString()); } - } catch (IOException e) { - LOGGER.debug(e.getMessage()); - throw e; } finally { getMethod.releaseConnection(); } @@ -182,7 +180,7 @@ public class EwsExchangeSession extends ExchangeSession { email = getAliasFromLogin() + getEmailSuffixFromHostname(); } } - + currentMailboxPath = "/users/" + email.toLowerCase(); // check EWS access @@ -191,18 +189,27 @@ public class EwsExchangeSession extends ExchangeSession { // workaround for Exchange bug: send fake request internalGetFolder(""); } catch (IOException e) { + // first failover: retry with NTLM + DavGatewayHttpClientFacade.addNTLM(httpClient); try { - // failover, try to retrieve EWS url from autodiscover - checkEndPointUrl(getEwsUrlFromAutoDiscover()); + checkEndPointUrl("/ews/exchange.asmx"); // workaround for Exchange bug: send fake request internalGetFolder(""); } catch (IOException e2) { - // autodiscover failed and initial exception was authentication failure => throw original exception - if (e instanceof DavMailAuthenticationException) { - throw (DavMailAuthenticationException) e; + LOGGER.debug(e2.getMessage()); + try { + // failover, try to retrieve EWS url from autodiscover + checkEndPointUrl(getEwsUrlFromAutoDiscover()); + // workaround for Exchange bug: send fake request + internalGetFolder(""); + } catch (IOException e3) { + // autodiscover failed and initial exception was authentication failure => throw original exception + if (e instanceof DavMailAuthenticationException) { + throw (DavMailAuthenticationException) e; + } + LOGGER.error(e2.getMessage()); + throw new DavMailAuthenticationException("EXCEPTION_EWS_NOT_AVAILABLE"); } - LOGGER.error(e2.getMessage()); - throw new DavMailAuthenticationException("EXCEPTION_EWS_NOT_AVAILABLE"); } } @@ -221,7 +228,7 @@ public class EwsExchangeSession extends ExchangeSession { LOGGER.error(e.getMessage(), e); throw new DavMailAuthenticationException("EXCEPTION_EWS_NOT_AVAILABLE"); } - LOGGER.debug("Current user email is " + email + ", alias is " + alias + " on "+ serverVersion); + LOGGER.debug("Current user email is " + email + ", alias is " + alias + " on " + serverVersion); } protected static class AutoDiscoverMethod extends PostMethod { @@ -1425,7 +1432,7 @@ public class EwsExchangeSession extends ExchangeSession { public Item getItem(String folderPath, String itemName) throws IOException { EWSMethod.Item item = getEwsItem(folderPath, itemName); if (item == null) { - throw new HttpNotFoundException(itemName + " not found in "+folderPath); + throw new HttpNotFoundException(itemName + " not found in " + folderPath); } String itemType = item.type; @@ -1439,7 +1446,7 @@ public class EwsExchangeSession extends ExchangeSession { executeMethod(getItemMethod); item = getItemMethod.getResponseItem(); if (item == null) { - throw new HttpNotFoundException(itemName + " not found in "+folderPath); + throw new HttpNotFoundException(itemName + " not found in " + folderPath); } return new Contact(item); } else if ("CalendarItem".equals(itemType) @@ -1448,7 +1455,7 @@ public class EwsExchangeSession extends ExchangeSession { || "Message".equals(itemType)) { return new Event(item); } else { - throw new HttpNotFoundException(itemName + " not found in "+folderPath); + throw new HttpNotFoundException(itemName + " not found in " + folderPath); } }