From 1227cd0b4a092bccd4f31459a7f18599d1c07d2e Mon Sep 17 00:00:00 2001 From: M66B Date: Sun, 25 Apr 2021 20:28:24 +0200 Subject: [PATCH] Updated to JakartaMail 1.6.7 --- .../main/java/com/sun/mail/iap/Protocol.java | 65 ++++++-- .../sun/mail/imap/protocol/IMAPProtocol.java | 1 + .../com/sun/mail/imap/protocol/UIDSet.java | 2 +- .../main/java/com/sun/mail/pop3/Protocol.java | 78 ++++++++-- .../main/java/com/sun/mail/pop3/package.html | 9 +- .../java/com/sun/mail/smtp/DigestMD5.java | 2 +- .../com/sun/mail/util/WriteTimeoutSocket.java | 10 +- .../mail/util/logging/CompactFormatter.java | 142 ++++++++++-------- .../util/logging/LogManagerProperties.java | 96 ++++++++++-- 9 files changed, 300 insertions(+), 105 deletions(-) diff --git a/app/src/main/java/com/sun/mail/iap/Protocol.java b/app/src/main/java/com/sun/mail/iap/Protocol.java index c27108c771..cd3baac42c 100644 --- a/app/src/main/java/com/sun/mail/iap/Protocol.java +++ b/app/src/main/java/com/sun/mail/iap/Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2019 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -30,7 +30,6 @@ import java.util.zip.Deflater; import java.util.zip.DeflaterOutputStream; import java.util.zip.Inflater; import java.util.zip.InflaterInputStream; -import java.lang.reflect.Constructor; import java.lang.reflect.Field; import com.sun.mail.util.PropUtil; @@ -545,23 +544,63 @@ public class Protocol { public SocketChannel getChannel() { SocketChannel ret = socket.getChannel(); if (ret != null) - return ret; + return ret; - // XXX - Android is broken and SSL wrapped sockets don't delegate - // the getChannel method to the wrapped Socket if (socket instanceof SSLSocket) { - try { - Field f = socket.getClass().getDeclaredField("socket"); - f.setAccessible(true); - Socket s = (Socket)f.get(socket); - ret = s.getChannel(); - } catch (Exception ex) { - // ignore anything that might go wrong - } + ret = Protocol.findSocketChannel(socket); } return ret; } + /** + * Android is broken and SSL wrapped sockets don't delegate + * the getChannel method to the wrapped Socket. + * + * @param socket a non null socket + * @return the SocketChannel or null if not found + */ + private static SocketChannel findSocketChannel(Socket socket) { + //Search class hierarchy for field name socket regardless of modifier. + for (Class k = socket.getClass(); k != Object.class; k = k.getSuperclass()) { + try { + Field f = k.getDeclaredField("socket"); + f.setAccessible(true); + Socket s = (Socket) f.get(socket); + SocketChannel ret = s.getChannel(); + if (ret != null) { + return ret; + } + } catch (Exception ignore) { + //ignore anything that might go wrong + } + } + + //Search class hierarchy for fields that can hold a Socket + //or subclass regardless of modifier. Fields declared as super types of Socket + //will be ignored. + for (Class k = socket.getClass(); k != Object.class; k = k.getSuperclass()) { + try { + for (Field f : k.getDeclaredFields()) { + if (Socket.class.isAssignableFrom(f.getType())) { + try { + f.setAccessible(true); + Socket s = (Socket) f.get(socket); + SocketChannel ret = s.getChannel(); + if (ret != null) { + return ret; + } + } catch (Exception ignore) { + //ignore anything that might go wrong + } + } + } + } catch (Exception ignore) { + //ignore anything that might go wrong + } + } + return null; + } + /** * Return the local SocketAddress (host and port) for this * end of the connection. 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 85727902ad..23d0b9efa0 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 @@ -630,6 +630,7 @@ public class IMAPProtocol extends Protocol { authenticated = true; } + /** * The AUTHENTICATE command with AUTH=PLAIN authentication scheme. * This is based heavly on the {@link #authlogin} method. diff --git a/app/src/main/java/com/sun/mail/imap/protocol/UIDSet.java b/app/src/main/java/com/sun/mail/imap/protocol/UIDSet.java index 222858155c..d4090ead3d 100644 --- a/app/src/main/java/com/sun/mail/imap/protocol/UIDSet.java +++ b/app/src/main/java/com/sun/mail/imap/protocol/UIDSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at diff --git a/app/src/main/java/com/sun/mail/pop3/Protocol.java b/app/src/main/java/com/sun/mail/pop3/Protocol.java index fb0a05aaa5..56423d1b20 100644 --- a/app/src/main/java/com/sun/mail/pop3/Protocol.java +++ b/app/src/main/java/com/sun/mail/pop3/Protocol.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2021 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -23,7 +23,6 @@ import java.security.*; import java.util.logging.Level; import java.nio.charset.StandardCharsets; import javax.net.ssl.SSLSocket; - import com.sun.mail.auth.Ntlm; import com.sun.mail.util.ASCIIUtility; import com.sun.mail.util.BASE64DecoderStream; @@ -44,7 +43,7 @@ class Response { } /** - * This class provides a POP3 connection and implements + * This class provides a POP3 connection and implements * the POP3 protocol requests. * * APOP support courtesy of "chamness". @@ -76,7 +75,7 @@ class Protocol { // sometimes the returned size isn't quite big enough private static final int SLOP = 128; - /** + /** * Open a connection to the POP3 server. */ Protocol(String host, int port, MailLogger logger, @@ -393,7 +392,7 @@ class Protocol { } /** - * Gets the APOP message digest. + * Gets the APOP message digest. * From RFC 1939: * * The 'digest' parameter is calculated by applying the MD5 @@ -446,6 +445,25 @@ class Protocol { return enabled; } + /** + * Run authentication query based on command and initial response + * + * @param command - command passed to server + * @param ir - initial response, part of the query + * @throws IOException + */ + protected void runAuthenticationCommand(String command, String ir) throws IOException { + if (logger.isLoggable(Level.FINE)) { + logger.fine(command + " using one line authentication format"); + } + + if (ir != null) { + resp = simpleCommand(command + " " + (ir.length() == 0 ? "=" : ir)); + } else { + resp = simpleCommand(command); + } + } + /** * Start the authentication handshake by issuing the AUTH command. * Delegate to the doAuth method to do the mechanism-specific @@ -461,11 +479,8 @@ class Protocol { logger.fine("AUTH " + mech + " command trace suppressed"); suspendTracing(); } - if (ir != null) - resp = simpleCommand("AUTH " + mech + " " + - (ir.length() == 0 ? "=" : ir)); - else - resp = simpleCommand("AUTH " + mech); + + runAuthenticationCommand("AUTH " + mech, ir); if (resp.cont) doAuth(host, authzid, user, passwd); @@ -681,6 +696,26 @@ class Protocol { return ASCIIUtility.toString(b); } + @Override + protected void runAuthenticationCommand(String command, String ir) throws IOException { + Boolean isTwoLineAuthenticationFormat = getBoolProp( + props, + prefix + ".auth.xoauth2.two.line.authentication.format"); + + if (isTwoLineAuthenticationFormat) { + if (logger.isLoggable(Level.FINE)) { + logger.fine(command + " using two line authentication format"); + } + + resp = twoLinesCommand( + command, + (ir.length() == 0 ? "=" : ir) + ); + } else { + super.runAuthenticationCommand(command, ir); + } + } + @Override void doAuth(String host, String authzid, String user, String passwd) throws IOException { @@ -1120,6 +1155,29 @@ class Protocol { return r; } + /** + * Issue a two line POP3 command and return the response + * Refer to {@link #simpleCommand(String)} for a single line command + * + * @param firstCommand first command we want to pass to server e.g AUTH XOAUTH2 + * @param secondCommand second command e.g Base64 encoded authorization string + * @return Response + * @throws IOException + */ + private Response twoLinesCommand(String firstCommand, String secondCommand) throws IOException { + String cmd = firstCommand + " " + secondCommand; + + batchCommandStart(cmd); + simpleCommand(firstCommand); + batchCommandContinue(cmd); + + Response r = simpleCommand(secondCommand); + + batchCommandEnd(); + + return r; + } + /** * Send the specified command. */ diff --git a/app/src/main/java/com/sun/mail/pop3/package.html b/app/src/main/java/com/sun/mail/pop3/package.html index 0a01a78be0..d1c095bc2d 100644 --- a/app/src/main/java/com/sun/mail/pop3/package.html +++ b/app/src/main/java/com/sun/mail/pop3/package.html @@ -4,7 +4,7 @@