mirror of https://github.com/M66B/FairEmail.git
Added multi discovery
This commit is contained in:
parent
7eba0d82c0
commit
9a09474c3a
|
@ -57,6 +57,7 @@ import java.util.Collections;
|
|||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
@ -241,12 +242,12 @@ public class EmailProvider implements Parcelable {
|
|||
}
|
||||
|
||||
@NonNull
|
||||
static 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);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
static EmailProvider fromEmail(Context context, String email, Discover discover) throws IOException {
|
||||
static List<EmailProvider> fromEmail(Context context, String email, Discover discover) throws IOException {
|
||||
int at = email.indexOf('@');
|
||||
String domain = (at < 0 ? email : email.substring(at + 1));
|
||||
if (at < 0)
|
||||
|
@ -258,130 +259,133 @@ public class EmailProvider implements Parcelable {
|
|||
if (PROPRIETARY.contains(domain))
|
||||
throw new IllegalArgumentException(context.getString(R.string.title_no_standard));
|
||||
|
||||
if (BuildConfig.DEBUG && false)
|
||||
try {
|
||||
// Scan ports
|
||||
EntityLog.log(context, "Provider from template domain=" + domain);
|
||||
return fromTemplate(context, domain, discover);
|
||||
} catch (Throwable ex) {
|
||||
Log.w(ex);
|
||||
throw new UnknownHostException(context.getString(R.string.title_setup_no_settings, domain));
|
||||
}
|
||||
|
||||
List<EmailProvider> providers = loadProfiles(context);
|
||||
for (EmailProvider provider : providers)
|
||||
if (provider.domain != null)
|
||||
for (String d : provider.domain)
|
||||
if (domain.toLowerCase(Locale.ROOT).matches(d)) {
|
||||
EntityLog.log(context, "Provider from domain=" + domain + " (" + d + ")");
|
||||
provider.log(context);
|
||||
return provider;
|
||||
return Arrays.asList(provider);
|
||||
}
|
||||
|
||||
EmailProvider autoconfig = null;
|
||||
List<EmailProvider> result = new ArrayList<>();
|
||||
for (EmailProvider provider : _fromDomain(context, domain.toLowerCase(Locale.ROOT), email, discover))
|
||||
if (result.contains(provider))
|
||||
Log.i("Duplicate " + provider);
|
||||
else
|
||||
result.add(provider);
|
||||
|
||||
try {
|
||||
autoconfig = _fromDomain(context, domain.toLowerCase(Locale.ROOT), email, discover);
|
||||
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, domain, "mx");
|
||||
|
||||
for (DnsHelper.DnsRecord record : records)
|
||||
if (!TextUtils.isEmpty(record.name))
|
||||
for (EmailProvider provider : providers) {
|
||||
if (provider.mx != null)
|
||||
for (String mx : provider.mx)
|
||||
if (record.name.toLowerCase(Locale.ROOT).matches(mx)) {
|
||||
EntityLog.log(context, "Provider from mx=" + record.name + " domain=" + domain);
|
||||
if (result.contains(provider))
|
||||
Log.i("Duplicate " + provider);
|
||||
else
|
||||
result.add(provider);
|
||||
break;
|
||||
}
|
||||
|
||||
String mxparent = UriHelper.getParentDomain(context, record.name);
|
||||
String pdomain = UriHelper.getParentDomain(context, provider.imap.host);
|
||||
if (mxparent.equalsIgnoreCase(pdomain)) {
|
||||
EntityLog.log(context, "Provider from mx=" + record.name + " host=" + provider.imap.host);
|
||||
if (result.contains(provider))
|
||||
Log.i("Duplicate " + provider);
|
||||
else
|
||||
result.add(provider);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (DnsHelper.DnsRecord record : records) {
|
||||
String target = record.name;
|
||||
while (result.size() == 0 && target != null && target.indexOf('.') > 0) {
|
||||
try {
|
||||
for (EmailProvider provider : _fromDomain(context, target.toLowerCase(Locale.ROOT), email, discover))
|
||||
if (result.contains(provider))
|
||||
Log.i("Duplicate " + provider);
|
||||
else
|
||||
result.add(provider);
|
||||
} catch (Throwable ex) {
|
||||
Log.w(ex);
|
||||
int dot = target.indexOf('.');
|
||||
target = target.substring(dot + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Throwable ex) {
|
||||
Log.w(ex);
|
||||
|
||||
try {
|
||||
// Retry at MX server addresses
|
||||
DnsHelper.DnsRecord[] records = DnsHelper.lookup(context, domain, "mx");
|
||||
|
||||
for (DnsHelper.DnsRecord record : records)
|
||||
if (!TextUtils.isEmpty(record.name))
|
||||
for (EmailProvider provider : providers) {
|
||||
if (provider.mx != null)
|
||||
for (String mx : provider.mx)
|
||||
if (record.name.toLowerCase(Locale.ROOT).matches(mx)) {
|
||||
EntityLog.log(context, "Provider from mx=" + record.name + " domain=" + domain);
|
||||
provider.log(context);
|
||||
return provider;
|
||||
}
|
||||
|
||||
String mxparent = UriHelper.getParentDomain(context, record.name);
|
||||
String pdomain = UriHelper.getParentDomain(context, provider.imap.host);
|
||||
if (mxparent.equalsIgnoreCase(pdomain)) {
|
||||
EntityLog.log(context, "Provider from mx=" + record.name + " host=" + provider.imap.host);
|
||||
provider.log(context);
|
||||
return provider;
|
||||
}
|
||||
}
|
||||
|
||||
for (DnsHelper.DnsRecord record : records) {
|
||||
String target = record.name;
|
||||
while (autoconfig == null && target != null && target.indexOf('.') > 0) {
|
||||
try {
|
||||
autoconfig = _fromDomain(context, target.toLowerCase(Locale.ROOT), email, discover);
|
||||
} catch (Throwable ex1) {
|
||||
Log.w(ex1);
|
||||
int dot = target.indexOf('.');
|
||||
target = target.substring(dot + 1);
|
||||
}
|
||||
}
|
||||
if (autoconfig != null)
|
||||
break;
|
||||
}
|
||||
} catch (Throwable ex1) {
|
||||
Log.w(ex1);
|
||||
}
|
||||
|
||||
if (autoconfig == null)
|
||||
throw ex;
|
||||
}
|
||||
|
||||
// Always prefer built-in profiles
|
||||
// - ISPDB is not always correct
|
||||
// - documentation links
|
||||
for (EmailProvider provider : providers)
|
||||
if (provider.imap.host.equals(autoconfig.imap.host) ||
|
||||
provider.smtp.host.equals(autoconfig.smtp.host)) {
|
||||
EntityLog.log(context, "Replacing auto config by profile=" + provider.name);
|
||||
provider.log(context);
|
||||
return provider;
|
||||
if (result.size() == 0)
|
||||
throw new UnknownHostException(context.getString(R.string.title_setup_no_settings, domain));
|
||||
|
||||
for (EmailProvider autoconfig : result)
|
||||
for (EmailProvider provider : providers) {
|
||||
// Always prefer built-in profiles
|
||||
// - ISPDB is not always correct
|
||||
// - documentation links
|
||||
if (provider.imap.host.equals(autoconfig.imap.host) ||
|
||||
provider.smtp.host.equals(autoconfig.smtp.host)) {
|
||||
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;
|
||||
}
|
||||
|
||||
// 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 autoconfig;
|
||||
return result;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static EmailProvider _fromDomain(Context context, String domain, String email, Discover discover) throws IOException {
|
||||
private static List<EmailProvider> _fromDomain(Context context, String domain, String email, Discover discover) throws IOException {
|
||||
List<EmailProvider> result = new ArrayList<>();
|
||||
|
||||
try {
|
||||
// Assume the provider knows best
|
||||
Log.i("Provider from DNS domain=" + domain);
|
||||
return fromDNS(context, domain, discover);
|
||||
result.add(fromDNS(context, domain, discover));
|
||||
} catch (Throwable ex) {
|
||||
Log.w(ex);
|
||||
try {
|
||||
// Check ISPDB
|
||||
Log.i("Provider from ISPDB domain=" + domain);
|
||||
return fromISPDB(context, domain, email);
|
||||
} catch (Throwable ex1) {
|
||||
Log.w(ex1);
|
||||
try {
|
||||
// Scan ports
|
||||
Log.i("Provider from template domain=" + domain);
|
||||
return fromTemplate(context, domain, discover);
|
||||
} catch (Throwable ex2) {
|
||||
Log.w(ex2);
|
||||
throw new UnknownHostException(context.getString(R.string.title_setup_no_settings, domain));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Check ISPDB
|
||||
Log.i("Provider from ISPDB domain=" + domain);
|
||||
result.add(fromISPDB(context, domain, email));
|
||||
} catch (Throwable ex) {
|
||||
Log.w(ex);
|
||||
}
|
||||
|
||||
try {
|
||||
// Scan ports
|
||||
Log.i("Provider from template domain=" + domain);
|
||||
result.add(fromScan(context, domain, discover));
|
||||
} catch (Throwable ex) {
|
||||
Log.w(ex);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -584,7 +588,6 @@ public class EmailProvider implements Parcelable {
|
|||
}
|
||||
|
||||
provider.validate();
|
||||
provider.log(context);
|
||||
|
||||
return provider;
|
||||
} finally {
|
||||
|
@ -643,13 +646,12 @@ public class EmailProvider implements Parcelable {
|
|||
}
|
||||
|
||||
provider.validate();
|
||||
provider.log(context);
|
||||
|
||||
return provider;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private static EmailProvider fromTemplate(Context context, String domain, Discover discover)
|
||||
private static EmailProvider fromScan(Context context, String domain, Discover discover)
|
||||
throws ExecutionException, InterruptedException, UnknownHostException {
|
||||
// https://tools.ietf.org/html/rfc8314
|
||||
Server imap = null;
|
||||
|
@ -731,7 +733,6 @@ public class EmailProvider implements Parcelable {
|
|||
if (smtp != null)
|
||||
provider.smtp = smtp;
|
||||
|
||||
provider.log(context);
|
||||
return provider;
|
||||
}
|
||||
|
||||
|
@ -744,11 +745,6 @@ public class EmailProvider implements Parcelable {
|
|||
provider.documentation.append("<a href=\"").append(href).append("\">").append(title).append("</a>");
|
||||
}
|
||||
|
||||
private void log(Context context) {
|
||||
EntityLog.log(context, "imap=" + imap);
|
||||
EntityLog.log(context, "smtp=" + smtp);
|
||||
}
|
||||
|
||||
protected EmailProvider(Parcel in) {
|
||||
if (in.readInt() == 0)
|
||||
imap = null;
|
||||
|
@ -812,6 +808,21 @@ public class EmailProvider implements Parcelable {
|
|||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof EmailProvider) {
|
||||
EmailProvider other = (EmailProvider) obj;
|
||||
return (Objects.equals(this.imap, other.imap) &&
|
||||
Objects.equals(this.smtp, other.smtp));
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(imap, smtp);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
|
@ -986,6 +997,22 @@ public class EmailProvider implements Parcelable {
|
|||
throw new SocketException("No STARTTLS");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Server) {
|
||||
Server other = (Server) obj;
|
||||
return (Objects.equals(this.host, other.host) &&
|
||||
this.port == other.port &&
|
||||
this.starttls == other.starttls);
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(host, port, starttls);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String toString() {
|
||||
|
|
|
@ -591,7 +591,9 @@ public class FragmentAccount extends FragmentBase {
|
|||
@Override
|
||||
protected EmailProvider onExecute(Context context, Bundle args) throws Throwable {
|
||||
String domain = args.getString("domain");
|
||||
return EmailProvider.fromDomain(context, domain, EmailProvider.Discover.IMAP);
|
||||
return EmailProvider
|
||||
.fromDomain(context, domain, EmailProvider.Discover.IMAP)
|
||||
.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -413,7 +413,9 @@ public class FragmentGmail extends FragmentBase {
|
|||
int at = user.indexOf('@');
|
||||
String username = user.substring(0, at);
|
||||
|
||||
EmailProvider provider = EmailProvider.fromDomain(context, "gmail.com", EmailProvider.Discover.ALL);
|
||||
EmailProvider provider = EmailProvider
|
||||
.fromDomain(context, "gmail.com", EmailProvider.Discover.ALL)
|
||||
.get(0);
|
||||
|
||||
List<EntityFolder> folders;
|
||||
|
||||
|
|
|
@ -584,7 +584,9 @@ public class FragmentIdentity extends FragmentBase {
|
|||
@Override
|
||||
protected EmailProvider onExecute(Context context, Bundle args) throws Throwable {
|
||||
String domain = args.getString("domain");
|
||||
return EmailProvider.fromDomain(context, domain, EmailProvider.Discover.SMTP);
|
||||
return EmailProvider
|
||||
.fromDomain(context, domain, EmailProvider.Discover.SMTP)
|
||||
.get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -277,208 +277,223 @@ public class FragmentQuickSetup extends FragmentBase {
|
|||
if (TextUtils.isEmpty(password))
|
||||
throw new IllegalArgumentException(context.getString(R.string.title_no_password));
|
||||
|
||||
int at = email.indexOf('@');
|
||||
String username = email.substring(0, at);
|
||||
|
||||
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
NetworkInfo ani = (cm == null ? null : cm.getActiveNetworkInfo());
|
||||
if (ani == null || !ani.isConnected())
|
||||
throw new IllegalArgumentException(context.getString(R.string.title_no_internet));
|
||||
|
||||
EmailProvider provider = EmailProvider.fromEmail(context, email, EmailProvider.Discover.ALL);
|
||||
args.putParcelable("provider", provider);
|
||||
|
||||
int at = email.indexOf('@');
|
||||
String username = email.substring(0, at);
|
||||
|
||||
String user = (provider.user == EmailProvider.UserType.EMAIL ? email : username);
|
||||
Log.i("User type=" + provider.user + " name=" + user);
|
||||
|
||||
List<EntityFolder> folders;
|
||||
String imap_fingerprint = null;
|
||||
String smtp_fingerprint = null;
|
||||
X509Certificate imap_certificate = null;
|
||||
X509Certificate smtp_certificate = null;
|
||||
|
||||
String aprotocol = (provider.imap.starttls ? "imap" : "imaps");
|
||||
int aencryption = (provider.imap.starttls ? EmailService.ENCRYPTION_STARTTLS : EmailService.ENCRYPTION_SSL);
|
||||
try (EmailService iservice = new EmailService(
|
||||
context, aprotocol, null, aencryption, false, EmailService.PURPOSE_CHECK, true)) {
|
||||
Throwable fail = null;
|
||||
List<EmailProvider> providers = EmailProvider.fromEmail(context, email, EmailProvider.Discover.ALL);
|
||||
for (EmailProvider provider : providers)
|
||||
try {
|
||||
iservice.connect(
|
||||
provider.imap.host, provider.imap.port,
|
||||
AUTH_TYPE_PASSWORD, null,
|
||||
user, password,
|
||||
null, null);
|
||||
} catch (EmailService.UntrustedException ex) {
|
||||
imap_certificate = ex.getCertificate();
|
||||
String similar = EntityCertificate.getSimilarDnsName(imap_certificate, provider.imap.host);
|
||||
if (similar == null)
|
||||
imap_fingerprint = EntityCertificate.getKeyFingerprint(imap_certificate);
|
||||
else
|
||||
provider.imap.host = similar;
|
||||
iservice.connect(
|
||||
provider.imap.host, provider.imap.port,
|
||||
AUTH_TYPE_PASSWORD, null,
|
||||
user, password,
|
||||
null, imap_fingerprint);
|
||||
} catch (Throwable ex) {
|
||||
Log.w(ex);
|
||||
// Why not AuthenticationFailedException?
|
||||
// Some providers terminate the connection with an invalid username
|
||||
if (user.equals(username))
|
||||
throw ex;
|
||||
else
|
||||
EntityLog.log(context, "imap=" + provider.imap);
|
||||
EntityLog.log(context, "smtp=" + provider.smtp);
|
||||
|
||||
String user = (provider.user == EmailProvider.UserType.EMAIL ? email : username);
|
||||
Log.i("User type=" + provider.user + " name=" + user);
|
||||
|
||||
List<EntityFolder> folders;
|
||||
String imap_fingerprint = null;
|
||||
String smtp_fingerprint = null;
|
||||
X509Certificate imap_certificate = null;
|
||||
X509Certificate smtp_certificate = null;
|
||||
|
||||
String aprotocol = (provider.imap.starttls ? "imap" : "imaps");
|
||||
int aencryption = (provider.imap.starttls ? EmailService.ENCRYPTION_STARTTLS : EmailService.ENCRYPTION_SSL);
|
||||
try (EmailService iservice = new EmailService(
|
||||
context, aprotocol, null, aencryption, false, EmailService.PURPOSE_CHECK, true)) {
|
||||
try {
|
||||
user = username;
|
||||
Log.i("Retry with user=" + user);
|
||||
iservice.connect(
|
||||
provider.imap.host, provider.imap.port,
|
||||
AUTH_TYPE_PASSWORD, null,
|
||||
user, password,
|
||||
null, null);
|
||||
} catch (Throwable ex1) {
|
||||
Log.w(ex1);
|
||||
if (!(ex instanceof AuthenticationFailedException) &&
|
||||
ex1 instanceof AuthenticationFailedException)
|
||||
throw ex1;
|
||||
} catch (EmailService.UntrustedException ex) {
|
||||
imap_certificate = ex.getCertificate();
|
||||
String similar = EntityCertificate.getSimilarDnsName(imap_certificate, provider.imap.host);
|
||||
if (similar == null)
|
||||
imap_fingerprint = EntityCertificate.getKeyFingerprint(imap_certificate);
|
||||
else
|
||||
provider.imap.host = similar;
|
||||
iservice.connect(
|
||||
provider.imap.host, provider.imap.port,
|
||||
AUTH_TYPE_PASSWORD, null,
|
||||
user, password,
|
||||
null, imap_fingerprint);
|
||||
} catch (Throwable ex) {
|
||||
Log.w(ex);
|
||||
// Why not AuthenticationFailedException?
|
||||
// Some providers terminate the connection with an invalid username
|
||||
if (user.equals(username))
|
||||
throw ex;
|
||||
else
|
||||
try {
|
||||
user = username;
|
||||
Log.i("Retry with user=" + user);
|
||||
iservice.connect(
|
||||
provider.imap.host, provider.imap.port,
|
||||
AUTH_TYPE_PASSWORD, null,
|
||||
user, password,
|
||||
null, null);
|
||||
} catch (Throwable ex1) {
|
||||
Log.w(ex1);
|
||||
if (!(ex instanceof AuthenticationFailedException) &&
|
||||
ex1 instanceof AuthenticationFailedException)
|
||||
throw ex1;
|
||||
else
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
folders = iservice.getFolders();
|
||||
|
||||
if (folders.size() == 1 &&
|
||||
EntityFolder.INBOX.equals(folders.get(0).type))
|
||||
try {
|
||||
Log.i("Creating system folders");
|
||||
Store istore = iservice.getStore();
|
||||
istore.getFolder(EntityFolder.DRAFTS).create(Folder.HOLDS_FOLDERS);
|
||||
istore.getFolder(EntityFolder.SENT).create(Folder.HOLDS_FOLDERS);
|
||||
istore.getFolder(EntityFolder.ARCHIVE).create(Folder.HOLDS_FOLDERS);
|
||||
istore.getFolder(EntityFolder.TRASH).create(Folder.HOLDS_FOLDERS);
|
||||
istore.getFolder(EntityFolder.JUNK).create(Folder.HOLDS_FOLDERS);
|
||||
folders = iservice.getFolders();
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
}
|
||||
|
||||
Long max_size;
|
||||
String iprotocol = (provider.smtp.starttls ? "smtp" : "smtps");
|
||||
int iencryption = (provider.smtp.starttls ? EmailService.ENCRYPTION_STARTTLS : EmailService.ENCRYPTION_SSL);
|
||||
try (EmailService iservice = new EmailService(
|
||||
context, iprotocol, null, iencryption, false,
|
||||
EmailService.PURPOSE_CHECK, true)) {
|
||||
iservice.setUseIp(provider.useip, null);
|
||||
try {
|
||||
iservice.connect(
|
||||
provider.smtp.host, provider.smtp.port,
|
||||
AUTH_TYPE_PASSWORD, null,
|
||||
user, password,
|
||||
null, null);
|
||||
} catch (EmailService.UntrustedException ex) {
|
||||
smtp_certificate = ex.getCertificate();
|
||||
String similar = EntityCertificate.getSimilarDnsName(smtp_certificate, provider.smtp.host);
|
||||
if (similar == null)
|
||||
smtp_fingerprint = EntityCertificate.getKeyFingerprint(smtp_certificate);
|
||||
else
|
||||
provider.smtp.host = similar;
|
||||
iservice.connect(
|
||||
provider.smtp.host, provider.smtp.port,
|
||||
AUTH_TYPE_PASSWORD, null,
|
||||
user, password,
|
||||
null, smtp_fingerprint);
|
||||
if (folders.size() == 1 &&
|
||||
EntityFolder.INBOX.equals(folders.get(0).type))
|
||||
try {
|
||||
Log.i("Creating system folders");
|
||||
Store istore = iservice.getStore();
|
||||
istore.getFolder(EntityFolder.DRAFTS).create(Folder.HOLDS_FOLDERS);
|
||||
istore.getFolder(EntityFolder.SENT).create(Folder.HOLDS_FOLDERS);
|
||||
istore.getFolder(EntityFolder.ARCHIVE).create(Folder.HOLDS_FOLDERS);
|
||||
istore.getFolder(EntityFolder.TRASH).create(Folder.HOLDS_FOLDERS);
|
||||
istore.getFolder(EntityFolder.JUNK).create(Folder.HOLDS_FOLDERS);
|
||||
folders = iservice.getFolders();
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
}
|
||||
|
||||
Long max_size;
|
||||
String iprotocol = (provider.smtp.starttls ? "smtp" : "smtps");
|
||||
int iencryption = (provider.smtp.starttls ? EmailService.ENCRYPTION_STARTTLS : EmailService.ENCRYPTION_SSL);
|
||||
try (EmailService iservice = new EmailService(
|
||||
context, iprotocol, null, iencryption, false,
|
||||
EmailService.PURPOSE_CHECK, true)) {
|
||||
iservice.setUseIp(provider.useip, null);
|
||||
try {
|
||||
iservice.connect(
|
||||
provider.smtp.host, provider.smtp.port,
|
||||
AUTH_TYPE_PASSWORD, null,
|
||||
user, password,
|
||||
null, null);
|
||||
} catch (EmailService.UntrustedException ex) {
|
||||
smtp_certificate = ex.getCertificate();
|
||||
String similar = EntityCertificate.getSimilarDnsName(smtp_certificate, provider.smtp.host);
|
||||
if (similar == null)
|
||||
smtp_fingerprint = EntityCertificate.getKeyFingerprint(smtp_certificate);
|
||||
else
|
||||
provider.smtp.host = similar;
|
||||
iservice.connect(
|
||||
provider.smtp.host, provider.smtp.port,
|
||||
AUTH_TYPE_PASSWORD, null,
|
||||
user, password,
|
||||
null, smtp_fingerprint);
|
||||
}
|
||||
|
||||
max_size = iservice.getMaxSize();
|
||||
}
|
||||
|
||||
if (check) {
|
||||
args.putParcelable("provider", provider);
|
||||
args.putSerializable("imap_certificate", imap_certificate);
|
||||
args.putSerializable("smtp_certificate", smtp_certificate);
|
||||
return provider;
|
||||
}
|
||||
|
||||
DB db = DB.getInstance(context);
|
||||
try {
|
||||
db.beginTransaction();
|
||||
|
||||
EntityAccount primary = db.account().getPrimaryAccount();
|
||||
|
||||
// Create account
|
||||
EntityAccount account = new EntityAccount();
|
||||
|
||||
account.host = provider.imap.host;
|
||||
account.encryption = aencryption;
|
||||
account.port = provider.imap.port;
|
||||
account.auth_type = AUTH_TYPE_PASSWORD;
|
||||
account.user = user;
|
||||
account.password = password;
|
||||
account.fingerprint = imap_fingerprint;
|
||||
|
||||
account.name = provider.name + "/" + username;
|
||||
|
||||
account.synchronize = true;
|
||||
account.primary = (primary == null);
|
||||
|
||||
if (provider.keepalive > 0)
|
||||
account.poll_interval = provider.keepalive;
|
||||
|
||||
account.partial_fetch = provider.partial;
|
||||
|
||||
account.created = new Date().getTime();
|
||||
account.last_connected = account.created;
|
||||
|
||||
account.id = db.account().insertAccount(account);
|
||||
args.putLong("account", account.id);
|
||||
EntityLog.log(context, "Quick added account=" + account.name);
|
||||
|
||||
// Create folders
|
||||
for (EntityFolder folder : folders) {
|
||||
EntityFolder existing = db.folder().getFolderByName(account.id, folder.name);
|
||||
if (existing == null) {
|
||||
folder.account = account.id;
|
||||
folder.setSpecials(account);
|
||||
folder.id = db.folder().insertFolder(folder);
|
||||
EntityLog.log(context, "Quick added folder=" + folder.name + " type=" + folder.type);
|
||||
if (folder.synchronize)
|
||||
EntityOperation.sync(context, folder.id, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Set swipe left/right folder
|
||||
for (EntityFolder folder : folders)
|
||||
if (EntityFolder.TRASH.equals(folder.type))
|
||||
account.swipe_left = folder.id;
|
||||
else if (EntityFolder.ARCHIVE.equals(folder.type))
|
||||
account.swipe_right = folder.id;
|
||||
|
||||
db.account().updateAccount(account);
|
||||
|
||||
// Create identity
|
||||
EntityIdentity identity = new EntityIdentity();
|
||||
identity.name = name;
|
||||
identity.email = email;
|
||||
identity.account = account.id;
|
||||
|
||||
identity.host = provider.smtp.host;
|
||||
identity.encryption = iencryption;
|
||||
identity.port = provider.smtp.port;
|
||||
identity.auth_type = AUTH_TYPE_PASSWORD;
|
||||
identity.user = user;
|
||||
identity.password = password;
|
||||
identity.fingerprint = smtp_fingerprint;
|
||||
identity.use_ip = provider.useip;
|
||||
identity.synchronize = true;
|
||||
identity.primary = true;
|
||||
identity.max_size = max_size;
|
||||
|
||||
identity.id = db.identity().insertIdentity(identity);
|
||||
EntityLog.log(context, "Quick added identity=" + identity.name + " email=" + identity.email);
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
|
||||
break;
|
||||
} catch (Throwable ex) {
|
||||
Log.w(ex);
|
||||
if (fail == null)
|
||||
fail = ex;
|
||||
}
|
||||
|
||||
max_size = iservice.getMaxSize();
|
||||
}
|
||||
|
||||
if (check) {
|
||||
args.putSerializable("imap_certificate", imap_certificate);
|
||||
args.putSerializable("smtp_certificate", smtp_certificate);
|
||||
return provider;
|
||||
}
|
||||
|
||||
DB db = DB.getInstance(context);
|
||||
try {
|
||||
db.beginTransaction();
|
||||
|
||||
EntityAccount primary = db.account().getPrimaryAccount();
|
||||
|
||||
// Create account
|
||||
EntityAccount account = new EntityAccount();
|
||||
|
||||
account.host = provider.imap.host;
|
||||
account.encryption = aencryption;
|
||||
account.port = provider.imap.port;
|
||||
account.auth_type = AUTH_TYPE_PASSWORD;
|
||||
account.user = user;
|
||||
account.password = password;
|
||||
account.fingerprint = imap_fingerprint;
|
||||
|
||||
account.name = provider.name + "/" + username;
|
||||
|
||||
account.synchronize = true;
|
||||
account.primary = (primary == null);
|
||||
|
||||
if (provider.keepalive > 0)
|
||||
account.poll_interval = provider.keepalive;
|
||||
|
||||
account.partial_fetch = provider.partial;
|
||||
|
||||
account.created = new Date().getTime();
|
||||
account.last_connected = account.created;
|
||||
|
||||
account.id = db.account().insertAccount(account);
|
||||
args.putLong("account", account.id);
|
||||
EntityLog.log(context, "Quick added account=" + account.name);
|
||||
|
||||
// Create folders
|
||||
for (EntityFolder folder : folders) {
|
||||
EntityFolder existing = db.folder().getFolderByName(account.id, folder.name);
|
||||
if (existing == null) {
|
||||
folder.account = account.id;
|
||||
folder.setSpecials(account);
|
||||
folder.id = db.folder().insertFolder(folder);
|
||||
EntityLog.log(context, "Quick added folder=" + folder.name + " type=" + folder.type);
|
||||
if (folder.synchronize)
|
||||
EntityOperation.sync(context, folder.id, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Set swipe left/right folder
|
||||
for (EntityFolder folder : folders)
|
||||
if (EntityFolder.TRASH.equals(folder.type))
|
||||
account.swipe_left = folder.id;
|
||||
else if (EntityFolder.ARCHIVE.equals(folder.type))
|
||||
account.swipe_right = folder.id;
|
||||
|
||||
db.account().updateAccount(account);
|
||||
|
||||
// Create identity
|
||||
EntityIdentity identity = new EntityIdentity();
|
||||
identity.name = name;
|
||||
identity.email = email;
|
||||
identity.account = account.id;
|
||||
|
||||
identity.host = provider.smtp.host;
|
||||
identity.encryption = iencryption;
|
||||
identity.port = provider.smtp.port;
|
||||
identity.auth_type = AUTH_TYPE_PASSWORD;
|
||||
identity.user = user;
|
||||
identity.password = password;
|
||||
identity.fingerprint = smtp_fingerprint;
|
||||
identity.use_ip = provider.useip;
|
||||
identity.synchronize = true;
|
||||
identity.primary = true;
|
||||
identity.max_size = max_size;
|
||||
|
||||
identity.id = db.identity().insertIdentity(identity);
|
||||
EntityLog.log(context, "Quick added identity=" + identity.name + " email=" + identity.email);
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
if (fail != null)
|
||||
throw fail;
|
||||
|
||||
ServiceSynchronize.eval(context, "quick setup");
|
||||
|
||||
|
|
Loading…
Reference in New Issue