diff --git a/app/src/main/java/com/sun/mail/imap/IMAPStore.java b/app/src/main/java/com/sun/mail/imap/IMAPStore.java index 929e82d331..cc9b7cca98 100644 --- a/app/src/main/java/com/sun/mail/imap/IMAPStore.java +++ b/app/src/main/java/com/sun/mail/imap/IMAPStore.java @@ -887,18 +887,27 @@ public class IMAPStore extends Store continue; } - if (m.equals("PLAIN")) - p.authplain(authzid, user, password); - else if (m.equals("LOGIN")) - p.authlogin(user, password); - else if (m.equals("NTLM")) - p.authntlm(authzid, user, password); - else if (m.equals("XOAUTH2")) - p.authoauth2(user, password); - else { - logger.log(Level.FINE, "no authenticator for mechanism {0}", m); - continue; - } + try { + if (m.equals("PLAIN")) + p.authplain(authzid, user, password); + else if (m.equals("LOGIN")) + p.authlogin(user, password); + else if (m.equals("NTLM")) + p.authntlm(authzid, user, password); + else if (m.equals("XOAUTH2")) + p.authoauth2(user, password); + else { + logger.log(Level.FINE, "no authenticator for mechanism {0}", m); + continue; + } + } catch (ProtocolException ex) { + if (m.equals("PLAIN") || m.equals("LOGIN")) { + eu.faircode.email.Log.w(ex); + eu.faircode.email.Log.i("Falling back to classic LOGIN"); + p.authclassic(user, password); + } else + throw ex; + } return; } diff --git a/app/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java b/app/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java index a8a88b6c01..ff300bbfde 100644 --- a/app/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java +++ b/app/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java @@ -627,6 +627,59 @@ public class IMAPProtocol extends Protocol { authenticated = true; } + public synchronized void authclassic(String u, String p) + throws ProtocolException { + List v = new ArrayList<>(); + String tag = null; + Response r = null; + boolean done = false; + + try { + + if (noauthdebug && isTracing()) { + logger.fine("LOGIN command trace suppressed"); + suspendTracing(); + } + + try { + Argument arg = new Argument(); + arg.writeNString(u); + arg.writeNString(p); + tag = writeCommand("LOGIN", arg); + } catch (Exception ex) { + r = Response.byeResponse(ex); + done = true; + } + + while (!done) { + try { + r = readResponse(); + if (r.isTagged() && r.getTag().equals(tag)) + done = true; + else if (r.isBYE()) // outta here + done = true; + } catch (Exception ioex) { + r = Response.byeResponse(ioex); + done = true; + } + v.add(r); + } + + } finally { + resumeTracing(); + } + + Response[] responses = v.toArray(new Response[v.size()]); + + handleCapabilityResponse(responses); + notifyResponseHandlers(responses); + + if (noauthdebug && isTracing()) + logger.fine("LOGIN command result: " + r); + handleLoginResult(r); + setCapabilities(r); + authenticated = true; + } /** * The AUTHENTICATE command with AUTH=PLAIN authentication scheme. diff --git a/patches/Scarlet.patch b/patches/Scarlet.patch new file mode 100644 index 0000000000..9f8f9eb050 --- /dev/null +++ b/patches/Scarlet.patch @@ -0,0 +1,108 @@ +diff --git a/app/src/main/java/com/sun/mail/imap/IMAPStore.java b/app/src/main/java/com/sun/mail/imap/IMAPStore.java +index 929e82d33..cc9b7cca9 100644 +--- a/app/src/main/java/com/sun/mail/imap/IMAPStore.java ++++ b/app/src/main/java/com/sun/mail/imap/IMAPStore.java +@@ -887,18 +887,27 @@ public class IMAPStore extends Store + continue; + } + +- if (m.equals("PLAIN")) +- p.authplain(authzid, user, password); +- else if (m.equals("LOGIN")) +- p.authlogin(user, password); +- else if (m.equals("NTLM")) +- p.authntlm(authzid, user, password); +- else if (m.equals("XOAUTH2")) +- p.authoauth2(user, password); +- else { +- logger.log(Level.FINE, "no authenticator for mechanism {0}", m); +- continue; +- } ++ try { ++ if (m.equals("PLAIN")) ++ p.authplain(authzid, user, password); ++ else if (m.equals("LOGIN")) ++ p.authlogin(user, password); ++ else if (m.equals("NTLM")) ++ p.authntlm(authzid, user, password); ++ else if (m.equals("XOAUTH2")) ++ p.authoauth2(user, password); ++ else { ++ logger.log(Level.FINE, "no authenticator for mechanism {0}", m); ++ continue; ++ } ++ } catch (ProtocolException ex) { ++ if (m.equals("PLAIN") || m.equals("LOGIN")) { ++ eu.faircode.email.Log.w(ex); ++ eu.faircode.email.Log.i("Falling back to classic LOGIN"); ++ p.authclassic(user, password); ++ } else ++ throw ex; ++ } + return; + } + +diff --git a/app/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java b/app/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java +index a8a88b6c0..ff300bbfd 100644 +--- a/app/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java ++++ b/app/src/main/java/com/sun/mail/imap/protocol/IMAPProtocol.java +@@ -627,6 +627,59 @@ public class IMAPProtocol extends Protocol { + authenticated = true; + } + ++ public synchronized void authclassic(String u, String p) ++ throws ProtocolException { ++ List v = new ArrayList<>(); ++ String tag = null; ++ Response r = null; ++ boolean done = false; ++ ++ try { ++ ++ if (noauthdebug && isTracing()) { ++ logger.fine("LOGIN command trace suppressed"); ++ suspendTracing(); ++ } ++ ++ try { ++ Argument arg = new Argument(); ++ arg.writeNString(u); ++ arg.writeNString(p); ++ tag = writeCommand("LOGIN", arg); ++ } catch (Exception ex) { ++ r = Response.byeResponse(ex); ++ done = true; ++ } ++ ++ while (!done) { ++ try { ++ r = readResponse(); ++ if (r.isTagged() && r.getTag().equals(tag)) ++ done = true; ++ else if (r.isBYE()) // outta here ++ done = true; ++ } catch (Exception ioex) { ++ r = Response.byeResponse(ioex); ++ done = true; ++ } ++ v.add(r); ++ } ++ ++ } finally { ++ resumeTracing(); ++ } ++ ++ Response[] responses = v.toArray(new Response[v.size()]); ++ ++ handleCapabilityResponse(responses); ++ notifyResponseHandlers(responses); ++ ++ if (noauthdebug && isTracing()) ++ logger.fine("LOGIN command result: " + r); ++ handleLoginResult(r); ++ setCapabilities(r); ++ authenticated = true; ++ } + + /** + * The AUTHENTICATE command with AUTH=PLAIN authentication scheme.