Added status to server scan

pull/210/head
M66B 2 years ago
parent 5ff4db1f82
commit 9cd9032fe5

@ -360,13 +360,23 @@ public class EmailProvider implements Parcelable {
return result; return result;
} }
interface IDiscovery {
void onStatus(String status);
}
@NonNull @NonNull
static List<EmailProvider> fromDomain(Context context, String domain, Discover discover) throws IOException { static List<EmailProvider> fromDomain(Context context, String domain, Discover discover) throws IOException {
return fromEmail(context, domain, discover); return fromEmail(context, domain, discover,
new IDiscovery() {
@Override
public void onStatus(String status) {
// Do nothing
}
});
} }
@NonNull @NonNull
static List<EmailProvider> fromEmail(Context context, String email, Discover discover) throws IOException { static List<EmailProvider> fromEmail(Context context, String email, Discover discover, IDiscovery intf) throws IOException {
int at = email.indexOf('@'); int at = email.indexOf('@');
String domain = (at < 0 ? email : email.substring(at + 1)); String domain = (at < 0 ? email : email.substring(at + 1));
if (at < 0) if (at < 0)
@ -400,7 +410,7 @@ public class EmailProvider implements Parcelable {
} }
List<EmailProvider> candidates = List<EmailProvider> candidates =
new ArrayList<>(_fromDomain(context, domain.toLowerCase(Locale.ROOT), email, discover)); new ArrayList<>(_fromDomain(context, domain.toLowerCase(Locale.ROOT), email, discover, intf));
if (false) // Unsafe: the password could be sent to an unrelated email server if (false) // Unsafe: the password could be sent to an unrelated email server
try { try {
@ -421,7 +431,7 @@ public class EmailProvider implements Parcelable {
InetAddress ialt = InetAddress.getByName(altName); InetAddress ialt = InetAddress.getByName(altName);
if (!ialt.equals(iaddr)) { if (!ialt.equals(iaddr)) {
EntityLog.log(context, "Using website common name=" + altName); EntityLog.log(context, "Using website common name=" + altName);
candidates.addAll(_fromDomain(context, altName.toLowerCase(Locale.ROOT), email, discover)); candidates.addAll(_fromDomain(context, altName.toLowerCase(Locale.ROOT), email, discover, intf));
} }
} catch (Throwable ex) { } catch (Throwable ex) {
Log.w(ex); Log.w(ex);
@ -465,7 +475,7 @@ public class EmailProvider implements Parcelable {
} }
while (candidates.size() == 0 && target.indexOf('.') > 0) { while (candidates.size() == 0 && target.indexOf('.') > 0) {
candidates.addAll(_fromDomain(context, target, email, discover)); candidates.addAll(_fromDomain(context, target, email, discover, intf));
int dot = target.indexOf('.'); int dot = target.indexOf('.');
target = target.substring(dot + 1); target = target.substring(dot + 1);
if (UriHelper.isTld(context, target)) if (UriHelper.isTld(context, target))
@ -565,13 +575,13 @@ public class EmailProvider implements Parcelable {
} }
@NonNull @NonNull
private static List<EmailProvider> _fromDomain(Context context, String domain, String email, Discover discover) { private static List<EmailProvider> _fromDomain(Context context, String domain, String email, Discover discover, IDiscovery intf) {
List<EmailProvider> result = new ArrayList<>(); List<EmailProvider> result = new ArrayList<>();
try { try {
// Assume the provider knows best // Assume the provider knows best
Log.i("Provider from DNS domain=" + domain); Log.i("Provider from DNS domain=" + domain);
result.add(fromDNS(context, domain, discover)); result.add(fromDNS(context, domain, discover, intf));
} catch (Throwable ex) { } catch (Throwable ex) {
Log.w(ex); Log.w(ex);
} }
@ -579,7 +589,7 @@ public class EmailProvider implements Parcelable {
try { try {
// Check ISPDB // Check ISPDB
Log.i("Provider from ISPDB domain=" + domain); Log.i("Provider from ISPDB domain=" + domain);
result.add(fromISPDB(context, domain, email)); result.add(fromISPDB(context, domain, email, intf));
} catch (Throwable ex) { } catch (Throwable ex) {
Log.w(ex); Log.w(ex);
} }
@ -587,7 +597,7 @@ public class EmailProvider implements Parcelable {
try { try {
// Scan ports // Scan ports
Log.i("Provider from scan domain=" + domain); Log.i("Provider from scan domain=" + domain);
result.add(fromScan(context, domain, discover)); result.add(fromScan(context, domain, discover, intf));
} catch (Throwable ex) { } catch (Throwable ex) {
Log.w(ex); Log.w(ex);
} }
@ -596,27 +606,28 @@ public class EmailProvider implements Parcelable {
} }
@NonNull @NonNull
private static EmailProvider fromISPDB(Context context, String domain, String email) throws Throwable { private static EmailProvider fromISPDB(Context context, String domain, String email, IDiscovery intf) throws Throwable {
// https://wiki.mozilla.org/Thunderbird:Autoconfiguration // https://wiki.mozilla.org/Thunderbird:Autoconfiguration
for (String link : Misc.getISPDBUrls(domain, email)) for (String link : Misc.getISPDBUrls(domain, email))
try { try {
URL url = new URL(link); URL url = new URL(link);
return getISPDB(context, domain, url); return getISPDB(context, domain, url, intf);
} catch (Throwable ex) { } catch (Throwable ex) {
Log.i(ex); Log.i(ex);
} }
URL url = new URL("https://autoconfig.thunderbird.net/v1.1/" + domain); URL url = new URL("https://autoconfig.thunderbird.net/v1.1/" + domain);
return getISPDB(context, domain, url); return getISPDB(context, domain, url, intf);
} }
@NonNull @NonNull
private static EmailProvider getISPDB(Context context, String domain, URL url) throws IOException, XmlPullParserException { private static EmailProvider getISPDB(Context context, String domain, URL url, IDiscovery intf) throws IOException, XmlPullParserException {
EmailProvider provider = new EmailProvider(domain); EmailProvider provider = new EmailProvider(domain);
HttpURLConnection request = null; HttpURLConnection request = null;
try { try {
Log.i("Fetching " + url); Log.i("Fetching " + url);
intf.onStatus(url.toString());
request = (HttpURLConnection) url.openConnection(); request = (HttpURLConnection) url.openConnection();
request.setRequestMethod("GET"); request.setRequestMethod("GET");
@ -805,14 +816,16 @@ public class EmailProvider implements Parcelable {
} }
@NonNull @NonNull
private static EmailProvider fromDNS(Context context, String domain, Discover discover) throws UnknownHostException { private static EmailProvider fromDNS(Context context, String domain, Discover discover, IDiscovery intf) throws UnknownHostException {
// https://tools.ietf.org/html/rfc6186 // https://tools.ietf.org/html/rfc6186
EmailProvider provider = new EmailProvider(domain); EmailProvider provider = new EmailProvider(domain);
if (discover == Discover.ALL || discover == Discover.IMAP) { if (discover == Discover.ALL || discover == Discover.IMAP) {
try { try {
// Identifies an IMAP server where TLS is initiated directly upon connection to the IMAP server. // Identifies an IMAP server where TLS is initiated directly upon connection to the IMAP server.
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_imaps._tcp." + domain, "srv"); String name = "_imaps._tcp." + domain;
intf.onStatus(name);
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, name, "srv");
if (records.length == 0) if (records.length == 0)
throw new UnknownHostException(domain); throw new UnknownHostException(domain);
// ... service is not supported at all at a particular domain by setting the target of an SRV RR to "." // ... service is not supported at all at a particular domain by setting the target of an SRV RR to "."
@ -837,7 +850,9 @@ public class EmailProvider implements Parcelable {
if (discover == Discover.ALL || discover == Discover.SMTP) if (discover == Discover.ALL || discover == Discover.SMTP)
try { try {
// Note that this covers connections both with and without Transport Layer Security (TLS) // Note that this covers connections both with and without Transport Layer Security (TLS)
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, "_submission._tcp." + domain, "srv"); String name = "_submission._tcp." + domain;
intf.onStatus(name);
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, name, "srv");
if (records.length == 0) if (records.length == 0)
throw new UnknownHostException(domain); throw new UnknownHostException(domain);
provider.smtp.score = 50; provider.smtp.score = 50;
@ -863,7 +878,7 @@ public class EmailProvider implements Parcelable {
} }
@NonNull @NonNull
private static EmailProvider fromScan(Context context, String domain, Discover discover) private static EmailProvider fromScan(Context context, String domain, Discover discover, IDiscovery intf)
throws ExecutionException, InterruptedException, UnknownHostException { throws ExecutionException, InterruptedException, UnknownHostException {
// https://tools.ietf.org/html/rfc8314 // https://tools.ietf.org/html/rfc8314
Server imap = null; Server imap = null;
@ -885,6 +900,7 @@ public class EmailProvider implements Parcelable {
Server untrusted = null; Server untrusted = null;
for (Server server : imaps) { for (Server server : imaps) {
intf.onStatus(server.toString());
Boolean result = server.isReachable.get(); Boolean result = server.isReachable.get();
if (result == null) { if (result == null) {
if (untrusted == null) if (untrusted == null)
@ -918,6 +934,7 @@ public class EmailProvider implements Parcelable {
Server untrusted = null; Server untrusted = null;
for (Server server : smtps) { for (Server server : smtps) {
intf.onStatus(server.toString());
Boolean result = server.isReachable.get(); Boolean result = server.isReachable.get();
if (result == null) { if (result == null) {
if (untrusted == null) if (untrusted == null)

@ -76,6 +76,7 @@ public class FragmentQuickSetup extends FragmentBase {
private Button btnCheck; private Button btnCheck;
private ContentLoadingProgressBar pbCheck; private ContentLoadingProgressBar pbCheck;
private TextView tvPatience; private TextView tvPatience;
private TextView tvProgress;
private TextView tvError; private TextView tvError;
private TextView tvErrorHint; private TextView tvErrorHint;
@ -141,6 +142,7 @@ public class FragmentQuickSetup extends FragmentBase {
btnCheck = view.findViewById(R.id.btnCheck); btnCheck = view.findViewById(R.id.btnCheck);
pbCheck = view.findViewById(R.id.pbCheck); pbCheck = view.findViewById(R.id.pbCheck);
tvPatience = view.findViewById(R.id.tvPatience); tvPatience = view.findViewById(R.id.tvPatience);
tvProgress = view.findViewById(R.id.tvProgress);
tvError = view.findViewById(R.id.tvError); tvError = view.findViewById(R.id.tvError);
tvErrorHint = view.findViewById(R.id.tvErrorHint); tvErrorHint = view.findViewById(R.id.tvErrorHint);
@ -248,6 +250,7 @@ public class FragmentQuickSetup extends FragmentBase {
tvSmtpFingerprint.setText(null); tvSmtpFingerprint.setText(null);
pbCheck.setVisibility(View.GONE); pbCheck.setVisibility(View.GONE);
tvPatience.setVisibility(View.GONE); tvPatience.setVisibility(View.GONE);
tvProgress.setVisibility(View.GONE);
pbSave.setVisibility(View.GONE); pbSave.setVisibility(View.GONE);
tvInstructions.setVisibility(View.GONE); tvInstructions.setVisibility(View.GONE);
tvInstructions.setMovementMethod(LinkMovementMethod.getInstance()); tvInstructions.setMovementMethod(LinkMovementMethod.getInstance());
@ -302,6 +305,7 @@ public class FragmentQuickSetup extends FragmentBase {
Helper.setViewsEnabled(view, true); Helper.setViewsEnabled(view, true);
pbCheck.setVisibility(View.GONE); pbCheck.setVisibility(View.GONE);
tvPatience.setVisibility(View.GONE); tvPatience.setVisibility(View.GONE);
tvProgress.setVisibility(View.GONE);
pbSave.setVisibility(View.GONE); pbSave.setVisibility(View.GONE);
} }
@ -333,13 +337,20 @@ public class FragmentQuickSetup extends FragmentBase {
Throwable fail = null; Throwable fail = null;
List<EmailProvider> providers; List<EmailProvider> providers;
if (best == null) if (best == null)
providers = EmailProvider.fromEmail(context, email, EmailProvider.Discover.ALL); providers = EmailProvider.fromEmail(context, email, EmailProvider.Discover.ALL,
new EmailProvider.IDiscovery() {
@Override
public void onStatus(String status) {
postProgress(status);
}
});
else else
providers = Arrays.asList(best); providers = Arrays.asList(best);
for (EmailProvider provider : providers) for (EmailProvider provider : providers)
try { try {
EntityLog.log(context, "Checking" + EntityLog.log(context, "Checking" +
" imap=" + provider.imap + " smtp=" + provider.smtp); " imap=" + provider.imap + " smtp=" + provider.smtp);
postProgress(provider.imap + "/" + provider.smtp);
if (fail == null) if (fail == null)
args.putParcelable("provider", provider); args.putParcelable("provider", provider);
@ -621,6 +632,12 @@ public class FragmentQuickSetup extends FragmentBase {
return null; return null;
} }
@Override
protected void onProgress(CharSequence status, Bundle data) {
tvProgress.setText(status);
tvProgress.setVisibility(View.VISIBLE);
}
@Override @Override
protected void onExecuted(Bundle args, EmailProvider result) { protected void onExecuted(Bundle args, EmailProvider result) {
setManual(false); setManual(false);

@ -30,10 +30,10 @@
android:layout_marginTop="6dp" android:layout_marginTop="6dp"
android:drawableEnd="@drawable/twotone_open_in_new_12" android:drawableEnd="@drawable/twotone_open_in_new_12"
android:drawablePadding="6dp" android:drawablePadding="6dp"
app:drawableTint="?android:attr/textColorLink"
android:text="@string/title_privacy_policy" android:text="@string/title_privacy_policy"
android:textAppearance="@style/TextAppearance.AppCompat.Small" android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textColor="?android:attr/textColorLink" android:textColor="?android:attr/textColorLink"
app:drawableTint="?android:attr/textColorLink"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvTitle" /> app:layout_constraintTop_toBottomOf="@id/tvTitle" />
@ -143,6 +143,16 @@
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btnCheck" /> app:layout_constraintTop_toBottomOf="@id/btnCheck" />
<TextView
android:id="@+id/tvProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="Progress"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvPatience" />
<TextView <TextView
android:id="@+id/tvErrorTitle" android:id="@+id/tvErrorTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -152,7 +162,7 @@
android:textAppearance="@style/TextAppearance.AppCompat.Medium" android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:textStyle="bold" android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvPatience" /> app:layout_constraintTop_toBottomOf="@id/tvProgress" />
<TextView <TextView
android:id="@+id/tvError" android:id="@+id/tvError"
@ -210,10 +220,10 @@
android:backgroundTint="?attr/colorInfoBackground" android:backgroundTint="?attr/colorInfoBackground"
android:drawableEnd="@drawable/twotone_support_24" android:drawableEnd="@drawable/twotone_support_24"
android:drawablePadding="6dp" android:drawablePadding="6dp"
app:drawableTint="?attr/colorInfoForeground"
android:text="@string/menu_faq" android:text="@string/menu_faq"
android:textColor="?attr/colorInfoForeground" android:textColor="?attr/colorInfoForeground"
android:textStyle="bold" android:textStyle="bold"
app:drawableTint="?attr/colorInfoForeground"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvInstructions" /> app:layout_constraintTop_toBottomOf="@id/tvInstructions" />
@ -225,10 +235,10 @@
android:backgroundTint="?attr/colorInfoBackground" android:backgroundTint="?attr/colorInfoBackground"
android:drawableEnd="@drawable/twotone_help_24" android:drawableEnd="@drawable/twotone_help_24"
android:drawablePadding="6dp" android:drawablePadding="6dp"
app:drawableTint="?attr/colorInfoForeground"
android:text="@string/title_setup_help" android:text="@string/title_setup_help"
android:textColor="?attr/colorInfoForeground" android:textColor="?attr/colorInfoForeground"
android:textStyle="bold" android:textStyle="bold"
app:drawableTint="?attr/colorInfoForeground"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvInstructions" /> app:layout_constraintTop_toBottomOf="@id/tvInstructions" />

Loading…
Cancel
Save