1
0
mirror of https://github.com/moparisthebest/k-9 synced 2025-01-11 13:49:15 -05:00

Added support for non-Exchange 2003 standard login paths (web scraping for login URL).

Added support for default mailbox path setting if we can't automatically determine what it is.
Fixed a bug exposed by changes relating to a fix for non-relative email paths being returned.
This commit is contained in:
Matthew Brace 2009-01-08 05:47:10 +00:00
parent 7954b02da6
commit 7d5d29e078

View File

@ -82,7 +82,7 @@ public class WebDavStore extends Store {
private String mPassword; /* Stores the password for authentications */ private String mPassword; /* Stores the password for authentications */
private String mUrl; /* Stores the base URL for the server */ private String mUrl; /* Stores the base URL for the server */
private String mHost; /* Stores the host name for the server */ private String mHost; /* Stores the host name for the server */
private URI mUri; /* Stores the Uniform Resource Indicator with all connection info */ private URI mUri; /* Stores the Uniform Resource Indicator with all connection info */
private CookieStore mAuthCookies; /* Stores cookies from authentication */ private CookieStore mAuthCookies; /* Stores cookies from authentication */
private boolean mAuthenticated = false; /* Stores authentication state */ private boolean mAuthenticated = false; /* Stores authentication state */
@ -90,8 +90,8 @@ public class WebDavStore extends Store {
private long mAuthTimeout = 5 * 60; private long mAuthTimeout = 5 * 60;
private HashMap<String, WebDavFolder> mFolderList = new HashMap<String, WebDavFolder>(); private HashMap<String, WebDavFolder> mFolderList = new HashMap<String, WebDavFolder>();
private boolean mSecure; private boolean mSecure;
private DefaultHttpClient mHttpClient = null; private DefaultHttpClient mHttpClient = null;
/** /**
* webdav://user:password@server:port CONNECTION_SECURITY_NONE * webdav://user:password@server:port CONNECTION_SECURITY_NONE
@ -124,7 +124,7 @@ public class WebDavStore extends Store {
} }
mHost = mUri.getHost(); mHost = mUri.getHost();
if (mHost.startsWith("http")) { if (mHost.startsWith("http")) {
String[] hostParts = mHost.split("://", 2); String[] hostParts = mHost.split("://", 2);
if (hostParts.length > 1) { if (hostParts.length > 1) {
mHost = hostParts[1]; mHost = hostParts[1];
@ -154,7 +154,7 @@ public class WebDavStore extends Store {
mPassword = userInfoParts[1]; mPassword = userInfoParts[1];
} }
} }
mSecure = mConnectionSecurity == CONNECTION_SECURITY_SSL_REQUIRED; mSecure = mConnectionSecurity == CONNECTION_SECURITY_SSL_REQUIRED;
} }
@ -181,7 +181,6 @@ public class WebDavStore extends Store {
messageBody = getFolderListXml(); messageBody = getFolderListXml();
headers.put("Brief", "t"); headers.put("Brief", "t");
dataset = processRequest(this.mUrl, "SEARCH", messageBody, headers); dataset = processRequest(this.mUrl, "SEARCH", messageBody, headers);
folderUrls = dataset.getHrefs(); folderUrls = dataset.getHrefs();
@ -404,27 +403,27 @@ public class WebDavStore extends Store {
} }
public static String getHttpRequestResponse(HttpEntity request, HttpEntity response) throws IllegalStateException, IOException{ public static String getHttpRequestResponse(HttpEntity request, HttpEntity response) throws IllegalStateException, IOException{
String responseText = ""; String responseText = "";
String requestText = ""; String requestText = "";
if (response != null) { if (response != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getContent()), 8192); BufferedReader reader = new BufferedReader(new InputStreamReader(response.getContent()), 8192);
String tempText = ""; String tempText = "";
while ((tempText = reader.readLine()) != null) { while ((tempText = reader.readLine()) != null) {
responseText += tempText; responseText += tempText;
} }
} }
if (request != null) { if (request != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(request.getContent()), 8192); BufferedReader reader = new BufferedReader(new InputStreamReader(request.getContent()), 8192);
String tempText = ""; String tempText = "";
while ((tempText = reader.readLine()) != null) { while ((tempText = reader.readLine()) != null) {
requestText += tempText; requestText += tempText;
} }
requestText = requestText.replaceAll("password=.*?&", "password=(omitted)&"); requestText = requestText.replaceAll("password=.*?&", "password=(omitted)&");
} }
return "Request: " + requestText + return "Request: " + requestText +
"\n\nResponse: " + responseText; "\n\nResponse: " + responseText;
} }
@ -439,6 +438,7 @@ public class WebDavStore extends Store {
CookieStore cookies = null; CookieStore cookies = null;
String[] urlParts = url.split("/"); String[] urlParts = url.split("/");
String finalUrl = ""; String finalUrl = "";
String loginUrl = new String();
for (int i = 0; i <= 2; i++) { for (int i = 0; i <= 2; i++) {
if (i != 0) { if (i != 0) {
@ -448,68 +448,118 @@ public class WebDavStore extends Store {
} }
} }
if (finalUrl.equals("")) {
throw new MessagingException("doAuthentication failed, unable to construct URL to post login credentials to.");
}
loginUrl = finalUrl + authPath;
try { try {
/* Browser Client */ /* Browser Client */
DefaultHttpClient httpclient = getTrustedHttpClient(); DefaultHttpClient httpclient = getTrustedHttpClient();
/* Post Method */
HttpPost httppost = new HttpPost(finalUrl + authPath);
/** Build the POST data to use */ /* Verb Fix issue */
ArrayList<BasicNameValuePair> pairs = new ArrayList(); /**
pairs.add(new BasicNameValuePair("username", username)); * This is in a separate block because I really don't like how it's done.
pairs.add(new BasicNameValuePair("password", password)); * This basically scrapes the OWA login page for the form submission URL.
pairs.add(new BasicNameValuePair("destination", finalUrl + "/exchange/" +username+"/")); * UGLY!
pairs.add(new BasicNameValuePair("flags", "0")); */
pairs.add(new BasicNameValuePair("SubmitCreds", "Log+On")); {
pairs.add(new BasicNameValuePair("forcedownlevel", "0")); HttpGet httpget = new HttpGet(finalUrl);
pairs.add(new BasicNameValuePair("trusted", "0")); HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
int statusCode = response.getStatusLine().getStatusCode();
try { if (statusCode > 300 ||
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(pairs); statusCode < 200) {
throw new MessagingException("Error during authentication: "+
response.getStatusLine().toString()+"\n\n");
}
if (entity != null) {
InputStream istream = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(istream), 4096);
String tempText = new String();
boolean matched = false;
httppost.setEntity(formEntity); while ((tempText = reader.readLine()) != null &&
!matched) {
if (tempText.indexOf(" action") >= 0) {
String[] tagParts = tempText.split("\"");
loginUrl = finalUrl + tagParts[1];
matched = true;
}
}
istream.close();
}
}
/** Perform the actual POST */ /* Post Method */
HttpResponse response = httpclient.execute(httppost); HttpPost httppost = new HttpPost(loginUrl);
HttpEntity entity = response.getEntity();
int status_code = response.getStatusLine().getStatusCode(); /** Build the POST data to use */
ArrayList<BasicNameValuePair> pairs = new ArrayList();
pairs.add(new BasicNameValuePair("username", username));
pairs.add(new BasicNameValuePair("password", password));
pairs.add(new BasicNameValuePair("destination", finalUrl + "/exchange/" +username+"/"));
pairs.add(new BasicNameValuePair("flags", "0"));
pairs.add(new BasicNameValuePair("SubmitCreds", "Log+On"));
pairs.add(new BasicNameValuePair("forcedownlevel", "0"));
pairs.add(new BasicNameValuePair("trusted", "0"));
try {
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(pairs);
String tempUrl = "";
httppost.setEntity(formEntity);
/** Perform the actual POST */
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
int status_code = response.getStatusLine().getStatusCode();
/** Verify success */ /** Verify success */
if (status_code > 300 || if (status_code > 300 ||
status_code < 200) { status_code < 200) {
throw new MessagingException("Error during authentication: "+ throw new MessagingException("Error during authentication: "+
response.getStatusLine().toString()+ "\n\n"+ response.getStatusLine().toString()+ "\n\n"+
getHttpRequestResponse(formEntity, entity)); getHttpRequestResponse(formEntity, entity));
} }
cookies = httpclient.getCookieStore(); cookies = httpclient.getCookieStore();
if (cookies == null) { if (cookies == null) {
throw new IOException("Error during authentication: No Cookies"); throw new IOException("Error during authentication: No Cookies");
} }
/** Get the URL for the mailbox and set it for the store */ /** Get the URL for the mailbox and set it for the store */
if (entity != null) { if (entity != null) {
InputStream istream = entity.getContent(); InputStream istream = entity.getContent();
BufferedReader reader = new BufferedReader(new InputStreamReader(istream), 8192);
String tempText = "";
while ((tempText = reader.readLine()) != null) {
if (tempText.indexOf("BASE href") >= 0) {
String[] tagParts = tempText.split("\"");
tempUrl = tagParts[1];
}
}
}
BufferedReader reader = new BufferedReader(new InputStreamReader(istream), 8192); if (tempUrl.equals("")) {
String tempText = ""; this.mUrl = finalUrl + "/Exchange/" + this.alias + "/";
} else {
this.mUrl = tempUrl;
}
while ((tempText = reader.readLine()) != null) { } catch (UnsupportedEncodingException uee) {
if (tempText.indexOf("BASE href") >= 0) { Log.e(Email.LOG_TAG, "Error encoding POST data for authencation");
String[] tagParts = tempText.split("\""); }
this.mUrl = tagParts[1];
}
}
}
} catch (UnsupportedEncodingException uee) {
Log.e(Email.LOG_TAG, "Error encoding POST data for authencation");
}
} catch (SSLException e) { } catch (SSLException e) {
throw new CertificateValidationException(e.getMessage(), e); throw new CertificateValidationException(e.getMessage(), e);
} catch (GeneralSecurityException gse) { } catch (GeneralSecurityException gse) {
throw new MessagingException( throw new MessagingException(
"Unable to open connection to SMTP server due to security error.", gse); "Unable to open connection to SMTP server due to security error.", gse);
} }
return cookies; return cookies;
} }
@ -576,10 +626,10 @@ public class WebDavStore extends Store {
} }
if (needAuth()) { if (needAuth()) {
try { try {
authenticate(); authenticate();
} catch (MessagingException e) { } catch (MessagingException e) {
Log.e(Email.LOG_TAG, "Generated MessagingException during authentication" + e.getStackTrace()); Log.e(Email.LOG_TAG, "Generated MessagingException during authentication" + e.getStackTrace());
} }
} }
if (this.mAuthenticated == false || if (this.mAuthenticated == false ||
@ -699,10 +749,10 @@ public class WebDavStore extends Store {
*/ */
if (needAuth()) { if (needAuth()) {
try { try {
authenticate(); authenticate();
} catch (MessagingException e) { } catch (MessagingException e) {
Log.e(Email.LOG_TAG, "Generated MessagingException during authentication" + e.getStackTrace()); Log.e(Email.LOG_TAG, "Generated MessagingException during authentication" + e.getStackTrace());
} }
} }
if (encodedName.equals("INBOX")) { if (encodedName.equals("INBOX")) {
@ -1355,18 +1405,15 @@ public class WebDavStore extends Store {
} }
public void setUrl(String url) { public void setUrl(String url) {
//TODO: bleh. This is an ugly hack, but does prevent a crash if the url is relative //TODO: This is a not as ugly hack (ie, it will actually work)
//FIXME: so fix, or better yet: //XXX: prevent URLs from getting to us that are broken
//XXX: prevent URLs from getting to us that are broken. if (!(url.toLowerCase().contains("http"))) {
if (! (url.toLowerCase().contains(WebDavStore.this.mUrl.toLowerCase()+this.mFolder.toString().toLowerCase()))) { if (!(url.startsWith("/"))){
if (!(url.startsWith("/"))){ url = "/" + url;
url = "/" + url; }
} url = WebDavStore.this.mUrl + this.mFolder + url;
url = WebDavStore.this.mUrl + this.mFolder+url; }
}
if (!(url.toLowerCase().contains(WebDavStore.this.mUrl.toLowerCase()))) {
url = WebDavStore.this.mUrl + url;
}
String[] urlParts = url.split("/"); String[] urlParts = url.split("/");
int length = urlParts.length; int length = urlParts.length;
String end = urlParts[length - 1]; String end = urlParts[length - 1];