Scan+score

This commit is contained in:
M66B
2021-08-16 21:14:25 +02:00
parent 9a09474c3a
commit a215bcf6e8
3 changed files with 76 additions and 64 deletions

View File

@@ -320,7 +320,6 @@ public class EmailProvider implements Parcelable {
}
}
}
} catch (Throwable ex) {
Log.w(ex);
}
@@ -338,22 +337,36 @@ public class EmailProvider implements Parcelable {
EntityLog.log(context, "Replacing auto config by profile=" + provider.name);
return Arrays.asList(provider);
}
// https://help.dreamhost.com/hc/en-us/articles/214918038-Email-client-configuration-overview
if (autoconfig.imap.host != null &&
autoconfig.imap.host.endsWith(".dreamhost.com"))
autoconfig.imap.host = "imap.dreamhost.com";
if (autoconfig.smtp.host != null &&
autoconfig.smtp.host.endsWith(".dreamhost.com"))
autoconfig.smtp.host = "smtp.dreamhost.com";
// https://docs.aws.amazon.com/workmail/latest/userguide/using_IMAP_client.html
if (autoconfig.imap.host != null &&
autoconfig.imap.host.endsWith(".awsapps.com"))
autoconfig.partial = false;
}
Collections.sort(providers, new Comparator<EmailProvider>() {
@Override
public int compare(EmailProvider p1, EmailProvider p2) {
return -Integer.compare(p1.getScore(), p2.getScore());
}
});
for (EmailProvider autoconfig : result) {
EntityLog.log(context, "Provider" +
" score=" + autoconfig.getScore() +
" imap=" + autoconfig.imap +
" smtp=" + autoconfig.smtp);
// https://help.dreamhost.com/hc/en-us/articles/214918038-Email-client-configuration-overview
if (autoconfig.imap.host != null &&
autoconfig.imap.host.endsWith(".dreamhost.com"))
autoconfig.imap.host = "imap.dreamhost.com";
if (autoconfig.smtp.host != null &&
autoconfig.smtp.host.endsWith(".dreamhost.com"))
autoconfig.smtp.host = "smtp.dreamhost.com";
// https://docs.aws.amazon.com/workmail/latest/userguide/using_IMAP_client.html
if (autoconfig.imap.host != null &&
autoconfig.imap.host.endsWith(".awsapps.com"))
autoconfig.partial = false;
}
return result;
}
@@ -611,6 +624,7 @@ public class EmailProvider implements Parcelable {
provider.imap.host = records[0].name;
provider.imap.port = records[0].port;
provider.imap.starttls = false;
provider.imap.checkCertificate(context);
EntityLog.log(context, "_imaps._tcp." + domain + "=" + provider.imap);
} catch (UnknownHostException ignored) {
// Identifies an IMAP server that MAY ... require the MUA to use the "STARTTLS" command
@@ -620,6 +634,7 @@ public class EmailProvider implements Parcelable {
provider.imap.host = records[0].name;
provider.imap.port = records[0].port;
provider.imap.starttls = (provider.imap.port == 143);
provider.imap.checkCertificate(context);
EntityLog.log(context, "_imap._tcp." + domain + "=" + provider.imap);
}
}
@@ -633,6 +648,7 @@ public class EmailProvider implements Parcelable {
provider.smtp.host = records[0].name;
provider.smtp.port = records[0].port;
provider.smtp.starttls = (provider.smtp.port == 587);
provider.smtp.checkCertificate(context);
EntityLog.log(context, "_submission._tcp." + domain + "=" + provider.smtp);
} catch (UnknownHostException ignored) {
// https://tools.ietf.org/html/rfc8314
@@ -642,6 +658,7 @@ public class EmailProvider implements Parcelable {
provider.smtp.host = records[0].name;
provider.smtp.port = records[0].port;
provider.smtp.starttls = false;
provider.smtp.checkCertificate(context);
EntityLog.log(context, "_submissions._tcp." + domain + "=" + provider.smtp);
}
@@ -808,6 +825,12 @@ public class EmailProvider implements Parcelable {
}
};
private int getScore() {
if (imap == null || smtp == null)
return -1;
return imap.score + smtp.score;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof EmailProvider) {
@@ -834,6 +857,7 @@ public class EmailProvider implements Parcelable {
public int port;
public boolean starttls;
private int score = 0;
private Future<Boolean> isReachable;
private Server() {
@@ -843,9 +867,20 @@ public class EmailProvider implements Parcelable {
this.host = (prefix == null ? "" : prefix + ".") + domain;
this.port = port;
this.starttls = starttls;
this.isReachable = getReachable(context);
}
private void checkCertificate(Context context) {
try {
getReachable(context).get();
} catch (Throwable ex) {
Log.e(ex);
}
}
private Future<Boolean> getReachable(Context context) {
Log.i("Scanning " + this);
this.isReachable = executor.submit(new Callable<Boolean>() {
return executor.submit(new Callable<Boolean>() {
// Returns:
// false: closed
// true: listening
@@ -881,10 +916,28 @@ public class EmailProvider implements Parcelable {
List<String> names = EntityCertificate.getDnsNames((X509Certificate) cert);
EntityLog.log(context, "Certificate " + address +
" " + TextUtils.join(",", names));
if (EntityCertificate.matches(host, names)) {
score += 2;
EntityLog.log(context, "Trusted " + address);
return true;
}
for (String name : names)
try {
String similar = name;
if (similar.startsWith("*."))
similar = similar.substring(2);
InetAddress isimilar = InetAddress.getByName(similar);
if (iaddr.equals(isimilar)) {
score += 1;
EntityLog.log(context, "Similar " + similar + " host=" + host);
host = similar;
return true;
}
} catch (Throwable ex) {
Log.w(ex);
}
}
EntityLog.log(context, "Untrusted " + address);