mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-23 18:02:15 -05:00
self-signed cert support for WebDav.
This commit is contained in:
parent
1a7539af1d
commit
8221094570
@ -107,7 +107,6 @@ public final class TrustManagerFactory {
|
|||||||
Application app = Email.app;
|
Application app = Email.app;
|
||||||
keyStoreFile = new File(app.getDir("KeyStore", Context.MODE_PRIVATE) + File.separator + "KeyStore.bks");
|
keyStoreFile = new File(app.getDir("KeyStore", Context.MODE_PRIVATE) + File.separator + "KeyStore.bks");
|
||||||
keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||||
//TODO: read store from disk.
|
|
||||||
java.io.FileInputStream fis;
|
java.io.FileInputStream fis;
|
||||||
try {
|
try {
|
||||||
fis = new java.io.FileInputStream(keyStoreFile);
|
fis = new java.io.FileInputStream(keyStoreFile);
|
||||||
@ -116,6 +115,9 @@ public final class TrustManagerFactory {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
keyStore.load(fis, "".toCharArray());
|
keyStore.load(fis, "".toCharArray());
|
||||||
|
//if (fis != null) {
|
||||||
|
// fis.close();
|
||||||
|
//}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Log.e(LOG_TAG, "KeyStore IOException while initializing TrustManagerFactory ", e);
|
Log.e(LOG_TAG, "KeyStore IOException while initializing TrustManagerFactory ", e);
|
||||||
keyStore = null;
|
keyStore = null;
|
||||||
|
@ -1,39 +1,51 @@
|
|||||||
package com.android.email.mail.store;
|
package com.android.email.mail.store;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import java.io.BufferedOutputStream;
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URL;
|
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.KeyManagementException;
|
import java.security.KeyManagementException;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.ParsePosition;
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
|
||||||
import javax.net.ssl.SSLException;
|
import javax.net.ssl.SSLException;
|
||||||
import javax.net.ssl.SSLSocketFactory;
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
import javax.net.ssl.TrustManager;
|
|
||||||
import javax.xml.parsers.SAXParser;
|
import javax.xml.parsers.SAXParser;
|
||||||
import javax.xml.parsers.SAXParserFactory;
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
import javax.xml.parsers.ParserConfigurationException;
|
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.auth.AuthScope;
|
||||||
|
import org.apache.http.auth.Credentials;
|
||||||
|
import org.apache.http.auth.UsernamePasswordCredentials;
|
||||||
|
import org.apache.http.client.CookieStore;
|
||||||
|
import org.apache.http.client.CredentialsProvider;
|
||||||
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
|
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.conn.scheme.Scheme;
|
||||||
|
import org.apache.http.conn.scheme.SchemeRegistry;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.client.DefaultHttpClient;
|
||||||
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.XMLReader;
|
||||||
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import com.android.email.Email;
|
import com.android.email.Email;
|
||||||
import com.android.email.mail.CertificateValidationException;
|
import com.android.email.mail.CertificateValidationException;
|
||||||
@ -44,37 +56,9 @@ import com.android.email.mail.Message;
|
|||||||
import com.android.email.mail.MessageRetrievalListener;
|
import com.android.email.mail.MessageRetrievalListener;
|
||||||
import com.android.email.mail.MessagingException;
|
import com.android.email.mail.MessagingException;
|
||||||
import com.android.email.mail.Store;
|
import com.android.email.mail.Store;
|
||||||
import com.android.email.mail.internet.MimeBodyPart;
|
|
||||||
import com.android.email.mail.internet.MimeMessage;
|
import com.android.email.mail.internet.MimeMessage;
|
||||||
import com.android.email.mail.internet.TextBody;
|
|
||||||
import com.android.email.mail.transport.EOLConvertingOutputStream;
|
|
||||||
import com.android.email.mail.transport.TrustedSocketFactory;
|
import com.android.email.mail.transport.TrustedSocketFactory;
|
||||||
|
|
||||||
import org.apache.http.HttpResponse;
|
|
||||||
import org.apache.http.HttpEntity;
|
|
||||||
import org.apache.http.auth.AuthScope;
|
|
||||||
import org.apache.http.auth.Credentials;
|
|
||||||
import org.apache.http.auth.UsernamePasswordCredentials;
|
|
||||||
import org.apache.http.client.CookieStore;
|
|
||||||
import org.apache.http.client.CredentialsProvider;
|
|
||||||
import org.apache.http.client.HttpClient;
|
|
||||||
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
|
||||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
|
|
||||||
import org.apache.http.client.methods.HttpGet;
|
|
||||||
import org.apache.http.client.methods.HttpPost;
|
|
||||||
import org.apache.http.conn.scheme.Scheme;
|
|
||||||
import org.apache.http.conn.scheme.SchemeRegistry;
|
|
||||||
import org.apache.http.conn.scheme.SocketFactory;
|
|
||||||
import org.apache.http.entity.StringEntity;
|
|
||||||
import org.apache.http.impl.client.DefaultHttpClient;
|
|
||||||
import org.apache.http.message.BasicNameValuePair;
|
|
||||||
|
|
||||||
import org.xml.sax.Attributes;
|
|
||||||
import org.xml.sax.InputSource;
|
|
||||||
import org.xml.sax.SAXException;
|
|
||||||
import org.xml.sax.XMLReader;
|
|
||||||
import org.xml.sax.helpers.DefaultHandler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
* Uses WebDAV formatted HTTP calls to an MS Exchange server to fetch emails
|
* Uses WebDAV formatted HTTP calls to an MS Exchange server to fetch emails
|
||||||
@ -107,6 +91,7 @@ public class WebDavStore extends Store {
|
|||||||
|
|
||||||
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* webdav://user:password@server:port CONNECTION_SECURITY_NONE
|
* webdav://user:password@server:port CONNECTION_SECURITY_NONE
|
||||||
@ -150,9 +135,9 @@ public class WebDavStore extends Store {
|
|||||||
mConnectionSecurity == CONNECTION_SECURITY_SSL_REQUIRED ||
|
mConnectionSecurity == CONNECTION_SECURITY_SSL_REQUIRED ||
|
||||||
mConnectionSecurity == CONNECTION_SECURITY_TLS_OPTIONAL ||
|
mConnectionSecurity == CONNECTION_SECURITY_TLS_OPTIONAL ||
|
||||||
mConnectionSecurity == CONNECTION_SECURITY_SSL_OPTIONAL) {
|
mConnectionSecurity == CONNECTION_SECURITY_SSL_OPTIONAL) {
|
||||||
this.mUrl = "https://" + mHost;
|
this.mUrl = "https://" + mHost + ":" + mUri.getPort();
|
||||||
} else {
|
} else {
|
||||||
this.mUrl = "http://" + mHost;
|
this.mUrl = "http://" + mHost + ":" + mUri.getPort();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mUri.getUserInfo() != null) {
|
if (mUri.getUserInfo() != null) {
|
||||||
@ -448,7 +433,7 @@ public class WebDavStore extends Store {
|
|||||||
ArrayList<BasicNameValuePair> pairs = new ArrayList();
|
ArrayList<BasicNameValuePair> pairs = new ArrayList();
|
||||||
pairs.add(new BasicNameValuePair("username", username));
|
pairs.add(new BasicNameValuePair("username", username));
|
||||||
pairs.add(new BasicNameValuePair("password", password));
|
pairs.add(new BasicNameValuePair("password", password));
|
||||||
pairs.add(new BasicNameValuePair("destination", finalUrl + "/Exchange/"));
|
pairs.add(new BasicNameValuePair("destination", finalUrl + "/exchange/" +username+"/"));
|
||||||
pairs.add(new BasicNameValuePair("flags", "0"));
|
pairs.add(new BasicNameValuePair("flags", "0"));
|
||||||
pairs.add(new BasicNameValuePair("SubmitCreds", "Log+On"));
|
pairs.add(new BasicNameValuePair("SubmitCreds", "Log+On"));
|
||||||
pairs.add(new BasicNameValuePair("forcedownlevel", "0"));
|
pairs.add(new BasicNameValuePair("forcedownlevel", "0"));
|
||||||
@ -466,7 +451,7 @@ public class WebDavStore extends Store {
|
|||||||
|
|
||||||
/** Verify success */
|
/** Verify success */
|
||||||
if (status_code < 500 &&
|
if (status_code < 500 &&
|
||||||
status_code > 400) {
|
status_code >= 400) {
|
||||||
String errorText = "";
|
String errorText = "";
|
||||||
String requestText = "";
|
String requestText = "";
|
||||||
if (entity != null) {
|
if (entity != null) {
|
||||||
@ -483,6 +468,7 @@ public class WebDavStore extends Store {
|
|||||||
while ((tempText = reader.readLine()) != null) {
|
while ((tempText = reader.readLine()) != null) {
|
||||||
requestText += tempText;
|
requestText += tempText;
|
||||||
}
|
}
|
||||||
|
requestText = requestText.replaceAll("password=.*?&", "password=(omitted)&");
|
||||||
throw new MessagingException("Error during authentication: "+
|
throw new MessagingException("Error during authentication: "+
|
||||||
response.getStatusLine().toString()+ "\n\nRequest: "+
|
response.getStatusLine().toString()+ "\n\nRequest: "+
|
||||||
requestText + "\n\nResponse: " +
|
requestText + "\n\nResponse: " +
|
||||||
@ -538,25 +524,25 @@ public class WebDavStore extends Store {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public DefaultHttpClient getTrustedHttpClient() throws KeyManagementException, NoSuchAlgorithmException{
|
public DefaultHttpClient getTrustedHttpClient() throws KeyManagementException, NoSuchAlgorithmException{
|
||||||
DefaultHttpClient httpclient = new DefaultHttpClient();
|
if (mHttpClient == null) {
|
||||||
/*
|
mHttpClient = new DefaultHttpClient();
|
||||||
SchemeRegistry reg = httpclient.getConnectionManager().getSchemeRegistry();
|
SchemeRegistry reg = mHttpClient.getConnectionManager().getSchemeRegistry();
|
||||||
reg.unregister("https");
|
Scheme s = new Scheme("https",new TrustedSocketFactory(mHost,mSecure),443);
|
||||||
Scheme s = new Scheme("https",new TrustedSocketFactory(mHost,mSecure),443);
|
reg.register(s);
|
||||||
reg.register(s);
|
|
||||||
*/
|
|
||||||
/*
|
//Add credentials for NTLM/Digest/Basic Auth
|
||||||
//Add credentials for NTLM/Digest/Basic Auth
|
Credentials creds = new UsernamePasswordCredentials(mUsername, mPassword);
|
||||||
Credentials creds = new UsernamePasswordCredentials(mUsername, mPassword);
|
CredentialsProvider credsProvider = mHttpClient.getCredentialsProvider();
|
||||||
CredentialsProvider credsProvider = httpclient.getCredentialsProvider();
|
// setting AuthScope for 80 and 443, in case we end up getting redirected
|
||||||
// setting AuthScope for 80 and 443, in case we end up getting redirected
|
// from 80 to 443.
|
||||||
// from 80 to 443.
|
credsProvider.setCredentials(new AuthScope(mHost, 80, AuthScope.ANY_REALM), creds);
|
||||||
credsProvider.setCredentials(new AuthScope(mHost, 80, AuthScope.ANY_REALM), creds);
|
credsProvider.setCredentials(new AuthScope(mHost, 443, AuthScope.ANY_REALM), creds);
|
||||||
credsProvider.setCredentials(new AuthScope(mHost, 443, AuthScope.ANY_REALM), creds);
|
credsProvider.setCredentials(new AuthScope(mHost, mUri.getPort(), AuthScope.ANY_REALM), creds);
|
||||||
credsProvider.setCredentials(new AuthScope(mHost, mUri.getPort(), AuthScope.ANY_REALM), creds);
|
mHttpClient.setCredentialsProvider(credsProvider);
|
||||||
httpclient.setCredentialsProvider(credsProvider);
|
}
|
||||||
*/
|
|
||||||
return httpclient;
|
return mHttpClient;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -622,13 +608,29 @@ public class WebDavStore extends Store {
|
|||||||
response = httpclient.execute(httpmethod);
|
response = httpclient.execute(httpmethod);
|
||||||
statusCode = response.getStatusLine().getStatusCode();
|
statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
|
||||||
|
entity = response.getEntity();
|
||||||
|
|
||||||
|
if (statusCode < 500 &&
|
||||||
|
statusCode >= 400) {
|
||||||
|
String errorText = "";
|
||||||
|
if (entity != null) {
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()), 8192);
|
||||||
|
String tempText = "";
|
||||||
|
|
||||||
|
while ((tempText = reader.readLine()) != null) {
|
||||||
|
errorText += tempText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IOException("Error during authentication: "+
|
||||||
|
response.getStatusLine().toString()+ "\n\nRequest: "+
|
||||||
|
messageBody + "\n\nResponse: " +
|
||||||
|
errorText);
|
||||||
|
}
|
||||||
if (statusCode < 200 ||
|
if (statusCode < 200 ||
|
||||||
statusCode > 300) {
|
statusCode > 300) {
|
||||||
throw new IOException("Error processing request, returned HTTP Response Code was " + statusCode);
|
throw new IOException("Error processing request, returned HTTP Response Code was " + statusCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
entity = response.getEntity();
|
|
||||||
|
|
||||||
if (entity != null &&
|
if (entity != null &&
|
||||||
needsParsing) {
|
needsParsing) {
|
||||||
try {
|
try {
|
||||||
@ -1053,7 +1055,7 @@ public class WebDavStore extends Store {
|
|||||||
|
|
||||||
if (statusCode < 200 ||
|
if (statusCode < 200 ||
|
||||||
statusCode > 300) {
|
statusCode > 300) {
|
||||||
throw new IOException("Status Code in invalid range");
|
throw new IOException("Status Code in invalid range, URL: "+wdMessage.getUrl());
|
||||||
}
|
}
|
||||||
|
|
||||||
entity = response.getEntity();
|
entity = response.getEntity();
|
||||||
@ -1091,7 +1093,7 @@ public class WebDavStore extends Store {
|
|||||||
} catch (URISyntaxException use) {
|
} catch (URISyntaxException use) {
|
||||||
Log.e(Email.LOG_TAG, "URISyntaxException caught " + use);
|
Log.e(Email.LOG_TAG, "URISyntaxException caught " + use);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
Log.e(Email.LOG_TAG, "Non-success response code loading message, response code was " + statusCode);
|
Log.e(Email.LOG_TAG, "Non-success response code loading message, response code was: " + statusCode + " Error: "+ioe.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
@ -1362,6 +1364,18 @@ 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
|
||||||
|
//FIXME: so fix, or better yet:
|
||||||
|
//XXX: prevent URLs from getting to us that are broken.
|
||||||
|
if (! (url.toLowerCase().contains(WebDavStore.this.mUrl.toLowerCase()+this.mFolder.toString().toLowerCase()))) {
|
||||||
|
if (!(url.startsWith("/"))){
|
||||||
|
url = "/" + 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];
|
||||||
|
@ -9,16 +9,17 @@ import java.security.NoSuchAlgorithmException;
|
|||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLSocket;
|
||||||
import javax.net.ssl.SSLSocketFactory;
|
import javax.net.ssl.SSLSocketFactory;
|
||||||
import javax.net.ssl.TrustManager;
|
import javax.net.ssl.TrustManager;
|
||||||
|
|
||||||
import org.apache.http.conn.ConnectTimeoutException;
|
import org.apache.http.conn.ConnectTimeoutException;
|
||||||
import org.apache.http.conn.scheme.SocketFactory;
|
import org.apache.http.conn.scheme.LayeredSocketFactory;
|
||||||
import org.apache.http.params.HttpParams;
|
import org.apache.http.params.HttpParams;
|
||||||
|
|
||||||
import com.android.email.mail.store.TrustManagerFactory;
|
import com.android.email.mail.store.TrustManagerFactory;
|
||||||
|
|
||||||
public class TrustedSocketFactory implements SocketFactory {
|
public class TrustedSocketFactory implements LayeredSocketFactory {
|
||||||
private SSLSocketFactory mSocketFactory;
|
private SSLSocketFactory mSocketFactory;
|
||||||
private org.apache.http.conn.ssl.SSLSocketFactory mSchemeSocketFactory;
|
private org.apache.http.conn.ssl.SSLSocketFactory mSchemeSocketFactory;
|
||||||
|
|
||||||
@ -46,5 +47,19 @@ public class TrustedSocketFactory implements SocketFactory {
|
|||||||
public boolean isSecure(Socket sock) throws IllegalArgumentException {
|
public boolean isSecure(Socket sock) throws IllegalArgumentException {
|
||||||
return mSchemeSocketFactory.isSecure(sock);
|
return mSchemeSocketFactory.isSecure(sock);
|
||||||
}
|
}
|
||||||
|
public Socket createSocket(
|
||||||
}
|
final Socket socket,
|
||||||
|
final String host,
|
||||||
|
final int port,
|
||||||
|
final boolean autoClose
|
||||||
|
) throws IOException, UnknownHostException {
|
||||||
|
SSLSocket sslSocket = (SSLSocket) mSocketFactory.createSocket(
|
||||||
|
socket,
|
||||||
|
host,
|
||||||
|
port,
|
||||||
|
autoClose
|
||||||
|
);
|
||||||
|
//hostnameVerifier.verify(host, sslSocket);
|
||||||
|
// verifyHostName() didn't blowup - good!
|
||||||
|
return sslSocket;
|
||||||
|
}}
|
||||||
|
Loading…
Reference in New Issue
Block a user