Fixed falling back to IPv4

pull/160/head
M66B 6 years ago
parent ea0b69f46b
commit e263ee43f6

@ -282,7 +282,7 @@ public class BoundaryCallbackMessages extends PagedList.BoundaryCallback<TupleMe
Log.i("Boundary server connecting account=" + account.name); Log.i("Boundary server connecting account=" + account.name);
istore = (IMAPStore) isession.getStore(protocol); istore = (IMAPStore) isession.getStore(protocol);
ConnectionHelper.connect(context, isession, istore, account); ConnectionHelper.connect(context, istore, account);
Log.i("Boundary server opening folder=" + browsable.name); Log.i("Boundary server opening folder=" + browsable.name);
ifolder = (IMAPFolder) istore.getFolder(browsable.name); ifolder = (IMAPFolder) istore.getFolder(browsable.name);

@ -16,11 +16,13 @@ import androidx.preference.PreferenceManager;
import com.bugsnag.android.BreadcrumbType; import com.bugsnag.android.BreadcrumbType;
import com.bugsnag.android.Bugsnag; import com.bugsnag.android.Bugsnag;
import com.sun.mail.imap.IMAPStore; import com.sun.mail.imap.IMAPStore;
import com.sun.mail.smtp.SMTPTransport;
import org.xbill.DNS.Lookup; import org.xbill.DNS.Lookup;
import org.xbill.DNS.SimpleResolver; import org.xbill.DNS.SimpleResolver;
import org.xbill.DNS.Type; import org.xbill.DNS.Type;
import java.lang.reflect.Field;
import java.net.Inet6Address; import java.net.Inet6Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
@ -34,7 +36,6 @@ import java.util.Map;
import javax.mail.Address; import javax.mail.Address;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.mail.Session; import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress; import javax.mail.internet.InternetAddress;
public class ConnectionHelper { public class ConnectionHelper {
@ -258,15 +259,15 @@ public class ConnectionHelper {
return true; return true;
} }
static void connect(Context context, Session isession, IMAPStore istore, EntityAccount account) throws MessagingException { static void connect(Context context, IMAPStore istore, EntityAccount account) throws MessagingException {
connect(context, isession, istore, account.host, account.port, account.user, account.password); connect(context, istore, account.host, account.port, account.user, account.password);
} }
static void connect(Context context, Session isession, Transport itransport, EntityIdentity identity) throws MessagingException { static void connect(Context context, SMTPTransport itransport, EntityIdentity identity) throws MessagingException {
connect(context, isession, itransport, identity.host, identity.port, identity.user, identity.password); connect(context, itransport, identity.host, identity.port, identity.user, identity.password);
} }
static void connect(Context context, Session isession, IMAPStore istore, String host, int port, String user, String password) throws MessagingException { static void connect(Context context, IMAPStore istore, String host, int port, String user, String password) throws MessagingException {
try { try {
istore.connect(host, port, user, password); istore.connect(host, port, user, password);
} catch (MessagingException ex) { } catch (MessagingException ex) {
@ -275,6 +276,9 @@ public class ConnectionHelper {
try { try {
Log.i("Binding to " + any4); Log.i("Binding to " + any4);
Field fSession = getDeclaredField(istore.getClass(), "session");
fSession.setAccessible(true);
Session isession = (Session) fSession.get(istore);
isession.getProperties().put("mail.imap.localaddress", any4); isession.getProperties().put("mail.imap.localaddress", any4);
isession.getProperties().put("mail.imaps.localaddress", any4); isession.getProperties().put("mail.imaps.localaddress", any4);
istore.connect(host, port, user, password); istore.connect(host, port, user, password);
@ -304,7 +308,7 @@ public class ConnectionHelper {
} }
} }
static void connect(Context context, Session isession, Transport itransport, String host, int port, String user, String password) throws MessagingException { static void connect(Context context, SMTPTransport itransport, String host, int port, String user, String password) throws MessagingException {
try { try {
itransport.connect(host, port, user, password); itransport.connect(host, port, user, password);
} catch (MessagingException ex) { } catch (MessagingException ex) {
@ -313,6 +317,9 @@ public class ConnectionHelper {
try { try {
Log.i("Binding to " + any4); Log.i("Binding to " + any4);
Field fSession = getDeclaredField(itransport.getClass(), "session");
fSession.setAccessible(true);
Session isession = (Session) fSession.get(itransport);
isession.getProperties().put("mail.smtp.localaddress", any4); isession.getProperties().put("mail.smtp.localaddress", any4);
isession.getProperties().put("mail.smtps.localaddress", any4); isession.getProperties().put("mail.smtps.localaddress", any4);
itransport.connect(host, port, user, password); itransport.connect(host, port, user, password);
@ -323,14 +330,28 @@ public class ConnectionHelper {
} }
} }
private static Field getDeclaredField(Class clazz, String name) throws NoSuchFieldException {
while (clazz != null) {
try {
return clazz.getDeclaredField(name);
} catch (NoSuchFieldException ex) {
clazz = clazz.getSuperclass();
}
}
throw new NoSuchFieldException(name);
}
private static boolean hasIPv6(String host) { private static boolean hasIPv6(String host) {
boolean has = false;
try { try {
for (InetAddress iaddr : InetAddress.getAllByName(host)) for (InetAddress iaddr : InetAddress.getAllByName(host)) {
Log.i(host + " resolves to " + iaddr);
if (iaddr instanceof Inet6Address) if (iaddr instanceof Inet6Address)
return true; has = true;
}
} catch (UnknownHostException ignored) { } catch (UnknownHostException ignored) {
} }
return false; return has;
} }
static boolean airplaneMode(Context context) { static boolean airplaneMode(Context context) {

@ -536,7 +536,7 @@ public class FragmentAccount extends FragmentBase {
Session isession = Session.getInstance(props, null); Session isession = Session.getInstance(props, null);
isession.setDebug(true); isession.setDebug(true);
try (IMAPStore istore = (IMAPStore) isession.getStore("imap" + (starttls ? "" : "s"))) { try (IMAPStore istore = (IMAPStore) isession.getStore("imap" + (starttls ? "" : "s"))) {
ConnectionHelper.connect(context, isession, istore, host, Integer.parseInt(port), user, password); ConnectionHelper.connect(context, istore, host, Integer.parseInt(port), user, password);
result.idle = istore.hasCapability("IDLE"); result.idle = istore.hasCapability("IDLE");
@ -893,7 +893,7 @@ public class FragmentAccount extends FragmentBase {
isession.setDebug(true); isession.setDebug(true);
try (IMAPStore istore = (IMAPStore) isession.getStore("imap" + (starttls ? "" : "s"))) { try (IMAPStore istore = (IMAPStore) isession.getStore("imap" + (starttls ? "" : "s"))) {
ConnectionHelper.connect(context, isession, istore, host, Integer.parseInt(port), user, password); ConnectionHelper.connect(context, istore, host, Integer.parseInt(port), user, password);
for (Folder ifolder : istore.getDefaultFolder().list("*")) { for (Folder ifolder : istore.getDefaultFolder().list("*")) {
// Check folder attributes // Check folder attributes

@ -63,6 +63,7 @@ import androidx.lifecycle.Lifecycle;
import com.google.android.material.snackbar.Snackbar; import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputLayout; import com.google.android.material.textfield.TextInputLayout;
import com.sun.mail.smtp.SMTPTransport;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.net.Inet6Address; import java.net.Inet6Address;
@ -74,7 +75,6 @@ import java.util.Objects;
import java.util.Properties; import java.util.Properties;
import javax.mail.Session; import javax.mail.Session;
import javax.mail.Transport;
import static android.app.Activity.RESULT_OK; import static android.app.Activity.RESULT_OK;
import static com.google.android.material.textfield.TextInputLayout.END_ICON_NONE; import static com.google.android.material.textfield.TextInputLayout.END_ICON_NONE;
@ -702,8 +702,8 @@ public class FragmentIdentity extends FragmentBase {
isession.setDebug(true); isession.setDebug(true);
// Create transport // Create transport
try (Transport itransport = isession.getTransport(protocol)) { try (SMTPTransport itransport = (SMTPTransport) isession.getTransport(protocol)) {
ConnectionHelper.connect(context, isession, itransport, host, Integer.parseInt(port), user, password); ConnectionHelper.connect(context, itransport, host, Integer.parseInt(port), user, password);
} }
} }

@ -53,6 +53,7 @@ import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputLayout; import com.google.android.material.textfield.TextInputLayout;
import com.sun.mail.imap.IMAPFolder; import com.sun.mail.imap.IMAPFolder;
import com.sun.mail.imap.IMAPStore; import com.sun.mail.imap.IMAPStore;
import com.sun.mail.smtp.SMTPTransport;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList; import java.util.ArrayList;
@ -62,7 +63,6 @@ import java.util.Properties;
import javax.mail.Folder; import javax.mail.Folder;
import javax.mail.Session; import javax.mail.Session;
import javax.mail.Transport;
import static android.app.Activity.RESULT_OK; import static android.app.Activity.RESULT_OK;
@ -257,7 +257,7 @@ public class FragmentQuickSetup extends FragmentBase {
Session isession = Session.getInstance(props, null); Session isession = Session.getInstance(props, null);
isession.setDebug(true); isession.setDebug(true);
try (IMAPStore istore = (IMAPStore) isession.getStore(provider.imap_starttls ? "imap" : "imaps")) { try (IMAPStore istore = (IMAPStore) isession.getStore(provider.imap_starttls ? "imap" : "imaps")) {
ConnectionHelper.connect(context, isession, istore, provider.imap_host, provider.imap_port, user, password); ConnectionHelper.connect(context, istore, provider.imap_host, provider.imap_port, user, password);
boolean inbox = false; boolean inbox = false;
boolean drafts = false; boolean drafts = false;
@ -320,8 +320,8 @@ public class FragmentQuickSetup extends FragmentBase {
Properties props = MessageHelper.getSessionProperties(null, false); Properties props = MessageHelper.getSessionProperties(null, false);
Session isession = Session.getInstance(props, null); Session isession = Session.getInstance(props, null);
isession.setDebug(true); isession.setDebug(true);
try (Transport itransport = isession.getTransport(provider.smtp_starttls ? "smtp" : "smtps")) { try (SMTPTransport itransport = (SMTPTransport) isession.getTransport(provider.smtp_starttls ? "smtp" : "smtps")) {
ConnectionHelper.connect(context, isession, itransport, provider.smtp_host, provider.smtp_port, user, password); ConnectionHelper.connect(context, itransport, provider.smtp_host, provider.smtp_port, user, password);
} }
} }

@ -36,6 +36,8 @@ import androidx.core.content.ContextCompat;
import androidx.lifecycle.Observer; import androidx.lifecycle.Observer;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
import com.sun.mail.smtp.SMTPTransport;
import java.io.IOException; import java.io.IOException;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.net.Inet6Address; import java.net.Inet6Address;
@ -55,7 +57,6 @@ import javax.mail.MessageRemovedException;
import javax.mail.MessagingException; import javax.mail.MessagingException;
import javax.mail.SendFailedException; import javax.mail.SendFailedException;
import javax.mail.Session; import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress; import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMessage;
@ -364,10 +365,10 @@ public class ServiceSend extends ServiceBase {
} }
// Create transport // Create transport
try (Transport itransport = isession.getTransport(protocol)) { try (SMTPTransport itransport = (SMTPTransport) isession.getTransport(protocol)) {
// Connect transport // Connect transport
db.identity().setIdentityState(ident.id, "connecting"); db.identity().setIdentityState(ident.id, "connecting");
ConnectionHelper.connect(this, isession, itransport, ident); ConnectionHelper.connect(this, itransport, ident);
db.identity().setIdentityState(ident.id, "connected"); db.identity().setIdentityState(ident.id, "connected");
// Send message // Send message

@ -737,7 +737,7 @@ public class ServiceSynchronize extends ServiceBase {
db.account().setAccountState(account.id, "connecting"); db.account().setAccountState(account.id, "connecting");
try { try {
ConnectionHelper.connect(this, isession, istore, account); ConnectionHelper.connect(this, istore, account);
} catch (Throwable ex) { } catch (Throwable ex) {
if (ex instanceof AuthenticationFailedException) { if (ex instanceof AuthenticationFailedException) {
NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

Loading…
Cancel
Save