mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-11 20:15:03 -05:00
Added support for DNS MX redirection in autoconfiguration.
Reworked the gui for the autoconfiguration activity.
This commit is contained in:
parent
1c4ebf15b7
commit
5aa0dce062
@ -1,65 +1,76 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical" >
|
||||||
|
|
||||||
<TextView android:id="@+id/status_message"
|
<ScrollView
|
||||||
android:layout_height="wrap_content"
|
android:id="@+id/scrollView1"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_above="@+id/controls_group" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/status_message"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="20dp"
|
android:layout_marginTop="20dp"
|
||||||
android:gravity="center_horizontal"
|
android:gravity="center_horizontal"
|
||||||
android:paddingBottom="6dip"/>
|
android:textSize="10dp"
|
||||||
|
android:paddingBottom="6dip" />
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_below="@id/status_message"
|
android:id="@+id/controls_group"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="158dp"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_marginBottom="10dp"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:orientation="vertical" >
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/linearLayout1"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginBottom="10dp"
|
android:layout_alignParentBottom="true"
|
||||||
android:orientation="vertical"
|
android:layout_alignParentLeft="true"
|
||||||
android:layout_centerHorizontal="true">
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal" >
|
||||||
|
|
||||||
<TextView android:id="@+id/autoconfig_warning"
|
<Button
|
||||||
android:gravity="center"
|
android:id="@+id/autoconfig_button_cancel"
|
||||||
android:textColor="#C44141"
|
|
||||||
android:textStyle="bold"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/account_setup_autoconfig_unsafe_connection" />
|
android:text="@string/cancel_action" />
|
||||||
|
|
||||||
<RelativeLayout
|
<Button
|
||||||
android:layout_width="fill_parent"
|
android:id="@+id/autoconfig_button_next"
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:layout_alignParentBottom="true">
|
|
||||||
|
|
||||||
<!-- kind of a hack.... need to have a look at whis this is behind the buttons -->
|
|
||||||
<ProgressBar android:id="@+id/autoconfig_progress"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_centerInParent="true"
|
android:drawableRight="@drawable/button_indicator_next"
|
||||||
android:layout_marginBottom="50dp"
|
android:text="@string/next_action" />
|
||||||
style="@android:style/Widget.ProgressBar.Large" />
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<TextView
|
||||||
android:layout_below="@id/autoconfig_progress"
|
android:id="@+id/autoconfig_warning"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:gravity="center"
|
android:layout_above="@+id/linearLayout1"
|
||||||
android:orientation="horizontal">
|
android:layout_alignParentLeft="true"
|
||||||
<Button android:id="@+id/autoconfig_button_cancel"
|
android:layout_marginBottom="20dp"
|
||||||
android:layout_width="wrap_content"
|
android:gravity="center"
|
||||||
android:layout_height="wrap_content"
|
android:text="@string/account_setup_autoconfig_unsafe_connection"
|
||||||
android:text="@string/cancel_action"/>
|
android:textColor="#C44141"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
<Button android:id="@+id/autoconfig_button_next"
|
<ProgressBar
|
||||||
android:drawableRight="@drawable/button_indicator_next"
|
android:id="@+id/autoconfig_progress"
|
||||||
android:layout_width="wrap_content"
|
style="@android:style/Widget.ProgressBar.Large.Inverse"
|
||||||
android:layout_height="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:text="@string/next_action"/>
|
android:layout_height="wrap_content"
|
||||||
</LinearLayout>
|
android:layout_alignBottom="@+id/autoconfig_warning"
|
||||||
</RelativeLayout>
|
android:layout_centerHorizontal="true" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@ -384,6 +384,8 @@ http://k9mail.googlecode.com/
|
|||||||
<string name="account_setup_autoconfig_fail">failed!</string>
|
<string name="account_setup_autoconfig_fail">failed!</string>
|
||||||
<string name="account_setup_autoconfig_forcemanual">No were settings found, use manual configuration to continue.</string>
|
<string name="account_setup_autoconfig_forcemanual">No were settings found, use manual configuration to continue.</string>
|
||||||
<string name="account_setup_autoconfig_trynext">Searching other places for configuration settings...</string>
|
<string name="account_setup_autoconfig_trynext">Searching other places for configuration settings...</string>
|
||||||
|
<string name="account_setup_autoconfig_trydns">Checking for DNS redirects...</string>
|
||||||
|
<string name="account_setup_autoconfig_new_domain">Retrying autoconfiguration for a new domain.</string>
|
||||||
|
|
||||||
<string name="account_setup_names_title">You\'re almost done!</string>
|
<string name="account_setup_names_title">You\'re almost done!</string>
|
||||||
<string name="account_setup_names_instructions">Your account is set up, and mail is on its way!</string>
|
<string name="account_setup_names_instructions">Your account is set up, and mail is on its way!</string>
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
package com.fsck.k9.activity.setup;
|
package com.fsck.k9.activity.setup;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.*;
|
import android.os.*;
|
||||||
import android.os.Process;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
@ -17,8 +14,13 @@ import com.fsck.k9.activity.K9Activity;
|
|||||||
import com.fsck.k9.helper.configxmlparser.AutoconfigInfo;
|
import com.fsck.k9.helper.configxmlparser.AutoconfigInfo;
|
||||||
import com.fsck.k9.helper.configxmlparser.ConfigurationXMLHandler;
|
import com.fsck.k9.helper.configxmlparser.ConfigurationXMLHandler;
|
||||||
import com.fsck.k9.mail.store.TrustManagerFactory;
|
import com.fsck.k9.mail.store.TrustManagerFactory;
|
||||||
|
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.impl.client.DefaultHttpClient;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
import org.xml.sax.InputSource;
|
import org.xml.sax.InputSource;
|
||||||
import org.xml.sax.Parser;
|
|
||||||
import org.xml.sax.SAXException;
|
import org.xml.sax.SAXException;
|
||||||
import org.xml.sax.XMLReader;
|
import org.xml.sax.XMLReader;
|
||||||
|
|
||||||
@ -27,11 +29,9 @@ import javax.xml.parsers.ParserConfigurationException;
|
|||||||
import javax.xml.parsers.SAXParserFactory;
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.concurrent.TimeoutException;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User: dzan
|
* User: dzan
|
||||||
@ -49,6 +49,7 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
|
|||||||
|
|
||||||
// location of mozilla's ispdb
|
// location of mozilla's ispdb
|
||||||
private String databaseBaseUrl = "https://live.mozillamessaging.com/autoconfig/v1.1/";
|
private String databaseBaseUrl = "https://live.mozillamessaging.com/autoconfig/v1.1/";
|
||||||
|
private String dnsMXLookupUrl = "https://live.mozillamessaging.com/dns/mx/";
|
||||||
|
|
||||||
// for now there are only 2 so I just hardcode them here
|
// for now there are only 2 so I just hardcode them here
|
||||||
// also note: order they are listed is the order they'll be checked
|
// also note: order they are listed is the order they'll be checked
|
||||||
@ -134,129 +135,16 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
|
|||||||
mPassword = getIntent().getStringExtra(PASSWORD);
|
mPassword = getIntent().getStringExtra(PASSWORD);
|
||||||
mMakeDefault = getIntent().getBooleanExtra(MAKEDEFAULT, false);
|
mMakeDefault = getIntent().getBooleanExtra(MAKEDEFAULT, false);
|
||||||
|
|
||||||
|
// inform user we start autoconfig
|
||||||
|
setMessage(R.string.account_setup_autoconfig_info, true);
|
||||||
|
|
||||||
|
// divide the address
|
||||||
|
String[] emailParts = splitEmail(mEmailAddress);
|
||||||
|
String user = emailParts[0];
|
||||||
|
String domain = emailParts[1];
|
||||||
|
|
||||||
// The real action, in a separate thread
|
// The real action, in a separate thread
|
||||||
new Thread() {
|
new AutoConfigurationThread(domain).start();
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
|
||||||
|
|
||||||
// declare some variables
|
|
||||||
String data = ""; // used to store downloaded xml before parsing
|
|
||||||
String tmpURL = "";
|
|
||||||
|
|
||||||
// notify the user we'll get started
|
|
||||||
setMessage(R.string.account_setup_autoconfig_info, true);
|
|
||||||
|
|
||||||
// divide the address
|
|
||||||
String[] emailParts = splitEmail(mEmailAddress);
|
|
||||||
String user = emailParts[0];
|
|
||||||
String domain = emailParts[1];
|
|
||||||
|
|
||||||
/*
|
|
||||||
Check if configuration data exists and if it does read in
|
|
||||||
*/
|
|
||||||
int i = 0;
|
|
||||||
while( i < urlTemplates.size() && !bFound ){
|
|
||||||
try{
|
|
||||||
// inform the user
|
|
||||||
setMessage(urlInfoStatements.get(i),true);
|
|
||||||
|
|
||||||
// to make sure
|
|
||||||
bParseFailed = false;
|
|
||||||
bForceManual = false;
|
|
||||||
bDoneSearching = false;
|
|
||||||
|
|
||||||
// preparing the urls
|
|
||||||
if( !domain.contains("%user%") ){ // else SHIT
|
|
||||||
tmpURL = urlTemplates.get(i).replaceAll("%domain%",domain);
|
|
||||||
tmpURL = tmpURL.replaceAll("%address%",mEmailAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
data = getXMLData(new URL(tmpURL));
|
|
||||||
|
|
||||||
// might be the user cancelled by now or the app was destroyed
|
|
||||||
if (mDestroyed) return;
|
|
||||||
if (mCanceled) { finish(); return; }
|
|
||||||
|
|
||||||
if( !data.isEmpty() ){
|
|
||||||
setMessage(R.string.account_setup_autoconfig_found,false);
|
|
||||||
|
|
||||||
// parse and finish
|
|
||||||
setMessage(R.string.account_setup_autoconfig_processing,true);
|
|
||||||
parse(data);
|
|
||||||
setMessage(R.string.account_setup_autoconfig_succesful,false);
|
|
||||||
|
|
||||||
// alert user these settings might be tampered with!!! ( no https )
|
|
||||||
if( i >= UNSAFE_URL_START ) bUnsafe = true;
|
|
||||||
|
|
||||||
bFound = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
}catch (SocketTimeoutException ex){
|
|
||||||
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '"+
|
|
||||||
tmpURL+"' ( time-out is"+TIMEOUT+" )", ex);
|
|
||||||
}catch (MalformedURLException ex){
|
|
||||||
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '"+
|
|
||||||
tmpURL+"'", ex);
|
|
||||||
}catch (UnknownHostException ex){
|
|
||||||
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '"+
|
|
||||||
tmpURL+"'", ex);
|
|
||||||
}catch (SSLPeerUnverifiedException ex){
|
|
||||||
Log.e(K9.LOG_TAG, "Error while testing settings", ex);
|
|
||||||
acceptKeyDialog(R.string.account_setup_failed_dlg_certificate_message_fmt,i,ex);
|
|
||||||
}catch (SAXException e) {
|
|
||||||
setMessage(R.string.account_setup_autoconfig_fail,false);
|
|
||||||
bParseFailed = true;
|
|
||||||
}catch (ParserConfigurationException e) {
|
|
||||||
setMessage(R.string.account_setup_autoconfig_fail,false);
|
|
||||||
bParseFailed = true;
|
|
||||||
}catch (ErrorCodeException ex) {
|
|
||||||
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '" +
|
|
||||||
tmpURL + "' site didn't respond as expected. Got code: " + ex.getErrorCode(), ex);
|
|
||||||
}catch(IOException ex) {
|
|
||||||
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '"+
|
|
||||||
tmpURL+"'", ex);
|
|
||||||
} finally {
|
|
||||||
// might be the user cancelled by now or the app was destroyed
|
|
||||||
if (mDestroyed) return;
|
|
||||||
if (mCanceled) { finish(); return; }
|
|
||||||
|
|
||||||
// check next url
|
|
||||||
++i;
|
|
||||||
|
|
||||||
// this was the last option..
|
|
||||||
if(i == urlTemplates.size() ){
|
|
||||||
bForceManual = true;
|
|
||||||
setMessage(R.string.account_setup_autoconfig_forcemanual, true);
|
|
||||||
}else{
|
|
||||||
if( bParseFailed )
|
|
||||||
setMessage(R.string.account_setup_autoconfig_trynext,true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// no server-side config was found
|
|
||||||
closeUserInformationIfNeeded(i-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
bDoneSearching = true;
|
|
||||||
runOnUiThread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
// TODO: set appropriate warning messages in here
|
|
||||||
// 1. All good, continue
|
|
||||||
// 2. Nothing came up, must manually config.. + help?
|
|
||||||
// 3. Data did not came over HTTPS this could be UNSAFE !!!!!!
|
|
||||||
mProgressCircle.setVisibility(View.INVISIBLE);
|
|
||||||
if( bUnsafe /*&& !bForceManual*/ ) mWarningMsg.setVisibility(View.VISIBLE);
|
|
||||||
mNextButton.setEnabled(true);
|
|
||||||
if( bForceManual )
|
|
||||||
mNextButton.setText(getString(R.string.account_setup_basics_manual_setup_action));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -272,6 +160,7 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
|
|||||||
mAutoConfigInfo = parser.getAutoconfigInfo();
|
mAutoConfigInfo = parser.getAutoconfigInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Checks if an url is available / exists
|
Checks if an url is available / exists
|
||||||
*/
|
*/
|
||||||
@ -300,12 +189,83 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
|
|||||||
}
|
}
|
||||||
catch (SocketTimeoutException ex)
|
catch (SocketTimeoutException ex)
|
||||||
{ throw ex; }
|
{ throw ex; }
|
||||||
|
catch (ConnectException ex){
|
||||||
|
// ignore this, it just means the url doesn't exist which happens often, we test for it!
|
||||||
|
}
|
||||||
finally
|
finally
|
||||||
{ conn.disconnect(); }
|
{ conn.disconnect(); }
|
||||||
|
|
||||||
return tmp;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Does an DNS MX lookup of the domain and returns a list of records.
|
||||||
|
* This uses the Mozilla webservice to do so.
|
||||||
|
*/
|
||||||
|
private List<String> doMXLookup(String domain) throws IOException{
|
||||||
|
HttpClient httpclient = new DefaultHttpClient();
|
||||||
|
HttpGet method = new HttpGet(dnsMXLookupUrl + domain);
|
||||||
|
|
||||||
|
// do request
|
||||||
|
HttpResponse response = httpclient.execute(method);
|
||||||
|
String data = EntityUtils.toString(response.getEntity());
|
||||||
|
return new ArrayList<String>(Arrays.asList(data.split("[\\r\\n]+")));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Does two things:
|
||||||
|
* 1. Detect the isp-domain parts of the mxServer hostnames
|
||||||
|
* 2. Filters these so we have a list of uniques also not containing the initial domainname used for mx lookup
|
||||||
|
*
|
||||||
|
* TODO:
|
||||||
|
* Speed this up! There are a lot of options...
|
||||||
|
* Use a Set instead of a list, don't rebuild tmpStr every time,...
|
||||||
|
*/
|
||||||
|
private List<String> getDomainPossibilities(List<String> mxServers, String origDomain){
|
||||||
|
List<String> filteredDomains = new ArrayList<String>();
|
||||||
|
String[] serverSplit;
|
||||||
|
String tmpStr, prevAtom;
|
||||||
|
int size = 0; // total atoms in server hostname
|
||||||
|
// number of atoms in last found domain
|
||||||
|
int parts = 2; // to begin with, minimum so never arrayoutofbound
|
||||||
|
|
||||||
|
for( String server : mxServers )
|
||||||
|
{
|
||||||
|
serverSplit = server.toLowerCase().split("\\.");
|
||||||
|
prevAtom = serverSplit[0];
|
||||||
|
|
||||||
|
// speed things up a bit ( ugly )
|
||||||
|
size = serverSplit.length;
|
||||||
|
tmpStr = "";
|
||||||
|
for( int k=size-1; k>(size-parts-1); --k) tmpStr += "."+serverSplit[k];
|
||||||
|
tmpStr = tmpStr.substring(1);
|
||||||
|
if( filteredDomains.contains(tmpStr)) continue;
|
||||||
|
|
||||||
|
// determine right domainname
|
||||||
|
for( int i = 1; i < serverSplit.length; ++i ){
|
||||||
|
// build domainstring to test
|
||||||
|
tmpStr = "";
|
||||||
|
for( int j=i; j<serverSplit.length; ++j) tmpStr += "."+serverSplit[j];
|
||||||
|
tmpStr = tmpStr.substring(1);
|
||||||
|
|
||||||
|
// we matched a as-wide-as-possible tld
|
||||||
|
if(com.fsck.k9.helper.Regex.TOP_LEVEL_DOMAIN_PATTERN.matcher(tmpStr).matches()){
|
||||||
|
tmpStr = prevAtom + "." + tmpStr;
|
||||||
|
size = 1 + (size - i);
|
||||||
|
if( !tmpStr.equals(origDomain) && !filteredDomains.contains(tmpStr) )
|
||||||
|
filteredDomains.add(tmpStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
prevAtom = serverSplit[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filteredDomains;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Adds messages to the view, provides the user with progress reports
|
Adds messages to the view, provides the user with progress reports
|
||||||
*/
|
*/
|
||||||
@ -330,7 +290,7 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void closeUserInformationIfNeeded(int urlNumb) {
|
private synchronized void closeUserInformationIfNeeded(int urlNumb) {
|
||||||
if( bForceManual ) return;
|
if( bForceManual ) return;
|
||||||
|
|
||||||
if( urlNumb == urlInfoStatements.size() - 1
|
if( urlNumb == urlInfoStatements.size() - 1
|
||||||
@ -343,6 +303,7 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We stop our thread
|
We stop our thread
|
||||||
*/
|
*/
|
||||||
@ -403,7 +364,7 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
|
|||||||
TODO: Rework this so it changes the url counter, not restart intent
|
TODO: Rework this so it changes the url counter, not restart intent
|
||||||
NOTE: It's called but doesn't work right now because for the connection the default sslfactory is yet used
|
NOTE: It's called but doesn't work right now because for the connection the default sslfactory is yet used
|
||||||
*/
|
*/
|
||||||
private void acceptKeyDialog(final int msgResId, final int urlNumber, final Object... args) {
|
/* private void acceptKeyDialog(final int msgResId, final int urlNumber, final Object... args) {
|
||||||
mHandler.post(new Runnable() {
|
mHandler.post(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
if (mDestroyed) {
|
if (mDestroyed) {
|
||||||
@ -464,9 +425,166 @@ public class AccountSetupAutoConfiguration extends K9Activity implements View.On
|
|||||||
.show();
|
.show();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Thread class to do the autoconfiguration
|
||||||
|
*/
|
||||||
|
private class AutoConfigurationThread extends Thread{
|
||||||
|
|
||||||
|
private String mDomain;
|
||||||
|
private List<String> mDomainAlternatives;
|
||||||
|
|
||||||
|
public AutoConfigurationThread(String domain) {
|
||||||
|
super();
|
||||||
|
this.mDomain = domain;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
//android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
|
||||||
|
|
||||||
|
// declare some variables
|
||||||
|
String data = ""; // used to store downloaded xml before parsing
|
||||||
|
String tmpURL = "";
|
||||||
|
|
||||||
|
int templateIndex = 0;
|
||||||
|
while( templateIndex < urlTemplates.size() && !bFound ){
|
||||||
|
try{
|
||||||
|
// inform the user
|
||||||
|
setMessage(urlInfoStatements.get(templateIndex),true);
|
||||||
|
|
||||||
|
// to make sure
|
||||||
|
bParseFailed = false;
|
||||||
|
bForceManual = false;
|
||||||
|
bDoneSearching = false;
|
||||||
|
|
||||||
|
// preparing the urls
|
||||||
|
if( !mDomain.contains("%user%") ){ // else SHIT
|
||||||
|
tmpURL = urlTemplates.get(templateIndex).replaceAll("%domain%",mDomain);
|
||||||
|
tmpURL = tmpURL.replaceAll("%address%",mEmailAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the xml data
|
||||||
|
data = getXMLData(new URL(tmpURL));
|
||||||
|
|
||||||
|
// might be the user cancelled by now or the app was destroyed
|
||||||
|
if (mDestroyed) return;
|
||||||
|
if (mCanceled) { finish(); return; }
|
||||||
|
|
||||||
|
// if we really have data
|
||||||
|
if( !data.isEmpty() ){
|
||||||
|
setMessage(R.string.account_setup_autoconfig_found,false);
|
||||||
|
|
||||||
|
// parse and finish
|
||||||
|
setMessage(R.string.account_setup_autoconfig_processing,true);
|
||||||
|
parse(data);
|
||||||
|
setMessage(R.string.account_setup_autoconfig_succesful,false);
|
||||||
|
|
||||||
|
// alert user these settings might be tampered with!!! ( no https )
|
||||||
|
if( templateIndex >= UNSAFE_URL_START ) bUnsafe = true;
|
||||||
|
|
||||||
|
bFound = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}catch (SocketTimeoutException ex){
|
||||||
|
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '"+
|
||||||
|
tmpURL+"' ( time-out is"+TIMEOUT+" )", ex);
|
||||||
|
}catch (MalformedURLException ex){
|
||||||
|
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '"+
|
||||||
|
tmpURL+"'", ex);
|
||||||
|
}catch (UnknownHostException ex){
|
||||||
|
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '"+
|
||||||
|
tmpURL+"'", ex);
|
||||||
|
}catch (SSLPeerUnverifiedException ex){
|
||||||
|
Log.e(K9.LOG_TAG, "Error while testing settings", ex);
|
||||||
|
// TODO: use custom trust manager so this exception could get thrown
|
||||||
|
//acceptKeyDialog(R.string.account_setup_failed_dlg_certificate_message_fmt,i,ex);
|
||||||
|
}catch (SAXException e) {
|
||||||
|
setMessage(R.string.account_setup_autoconfig_fail,false);
|
||||||
|
bParseFailed = true;
|
||||||
|
}catch (ParserConfigurationException e) {
|
||||||
|
setMessage(R.string.account_setup_autoconfig_fail,false);
|
||||||
|
bParseFailed = true;
|
||||||
|
}catch (ErrorCodeException ex) {
|
||||||
|
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '" +
|
||||||
|
tmpURL + "' site didn't respond as expected. Got code: " + ex.getErrorCode(), ex);
|
||||||
|
}catch(IOException ex) {
|
||||||
|
Log.e(K9.LOG_TAG, "Error while attempting auto-configuration with url '"+
|
||||||
|
tmpURL+"'", ex);
|
||||||
|
} finally {
|
||||||
|
// might be the user cancelled by now or the app was destroyed
|
||||||
|
if (mDestroyed) return;
|
||||||
|
if (mCanceled) { finish(); return; }
|
||||||
|
|
||||||
|
// check next url
|
||||||
|
++templateIndex;
|
||||||
|
|
||||||
|
if( !bFound ) closeUserInformationIfNeeded(templateIndex-1);
|
||||||
|
|
||||||
|
// did parsing fail? tell user
|
||||||
|
if( bParseFailed )
|
||||||
|
setMessage(R.string.account_setup_autoconfig_trynext,true);
|
||||||
|
|
||||||
|
// this is the last domain to try in the list
|
||||||
|
if( templateIndex == urlTemplates.size()){
|
||||||
|
// we can still try DNS MX
|
||||||
|
if( mDomainAlternatives == null ){
|
||||||
|
try {
|
||||||
|
setMessage(R.string.account_setup_autoconfig_trydns, true);
|
||||||
|
mDomainAlternatives = getDomainPossibilities(doMXLookup(mDomain), mDomain);
|
||||||
|
if( mDomainAlternatives.size() > 0 )
|
||||||
|
setMessage(R.string.account_setup_autoconfig_found, false);
|
||||||
|
else
|
||||||
|
setMessage(R.string.account_setup_autoconfig_missing, false);
|
||||||
|
} catch (IOException e) {
|
||||||
|
mDomainAlternatives = new ArrayList<String>(); // setting empty list = no options left
|
||||||
|
setMessage(R.string.account_setup_autoconfig_missing, false);
|
||||||
|
Log.e(K9.LOG_TAG, "Error while getting DNS MX data in autoconfiguration", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// still domains remaining to try, restart whole lookup with new domain
|
||||||
|
if( mDomainAlternatives.size() > 0 ){
|
||||||
|
mDomain = mDomainAlternatives.get(0);
|
||||||
|
mDomainAlternatives.remove(0);
|
||||||
|
templateIndex = 0;
|
||||||
|
setMessage(R.string.account_setup_autoconfig_new_domain, true);
|
||||||
|
// out of options... manual configuration
|
||||||
|
}else{
|
||||||
|
bForceManual = true;
|
||||||
|
setMessage(R.string.account_setup_autoconfig_forcemanual, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remember we've searched already
|
||||||
|
bDoneSearching = true;
|
||||||
|
|
||||||
|
// update ui state
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
// hide progress circle & enable button for any case
|
||||||
|
mProgressCircle.setVisibility(View.INVISIBLE);
|
||||||
|
mNextButton.setEnabled(true);
|
||||||
|
|
||||||
|
// 1. All good, continue
|
||||||
|
// all is fine
|
||||||
|
|
||||||
|
// 2. Nothing came up, must manually config.. + help?
|
||||||
|
if( bForceManual ) mNextButton.setText(getString(R.string.account_setup_basics_manual_setup_action));
|
||||||
|
|
||||||
|
// 3. Data did not came over HTTPS this could be UNSAFE !!!!!!
|
||||||
|
if( bUnsafe ) mWarningMsg.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Small custom exception to pass http response codes around
|
Small custom exception to pass http response codes around
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user