You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2019/10/17 06:02:40 UTC

[mina-sshd] branch master updated (d2599ea -> 77859da)

This is an automated email from the ASF dual-hosted git repository.

lgoldstein pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git.


    from d2599ea  Upgraded Netty version to 4.1.42
     new 06eeff8  [SSHD-946] Supporting 'encrypt-then-MAC' mode
     new 4832f6b  Log more session related information in CLI client/server code if verbosity enabled
     new 0f7091f  [SSHD-948] Do not accept password authentication if the session is not encrypted
     new e1f5761  [SSHD-948] Do not accept password change request if the session does not use MAC(s) for packet validation
     new 463cdf9  [SSHD-914] Expanded tomcat-apr sources JAR to its component files
     new 77859da  [SSHD-914] Added Python 3 script based on Paramiko package to interact with MINA SSHD as an SFTP client

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .gitignore                                         |   3 +
 CHANGES.md                                         |  15 +-
 README.md                                          |   5 +-
 pom.xml                                            |   3 +
 src/tomcat-apr-5.5.23-sources.jar                  | Bin 25227 -> 0 bytes
 .../main/java/org/apache/sshd/cli/CliSupport.java  | 115 +++++-
 .../sshd/cli/client/SshClientCliSupport.java       |   3 +-
 .../java/org/apache/sshd/common/SshConstants.java  |   3 +-
 .../apache/sshd/common/kex/KexProposalOption.java  |  17 +
 .../java/org/apache/sshd/common/mac/BaseMac.java   |  18 +-
 .../org/apache/sshd/common/mac/BuiltinMacs.java    |  53 ++-
 .../org/apache/sshd/common/mac/MacInformation.java |   4 +
 .../apache/sshd/common/session/SessionContext.java |  46 +++
 .../org/apache/sshd/common/util/buffer/Buffer.java |  18 +-
 .../sshd/common/util/buffer/ByteArrayBuffer.java   |   5 +
 .../apache/sshd/util/test/JUnitTestSupport.java    |   8 +
 .../client/auth/password/UserAuthPassword.java     |  46 ++-
 .../java/org/apache/sshd/common/BaseBuilder.java   |   7 +-
 .../sshd/common/auth/UserAuthMethodFactory.java    |  68 ++++
 .../org/apache/sshd/common/io/PacketWriter.java    |  22 +-
 .../common/session/helpers/AbstractSession.java    | 174 ++++++---
 .../sshd/common/session/helpers/SessionHelper.java |   3 +-
 .../auth/password/PasswordAuthenticator.java       |  20 +-
 .../server/auth/password/UserAuthPassword.java     |  47 ++-
 .../server/jaas/JaasPasswordAuthenticator.java     |  16 +-
 .../sshd/server/session/AbstractServerSession.java |  15 +-
 .../sshd/common/auth/AuthenticationTest.java       |  44 +--
 .../sshd/common/compression/CompressionTest.java   |   6 +-
 .../mac/EncryptThenMacTest.java}                   | 100 ++---
 .../{MacTest.java => MacCompatibilityTest.java}    |  21 +-
 .../apache/sshd/server/auth/WelcomeBannerTest.java |   5 +-
 .../server/jaas/JaasPasswordAuthenticatorTest.java |  14 +-
 .../sshd/util/test/BogusPasswordAuthenticator.java |   6 +-
 .../auth/password/LdapPasswordAuthenticator.java   |   9 +-
 sshd-sources/python/sftpclient.py                  | 406 +++++++++++++++++++++
 .../tomcat-apr-5.5.23-sources/META-INF/INDEX.LIST  |   8 +
 .../tomcat-apr-5.5.23-sources/META-INF/MANIFEST.MF |   4 +
 sshd-sources/tomcat-apr-5.5.23-sources/README.txt  |   1 +
 .../org/apache/tomcat/jni/Address.java             |  53 +++
 .../org/apache/tomcat/jni/BIOCallback.java         |  18 +
 .../org/apache/tomcat/jni/Directory.java           |  27 ++
 .../org/apache/tomcat/jni/Error.java               |  82 +++++
 .../org/apache/tomcat/jni/File.java                | 168 +++++++++
 .../org/apache/tomcat/jni/FileInfo.java            |  28 ++
 .../org/apache/tomcat/jni/Global.java              |  24 ++
 .../org/apache/tomcat/jni/Library.java             | 219 +++++++++++
 .../org/apache/tomcat/jni/Local.java               |  22 ++
 .../org/apache/tomcat/jni/Lock.java                |  37 ++
 .../org/apache/tomcat/jni/Mmap.java                |  24 ++
 .../org/apache/tomcat/jni/Multicast.java           |  20 +
 .../org/apache/tomcat/jni/OS.java                  |  79 ++++
 .../org/apache/tomcat/jni/PasswordCallback.java    |  12 +
 .../org/apache/tomcat/jni/Poll.java                |  41 +++
 .../org/apache/tomcat/jni/Pool.java                |  38 ++
 .../org/apache/tomcat/jni/PoolCallback.java        |  12 +
 .../org/apache/tomcat/jni/Proc.java                |  59 +++
 .../org/apache/tomcat/jni/ProcErrorCallback.java   |  12 +
 .../org/apache/tomcat/jni/Procattr.java            |  37 ++
 .../org/apache/tomcat/jni/Registry.java            |  83 +++++
 .../org/apache/tomcat/jni/SSL.java                 | 158 ++++++++
 .../org/apache/tomcat/jni/SSLContext.java          |  41 +++
 .../org/apache/tomcat/jni/SSLSocket.java           |  26 ++
 .../org/apache/tomcat/jni/Shm.java                 |  30 ++
 .../org/apache/tomcat/jni/Sockaddr.java            |  17 +
 .../org/apache/tomcat/jni/Socket.java              | 120 ++++++
 .../org/apache/tomcat/jni/Status.java              | 270 ++++++++++++++
 .../org/apache/tomcat/jni/Stdlib.java              |  28 ++
 .../org/apache/tomcat/jni/Thread.java              |  12 +
 .../org/apache/tomcat/jni/Time.java                |  58 +++
 .../org/apache/tomcat/jni/User.java                |  38 ++
 70 files changed, 3023 insertions(+), 228 deletions(-)
 delete mode 100644 src/tomcat-apr-5.5.23-sources.jar
 copy sshd-core/src/test/java/org/apache/sshd/{server/auth/WelcomeBannerPhaseTest.java => common/mac/EncryptThenMacTest.java} (53%)
 rename sshd-core/src/test/java/org/apache/sshd/common/mac/{MacTest.java => MacCompatibilityTest.java} (91%)
 create mode 100644 sshd-sources/python/sftpclient.py
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/META-INF/INDEX.LIST
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/META-INF/MANIFEST.MF
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/README.txt
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Address.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/BIOCallback.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Directory.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Error.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/File.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/FileInfo.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Global.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Library.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Local.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Lock.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Mmap.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Multicast.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/OS.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PasswordCallback.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Poll.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Pool.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PoolCallback.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Proc.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/ProcErrorCallback.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Procattr.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Registry.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSL.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLContext.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLSocket.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Shm.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Sockaddr.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Socket.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Status.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Stdlib.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Thread.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Time.java
 create mode 100644 sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/User.java


[mina-sshd] 02/06: Log more session related information in CLI client/server code if verbosity enabled

Posted by lg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit 4832f6b3af6a4b7e09ae405d51f0d8f5a91f9e09
Author: Lyor Goldstein <lg...@apache.org>
AuthorDate: Wed Oct 16 07:57:31 2019 +0300

    Log more session related information in CLI client/server code if verbosity enabled
---
 .../main/java/org/apache/sshd/cli/CliSupport.java  | 115 +++++++++++++++++++--
 1 file changed, 105 insertions(+), 10 deletions(-)

diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/CliSupport.java b/sshd-cli/src/main/java/org/apache/sshd/cli/CliSupport.java
index 783c219..3b6e417 100644
--- a/sshd-cli/src/main/java/org/apache/sshd/cli/CliSupport.java
+++ b/sshd-cli/src/main/java/org/apache/sshd/cli/CliSupport.java
@@ -20,7 +20,10 @@ package org.apache.sshd.cli;
 
 import java.io.IOException;
 import java.io.PrintStream;
+import java.io.PrintWriter;
 import java.net.SocketAddress;
+import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.logging.Level;
 
@@ -35,6 +38,9 @@ import org.apache.sshd.common.io.IoAcceptor;
 import org.apache.sshd.common.io.IoConnector;
 import org.apache.sshd.common.io.IoServiceEventListener;
 import org.apache.sshd.common.io.IoServiceFactoryFactory;
+import org.apache.sshd.common.kex.KexProposalOption;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.session.SessionListener;
 import org.apache.sshd.common.util.GenericUtils;
 
 /**
@@ -131,9 +137,27 @@ public abstract class CliSupport {
             return manager;
         }
 
-        manager.setIoServiceEventListener(new IoServiceEventListener() {
-            private final PrintStream out = Level.INFO.equals(level) ? stderr : stdout;
+        PrintStream out = Level.INFO.equals(level) ? stderr : stdout;
+        manager.setIoServiceEventListener(createLoggingIoServiceEventListener(out));
+        manager.addSessionListener(createLoggingSessionListener(out));
+        return manager;
+    }
+
+    public static void printStackTrace(Appendable out, Throwable reason) {
+        if ((reason == null) || (out == null)) {
+            return;
+        }
 
+        if (out instanceof PrintStream) {
+            reason.printStackTrace((PrintStream) out);
+        } else if (out instanceof PrintWriter) {
+            reason.printStackTrace((PrintWriter) out);
+        }
+    }
+
+    @SuppressWarnings("checkstyle:anoninnerlength")
+    public static IoServiceEventListener createLoggingIoServiceEventListener(Appendable out) {
+        return new IoServiceEventListener() {
             @Override
             public void connectionEstablished(
                     IoConnector connector, SocketAddress local, AttributeRepository context, SocketAddress remote)
@@ -141,7 +165,7 @@ public abstract class CliSupport {
                 out.append("Connection established via ").append(Objects.toString(connector))
                     .append("- local=").append(Objects.toString(local))
                     .append(", remote=").append(Objects.toString(remote))
-                    .println();
+                    .append(System.lineSeparator());
             }
 
             @Override
@@ -152,8 +176,9 @@ public abstract class CliSupport {
                     .append(" - local=").append(Objects.toString(local))
                     .append(", remote=").append(Objects.toString(remote))
                     .append(": (").append(reason.getClass().getSimpleName()).append(')')
-                    .append(" ").println(reason.getMessage());
-                reason.printStackTrace(out);
+                    .append(' ').append(reason.getMessage())
+                    .append(System.lineSeparator());
+                printStackTrace(out, reason);
             }
 
             @Override
@@ -163,7 +188,7 @@ public abstract class CliSupport {
                     .append(" - local=").append(Objects.toString(local))
                     .append(", remote=").append(Objects.toString(remote))
                     .append(", service=").append(Objects.toString(service))
-                    .println();
+                    .append(System.lineSeparator());
             }
 
             @Override
@@ -175,12 +200,82 @@ public abstract class CliSupport {
                     .append(", remote=").append(Objects.toString(remote))
                     .append(", service=").append(Objects.toString(service))
                     .append(": (").append(reason.getClass().getSimpleName()).append(')')
-                    .append(" ").println(reason.getMessage());
-                reason.printStackTrace(out);
+                    .append(' ').append(reason.getMessage())
+                    .append(System.lineSeparator());
+                printStackTrace(out, reason);
             }
-        });
+        };
+    }
 
-        return manager;
+    @SuppressWarnings("checkstyle:anoninnerlength")
+    public static SessionListener createLoggingSessionListener(Appendable out) {
+        return new SessionListener() {
+            @Override
+            public void sessionPeerIdentificationReceived(
+                    Session session, String version, List<String> extraLines) {
+                try {
+                    out.append(Objects.toString(session))
+                        .append(" peer identification=").append(version)
+                        .append(System.lineSeparator());
+                    if (GenericUtils.isNotEmpty(extraLines)) {
+                        for (String l : extraLines) {
+                            out.append("    => ").append(l).append(System.lineSeparator());
+                        }
+                    }
+                } catch (IOException e) {
+                    // ignored
+                }
+            }
+
+            @Override
+            public void sessionNegotiationEnd(Session session,
+                    Map<KexProposalOption, String> clientProposal,
+                    Map<KexProposalOption, String> serverProposal,
+                    Map<KexProposalOption, String> negotiatedOptions,
+                    Throwable reason) {
+                if (reason != null) {
+                    return;
+                }
+
+                try {
+                    out.append(Objects.toString(session))
+                        .append(" KEX negotiation results:")
+                        .append(System.lineSeparator());
+                    for (KexProposalOption opt : KexProposalOption.VALUES) {
+                        String value = negotiatedOptions.get(opt);
+                        out.append("    ").append(opt.getDescription())
+                            .append(": ").append(value)
+                            .append(System.lineSeparator());
+                    }
+                } catch (IOException e) {
+                    // ignored
+                }
+            }
+
+            @Override
+            public void sessionException(Session session, Throwable t) {
+                try {
+                    out.append(Objects.toString(session))
+                        .append(' ').append(t.getClass().getSimpleName())
+                        .append(": ").append(t.getMessage())
+                        .append(System.lineSeparator());
+                    printStackTrace(out, t);
+                } catch (IOException e) {
+                    // ignored
+                }
+            }
+
+            @Override
+            public void sessionClosed(Session session) {
+                try {
+                    out.append(Objects.toString(session))
+                        .append(" closed")
+                        .append(System.lineSeparator());
+                } catch (IOException e) {
+                    // ignored
+                }
+            }
+        };
     }
 
     public static Level resolveLoggingVerbosity(String... args) {


[mina-sshd] 04/06: [SSHD-948] Do not accept password change request if the session does not use MAC(s) for packet validation

Posted by lg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit e1f57616b3ea65951ea9365d44fc44607211cb49
Author: Lyor Goldstein <lg...@apache.org>
AuthorDate: Wed Oct 16 11:20:03 2019 +0300

    [SSHD-948] Do not accept password change request if the session does not use MAC(s) for packet validation
---
 CHANGES.md                                         |  4 ++
 .../apache/sshd/common/session/SessionContext.java | 24 ++++++++++++
 .../client/auth/password/UserAuthPassword.java     |  7 ++++
 .../sshd/common/auth/UserAuthMethodFactory.java    | 29 ++++++++++++++
 .../auth/password/PasswordAuthenticator.java       | 20 +++++++++-
 .../server/auth/password/UserAuthPassword.java     | 38 +++++++++++++-----
 .../server/jaas/JaasPasswordAuthenticator.java     | 16 ++++----
 .../sshd/common/auth/AuthenticationTest.java       | 45 +++++++++-------------
 .../server/jaas/JaasPasswordAuthenticatorTest.java | 14 ++++---
 .../sshd/util/test/BogusPasswordAuthenticator.java |  6 ++-
 .../auth/password/LdapPasswordAuthenticator.java   |  9 +++--
 11 files changed, 156 insertions(+), 56 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index b9f692d..6ac150d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -40,6 +40,10 @@ of their invocation (if any)
 * Default MAC(s) list is set according to the [ssh_config(5)](https://www.freebsd.org/cgi/man.cgi?query=ssh_config&sektion=5)
 order as **first** ones, where the supported MAC(s) that do no appear in it come last.
 
+* `PasswordAuthenticator` has a `handleClientPasswordChangeRequest` method that is invoked if
+a password change has been indicated by the user during authentication via the "password"
+method - by default throws `UnsupportedOperationException`.
+
 ## Minor code helpers
 
 * `SessionListener` supports `sessionPeerIdentificationReceived` method that is invoked once successful
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/session/SessionContext.java b/sshd-common/src/main/java/org/apache/sshd/common/session/SessionContext.java
index c6ab1fc..a394868 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/session/SessionContext.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/session/SessionContext.java
@@ -131,6 +131,8 @@ public interface SessionContext
      * @param session The {@link SessionContext} to be examined
      * @return {@code true} if the context is not {@code null} and the ciphers
      * have been established to anything other than &quot;none&quot;.
+     * @see #getNegotiatedKexParameter(KexProposalOption) getNegotiatedKexParameter
+     * @see KexProposalOption#CIPHER_PROPOSALS CIPHER_PROPOSALS
      */
     static boolean isSecureSessionTransport(SessionContext session) {
         if (session == null) {
@@ -147,4 +149,26 @@ public interface SessionContext
 
         return true;
     }
+
+    /**
+     * @param session The {@link SessionContext} to be examined
+     * @return {@code true} if the context is not {@code null} and the MAC(s)
+     * used to verify packet integrity have been established.
+     * @see #getNegotiatedKexParameter(KexProposalOption) getNegotiatedKexParameter
+     * @see KexProposalOption#MAC_PROPOSALS MAC_PROPOSALS
+     */
+    static boolean isDataIntegrityTransport(SessionContext session) {
+        if (session == null) {
+            return false;
+        }
+
+        for (KexProposalOption opt : KexProposalOption.MAC_PROPOSALS) {
+            String value = session.getNegotiatedKexParameter(opt);
+            if (GenericUtils.isEmpty(value)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
 }
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/password/UserAuthPassword.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/password/UserAuthPassword.java
index 119ad99..08db76c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/password/UserAuthPassword.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/password/UserAuthPassword.java
@@ -99,6 +99,13 @@ public class UserAuthPassword extends AbstractUserAuth {
             return false;
         }
 
+        if (!UserAuthMethodFactory.isDataIntegrityAuthenticationTransport(session)) {
+            if (debugEnabled) {
+                log.debug("processAuthDataRequest({})[{}] session is not validated via MAC", session, service);
+            }
+            return false;
+        }
+
         String prompt = buffer.getString();
         String lang = buffer.getString();
         UserInteraction ui = session.getUserInteraction();
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/auth/UserAuthMethodFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/auth/UserAuthMethodFactory.java
index 37a8768..94b688c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/auth/UserAuthMethodFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/auth/UserAuthMethodFactory.java
@@ -64,6 +64,14 @@ public interface UserAuthMethodFactory<S extends SessionContext, M extends UserA
     boolean DEFAULT_ALLOW_INSECURE_AUTH = false;
 
     /**
+     * If set to {@code true} then {@link #isDataIntegrityAuthenticationTransport(SessionContext)}
+     * returns {@code true} even if transport has no MAC(s) to verify message integrity
+     */
+    String ALLOW_NON_INTEGRITY_AUTH = "allow-non-integrity-auth";
+
+    boolean DEFAULT_ALLOW_NON_INTEGRITY_AUTH = false;
+
+    /**
      * @param session The session for which authentication is required
      * @return The authenticator instance
      * @throws IOException If failed to create the instance
@@ -121,4 +129,25 @@ public interface UserAuthMethodFactory<S extends SessionContext, M extends UserA
 
         return SessionContext.isSecureSessionTransport(session);
     }
+
+    /**
+     * @param session The {@link SessionContext} being used for authentication
+     * @return {@code true} if the context is not {@code null} and the MAC(s)
+     * used to verify packet integrity have been established.
+     * @see {@value #ALLOW_NON_INTEGRITY_AUTH}
+     * @see SessionContext#isDataIntegrityTransport(SessionContext)
+     */
+    static boolean isDataIntegrityAuthenticationTransport(SessionContext session) {
+        if (session == null) {
+            return false;
+        }
+
+        boolean allowNonValidated = PropertyResolverUtils.getBooleanProperty(
+            session, ALLOW_NON_INTEGRITY_AUTH, DEFAULT_ALLOW_NON_INTEGRITY_AUTH);
+        if (allowNonValidated) {
+            return true;
+        }
+
+        return SessionContext.isDataIntegrityTransport(session);
+    }
 }
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/password/PasswordAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/password/PasswordAuthenticator.java
index fcc91e1..9cf3d6c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/password/PasswordAuthenticator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/password/PasswordAuthenticator.java
@@ -40,5 +40,23 @@ public interface PasswordAuthenticator {
      * @throws AsyncAuthException If the authentication is performed asynchronously
      */
     boolean authenticate(String username, String password, ServerSession session)
-            throws PasswordChangeRequiredException, AsyncAuthException;
+        throws PasswordChangeRequiredException, AsyncAuthException;
+
+    /**
+     * Invoked when the client sends a {@code SSH_MSG_USERAUTH_REQUEST} indicating
+     * a password change. This can happen if the {@code authenticate} method
+     * threw {@link PasswordChangeRequiredException} thus telling the client that
+     * it needs to provide a new password. Throws {@link UnsupportedOperationException}
+     * by default.
+     *
+     * @param session  The {@link ServerSession} attempting the authentication
+     * @param username The username credential
+     * @param oldPassword The old password
+     * @param newPassword The new password
+     * @return {@code true} if password change accepted
+     */
+    default boolean handleClientPasswordChangeRequest(
+            ServerSession session, String username, String oldPassword, String newPassword) {
+        throw new UnsupportedOperationException("Password change not supported");
+    }
 }
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/password/UserAuthPassword.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/password/UserAuthPassword.java
index 6c5be5e..cc94cb6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/password/UserAuthPassword.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/password/UserAuthPassword.java
@@ -43,13 +43,22 @@ public class UserAuthPassword extends AbstractUserAuth {
     public Boolean doAuth(Buffer buffer, boolean init) throws Exception {
         ValidateUtils.checkTrue(init, "Instance not initialized");
 
+        ServerSession session = getServerSession();
+        if (!UserAuthMethodFactory.isSecureAuthenticationTransport(session)) {
+            if (log.isDebugEnabled()) {
+                log.debug("doAuth({}) session is not secure", session);
+            }
+            return false;
+        }
+
+        String username = getUsername();
         boolean newPassword = buffer.getBoolean();
         String password = buffer.getString();
         if (newPassword) {
             return handleClientPasswordChangeRequest(
-                buffer, getServerSession(), getUsername(), password, buffer.getString());
+                buffer, session, username, password, buffer.getString());
         } else {
-            return checkPassword(buffer, getServerSession(), getUsername(), password);
+            return checkPassword(buffer, session, username, password);
         }
     }
 
@@ -74,13 +83,6 @@ public class UserAuthPassword extends AbstractUserAuth {
             Buffer buffer, ServerSession session, String username, String password)
                 throws Exception {
         boolean debugEnabled = log.isDebugEnabled();
-        if (!UserAuthMethodFactory.isSecureAuthenticationTransport(session)) {
-            if (debugEnabled) {
-                log.debug("checkPassword({}) session is not secure", session);
-            }
-            return false;
-        }
-
         PasswordAuthenticator auth = session.getPasswordAuthenticator();
         if (auth == null) {
             if (debugEnabled) {
@@ -132,7 +134,23 @@ public class UserAuthPassword extends AbstractUserAuth {
     protected Boolean handleClientPasswordChangeRequest(
             Buffer buffer, ServerSession session, String username, String oldPassword, String newPassword)
                 throws Exception {
-        throw new UnsupportedOperationException("Password change not supported");
+        boolean debugEnabled = log.isDebugEnabled();
+        if (!UserAuthMethodFactory.isDataIntegrityAuthenticationTransport(session)) {
+            if (debugEnabled) {
+                log.debug("handleClientPasswordChangeRequest({}) session is not validated via MAC", session);
+            }
+            return false;
+        }
+
+        PasswordAuthenticator auth = session.getPasswordAuthenticator();
+        if (auth == null) {
+            if (debugEnabled) {
+                log.debug("handleClientPasswordChangeRequest({}) no password authenticator", session);
+            }
+            return false;
+        }
+
+        return auth.handleClientPasswordChangeRequest(session, username, oldPassword, newPassword);
     }
 
     /**
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticator.java
index 30d0d89..70e3594 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticator.java
@@ -35,7 +35,6 @@ import org.apache.sshd.server.session.ServerSession;
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class JaasPasswordAuthenticator extends AbstractLoggingBean implements PasswordAuthenticator {
-
     private String domain;
 
     public JaasPasswordAuthenticator() {
@@ -55,14 +54,11 @@ public class JaasPasswordAuthenticator extends AbstractLoggingBean implements Pa
     }
 
     @Override
-    public boolean authenticate(String username, String password, ServerSession session) {
-        return authenticate(username, password);
-    }
-
-    public boolean authenticate(final String username, final String password) {
+    public boolean authenticate(
+            String username, String password, ServerSession session) {
         try {
             Subject subject = new Subject();
-            LoginContext loginContext = new LoginContext(domain, subject, callbacks -> {
+            LoginContext loginContext = new LoginContext(getDomain(), subject, callbacks -> {
                 for (Callback callback : callbacks) {
                     if (callback instanceof NameCallback) {
                         ((NameCallback) callback).setName(username);
@@ -77,7 +73,11 @@ public class JaasPasswordAuthenticator extends AbstractLoggingBean implements Pa
             loginContext.logout();
             return true;
         } catch (Exception e) {
-            log.error("Authentication failed with error", e);
+            log.warn("authenticate({}) failed ({}) to authenticate user={}: {}",
+                session, e.getClass().getSimpleName(), username, e.getMessage());
+            if (log.isDebugEnabled()) {
+                log.debug("authenticate(" + session + ")[" + username + "] failure details", e);
+            }
             return false;
         }
     }
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java b/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
index 8082416..dd95792 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
@@ -174,37 +174,30 @@ public class AuthenticationTest extends BaseTestSupport {
     public void testChangePassword() throws Exception {
         PasswordAuthenticator delegate = sshd.getPasswordAuthenticator();
         AtomicInteger attemptsCount = new AtomicInteger(0);
-        sshd.setPasswordAuthenticator((username, password, session) -> {
-            if (attemptsCount.incrementAndGet() == 1) {
-                throw new PasswordChangeRequiredException(attemptsCount.toString(),
+        AtomicInteger changesCount = new AtomicInteger(0);
+        sshd.setPasswordAuthenticator(new PasswordAuthenticator() {
+            @Override
+            public boolean authenticate(String username, String password, ServerSession session) {
+                if (attemptsCount.incrementAndGet() == 1) {
+                    throw new PasswordChangeRequiredException(attemptsCount.toString(),
                         getCurrentTestName(), ServerAuthenticationManager.DEFAULT_WELCOME_BANNER_LANGUAGE);
-            }
+                }
 
-            return delegate.authenticate(username, password, session);
-        });
+                return delegate.authenticate(username, password, session);
+            }
 
-        AtomicInteger changesCount = new AtomicInteger(0);
-        sshd.setUserAuthFactories(Collections.singletonList(
-            new org.apache.sshd.server.auth.password.UserAuthPasswordFactory() {
-                @Override
-                public org.apache.sshd.server.auth.password.UserAuthPassword createUserAuth(ServerSession session) throws IOException {
-                    return new org.apache.sshd.server.auth.password.UserAuthPassword() {
-                        @Override
-                        protected Boolean handleClientPasswordChangeRequest(
-                                Buffer buffer, ServerSession session, String username, String oldPassword, String newPassword)
-                                    throws Exception {
-                            if (changesCount.incrementAndGet() == 1) {
-                                assertNotEquals("Non-different passwords", oldPassword, newPassword);
-                                return checkPassword(buffer, session, username, newPassword);
-                            } else {
-                                return super.handleClientPasswordChangeRequest(
-                                    buffer, session, username, oldPassword, newPassword);
-                            }
-                        }
-                    };
+            @Override
+            public boolean handleClientPasswordChangeRequest(
+                    ServerSession session, String username, String oldPassword, String newPassword) {
+                if (changesCount.incrementAndGet() == 1) {
+                    assertNotEquals("Non-different passwords", oldPassword, newPassword);
+                    return authenticate(username, newPassword, session);
+                } else {
+                    return PasswordAuthenticator.super.handleClientPasswordChangeRequest(
+                        session, username, oldPassword, newPassword);
                 }
             }
-        ));
+        });
         PropertyResolverUtils.updateProperty(sshd,
             ServerAuthenticationManager.AUTH_METHODS, UserAuthPasswordFactory.NAME);
 
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticatorTest.java b/sshd-core/src/test/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticatorTest.java
index cd0114e..f87a2f1 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticatorTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticatorTest.java
@@ -82,11 +82,13 @@ public class JaasPasswordAuthenticatorTest extends BaseTestSupport {
     @Test
     public void testAuthenticator() {
         JaasPasswordAuthenticator auth = new JaasPasswordAuthenticator();
-        assertNull(auth.getDomain());
+        assertNull("Unexpected initial domain", auth.getDomain());
+
         auth.setDomain("domain");
-        assertEquals("domain", auth.getDomain());
-        assertTrue(auth.authenticate("sshd", "sshd"));
-        assertFalse(auth.authenticate("sshd", "dummy"));
+        assertEquals("Mismatched domain", "domain", auth.getDomain());
+
+        assertTrue(auth.authenticate("sshd", "sshd", null));
+        assertFalse(auth.authenticate("sshd", "dummy", null));
     }
 
     protected static class DummyLoginModule implements LoginModule {
@@ -102,7 +104,9 @@ public class JaasPasswordAuthenticatorTest extends BaseTestSupport {
         }
 
         @Override
-        public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState, Map<String, ?> options) {
+        public void initialize(
+                Subject subject, CallbackHandler callbackHandler,
+                Map<String, ?> sharedState, Map<String, ?> options) {
             this.subject = subject;
             this.callbackHandler = callbackHandler;
         }
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/BogusPasswordAuthenticator.java b/sshd-core/src/test/java/org/apache/sshd/util/test/BogusPasswordAuthenticator.java
index 47df909..1382ac9 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/test/BogusPasswordAuthenticator.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/test/BogusPasswordAuthenticator.java
@@ -23,7 +23,8 @@ import org.apache.sshd.server.auth.password.PasswordAuthenticator;
 import org.apache.sshd.server.session.ServerSession;
 
 /**
- * TODO Add javadoc
+ * A test {@link PasswordAuthenticator} that accepts an authentication
+ * attempt if the username is not {@code null} and same as password
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
@@ -38,7 +39,8 @@ public class BogusPasswordAuthenticator extends AbstractLoggingBean implements P
     public boolean authenticate(String username, String password, ServerSession session) {
         boolean result = (username != null) && username.equals(password);
         if (log.isDebugEnabled()) {
-            log.debug("authenticate({}) {} / {} - success = {}", session, username, password, result);
+            log.debug("authenticate({}) {} / {} - success={}",
+                session, username, password, result);
         }
 
         return result;
diff --git a/sshd-ldap/src/main/java/org/apache/sshd/server/auth/password/LdapPasswordAuthenticator.java b/sshd-ldap/src/main/java/org/apache/sshd/server/auth/password/LdapPasswordAuthenticator.java
index 83165e7..6413d79 100644
--- a/sshd-ldap/src/main/java/org/apache/sshd/server/auth/password/LdapPasswordAuthenticator.java
+++ b/sshd-ldap/src/main/java/org/apache/sshd/server/auth/password/LdapPasswordAuthenticator.java
@@ -62,14 +62,14 @@ public class LdapPasswordAuthenticator extends LdapAuthenticator implements Pass
     }
 
     @Override
-    public boolean authenticate(String username, String password, ServerSession session) throws PasswordChangeRequiredException {
+    public boolean authenticate(String username, String password, ServerSession session)
+            throws PasswordChangeRequiredException {
         try {
             Map<String, ?> attrs = resolveAttributes(username, password, session);
             return authenticate(username, password, session, attrs);
         } catch (NamingException | RuntimeException e) {
             log.warn("authenticate({}@{}) failed ({}) to query: {}",
-                      username, session, e.getClass().getSimpleName(), e.getMessage());
-
+                  username, session, e.getClass().getSimpleName(), e.getMessage());
             if (log.isDebugEnabled()) {
                 log.debug("authenticate(" + username + "@" + session + ") query failure details", e);
             }
@@ -78,7 +78,8 @@ public class LdapPasswordAuthenticator extends LdapAuthenticator implements Pass
         }
     }
 
-    protected boolean authenticate(String username, String password, ServerSession session, Map<String, ?> attrs) {
+    protected boolean authenticate(
+            String username, String password, ServerSession session, Map<String, ?> attrs) {
         /*
          * By default we assume that the user + password are the same for
          * accessing the LDAP as the user's account, so the very LDAP query


[mina-sshd] 03/06: [SSHD-948] Do not accept password authentication if the session is not encrypted

Posted by lg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit 0f7091fe60b7c13db03556754a6f7ca9e975e54d
Author: Lyor Goldstein <lg...@apache.org>
AuthorDate: Wed Oct 16 09:03:25 2019 +0300

    [SSHD-948] Do not accept password authentication if the session is not encrypted
---
 CHANGES.md                                         |  4 ++-
 .../apache/sshd/common/session/SessionContext.java | 22 ++++++++++++
 .../client/auth/password/UserAuthPassword.java     | 39 +++++++++++++++++-----
 .../sshd/common/auth/UserAuthMethodFactory.java    | 39 ++++++++++++++++++++++
 .../server/auth/password/UserAuthPassword.java     | 25 ++++++++++----
 .../sshd/server/session/AbstractServerSession.java | 15 +++++----
 .../sshd/common/auth/AuthenticationTest.java       |  3 +-
 7 files changed, 124 insertions(+), 23 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 73664a9..b9f692d 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -80,10 +80,12 @@ exchange via properties.
 
 * [SSHD-943](https://issues.apache.org/jira/browse/SSHD-943) - Provide session instance when KEX factory is invoked in order to create a KeyExchange instance.
 
-* [SSHD-945](https://issues.apache.org/jira/browse/SSHD-945) - Added sshd-contrib code that uses SHA1 with DSA regardless of its key length
+* [SSHD-945](https://issues.apache.org/jira/browse/SSHD-945) - Added sshd-contrib code that uses SHA1 with DSA regardless of its key length.
 
 * [SSHD-946](https://issues.apache.org/jira/browse/SSHD-946) - Supporting 'encrypt-then-MAC' mode.
 
 * [SSHD-947](https://issues.apache.org/jira/browse/SSHD-947) - Added configuration allowing the user to specify whether client should wait
 for the server's identification before sending KEX-INIT message.
 
+* [SSHD-948](https://issues.apache.org/jira/browse/SSHD-948) - Do not accept password authentication if the session is not encrypted.
+
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/session/SessionContext.java b/sshd-common/src/main/java/org/apache/sshd/common/session/SessionContext.java
index 23d5c60..c6ab1fc 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/session/SessionContext.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/session/SessionContext.java
@@ -23,6 +23,7 @@ import java.util.Map;
 
 import org.apache.sshd.common.AttributeStore;
 import org.apache.sshd.common.auth.UsernameHolder;
+import org.apache.sshd.common.cipher.BuiltinCiphers;
 import org.apache.sshd.common.kex.KexProposalOption;
 import org.apache.sshd.common.kex.KexState;
 import org.apache.sshd.common.util.GenericUtils;
@@ -125,4 +126,25 @@ public interface SessionContext
         return GenericUtils.isNotEmpty(version)
             && (version.startsWith(DEFAULT_SSH_VERSION_PREFIX) || version.startsWith(FALLBACK_SSH_VERSION_PREFIX));
     }
+
+    /**
+     * @param session The {@link SessionContext} to be examined
+     * @return {@code true} if the context is not {@code null} and the ciphers
+     * have been established to anything other than &quot;none&quot;.
+     */
+    static boolean isSecureSessionTransport(SessionContext session) {
+        if (session == null) {
+            return false;
+        }
+
+        for (KexProposalOption opt : KexProposalOption.CIPHER_PROPOSALS) {
+            String value = session.getNegotiatedKexParameter(opt);
+            if (GenericUtils.isEmpty(value)
+                    || BuiltinCiphers.Constants.NONE.equalsIgnoreCase(value)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
 }
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/password/UserAuthPassword.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/password/UserAuthPassword.java
index 6785305..119ad99 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/password/UserAuthPassword.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/password/UserAuthPassword.java
@@ -27,12 +27,14 @@ import org.apache.sshd.client.auth.keyboard.UserInteraction;
 import org.apache.sshd.client.session.ClientSession;
 import org.apache.sshd.common.RuntimeSshException;
 import org.apache.sshd.common.SshConstants;
+import org.apache.sshd.common.auth.UserAuthMethodFactory;
 import org.apache.sshd.common.io.IoWriteFuture;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
 
 /**
- * Implements the &quot;password&quot; authentication mechanism
+ * Implements the client-side &quot;password&quot; authentication mechanism
+ *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public class UserAuthPassword extends AbstractUserAuth {
@@ -53,6 +55,13 @@ public class UserAuthPassword extends AbstractUserAuth {
 
     @Override
     protected boolean sendAuthDataRequest(ClientSession session, String service) throws Exception {
+        if (!UserAuthMethodFactory.isSecureAuthenticationTransport(session)) {
+            if (log.isDebugEnabled()) {
+                log.debug("sendAuthDataRequest({})[{}] session is not secure", session, service);
+            }
+            return false;
+        }
+
         if ((passwords == null) || (!passwords.hasNext())) {
             if (log.isDebugEnabled()) {
                 log.debug("sendAuthDataRequest({})[{}] no more passwords to send", session, service);
@@ -64,17 +73,30 @@ public class UserAuthPassword extends AbstractUserAuth {
         current = passwords.next();
         String username = session.getUsername();
         Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_USERAUTH_REQUEST,
-                username.length() + service.length() + getName().length() + current.length() + Integer.SIZE);
+            username.length() + service.length()
+            + GenericUtils.length(getName()) + current.length()
+            + Integer.SIZE /* a few extra encoding fields overhead */);
         sendPassword(buffer, session, current, current);
         return true;
     }
 
     @Override
-    protected boolean processAuthDataRequest(ClientSession session, String service, Buffer buffer) throws Exception {
+    protected boolean processAuthDataRequest(
+            ClientSession session, String service, Buffer buffer)
+                throws Exception {
         int cmd = buffer.getUByte();
         if (cmd != SshConstants.SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) {
-            throw new IllegalStateException("processAuthDataRequest(" + session + ")[" + service + "]"
-                            + " received unknown packet: cmd=" + SshConstants.getCommandMessageName(cmd));
+            throw new IllegalStateException(
+                "processAuthDataRequest(" + session + ")[" + service + "]"
+                + " received unknown packet: cmd=" + SshConstants.getCommandMessageName(cmd));
+        }
+
+        boolean debugEnabled = log.isDebugEnabled();
+        if (!UserAuthMethodFactory.isSecureAuthenticationTransport(session)) {
+            if (debugEnabled) {
+                log.debug("processAuthDataRequest({})[{}] session is not secure", session, service);
+            }
+            return false;
         }
 
         String prompt = buffer.getString();
@@ -82,7 +104,6 @@ public class UserAuthPassword extends AbstractUserAuth {
         UserInteraction ui = session.getUserInteraction();
         boolean interactive;
         String password;
-        boolean debugEnabled = log.isDebugEnabled();
         try {
             interactive = (ui != null) && ui.isInteractionAllowed(session);
             password = interactive ? ui.getUpdatedPassword(session, prompt, lang) : null;
@@ -131,14 +152,16 @@ public class UserAuthPassword extends AbstractUserAuth {
      * on the success/failure of the request packet being sent
      * @throws IOException If failed to send the message.
      */
-    protected IoWriteFuture sendPassword(Buffer buffer, ClientSession session, String oldPassword, String newPassword) throws IOException {
+    protected IoWriteFuture sendPassword(
+            Buffer buffer, ClientSession session, String oldPassword, String newPassword)
+                throws IOException {
         String username = session.getUsername();
         String service = getService();
         String name = getName();
         boolean modified = !Objects.equals(oldPassword, newPassword);
         if (log.isDebugEnabled()) {
             log.debug("sendPassword({})[{}] send SSH_MSG_USERAUTH_REQUEST for {} - modified={}",
-                      session, service, name, modified);
+                  session, service, name, modified);
         }
 
         buffer = session.createBuffer(SshConstants.SSH_MSG_USERAUTH_REQUEST,
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/auth/UserAuthMethodFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/auth/UserAuthMethodFactory.java
index 4004120..37a8768 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/auth/UserAuthMethodFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/auth/UserAuthMethodFactory.java
@@ -23,6 +23,7 @@ import java.io.IOException;
 import java.util.Collection;
 
 import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.PropertyResolverUtils;
 import org.apache.sshd.common.session.SessionContext;
 
 /**
@@ -55,6 +56,14 @@ public interface UserAuthMethodFactory<S extends SessionContext, M extends UserA
     String HOST_BASED = "hostbased";
 
     /**
+     * If set to {@code true} then {@link #isSecureAuthenticationTransport(SessionContext)}
+     * returns {@code true} even if transport is insecure.
+     */
+    String ALLOW_INSECURE_AUTH = "allow-insecure-auth";
+
+    boolean DEFAULT_ALLOW_INSECURE_AUTH = false;
+
+    /**
      * @param session The session for which authentication is required
      * @return The authenticator instance
      * @throws IOException If failed to create the instance
@@ -82,4 +91,34 @@ public interface UserAuthMethodFactory<S extends SessionContext, M extends UserA
             return null;
         }
     }
+
+    /**
+     * According to <A HREF="https://tools.ietf.org/html/rfc4252#section-8">RFC 4252 - section 8</A>:
+     * <PRE>
+     *      Both the server and the client should check whether the underlying
+     *      transport layer provides confidentiality (i.e., if encryption is
+     *      being used).  If no confidentiality is provided ("none" cipher),
+     *      password authentication SHOULD be disabled.  If there is no
+     *      confidentiality or no MAC, password change SHOULD be disabled.
+     * </PRE>
+     *
+     * @param session The {@link SessionContext} being used for authentication
+     * @return {@code true} if the context is not {@code null} and the ciphers
+     * have been established to anything other than &quot;none&quot;.
+     * @see {@value #ALLOW_INSECURE_AUTH}
+     * @see SessionContext#isSecureSessionTransport(SessionContext)
+     */
+    static boolean isSecureAuthenticationTransport(SessionContext session) {
+        if (session == null) {
+            return false;
+        }
+
+        boolean allowInsecure = PropertyResolverUtils.getBooleanProperty(
+            session, ALLOW_INSECURE_AUTH, DEFAULT_ALLOW_INSECURE_AUTH);
+        if (allowInsecure) {
+            return true;
+        }
+
+        return SessionContext.isSecureSessionTransport(session);
+    }
 }
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/password/UserAuthPassword.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/password/UserAuthPassword.java
index 4a39af7..6c5be5e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/password/UserAuthPassword.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/password/UserAuthPassword.java
@@ -20,6 +20,7 @@ package org.apache.sshd.server.auth.password;
 
 import org.apache.sshd.common.RuntimeSshException;
 import org.apache.sshd.common.SshConstants;
+import org.apache.sshd.common.auth.UserAuthMethodFactory;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.ValidateUtils;
 import org.apache.sshd.common.util.buffer.Buffer;
@@ -27,7 +28,7 @@ import org.apache.sshd.server.auth.AbstractUserAuth;
 import org.apache.sshd.server.session.ServerSession;
 
 /**
- * TODO Add javadoc
+ * Implements the server-side &quot;password&quot; authentication mechanism
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
@@ -45,7 +46,8 @@ public class UserAuthPassword extends AbstractUserAuth {
         boolean newPassword = buffer.getBoolean();
         String password = buffer.getString();
         if (newPassword) {
-            return handleClientPasswordChangeRequest(buffer, getServerSession(), getUsername(), password, buffer.getString());
+            return handleClientPasswordChangeRequest(
+                buffer, getServerSession(), getUsername(), password, buffer.getString());
         } else {
             return checkPassword(buffer, getServerSession(), getUsername(), password);
         }
@@ -68,9 +70,18 @@ public class UserAuthPassword extends AbstractUserAuth {
      * {@link PasswordChangeRequiredException} which is handled internally)
      * @see #handleServerPasswordChangeRequest(Buffer, ServerSession, String, String, PasswordChangeRequiredException)
      */
-    protected Boolean checkPassword(Buffer buffer, ServerSession session, String username, String password) throws Exception {
-        PasswordAuthenticator auth = session.getPasswordAuthenticator();
+    protected Boolean checkPassword(
+            Buffer buffer, ServerSession session, String username, String password)
+                throws Exception {
         boolean debugEnabled = log.isDebugEnabled();
+        if (!UserAuthMethodFactory.isSecureAuthenticationTransport(session)) {
+            if (debugEnabled) {
+                log.debug("checkPassword({}) session is not secure", session);
+            }
+            return false;
+        }
+
+        PasswordAuthenticator auth = session.getPasswordAuthenticator();
         if (auth == null) {
             if (debugEnabled) {
                 log.debug("checkPassword({}) no password authenticator", session);
@@ -84,13 +95,14 @@ public class UserAuthPassword extends AbstractUserAuth {
                 authed = auth.authenticate(username, password, session);
             } catch (Error e) {
                 log.warn("checkPassword({}) failed ({}) to consult authenticator: {}",
-                         session, e.getClass().getSimpleName(), e.getMessage());
+                     session, e.getClass().getSimpleName(), e.getMessage());
                 if (debugEnabled) {
                     log.debug("checkPassword(" + session + ") authenticator failure details", e);
                 }
 
                 throw new RuntimeSshException(e);
             }
+
             if (debugEnabled) {
                 log.debug("checkPassword({}) authentication result: {}", session, authed);
             }
@@ -99,6 +111,7 @@ public class UserAuthPassword extends AbstractUserAuth {
             if (debugEnabled) {
                 log.debug("checkPassword({}) password change required: {}", session, e.getMessage());
             }
+
             return handleServerPasswordChangeRequest(buffer, session, username, password, e);
         }
     }
@@ -143,7 +156,7 @@ public class UserAuthPassword extends AbstractUserAuth {
         String lang = e.getLanguage();
         if (log.isDebugEnabled()) {
             log.debug("handlePasswordChangeRequest({}) password change required - prompt={}, lang={}",
-                      session, prompt, lang);
+                  session, prompt, lang);
         }
 
         buffer = session.createBuffer(SshConstants.SSH_MSG_USERAUTH_PASSWD_CHANGEREQ,
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java b/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
index 08d2d74..7da497a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
@@ -242,7 +242,7 @@ public abstract class AbstractServerSession extends AbstractSession implements S
         FactoryManager factoryManager = getFactoryManager();
         currentService = ServiceFactory.create(
             factoryManager.getServiceFactories(),
-            ValidateUtils.checkNotNullAndNotEmpty(name, "No service name"),
+            ValidateUtils.checkNotNullAndNotEmpty(name, "No service name specified"),
             this);
         /*
          * According to RFC4253:
@@ -404,7 +404,8 @@ public abstract class AbstractServerSession extends AbstractSession implements S
      * @param provided  The available signature types - may be {@code null}/empty
      * @return The resolved proposal - {@code null} by default
      */
-    protected String resolveEmptySignaturesProposal(Iterable<String> supported, Iterable<String> provided) {
+    protected String resolveEmptySignaturesProposal(
+            Iterable<String> supported, Iterable<String> provided) {
         if (log.isDebugEnabled()) {
             log.debug("resolveEmptySignaturesProposal({})[{}] none of the keys appears in supported list: {}",
                   this, provided, supported);
@@ -470,7 +471,8 @@ public abstract class AbstractServerSession extends AbstractSession implements S
 
         if (err != null) {
             IoSession networkSession = getIoSession();
-            networkSession.writePacket(new ByteArrayBuffer((err.getMessage() + "\n").getBytes(StandardCharsets.UTF_8)))
+            networkSession.writePacket(
+                    new ByteArrayBuffer((err.getMessage() + "\n").getBytes(StandardCharsets.UTF_8)))
                  .addListener(future -> close(true));
             throw err;
         }
@@ -483,7 +485,8 @@ public abstract class AbstractServerSession extends AbstractSession implements S
     }
 
     @Override
-    protected void receiveKexInit(Map<KexProposalOption, String> proposal, byte[] seed) throws IOException {
+    protected void receiveKexInit(Map<KexProposalOption, String> proposal, byte[] seed)
+            throws IOException {
         mergeProposals(clientProposal, proposal);
         setClientKexData(seed);
     }
@@ -538,9 +541,7 @@ public abstract class AbstractServerSession extends AbstractSession implements S
     }
 
     /**
-     * Returns the session id.
-     *
-     * @return The session id.
+     * @return The underlying {@link IoSession} id.
      */
     public long getId() {
         IoSession networkSession = getIoSession();
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java b/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
index 07e1a76..8082416 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
@@ -197,7 +197,8 @@ public class AuthenticationTest extends BaseTestSupport {
                                 assertNotEquals("Non-different passwords", oldPassword, newPassword);
                                 return checkPassword(buffer, session, username, newPassword);
                             } else {
-                                return super.handleClientPasswordChangeRequest(buffer, session, username, oldPassword, newPassword);
+                                return super.handleClientPasswordChangeRequest(
+                                    buffer, session, username, oldPassword, newPassword);
                             }
                         }
                     };


[mina-sshd] 06/06: [SSHD-914] Added Python 3 script based on Paramiko package to interact with MINA SSHD as an SFTP client

Posted by lg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit 77859da20def8127c2a9c2350f46435a8db68fba
Author: Lyor Goldstein <lg...@apache.org>
AuthorDate: Wed Oct 16 14:17:46 2019 +0300

    [SSHD-914] Added Python 3 script based on Paramiko package to interact with MINA SSHD as an SFTP client
---
 .gitignore                                         |   3 +
 pom.xml                                            |   3 +
 sshd-sources/python/sftpclient.py                  | 406 +++++++++++++++++++++
 .../tomcat-apr-5.5.23-sources/META-INF/INDEX.LIST  |   0
 .../tomcat-apr-5.5.23-sources/META-INF/MANIFEST.MF |   0
 .../tomcat-apr-5.5.23-sources/README.txt           |   0
 .../org/apache/tomcat/jni/Address.java             |   0
 .../org/apache/tomcat/jni/BIOCallback.java         |   0
 .../org/apache/tomcat/jni/Directory.java           |   0
 .../org/apache/tomcat/jni/Error.java               |   0
 .../org/apache/tomcat/jni/File.java                |   0
 .../org/apache/tomcat/jni/FileInfo.java            |   0
 .../org/apache/tomcat/jni/Global.java              |   0
 .../org/apache/tomcat/jni/Library.java             |   0
 .../org/apache/tomcat/jni/Local.java               |   0
 .../org/apache/tomcat/jni/Lock.java                |   0
 .../org/apache/tomcat/jni/Mmap.java                |   0
 .../org/apache/tomcat/jni/Multicast.java           |   0
 .../org/apache/tomcat/jni/OS.java                  |   0
 .../org/apache/tomcat/jni/PasswordCallback.java    |   0
 .../org/apache/tomcat/jni/Poll.java                |   0
 .../org/apache/tomcat/jni/Pool.java                |   0
 .../org/apache/tomcat/jni/PoolCallback.java        |   0
 .../org/apache/tomcat/jni/Proc.java                |   0
 .../org/apache/tomcat/jni/ProcErrorCallback.java   |   0
 .../org/apache/tomcat/jni/Procattr.java            |   0
 .../org/apache/tomcat/jni/Registry.java            |   0
 .../org/apache/tomcat/jni/SSL.java                 |   0
 .../org/apache/tomcat/jni/SSLContext.java          |   0
 .../org/apache/tomcat/jni/SSLSocket.java           |   0
 .../org/apache/tomcat/jni/Shm.java                 |   0
 .../org/apache/tomcat/jni/Sockaddr.java            |   0
 .../org/apache/tomcat/jni/Socket.java              |   0
 .../org/apache/tomcat/jni/Status.java              |   0
 .../org/apache/tomcat/jni/Stdlib.java              |   0
 .../org/apache/tomcat/jni/Thread.java              |   0
 .../org/apache/tomcat/jni/Time.java                |   0
 .../org/apache/tomcat/jni/User.java                |   0
 38 files changed, 412 insertions(+)

diff --git a/.gitignore b/.gitignore
index 485a2b4..39cdffd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,9 @@ Servers/
 RemoteSystemsTempFiles/
 .classpath
 .project
+# Puthon related files
+.pydevproject
+*.pyc
 .checkstyle
 .eclipse-pmd
 .pmd
diff --git a/pom.xml b/pom.xml
index dc7b41f..14cf8e9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -637,6 +637,7 @@
                         <excludes>
                             <exclude>*.md</exclude>
                             <exclude>docs/**</exclude>
+                            <exclude>sshd-sources/**</exclude>
                             <exclude>src/test/resources/**</exclude>
                             <exclude>**/stty-output-*.txt</exclude>
                             <exclude>**/target/**</exclude>
@@ -659,6 +660,8 @@
                             <exclude>.project</exclude>
                             <exclude>.classpath</exclude>
                             <exclude>.springBeans</exclude>
+                            <exclude>.pydevproject</exclude>
+                            <exclude>*.pyc</exclude>
                             <exclude>.settings/**</exclude>
                             <exclude>.repository/**</exclude>
                             <exclude>.gitignore</exclude>
diff --git a/sshd-sources/python/sftpclient.py b/sshd-sources/python/sftpclient.py
new file mode 100644
index 0000000..f8df143
--- /dev/null
+++ b/sshd-sources/python/sftpclient.py
@@ -0,0 +1,406 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+'''
+Simple wrapper for Paramiko SFTP client (see http://www.paramiko.org/)
+'''
+
+import getpass
+import json
+import os
+import signal
+import sys
+
+import paramiko
+
+
+VERSION='1.0'
+
+# -----------------------------------------------------------------------------------------
+
+def die(msg=None,rc=1):
+    """
+    Cleanly exits the program with an error message
+    """
+
+    if msg:
+        print(msg)
+
+    sys.exit(rc)
+
+# ----------------------------------------------------------------------------
+
+def isEmpty(s):
+    if (s is None) or (len(s) <= 0):
+        return True
+    else:
+        return False
+
+# ----------------------------------------------------------------------------
+
+def isNumberString(value):
+    """
+    Checks if value is a string that has only digits - possibly with leading '+' or '-'
+    """
+    if not value:
+        return False
+
+    sign = value[0]
+    if (sign == '+') or (sign == '-'):
+        if len(value) <= 1:
+            return False
+
+        absValue = value[1:]
+        return absValue.isdigit()
+    else:
+        if len(value) <= 0:
+            return False
+        else:
+            return value.isdigit()
+
+def isNumberValue(value):
+    return isinstance(value, (int, float))
+
+# ----------------------------------------------------------------------------
+
+def isFloatingPointString(value):
+    """
+    Checks if value is a string that has only digits - possibly with leading '+' or '-' - AND a single dot
+    """
+    if isEmpty(value):
+        return False
+
+    sign = value[0]
+    if (sign == '+') or (sign == '-'):
+        if len(value) <= 1:
+            return False
+
+        absValue = value[1:]
+    else:
+        absValue = value
+
+    dotPos = absValue.find('.')
+    # Must have a dot and it cannot be the last character
+    if (dotPos < 0) or (dotPos == (len(absValue) - 1)):
+        return False
+
+    # Must have EXACTLY one dot
+    dotCount = absValue.count('.')
+    if dotCount != 1:
+        return False
+
+    # Make sure both sides of the dot are integer numbers
+    intPart = absValue[0:dotPos]
+    if not isNumberString(intPart):
+        return False
+
+    facPart = absValue[dotPos + 1:]
+    # Do not allow 123.-5
+    sign = facPart[0]
+    if (sign == '+') or (sign == '-'):
+        return False
+
+    if not isNumberString(facPart):
+        return False
+
+    return True
+
+# ----------------------------------------------------------------------------
+
+def normalizeValue(value):
+    """
+    Checks if value is 'True', 'False' or all numeric and converts it accordingly
+    Otherwise it just returns it
+
+    Args:
+        value (str) - String value
+    """
+
+    if not value:
+        return value
+
+    loCase = value.lower()
+    if loCase == "none":
+        return None
+    elif loCase == "true":
+        return True
+    elif loCase == "false":
+        return False
+    elif isNumberString(loCase):
+        return int(loCase)
+    else:
+        return value
+
+# ----------------------------------------------------------------------------
+
+def parseCommandLineArguments(args):
+    """
+    Parses an array of arguments having the format: --name=value. If
+    only --name is provided then it is assumed to a TRUE boolean value.
+    If the value is all digits, then it is assumed to be a number.
+
+    If the same key is specified more than once, then a list of
+    the accumulated values is created. The result is a dictionary
+    with the names as the keys and value as their mapped values
+
+    Args:
+        args (str[]) - The command line arguments to parse
+    """
+
+    valsMap = {}
+    if len(args) <= 0:
+        return valsMap
+
+    for item in args:
+        if not item.startswith("--"):
+            raise Exception("Missing option identifier: %s" % item)
+
+        propPair = item[2:]     # strip the prefix
+        sepPos = propPair.find('=')
+
+        if sepPos == 0:
+            raise Exception("Missing name: %s" % item)
+        if sepPos >= (len(propPair) - 1):
+            raise Exception("Missing value: %s" % item)
+
+        propName = propPair
+        propValue = None
+        if sepPos < 0:
+            propValue = True
+        else:
+            propName = propPair[0:sepPos]
+            propValue = normalizeValue(propPair[sepPos + 1:])
+
+        if propName in valsMap:
+            curValue = valsMap[propName]
+            if not isinstance(curValue, list):
+                curValue = [ curValue ]
+            curValue.append(propValue)
+            valsMap[propName] = curValue
+        else:
+            valsMap[propName] = propValue
+
+    return valsMap
+
+# ----------------------------------------------------------------------------
+
+def resolvePathVariables(path):
+    """
+    Expands ~/xxx and ${XXX} variables
+    """
+    if isEmpty(path):
+        return path
+
+    path = os.path.expanduser(path)
+    path = os.path.expandvars(path)
+    return path
+
+# ----------------------------------------------------------------------------
+
+def _decode_list(data):
+    # can happen for internal sub-lists of objects
+    if isinstance(data, dict):
+        return _decode_dict(data)
+
+    rv = []
+    for item in data:
+        if isinstance(item, list):
+            item = _decode_list(item)
+        elif isinstance(item, dict):
+            item = _decode_dict(item)
+        rv.append(item)
+    return rv
+
+# ----------------------------------------------------------------------------
+
+def _decode_dict(data):
+    # can happen for internal sub-lists of objects
+    if isinstance(data, list):
+        return _decode_list(data)
+
+    rv = {}
+    for key, value in data.items():
+        if isinstance(value, list):
+            value = _decode_list(value)
+        elif isinstance(value, dict):
+            value = _decode_dict(value)
+        rv[key] = value
+
+    return rv
+
+# ----------------------------------------------------------------------------
+
+def loadJsonFile(configFile):
+    if isEmpty(configFile):
+        return {}
+
+    with open(configFile) as config_file:
+        return json.load(config_file, object_hook=_decode_dict);
+
+# ----------------------------------------------------------------------------
+
+def createSftpClient(args):
+    host = args.get("host", "localhost")
+    port = args.get("port", 22)
+    username = args.get("username", None)
+    if isEmpty(username):
+        username = getpass.getuser()
+    password = args.get("password", None)
+    keyfile = args.get("keyFile", None)
+    keytype = args.get("keyType", "RSA")
+
+    sftp = None
+    transport = None
+    try:
+        key = None
+        if keyfile is not None:
+            # Get private key used to authenticate user.
+            if keytype == 'DSA':
+                # The private key is a DSA type key.
+                key = paramiko.DSSKey.from_private_key_file(keyfile)
+            else:
+                # The private key is a RSA type key.
+                key = paramiko.RSAKey.from_private_key(keyfile)
+
+        # Create Transport object using supplied method of authentication.
+        transport = paramiko.Transport((host, port))
+        transport.connect(None, username, password, key)
+ 
+        sftp = paramiko.SFTPClient.from_transport(transport)
+        return sftp
+    except Exception as e:
+        print('An error occurred creating SFTP client: %s: %s' % (e.__class__, e))
+
+        if sftp is not None:
+            try:
+                sftp.close()
+            except Exception as err:
+                print('Failed to close SFTP client: %s: %s' % (err.__class__, err))
+
+        if transport is not None:
+            try:
+                transport.close()
+            except Exception as err:
+                print('Failed to close transport: %s: %s' % (err.__class__, err))
+
+        raise e
+    
+# =========================================================================================
+
+def doList(sftp, curdir, argsList):
+    dirPath = curdir;
+    if not isEmpty(argsList):
+        dirPath = argsList.pop(0)
+        dirPath = dirPath.strip()
+        dirPath = os.path.join(curdir, dirPath)
+
+    # Also available: listdir_attr, listdir
+    dirlist = sftp.listdir_iter(path=dirPath)
+    for row in dirlist:
+        # see https://docs.paramiko.org/en/2.6/api/sftp.html#paramiko.sftp_attr.SFTPAttributes
+        print("    %s" % str(row))
+
+def doChdir(sftp, homedir, curdir, argsList):
+    dirPath = homedir
+    if not isEmpty(argsList):
+        dirPath = argsList.pop(0)
+        dirPath = dirPath.strip()
+        dirPath = os.path.join(curdir, dirPath)
+    sftp.chdir(dirPath)
+
+# ----------------------------------------------------------------------------
+
+# see https://github.com/paramiko/paramiko/blob/master/demos/demo_sftp.py
+# see https://docs.paramiko.org/en/2.6/api/sftp.html
+def doSftp(sftp):
+    homedir = sftp.normalize('.')
+    sftp.chdir(homedir)
+    
+    while True:
+        curdir = sftp.getcwd()
+        sys.stdout.write("%s > " % curdir)
+        l = sys.stdin.readline()
+        l = l.strip()
+    
+        if isEmpty(l):
+            continue
+        
+        argsList = l.split(' ')
+        op = argsList.pop(0)
+        
+        if (op == "quit") or (op == "exit") or (op == "bye"):
+            break
+        elif (op == "ls") or (op == "list"):
+            doList(sftp, curdir, argsList)
+        elif (op == "cd"):
+            doChdir(sftp, homedir, curdir, argsList)
+        # TODO get_channel()
+        #    show info using get_transport() on it
+        #    get_security_options() on transport
+        else:
+            print("Unknown command: %s" % l)
+
+def doMain(args):
+    sftp = createSftpClient(args)
+    try:
+        doSftp(sftp);
+    except Exception as e:
+        print('An error occurred using the SFTP client: %s: %s' % (e.__class__, e))
+        raise e
+    finally:
+        sftp.close()
+
+#
+# Usage: python3 sftpclient.py --arg1=value1 --arg2=value2 ...
+#
+# Where available arguments are:
+#
+#    * host - default=localhost
+#    * port - default=22
+#    * username - the login user - default=currently logged in user
+#    * password - the password - can be omitted if key file used
+#    * keyFile - path to key file
+#    * keyType - type of key in file (RSA/DSA) - default=RSA
+def main(args):
+    if len(args) > 0:
+        subArgs = parseCommandLineArguments(args)
+    else:
+        subArgs = {}
+    doMain(subArgs)
+    sys.exit(0)
+    
+# ----------------------------------------------------------------------------
+
+def signal_handler(signal, frame):
+    die('Exit due to Control+C')
+
+if __name__ == "__main__":
+    pyVersion = sys.version_info
+    if pyVersion.major != 3:
+        die("Major Python version must be 3.x: %s" % str(pyVersion))
+    if pyVersion.minor < 0:
+        print("Warning: minor Python version %s should be at least 3.0+" % str(pyVersion))
+
+    signal.signal(signal.SIGINT, signal_handler)
+    if os.name == 'nt':
+        print("Use Ctrl+Break to stop the script")
+    else:
+        print("Use Ctrl+C to stop the script")
+    main(sys.argv[1:])
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/META-INF/INDEX.LIST b/sshd-sources/tomcat-apr-5.5.23-sources/META-INF/INDEX.LIST
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/META-INF/INDEX.LIST
rename to sshd-sources/tomcat-apr-5.5.23-sources/META-INF/INDEX.LIST
diff --git a/src/tomcat-apr-5.5.23-sources/META-INF/MANIFEST.MF b/sshd-sources/tomcat-apr-5.5.23-sources/META-INF/MANIFEST.MF
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/META-INF/MANIFEST.MF
rename to sshd-sources/tomcat-apr-5.5.23-sources/META-INF/MANIFEST.MF
diff --git a/src/tomcat-apr-5.5.23-sources/README.txt b/sshd-sources/tomcat-apr-5.5.23-sources/README.txt
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/README.txt
rename to sshd-sources/tomcat-apr-5.5.23-sources/README.txt
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Address.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Address.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Address.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Address.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/BIOCallback.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/BIOCallback.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/BIOCallback.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/BIOCallback.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Directory.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Directory.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Directory.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Directory.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Error.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Error.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Error.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Error.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/File.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/File.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/File.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/File.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/FileInfo.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/FileInfo.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/FileInfo.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/FileInfo.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Global.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Global.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Global.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Global.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Library.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Library.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Library.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Library.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Local.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Local.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Local.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Local.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Lock.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Lock.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Lock.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Lock.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Mmap.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Mmap.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Mmap.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Mmap.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Multicast.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Multicast.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Multicast.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Multicast.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/OS.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/OS.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/OS.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/OS.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PasswordCallback.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PasswordCallback.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PasswordCallback.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PasswordCallback.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Poll.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Poll.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Poll.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Poll.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Pool.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Pool.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Pool.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Pool.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PoolCallback.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PoolCallback.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PoolCallback.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PoolCallback.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Proc.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Proc.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Proc.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Proc.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/ProcErrorCallback.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/ProcErrorCallback.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/ProcErrorCallback.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/ProcErrorCallback.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Procattr.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Procattr.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Procattr.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Procattr.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Registry.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Registry.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Registry.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Registry.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSL.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSL.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSL.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSL.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLContext.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLContext.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLContext.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLContext.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLSocket.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLSocket.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLSocket.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLSocket.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Shm.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Shm.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Shm.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Shm.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Sockaddr.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Sockaddr.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Sockaddr.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Sockaddr.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Socket.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Socket.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Socket.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Socket.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Status.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Status.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Status.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Status.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Stdlib.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Stdlib.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Stdlib.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Stdlib.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Thread.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Thread.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Thread.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Thread.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Time.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Time.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Time.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Time.java
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/User.java b/sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/User.java
similarity index 100%
rename from src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/User.java
rename to sshd-sources/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/User.java


[mina-sshd] 05/06: [SSHD-914] Expanded tomcat-apr sources JAR to its component files

Posted by lg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit 463cdf9716e2d0f84ac4dc02748a3c25f247ca94
Author: Lyor Goldstein <lg...@apache.org>
AuthorDate: Wed Oct 16 13:25:27 2019 +0300

    [SSHD-914] Expanded tomcat-apr sources JAR to its component files
---
 src/tomcat-apr-5.5.23-sources.jar                  | Bin 25227 -> 0 bytes
 src/tomcat-apr-5.5.23-sources/META-INF/INDEX.LIST  |   8 +
 src/tomcat-apr-5.5.23-sources/META-INF/MANIFEST.MF |   4 +
 src/tomcat-apr-5.5.23-sources/README.txt           |   1 +
 .../org/apache/tomcat/jni/Address.java             |  53 ++++
 .../org/apache/tomcat/jni/BIOCallback.java         |  18 ++
 .../org/apache/tomcat/jni/Directory.java           |  27 +++
 .../org/apache/tomcat/jni/Error.java               |  82 +++++++
 .../org/apache/tomcat/jni/File.java                | 168 +++++++++++++
 .../org/apache/tomcat/jni/FileInfo.java            |  28 +++
 .../org/apache/tomcat/jni/Global.java              |  24 ++
 .../org/apache/tomcat/jni/Library.java             | 219 +++++++++++++++++
 .../org/apache/tomcat/jni/Local.java               |  22 ++
 .../org/apache/tomcat/jni/Lock.java                |  37 +++
 .../org/apache/tomcat/jni/Mmap.java                |  24 ++
 .../org/apache/tomcat/jni/Multicast.java           |  20 ++
 .../org/apache/tomcat/jni/OS.java                  |  79 ++++++
 .../org/apache/tomcat/jni/PasswordCallback.java    |  12 +
 .../org/apache/tomcat/jni/Poll.java                |  41 ++++
 .../org/apache/tomcat/jni/Pool.java                |  38 +++
 .../org/apache/tomcat/jni/PoolCallback.java        |  12 +
 .../org/apache/tomcat/jni/Proc.java                |  59 +++++
 .../org/apache/tomcat/jni/ProcErrorCallback.java   |  12 +
 .../org/apache/tomcat/jni/Procattr.java            |  37 +++
 .../org/apache/tomcat/jni/Registry.java            |  83 +++++++
 .../org/apache/tomcat/jni/SSL.java                 | 158 ++++++++++++
 .../org/apache/tomcat/jni/SSLContext.java          |  41 ++++
 .../org/apache/tomcat/jni/SSLSocket.java           |  26 ++
 .../org/apache/tomcat/jni/Shm.java                 |  30 +++
 .../org/apache/tomcat/jni/Sockaddr.java            |  17 ++
 .../org/apache/tomcat/jni/Socket.java              | 120 +++++++++
 .../org/apache/tomcat/jni/Status.java              | 270 +++++++++++++++++++++
 .../org/apache/tomcat/jni/Stdlib.java              |  28 +++
 .../org/apache/tomcat/jni/Thread.java              |  12 +
 .../org/apache/tomcat/jni/Time.java                |  58 +++++
 .../org/apache/tomcat/jni/User.java                |  38 +++
 36 files changed, 1906 insertions(+)

diff --git a/src/tomcat-apr-5.5.23-sources.jar b/src/tomcat-apr-5.5.23-sources.jar
deleted file mode 100644
index 5f6fd04..0000000
Binary files a/src/tomcat-apr-5.5.23-sources.jar and /dev/null differ
diff --git a/src/tomcat-apr-5.5.23-sources/META-INF/INDEX.LIST b/src/tomcat-apr-5.5.23-sources/META-INF/INDEX.LIST
new file mode 100644
index 0000000..ca06ffe
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/META-INF/INDEX.LIST
@@ -0,0 +1,8 @@
+JarIndex-Version: 1.0
+
+tomcat-apr.jar
+org
+org/apache
+org/apache/tomcat
+org/apache/tomcat/jni
+
diff --git a/src/tomcat-apr-5.5.23-sources/META-INF/MANIFEST.MF b/src/tomcat-apr-5.5.23-sources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..3619fa7
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/META-INF/MANIFEST.MF
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Ant-Version: Apache Ant 1.6.5
+Created-By: 1.4.2_12-b03 (Sun Microsystems Inc.)
+
diff --git a/src/tomcat-apr-5.5.23-sources/README.txt b/src/tomcat-apr-5.5.23-sources/README.txt
new file mode 100644
index 0000000..0b17e72
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/README.txt
@@ -0,0 +1 @@
+See https://github.com/apache/tomcat-native project from which the JAR was created
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Address.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Address.java
new file mode 100644
index 0000000..51ffc7a
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Address.java
@@ -0,0 +1,53 @@
+/*    */ package org.apache.tomcat.jni;
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ public class Address
+/*    */ {
+/* 28 */   public static String APR_ANYADDR = "0.0.0.0";
+/*    */   
+/*    */   public static native boolean fill(Sockaddr paramSockaddr, long paramLong);
+/*    */   
+/*    */   public static native Sockaddr getInfo(long paramLong);
+/*    */   
+/*    */   public static native long info(String paramString, int paramInt1, int paramInt2, int paramInt3, long paramLong)
+/*    */     throws Exception;
+/*    */   
+/*    */   public static native String getnameinfo(long paramLong, int paramInt);
+/*    */   
+/*    */   public static native String getip(long paramLong);
+/*    */   
+/*    */   public static native int getservbyname(long paramLong, String paramString);
+/*    */   
+/*    */   public static native long get(int paramInt, long paramLong)
+/*    */     throws Exception;
+/*    */   
+/*    */   public static native boolean equal(long paramLong1, long paramLong2);
+/*    */ }
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Address.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/BIOCallback.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/BIOCallback.java
new file mode 100644
index 0000000..674b7f7
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/BIOCallback.java
@@ -0,0 +1,18 @@
+package org.apache.tomcat.jni;
+
+public abstract interface BIOCallback
+{
+  public abstract int write(byte[] paramArrayOfByte);
+  
+  public abstract int read(byte[] paramArrayOfByte);
+  
+  public abstract int puts(String paramString);
+  
+  public abstract String gets(int paramInt);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\BIOCallback.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Directory.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Directory.java
new file mode 100644
index 0000000..c5bfe7f
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Directory.java
@@ -0,0 +1,27 @@
+package org.apache.tomcat.jni;
+
+public class Directory
+{
+  public static native int make(String paramString, int paramInt, long paramLong);
+  
+  public static native int makeRecursive(String paramString, int paramInt, long paramLong);
+  
+  public static native int remove(String paramString, long paramLong);
+  
+  public static native String tempGet(long paramLong);
+  
+  public static native long open(String paramString, long paramLong)
+    throws Error;
+  
+  public static native int close(long paramLong);
+  
+  public static native int rewind(long paramLong);
+  
+  public static native int read(FileInfo paramFileInfo, int paramInt, long paramLong);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Directory.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Error.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Error.java
new file mode 100644
index 0000000..6112e88
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Error.java
@@ -0,0 +1,82 @@
+/*    */ package org.apache.tomcat.jni;
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ public class Error
+/*    */   extends Exception
+/*    */ {
+/*    */   private int error;
+/*    */   
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */   private String description;
+/*    */   
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */   private Error(int error, String description)
+/*    */   {
+/* 46 */     super(description);
+/* 47 */     this.error = error;
+/* 48 */     this.description = description;
+/*    */   }
+/*    */   
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */   public int getError()
+/*    */   {
+/* 58 */     return this.error;
+/*    */   }
+/*    */   
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */   public String getDescription()
+/*    */   {
+/* 68 */     return this.description;
+/*    */   }
+/*    */   
+/*    */   public static native int osError();
+/*    */   
+/*    */   public static native int netosError();
+/*    */   
+/*    */   public static native String strerror(int paramInt);
+/*    */ }
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Error.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/File.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/File.java
new file mode 100644
index 0000000..91726de
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/File.java
@@ -0,0 +1,168 @@
+package org.apache.tomcat.jni;
+
+import java.nio.ByteBuffer;
+
+public class File
+{
+  public static final int APR_FOPEN_READ = 1;
+  public static final int APR_FOPEN_WRITE = 2;
+  public static final int APR_FOPEN_CREATE = 4;
+  public static final int APR_FOPEN_APPEND = 8;
+  public static final int APR_FOPEN_TRUNCATE = 16;
+  public static final int APR_FOPEN_BINARY = 32;
+  public static final int APR_FOPEN_EXCL = 64;
+  public static final int APR_FOPEN_BUFFERED = 128;
+  public static final int APR_FOPEN_DELONCLOSE = 256;
+  public static final int APR_FOPEN_XTHREAD = 512;
+  public static final int APR_FOPEN_SHARELOCK = 1024;
+  public static final int APR_FOPEN_NOCLEANUP = 2048;
+  public static final int APR_FOPEN_SENDFILE_ENABLED = 4096;
+  public static final int APR_FOPEN_LARGEFILE = 16384;
+  public static final int APR_SET = 0;
+  public static final int APR_CUR = 1;
+  public static final int APR_END = 2;
+  public static final int APR_FILE_ATTR_READONLY = 1;
+  public static final int APR_FILE_ATTR_EXECUTABLE = 2;
+  public static final int APR_FILE_ATTR_HIDDEN = 4;
+  public static final int APR_FLOCK_SHARED = 1;
+  public static final int APR_FLOCK_EXCLUSIVE = 2;
+  public static final int APR_FLOCK_TYPEMASK = 15;
+  public static final int APR_FLOCK_NONBLOCK = 16;
+  public static final int APR_NOFILE = 0;
+  public static final int APR_REG = 1;
+  public static final int APR_DIR = 2;
+  public static final int APR_CHR = 3;
+  public static final int APR_BLK = 4;
+  public static final int APR_PIPE = 5;
+  public static final int APR_LNK = 6;
+  public static final int APR_SOCK = 7;
+  public static final int APR_UNKFILE = 127;
+  public static final int APR_FPROT_USETID = 32768;
+  public static final int APR_FPROT_UREAD = 1024;
+  public static final int APR_FPROT_UWRITE = 512;
+  public static final int APR_FPROT_UEXECUTE = 256;
+  public static final int APR_FPROT_GSETID = 16384;
+  public static final int APR_FPROT_GREAD = 64;
+  public static final int APR_FPROT_GWRITE = 32;
+  public static final int APR_FPROT_GEXECUTE = 16;
+  public static final int APR_FPROT_WSTICKY = 8192;
+  public static final int APR_FPROT_WREAD = 4;
+  public static final int APR_FPROT_WWRITE = 2;
+  public static final int APR_FPROT_WEXECUTE = 1;
+  public static final int APR_FPROT_OS_DEFAULT = 4095;
+  public static final int APR_FINFO_LINK = 1;
+  public static final int APR_FINFO_MTIME = 16;
+  public static final int APR_FINFO_CTIME = 32;
+  public static final int APR_FINFO_ATIME = 64;
+  public static final int APR_FINFO_SIZE = 256;
+  public static final int APR_FINFO_CSIZE = 512;
+  public static final int APR_FINFO_DEV = 4096;
+  public static final int APR_FINFO_INODE = 8192;
+  public static final int APR_FINFO_NLINK = 16384;
+  public static final int APR_FINFO_TYPE = 32768;
+  public static final int APR_FINFO_USER = 65536;
+  public static final int APR_FINFO_GROUP = 131072;
+  public static final int APR_FINFO_UPROT = 1048576;
+  public static final int APR_FINFO_GPROT = 2097152;
+  public static final int APR_FINFO_WPROT = 4194304;
+  public static final int APR_FINFO_ICASE = 16777216;
+  public static final int APR_FINFO_NAME = 33554432;
+  public static final int APR_FINFO_MIN = 33136;
+  public static final int APR_FINFO_IDENT = 12288;
+  public static final int APR_FINFO_OWNER = 196608;
+  public static final int APR_FINFO_PROT = 7340032;
+  public static final int APR_FINFO_NORM = 7582064;
+  public static final int APR_FINFO_DIRENT = 33554432;
+  
+  public static native long open(String paramString, int paramInt1, int paramInt2, long paramLong)
+    throws Error;
+  
+  public static native int close(long paramLong);
+  
+  public static native int flush(long paramLong);
+  
+  public static native long mktemp(String paramString, int paramInt, long paramLong)
+    throws Error;
+  
+  public static native int remove(String paramString, long paramLong);
+  
+  public static native int rename(String paramString1, String paramString2, long paramLong);
+  
+  public static native int copy(String paramString1, String paramString2, int paramInt, long paramLong);
+  
+  public static native int append(String paramString1, String paramString2, int paramInt, long paramLong);
+  
+  public static native int puts(byte[] paramArrayOfByte, long paramLong);
+  
+  public static native long seek(long paramLong1, int paramInt, long paramLong2)
+    throws Error;
+  
+  public static native int putc(byte paramByte, long paramLong);
+  
+  public static native int ungetc(byte paramByte, long paramLong);
+  
+  public static native int write(long paramLong, byte[] paramArrayOfByte, int paramInt1, int paramInt2);
+  
+  public static native int writeb(long paramLong, ByteBuffer paramByteBuffer, int paramInt1, int paramInt2);
+  
+  public static native int writeFull(long paramLong, byte[] paramArrayOfByte, int paramInt1, int paramInt2);
+  
+  public static native int writeFullb(long paramLong, ByteBuffer paramByteBuffer, int paramInt1, int paramInt2);
+  
+  public static native int writev(long paramLong, byte[][] paramArrayOfByte);
+  
+  public static native int writevFull(long paramLong, byte[][] paramArrayOfByte);
+  
+  public static native int read(long paramLong, byte[] paramArrayOfByte, int paramInt1, int paramInt2);
+  
+  public static native int readb(long paramLong, ByteBuffer paramByteBuffer, int paramInt1, int paramInt2);
+  
+  public static native int readFull(long paramLong, byte[] paramArrayOfByte, int paramInt1, int paramInt2);
+  
+  public static native int readFullb(long paramLong, ByteBuffer paramByteBuffer, int paramInt1, int paramInt2);
+  
+  public static native int gets(byte[] paramArrayOfByte, int paramInt, long paramLong);
+  
+  public static native int getc(long paramLong)
+    throws Error;
+  
+  public static native int eof(long paramLong);
+  
+  public static native String nameGet(long paramLong);
+  
+  public static native int permsSet(String paramString, int paramInt);
+  
+  public static native int attrsSet(String paramString, int paramInt1, int paramInt2, long paramLong);
+  
+  public static native int mtimeSet(String paramString, long paramLong1, long paramLong2);
+  
+  public static native int lock(long paramLong, int paramInt);
+  
+  public static native int unlock(long paramLong);
+  
+  public static native int flagsGet(long paramLong);
+  
+  public static native int trunc(long paramLong1, long paramLong2);
+  
+  public static native int pipeCreate(long[] paramArrayOfLong, long paramLong);
+  
+  public static native long pipeTimeoutGet(long paramLong)
+    throws Error;
+  
+  public static native int pipeTimeoutSet(long paramLong1, long paramLong2);
+  
+  public static native long dup(long paramLong1, long paramLong2, long paramLong3)
+    throws Error;
+  
+  public static native int dup2(long paramLong1, long paramLong2, long paramLong3);
+  
+  public static native int stat(FileInfo paramFileInfo, String paramString, int paramInt, long paramLong);
+  
+  public static native int infoGet(FileInfo paramFileInfo, int paramInt, long paramLong);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\File.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/FileInfo.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/FileInfo.java
new file mode 100644
index 0000000..7e2fdc6
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/FileInfo.java
@@ -0,0 +1,28 @@
+package org.apache.tomcat.jni;
+
+public class FileInfo
+{
+  public long pool;
+  public int valid;
+  public int protection;
+  public int filetype;
+  public int user;
+  public int group;
+  public int inode;
+  public int device;
+  public int nlink;
+  public long size;
+  public long csize;
+  public long atime;
+  public long mtime;
+  public long ctime;
+  public String fname;
+  public String name;
+  public long filehand;
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\FileInfo.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Global.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Global.java
new file mode 100644
index 0000000..f7dbc2e
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Global.java
@@ -0,0 +1,24 @@
+package org.apache.tomcat.jni;
+
+public class Global
+{
+  public static native long create(String paramString, int paramInt, long paramLong)
+    throws Error;
+  
+  public static native long childInit(String paramString, long paramLong)
+    throws Error;
+  
+  public static native int lock(long paramLong);
+  
+  public static native int trylock(long paramLong);
+  
+  public static native int unlock(long paramLong);
+  
+  public static native int destroy(long paramLong);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Global.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Library.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Library.java
new file mode 100644
index 0000000..ca7565a
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Library.java
@@ -0,0 +1,219 @@
+/*     */ package org.apache.tomcat.jni;
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ public final class Library
+/*     */ {
+/*  29 */   private static String[] NAMES = { "tcnative-1", "libtcnative-1" };
+/*     */   
+/*     */ 
+/*     */ 
+/*  33 */   private static Library _instance = null;
+/*     */   
+/*     */   private Library()
+/*     */   {
+/*  37 */     boolean loaded = false;
+/*  38 */     String err = "";
+/*  39 */     for (int i = 0; i < NAMES.length; i++) {
+/*     */       try {
+/*  41 */         System.loadLibrary(NAMES[i]);
+/*  42 */         loaded = true;
+/*     */       }
+/*     */       catch (Throwable e) {
+/*  45 */         if (i > 0)
+/*  46 */           err = err + ", ";
+/*  47 */         err = err + e.getMessage();
+/*     */       }
+/*  49 */       if (loaded)
+/*     */         break;
+/*     */     }
+/*  52 */     if (!loaded) {
+/*  53 */       err = err + "(";
+/*  54 */       err = err + System.getProperty("java.library.path");
+/*  55 */       err = err + ")";
+/*  56 */       throw new UnsatisfiedLinkError(err);
+/*     */     }
+/*     */   }
+/*     */   
+/*     */   private Library(String libraryName)
+/*     */   {
+/*  62 */     System.loadLibrary(libraryName);
+/*     */   }
+/*     */   
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*  81 */   public static int TCN_MAJOR_VERSION = 0;
+/*     */   
+/*  83 */   public static int TCN_MINOR_VERSION = 0;
+/*     */   
+/*  85 */   public static int TCN_PATCH_VERSION = 0;
+/*     */   
+/*  87 */   public static int TCN_IS_DEV_VERSION = 0;
+/*     */   
+/*  89 */   public static int APR_MAJOR_VERSION = 0;
+/*     */   
+/*  91 */   public static int APR_MINOR_VERSION = 0;
+/*     */   
+/*  93 */   public static int APR_PATCH_VERSION = 0;
+/*     */   
+/*  95 */   public static int APR_IS_DEV_VERSION = 0;
+/*     */   
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/* 103 */   public static boolean APR_HAVE_IPV6 = false;
+/* 104 */   public static boolean APR_HAS_SHARED_MEMORY = false;
+/* 105 */   public static boolean APR_HAS_THREADS = false;
+/* 106 */   public static boolean APR_HAS_SENDFILE = false;
+/* 107 */   public static boolean APR_HAS_MMAP = false;
+/* 108 */   public static boolean APR_HAS_FORK = false;
+/* 109 */   public static boolean APR_HAS_RANDOM = false;
+/* 110 */   public static boolean APR_HAS_OTHER_CHILD = false;
+/* 111 */   public static boolean APR_HAS_DSO = false;
+/* 112 */   public static boolean APR_HAS_SO_ACCEPTFILTER = false;
+/* 113 */   public static boolean APR_HAS_UNICODE_FS = false;
+/* 114 */   public static boolean APR_HAS_PROC_INVOKED = false;
+/* 115 */   public static boolean APR_HAS_USER = false;
+/* 116 */   public static boolean APR_HAS_LARGE_FILES = false;
+/* 117 */   public static boolean APR_HAS_XTHREAD_FILES = false;
+/* 118 */   public static boolean APR_HAS_OS_UUID = false;
+/*     */   
+/* 120 */   public static boolean APR_IS_BIGENDIAN = false;
+/*     */   
+/*     */ 
+/*     */ 
+/* 124 */   public static boolean APR_FILES_AS_SOCKETS = false;
+/*     */   
+/*     */ 
+/* 127 */   public static boolean APR_CHARSET_EBCDIC = false;
+/*     */   
+/*     */ 
+/* 130 */   public static boolean APR_TCP_NODELAY_INHERITED = false;
+/*     */   
+/*     */ 
+/* 133 */   public static boolean APR_O_NONBLOCK_INHERITED = false;
+/*     */   public static int APR_SIZEOF_VOIDP;
+/*     */   public static int APR_PATH_MAX;
+/*     */   public static int APRMAXHOSTLEN;
+/*     */   
+/*     */   private static native boolean initialize();
+/*     */   
+/*     */   public static native void terminate();
+/*     */   
+/*     */   private static native boolean has(int paramInt);
+/*     */   
+/*     */   private static native int version(int paramInt);
+/*     */   
+/*     */   private static native int size(int paramInt);
+/*     */   
+/*     */   public static native String versionString();
+/*     */   
+/*     */   public static native String aprVersionString();
+/*     */   
+/*     */   public static native long globalPool();
+/*     */   
+/*     */   public static boolean initialize(String libraryName) throws Exception {
+/* 155 */     if (_instance == null) {
+/* 156 */       if (libraryName == null) {
+/* 157 */         _instance = new Library();
+/*     */       } else
+/* 159 */         _instance = new Library(libraryName);
+/* 160 */       TCN_MAJOR_VERSION = version(1);
+/* 161 */       TCN_MINOR_VERSION = version(2);
+/* 162 */       TCN_PATCH_VERSION = version(3);
+/* 163 */       TCN_IS_DEV_VERSION = version(4);
+/* 164 */       APR_MAJOR_VERSION = version(17);
+/* 165 */       APR_MINOR_VERSION = version(18);
+/* 166 */       APR_PATCH_VERSION = version(19);
+/* 167 */       APR_IS_DEV_VERSION = version(20);
+/*     */       
+/* 169 */       APR_SIZEOF_VOIDP = size(1);
+/* 170 */       APR_PATH_MAX = size(2);
+/* 171 */       APRMAXHOSTLEN = size(3);
+/* 172 */       APR_MAX_IOVEC_SIZE = size(4);
+/* 173 */       APR_MAX_SECS_TO_LINGER = size(5);
+/* 174 */       APR_MMAP_THRESHOLD = size(6);
+/* 175 */       APR_MMAP_LIMIT = size(7);
+/*     */       
+/* 177 */       APR_HAVE_IPV6 = has(0);
+/* 178 */       APR_HAS_SHARED_MEMORY = has(1);
+/* 179 */       APR_HAS_THREADS = has(2);
+/* 180 */       APR_HAS_SENDFILE = has(3);
+/* 181 */       APR_HAS_MMAP = has(4);
+/* 182 */       APR_HAS_FORK = has(5);
+/* 183 */       APR_HAS_RANDOM = has(6);
+/* 184 */       APR_HAS_OTHER_CHILD = has(7);
+/* 185 */       APR_HAS_DSO = has(8);
+/* 186 */       APR_HAS_SO_ACCEPTFILTER = has(9);
+/* 187 */       APR_HAS_UNICODE_FS = has(10);
+/* 188 */       APR_HAS_PROC_INVOKED = has(11);
+/* 189 */       APR_HAS_USER = has(12);
+/* 190 */       APR_HAS_LARGE_FILES = has(13);
+/* 191 */       APR_HAS_XTHREAD_FILES = has(14);
+/* 192 */       APR_HAS_OS_UUID = has(15);
+/* 193 */       APR_IS_BIGENDIAN = has(16);
+/* 194 */       APR_FILES_AS_SOCKETS = has(17);
+/* 195 */       APR_CHARSET_EBCDIC = has(18);
+/* 196 */       APR_TCP_NODELAY_INHERITED = has(19);
+/* 197 */       APR_O_NONBLOCK_INHERITED = has(20);
+/* 198 */       if (APR_MAJOR_VERSION < 1) {
+/* 199 */         throw new UnsatisfiedLinkError("Unsupported APR Version (" + aprVersionString() + ")");
+/*     */       }
+/*     */       
+/* 202 */       if (!APR_HAS_THREADS) {
+/* 203 */         throw new UnsatisfiedLinkError("Missing APR_HAS_THREADS");
+/*     */       }
+/*     */     }
+/* 206 */     return initialize();
+/*     */   }
+/*     */   
+/*     */   public static int APR_MAX_IOVEC_SIZE;
+/*     */   public static int APR_MAX_SECS_TO_LINGER;
+/*     */   public static int APR_MMAP_THRESHOLD;
+/*     */   public static int APR_MMAP_LIMIT;
+/*     */ }
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Library.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Local.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Local.java
new file mode 100644
index 0000000..b11cb09
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Local.java
@@ -0,0 +1,22 @@
+package org.apache.tomcat.jni;
+
+public class Local
+{
+  public static native long create(String paramString, long paramLong)
+    throws Exception;
+  
+  public static native int bind(long paramLong1, long paramLong2);
+  
+  public static native int listen(long paramLong, int paramInt);
+  
+  public static native long accept(long paramLong)
+    throws Exception;
+  
+  public static native int connect(long paramLong1, long paramLong2);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Local.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Lock.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Lock.java
new file mode 100644
index 0000000..f5453d0
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Lock.java
@@ -0,0 +1,37 @@
+package org.apache.tomcat.jni;
+
+public class Lock
+{
+  public static final int APR_LOCK_FCNTL = 0;
+  public static final int APR_LOCK_FLOCK = 1;
+  public static final int APR_LOCK_SYSVSEM = 2;
+  public static final int APR_LOCK_PROC_PTHREAD = 3;
+  public static final int APR_LOCK_POSIXSEM = 4;
+  public static final int APR_LOCK_DEFAULT = 5;
+  
+  public static native long create(String paramString, int paramInt, long paramLong)
+    throws Error;
+  
+  public static native long childInit(String paramString, long paramLong)
+    throws Error;
+  
+  public static native int lock(long paramLong);
+  
+  public static native int trylock(long paramLong);
+  
+  public static native int unlock(long paramLong);
+  
+  public static native int destroy(long paramLong);
+  
+  public static native String lockfile(long paramLong);
+  
+  public static native String name(long paramLong);
+  
+  public static native String defname();
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Lock.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Mmap.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Mmap.java
new file mode 100644
index 0000000..fc9b71f
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Mmap.java
@@ -0,0 +1,24 @@
+package org.apache.tomcat.jni;
+
+public class Mmap
+{
+  public static final int APR_MMAP_READ = 1;
+  public static final int APR_MMAP_WRITE = 2;
+  
+  public static native long create(long paramLong1, long paramLong2, long paramLong3, int paramInt, long paramLong4)
+    throws Error;
+  
+  public static native long dup(long paramLong1, long paramLong2)
+    throws Error;
+  
+  public static native int delete(long paramLong);
+  
+  public static native long offset(long paramLong1, long paramLong2)
+    throws Error;
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Mmap.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Multicast.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Multicast.java
new file mode 100644
index 0000000..80f63d1
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Multicast.java
@@ -0,0 +1,20 @@
+package org.apache.tomcat.jni;
+
+public class Multicast
+{
+  public static native int join(long paramLong1, long paramLong2, long paramLong3, long paramLong4);
+  
+  public static native int leave(long paramLong1, long paramLong2, long paramLong3, long paramLong4);
+  
+  public static native int hops(long paramLong, int paramInt);
+  
+  public static native int loopback(long paramLong, boolean paramBoolean);
+  
+  public static native int ointerface(long paramLong1, long paramLong2);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Multicast.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/OS.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/OS.java
new file mode 100644
index 0000000..499c1fd
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/OS.java
@@ -0,0 +1,79 @@
+/*    */ package org.apache.tomcat.jni;
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ public class OS
+/*    */ {
+/*    */   private static final int UNIX = 1;
+/*    */   
+/*    */ 
+/*    */ 
+/*    */   private static final int NETWARE = 2;
+/*    */   
+/*    */ 
+/*    */ 
+/*    */   private static final int WIN32 = 3;
+/*    */   
+/*    */ 
+/*    */ 
+/*    */   private static final int WIN64 = 4;
+/*    */   
+/*    */ 
+/*    */   private static final int LINUX = 5;
+/*    */   
+/*    */ 
+/*    */   private static final int SOLARIS = 6;
+/*    */   
+/*    */ 
+/*    */   private static final int BSD = 7;
+/*    */   
+/*    */ 
+/*    */   public static final int LOG_EMERG = 1;
+/*    */   
+/*    */ 
+/*    */   public static final int LOG_ERROR = 2;
+/*    */   
+/*    */ 
+/*    */   public static final int LOG_NOTICE = 3;
+/*    */   
+/*    */ 
+/*    */   public static final int LOG_WARN = 4;
+/*    */   
+/*    */ 
+/*    */   public static final int LOG_INFO = 5;
+/*    */   
+/*    */ 
+/*    */   public static final int LOG_DEBUG = 6;
+/*    */   
+/*    */ 
+/* 50 */   public static final boolean IS_UNIX = is(1);
+/* 51 */   public static final boolean IS_NETWARE = is(2);
+/* 52 */   public static final boolean IS_WIN32 = is(3);
+/* 53 */   public static final boolean IS_WIN64 = is(4);
+/* 54 */   public static final boolean IS_LINUX = is(5);
+/* 55 */   public static final boolean IS_SOLARIS = is(6);
+/* 56 */   public static final boolean IS_BSD = is(7);
+/*    */   
+/*    */   private static native boolean is(int paramInt);
+/*    */   
+/*    */   public static native String defaultEncoding(long paramLong);
+/*    */   
+/*    */   public static native String localeEncoding(long paramLong);
+/*    */   
+/*    */   public static native int random(byte[] paramArrayOfByte, int paramInt);
+/*    */   
+/*    */   public static native int info(long[] paramArrayOfLong);
+/*    */   
+/*    */   public static native String expand(String paramString);
+/*    */   
+/*    */   public static native void sysloginit(String paramString);
+/*    */   
+/*    */   public static native void syslog(int paramInt, String paramString);
+/*    */ }
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\OS.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PasswordCallback.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PasswordCallback.java
new file mode 100644
index 0000000..c78736a
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PasswordCallback.java
@@ -0,0 +1,12 @@
+package org.apache.tomcat.jni;
+
+public abstract interface PasswordCallback
+{
+  public abstract String callback(String paramString);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\PasswordCallback.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Poll.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Poll.java
new file mode 100644
index 0000000..4b67f87
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Poll.java
@@ -0,0 +1,41 @@
+package org.apache.tomcat.jni;
+
+public class Poll
+{
+  public static final int APR_POLLIN = 1;
+  public static final int APR_POLLPRI = 2;
+  public static final int APR_POLLOUT = 4;
+  public static final int APR_POLLERR = 16;
+  public static final int APR_POLLHUP = 32;
+  public static final int APR_POLLNVAL = 64;
+  public static final int APR_POLLSET_THREADSAFE = 1;
+  public static final int APR_NO_DESC = 0;
+  public static final int APR_POLL_SOCKET = 1;
+  public static final int APR_POLL_FILE = 2;
+  public static final int APR_POLL_LASTDESC = 3;
+  
+  public static native long create(int paramInt1, long paramLong1, int paramInt2, long paramLong2)
+    throws Error;
+  
+  public static native int destroy(long paramLong);
+  
+  public static native int add(long paramLong1, long paramLong2, int paramInt);
+  
+  public static native int remove(long paramLong1, long paramLong2);
+  
+  public static native int poll(long paramLong1, long paramLong2, long[] paramArrayOfLong, boolean paramBoolean);
+  
+  public static native int maintain(long paramLong, long[] paramArrayOfLong, boolean paramBoolean);
+  
+  public static native void setTtl(long paramLong1, long paramLong2);
+  
+  public static native long getTtl(long paramLong);
+  
+  public static native int pollset(long paramLong, long[] paramArrayOfLong);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Poll.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Pool.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Pool.java
new file mode 100644
index 0000000..5c8f3a7
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Pool.java
@@ -0,0 +1,38 @@
+package org.apache.tomcat.jni;
+
+import java.nio.ByteBuffer;
+
+public class Pool
+{
+  public static native long create(long paramLong);
+  
+  public static native void clear(long paramLong);
+  
+  public static native void destroy(long paramLong);
+  
+  public static native long parentGet(long paramLong);
+  
+  public static native boolean isAncestor(long paramLong1, long paramLong2);
+  
+  public static native long cleanupRegister(long paramLong, Object paramObject);
+  
+  public static native void cleanupKill(long paramLong1, long paramLong2);
+  
+  public static native void noteSubprocess(long paramLong1, long paramLong2, int paramInt);
+  
+  public static native ByteBuffer alloc(long paramLong, int paramInt);
+  
+  public static native ByteBuffer calloc(long paramLong, int paramInt);
+  
+  public static native int dataSet(long paramLong, String paramString, Object paramObject);
+  
+  public static native Object dataGet(long paramLong, String paramString);
+  
+  public static native void cleanupForExec();
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Pool.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PoolCallback.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PoolCallback.java
new file mode 100644
index 0000000..52ed517
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/PoolCallback.java
@@ -0,0 +1,12 @@
+package org.apache.tomcat.jni;
+
+public abstract interface PoolCallback
+{
+  public abstract int callback();
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\PoolCallback.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Proc.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Proc.java
new file mode 100644
index 0000000..6f0e5d8
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Proc.java
@@ -0,0 +1,59 @@
+package org.apache.tomcat.jni;
+
+public class Proc
+{
+  public static final int APR_SHELLCM = 0;
+  public static final int APR_PROGRAM = 1;
+  public static final int APR_PROGRAM_ENV = 2;
+  public static final int APR_PROGRAM_PATH = 3;
+  public static final int APR_SHELLCMD_ENV = 4;
+  public static final int APR_WAIT = 0;
+  public static final int APR_NOWAIT = 1;
+  public static final int APR_PROC_EXIT = 1;
+  public static final int APR_PROC_SIGNAL = 2;
+  public static final int APR_PROC_SIGNAL_CORE = 4;
+  public static final int APR_NO_PIPE = 0;
+  public static final int APR_FULL_BLOCK = 1;
+  public static final int APR_FULL_NONBLOCK = 2;
+  public static final int APR_PARENT_BLOCK = 3;
+  public static final int APR_CHILD_BLOCK = 4;
+  public static final int APR_LIMIT_CPU = 0;
+  public static final int APR_LIMIT_MEM = 1;
+  public static final int APR_LIMIT_NPROC = 2;
+  public static final int APR_LIMIT_NOFILE = 3;
+  public static final int APR_OC_REASON_DEATH = 0;
+  public static final int APR_OC_REASON_UNWRITABLE = 1;
+  public static final int APR_OC_REASON_RESTART = 2;
+  public static final int APR_OC_REASON_UNREGISTER = 3;
+  public static final int APR_OC_REASON_LOST = 4;
+  public static final int APR_OC_REASON_RUNNING = 5;
+  public static final int APR_KILL_NEVER = 0;
+  public static final int APR_KILL_ALWAYS = 1;
+  public static final int APR_KILL_AFTER_TIMEOUT = 2;
+  public static final int APR_JUST_WAIT = 3;
+  public static final int APR_KILL_ONLY_ONCE = 4;
+  public static final int APR_PROC_DETACH_FOREGROUND = 0;
+  public static final int APR_PROC_DETACH_DAEMONIZE = 1;
+  public static final int MAX_ARGS_SIZE = 1024;
+  public static final int MAX_ENV_SIZE = 1024;
+  
+  public static native long alloc(long paramLong);
+  
+  public static native int fork(long[] paramArrayOfLong, long paramLong);
+  
+  public static native int create(long paramLong1, String paramString, String[] paramArrayOfString1, String[] paramArrayOfString2, long paramLong2, long paramLong3);
+  
+  public static native int wait(long paramLong, int[] paramArrayOfInt, int paramInt);
+  
+  public static native int waitAllProcs(long paramLong1, int[] paramArrayOfInt, int paramInt, long paramLong2);
+  
+  public static native int detach(int paramInt);
+  
+  public static native int kill(long paramLong, int paramInt);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Proc.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/ProcErrorCallback.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/ProcErrorCallback.java
new file mode 100644
index 0000000..572a867
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/ProcErrorCallback.java
@@ -0,0 +1,12 @@
+package org.apache.tomcat.jni;
+
+public abstract interface ProcErrorCallback
+{
+  public abstract void callback(long paramLong, int paramInt, String paramString);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\ProcErrorCallback.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Procattr.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Procattr.java
new file mode 100644
index 0000000..934262a
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Procattr.java
@@ -0,0 +1,37 @@
+package org.apache.tomcat.jni;
+
+public class Procattr
+{
+  public static native long create(long paramLong)
+    throws Error;
+  
+  public static native int ioSet(long paramLong, int paramInt1, int paramInt2, int paramInt3);
+  
+  public static native int childInSet(long paramLong1, long paramLong2, long paramLong3);
+  
+  public static native int childOutSet(long paramLong1, long paramLong2, long paramLong3);
+  
+  public static native int childErrSet(long paramLong1, long paramLong2, long paramLong3);
+  
+  public static native int dirSet(long paramLong, String paramString);
+  
+  public static native int cmdtypeSet(long paramLong, int paramInt);
+  
+  public static native int detachSet(long paramLong, int paramInt);
+  
+  public static native int errorCheckSet(long paramLong, int paramInt);
+  
+  public static native int addrspaceSet(long paramLong, int paramInt);
+  
+  public static native void errfnSet(long paramLong1, long paramLong2, Object paramObject);
+  
+  public static native int userSet(long paramLong, String paramString1, String paramString2);
+  
+  public static native int groupSet(long paramLong, String paramString);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Procattr.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Registry.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Registry.java
new file mode 100644
index 0000000..dade25d
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Registry.java
@@ -0,0 +1,83 @@
+package org.apache.tomcat.jni;
+
+public class Registry
+{
+  public static final int HKEY_CLASSES_ROOT = 1;
+  public static final int HKEY_CURRENT_CONFIG = 2;
+  public static final int HKEY_CURRENT_USER = 3;
+  public static final int HKEY_LOCAL_MACHINE = 4;
+  public static final int HKEY_USERS = 5;
+  public static final int KEY_ALL_ACCESS = 1;
+  public static final int KEY_CREATE_LINK = 2;
+  public static final int KEY_CREATE_SUB_KEY = 4;
+  public static final int KEY_ENUMERATE_SUB_KEYS = 8;
+  public static final int KEY_EXECUTE = 16;
+  public static final int KEY_NOTIFY = 32;
+  public static final int KEY_QUERY_VALUE = 64;
+  public static final int KEY_READ = 128;
+  public static final int KEY_SET_VALUE = 256;
+  public static final int KEY_WOW64_64KEY = 512;
+  public static final int KEY_WOW64_32KEY = 1024;
+  public static final int KEY_WRITE = 2048;
+  public static final int REG_BINARY = 1;
+  public static final int REG_DWORD = 2;
+  public static final int REG_EXPAND_SZ = 3;
+  public static final int REG_MULTI_SZ = 4;
+  public static final int REG_QWORD = 5;
+  public static final int REG_SZ = 6;
+  
+  public static native long create(int paramInt1, String paramString, int paramInt2, long paramLong)
+    throws Error;
+  
+  public static native long open(int paramInt1, String paramString, int paramInt2, long paramLong)
+    throws Error;
+  
+  public static native int close(long paramLong);
+  
+  public static native int getType(long paramLong, String paramString);
+  
+  public static native int getValueI(long paramLong, String paramString)
+    throws Error;
+  
+  public static native long getValueJ(long paramLong, String paramString)
+    throws Error;
+  
+  public static native int getSize(long paramLong, String paramString);
+  
+  public static native String getValueS(long paramLong, String paramString)
+    throws Error;
+  
+  public static native String[] getValueA(long paramLong, String paramString)
+    throws Error;
+  
+  public static native byte[] getValueB(long paramLong, String paramString)
+    throws Error;
+  
+  public static native int setValueI(long paramLong, String paramString, int paramInt);
+  
+  public static native int setValueJ(long paramLong, String paramString, int paramInt);
+  
+  public static native int setValueS(long paramLong, String paramString1, String paramString2);
+  
+  public static native int setValueE(long paramLong, String paramString1, String paramString2);
+  
+  public static native int setValueA(long paramLong, String paramString, String[] paramArrayOfString);
+  
+  public static native int setValueB(long paramLong, String paramString, byte[] paramArrayOfByte);
+  
+  public static native String[] enumKeys(long paramLong)
+    throws Error;
+  
+  public static native String[] enumValues(long paramLong)
+    throws Error;
+  
+  public static native int deleteValue(long paramLong, String paramString);
+  
+  public static native int deleteKey(int paramInt, String paramString, boolean paramBoolean);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Registry.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSL.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSL.java
new file mode 100644
index 0000000..24427ee
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSL.java
@@ -0,0 +1,158 @@
+package org.apache.tomcat.jni;
+
+public final class SSL
+{
+  public static final int UNSET = -1;
+  public static final int SSL_ALGO_UNKNOWN = 0;
+  public static final int SSL_ALGO_RSA = 1;
+  public static final int SSL_ALGO_DSA = 2;
+  public static final int SSL_ALGO_ALL = 3;
+  public static final int SSL_AIDX_RSA = 0;
+  public static final int SSL_AIDX_DSA = 1;
+  public static final int SSL_AIDX_MAX = 2;
+  public static final int SSL_TMP_KEY_RSA_512 = 0;
+  public static final int SSL_TMP_KEY_RSA_1024 = 1;
+  public static final int SSL_TMP_KEY_RSA_2048 = 2;
+  public static final int SSL_TMP_KEY_RSA_4096 = 3;
+  public static final int SSL_TMP_KEY_DH_512 = 4;
+  public static final int SSL_TMP_KEY_DH_1024 = 5;
+  public static final int SSL_TMP_KEY_DH_2048 = 6;
+  public static final int SSL_TMP_KEY_DH_4096 = 7;
+  public static final int SSL_TMP_KEY_MAX = 8;
+  public static final int SSL_OPT_NONE = 0;
+  public static final int SSL_OPT_RELSET = 1;
+  public static final int SSL_OPT_STDENVVARS = 2;
+  public static final int SSL_OPT_EXPORTCERTDATA = 8;
+  public static final int SSL_OPT_FAKEBASICAUTH = 16;
+  public static final int SSL_OPT_STRICTREQUIRE = 32;
+  public static final int SSL_OPT_OPTRENEGOTIATE = 64;
+  public static final int SSL_OPT_ALL = 122;
+  public static final int SSL_PROTOCOL_NONE = 0;
+  public static final int SSL_PROTOCOL_SSLV2 = 1;
+  public static final int SSL_PROTOCOL_SSLV3 = 2;
+  public static final int SSL_PROTOCOL_TLSV1 = 4;
+  public static final int SSL_PROTOCOL_ALL = 7;
+  public static final int SSL_CVERIFY_UNSET = -1;
+  public static final int SSL_CVERIFY_NONE = 0;
+  public static final int SSL_CVERIFY_OPTIONAL = 1;
+  public static final int SSL_CVERIFY_REQUIRE = 2;
+  public static final int SSL_CVERIFY_OPTIONAL_NO_CA = 3;
+  public static final int SSL_VERIFY_NONE = 0;
+  public static final int SSL_VERIFY_PEER = 1;
+  public static final int SSL_VERIFY_FAIL_IF_NO_PEER_CERT = 2;
+  public static final int SSL_VERIFY_CLIENT_ONCE = 4;
+  public static final int SSL_VERIFY_PEER_STRICT = 3;
+  public static final int SSL_OP_MICROSOFT_SESS_ID_BUG = 1;
+  public static final int SSL_OP_NETSCAPE_CHALLENGE_BUG = 2;
+  public static final int SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = 8;
+  public static final int SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG = 16;
+  public static final int SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER = 32;
+  public static final int SSL_OP_MSIE_SSLV2_RSA_PADDING = 64;
+  public static final int SSL_OP_SSLEAY_080_CLIENT_DH_BUG = 128;
+  public static final int SSL_OP_TLS_D5_BUG = 256;
+  public static final int SSL_OP_TLS_BLOCK_PADDING_BUG = 512;
+  public static final int SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS = 2048;
+  public static final int SSL_OP_ALL = 4095;
+  public static final int SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION = 65536;
+  public static final int SSL_OP_SINGLE_DH_USE = 1048576;
+  public static final int SSL_OP_EPHEMERAL_RSA = 2097152;
+  public static final int SSL_OP_CIPHER_SERVER_PREFERENCE = 4194304;
+  public static final int SSL_OP_TLS_ROLLBACK_BUG = 8388608;
+  public static final int SSL_OP_NO_SSLv2 = 16777216;
+  public static final int SSL_OP_NO_SSLv3 = 33554432;
+  public static final int SSL_OP_NO_TLSv1 = 67108864;
+  public static final int SSL_OP_PKCS1_CHECK_1 = 134217728;
+  public static final int SSL_OP_PKCS1_CHECK_2 = 268435456;
+  public static final int SSL_OP_NETSCAPE_CA_DN_BUG = 536870912;
+  public static final int SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG = 1073741824;
+  public static final int SSL_CRT_FORMAT_UNDEF = 0;
+  public static final int SSL_CRT_FORMAT_ASN1 = 1;
+  public static final int SSL_CRT_FORMAT_TEXT = 2;
+  public static final int SSL_CRT_FORMAT_PEM = 3;
+  public static final int SSL_CRT_FORMAT_NETSCAPE = 4;
+  public static final int SSL_CRT_FORMAT_PKCS12 = 5;
+  public static final int SSL_CRT_FORMAT_SMIME = 6;
+  public static final int SSL_CRT_FORMAT_ENGINE = 7;
+  public static final int SSL_MODE_CLIENT = 0;
+  public static final int SSL_MODE_SERVER = 1;
+  public static final int SSL_MODE_COMBINED = 2;
+  public static final int SSL_SHUTDOWN_TYPE_UNSET = 0;
+  public static final int SSL_SHUTDOWN_TYPE_STANDARD = 1;
+  public static final int SSL_SHUTDOWN_TYPE_UNCLEAN = 2;
+  public static final int SSL_SHUTDOWN_TYPE_ACCURATE = 3;
+  public static final int SSL_INFO_SESSION_ID = 1;
+  public static final int SSL_INFO_CIPHER = 2;
+  public static final int SSL_INFO_CIPHER_USEKEYSIZE = 3;
+  public static final int SSL_INFO_CIPHER_ALGKEYSIZE = 4;
+  public static final int SSL_INFO_CIPHER_VERSION = 5;
+  public static final int SSL_INFO_CIPHER_DESCRIPTION = 6;
+  public static final int SSL_INFO_PROTOCOL = 7;
+  public static final int SSL_INFO_CLIENT_S_DN = 16;
+  public static final int SSL_INFO_CLIENT_I_DN = 32;
+  public static final int SSL_INFO_SERVER_S_DN = 64;
+  public static final int SSL_INFO_SERVER_I_DN = 128;
+  public static final int SSL_INFO_DN_COUNTRYNAME = 1;
+  public static final int SSL_INFO_DN_STATEORPROVINCENAME = 2;
+  public static final int SSL_INFO_DN_LOCALITYNAME = 3;
+  public static final int SSL_INFO_DN_ORGANIZATIONNAME = 4;
+  public static final int SSL_INFO_DN_ORGANIZATIONALUNITNAME = 5;
+  public static final int SSL_INFO_DN_COMMONNAME = 6;
+  public static final int SSL_INFO_DN_TITLE = 7;
+  public static final int SSL_INFO_DN_INITIALS = 8;
+  public static final int SSL_INFO_DN_GIVENNAME = 9;
+  public static final int SSL_INFO_DN_SURNAME = 10;
+  public static final int SSL_INFO_DN_DESCRIPTION = 11;
+  public static final int SSL_INFO_DN_UNIQUEIDENTIFIER = 12;
+  public static final int SSL_INFO_DN_EMAILADDRESS = 13;
+  public static final int SSL_INFO_CLIENT_M_VERSION = 257;
+  public static final int SSL_INFO_CLIENT_M_SERIAL = 258;
+  public static final int SSL_INFO_CLIENT_V_START = 259;
+  public static final int SSL_INFO_CLIENT_V_END = 260;
+  public static final int SSL_INFO_CLIENT_A_SIG = 261;
+  public static final int SSL_INFO_CLIENT_A_KEY = 262;
+  public static final int SSL_INFO_CLIENT_CERT = 263;
+  public static final int SSL_INFO_CLIENT_V_REMAIN = 264;
+  public static final int SSL_INFO_SERVER_M_VERSION = 513;
+  public static final int SSL_INFO_SERVER_M_SERIAL = 514;
+  public static final int SSL_INFO_SERVER_V_START = 515;
+  public static final int SSL_INFO_SERVER_V_END = 516;
+  public static final int SSL_INFO_SERVER_A_SIG = 517;
+  public static final int SSL_INFO_SERVER_A_KEY = 518;
+  public static final int SSL_INFO_SERVER_CERT = 519;
+  public static final int SSL_INFO_CLIENT_CERT_CHAIN = 1024;
+  
+  public static native int version();
+  
+  public static native String versionString();
+  
+  public static native int initialize(String paramString);
+  
+  public static native boolean randLoad(String paramString);
+  
+  public static native boolean randSave(String paramString);
+  
+  public static native boolean randMake(String paramString, int paramInt, boolean paramBoolean);
+  
+  public static native void randSet(String paramString);
+  
+  public static native long newBIO(long paramLong, BIOCallback paramBIOCallback)
+    throws Exception;
+  
+  public static native int closeBIO(long paramLong);
+  
+  public static native void setPasswordCallback(PasswordCallback paramPasswordCallback);
+  
+  public static native void setPassword(String paramString);
+  
+  public static native boolean generateRSATempKey(int paramInt);
+  
+  public static native boolean loadDSATempKey(int paramInt, String paramString);
+  
+  public static native String getLastError();
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\SSL.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLContext.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLContext.java
new file mode 100644
index 0000000..7352165
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLContext.java
@@ -0,0 +1,41 @@
+package org.apache.tomcat.jni;
+
+public final class SSLContext
+{
+  public static native long make(long paramLong, int paramInt1, int paramInt2)
+    throws Exception;
+  
+  public static native int free(long paramLong);
+  
+  public static native void setContextId(long paramLong, String paramString);
+  
+  public static native void setBIO(long paramLong1, long paramLong2, int paramInt);
+  
+  public static native void setOptions(long paramLong, int paramInt);
+  
+  public static native void setQuietShutdown(long paramLong, boolean paramBoolean);
+  
+  public static native boolean setCipherSuite(long paramLong, String paramString)
+    throws Exception;
+  
+  public static native boolean setCARevocation(long paramLong, String paramString1, String paramString2)
+    throws Exception;
+  
+  public static native boolean setCertificateChainFile(long paramLong, String paramString, boolean paramBoolean);
+  
+  public static native boolean setCertificate(long paramLong, String paramString1, String paramString2, String paramString3, int paramInt)
+    throws Exception;
+  
+  public static native boolean setCACertificate(long paramLong, String paramString1, String paramString2)
+    throws Exception;
+  
+  public static native void setShutdowType(long paramLong, int paramInt);
+  
+  public static native void setVerify(long paramLong, int paramInt1, int paramInt2);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\SSLContext.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLSocket.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLSocket.java
new file mode 100644
index 0000000..42aea3f
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/SSLSocket.java
@@ -0,0 +1,26 @@
+package org.apache.tomcat.jni;
+
+public class SSLSocket
+{
+  public static native int attach(long paramLong1, long paramLong2)
+    throws Exception;
+  
+  public static native int handshake(long paramLong);
+  
+  public static native int renegotiate(long paramLong);
+  
+  public static native byte[] getInfoB(long paramLong, int paramInt)
+    throws Exception;
+  
+  public static native String getInfoS(long paramLong, int paramInt)
+    throws Exception;
+  
+  public static native int getInfoI(long paramLong, int paramInt)
+    throws Exception;
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\SSLSocket.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Shm.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Shm.java
new file mode 100644
index 0000000..a13d59e
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Shm.java
@@ -0,0 +1,30 @@
+package org.apache.tomcat.jni;
+
+import java.nio.ByteBuffer;
+
+public class Shm
+{
+  public static native long create(long paramLong1, String paramString, long paramLong2)
+    throws Error;
+  
+  public static native int remove(String paramString, long paramLong);
+  
+  public static native int destroy(long paramLong);
+  
+  public static native long attach(String paramString, long paramLong)
+    throws Error;
+  
+  public static native int detach(long paramLong);
+  
+  public static native long baseaddr(long paramLong);
+  
+  public static native long size(long paramLong);
+  
+  public static native ByteBuffer buffer(long paramLong);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Shm.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Sockaddr.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Sockaddr.java
new file mode 100644
index 0000000..37ba642
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Sockaddr.java
@@ -0,0 +1,17 @@
+package org.apache.tomcat.jni;
+
+public class Sockaddr
+{
+  public long pool;
+  public String hostname;
+  public String servname;
+  public int port;
+  public int family;
+  public long next;
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Sockaddr.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Socket.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Socket.java
new file mode 100644
index 0000000..043acb8
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Socket.java
@@ -0,0 +1,120 @@
+package org.apache.tomcat.jni;
+
+import java.nio.ByteBuffer;
+
+public class Socket
+{
+  public static final int SOCK_STREAM = 0;
+  public static final int SOCK_DGRAM = 1;
+  public static final int APR_SO_LINGER = 1;
+  public static final int APR_SO_KEEPALIVE = 2;
+  public static final int APR_SO_DEBUG = 4;
+  public static final int APR_SO_NONBLOCK = 8;
+  public static final int APR_SO_REUSEADDR = 16;
+  public static final int APR_SO_SNDBUF = 64;
+  public static final int APR_SO_RCVBUF = 128;
+  public static final int APR_SO_DISCONNECTED = 256;
+  public static final int APR_TCP_NODELAY = 512;
+  public static final int APR_TCP_NOPUSH = 1024;
+  public static final int APR_RESET_NODELAY = 2048;
+  public static final int APR_INCOMPLETE_READ = 4096;
+  public static final int APR_INCOMPLETE_WRITE = 8192;
+  public static final int APR_IPV6_V6ONLY = 16384;
+  public static final int APR_TCP_DEFER_ACCEPT = 32768;
+  public static final int APR_SHUTDOWN_READ = 0;
+  public static final int APR_SHUTDOWN_WRITE = 1;
+  public static final int APR_SHUTDOWN_READWRITE = 2;
+  public static final int APR_IPV4_ADDR_OK = 1;
+  public static final int APR_IPV6_ADDR_OK = 2;
+  public static final int APR_UNSPEC = 0;
+  public static final int APR_INET = 1;
+  public static final int APR_INET6 = 2;
+  public static final int APR_PROTO_TCP = 6;
+  public static final int APR_PROTO_UDP = 17;
+  public static final int APR_PROTO_SCTP = 132;
+  public static final int APR_LOCAL = 0;
+  public static final int APR_REMOTE = 1;
+  public static final int SOCKET_GET_POOL = 0;
+  public static final int SOCKET_GET_IMPL = 1;
+  public static final int SOCKET_GET_APRS = 2;
+  public static final int SOCKET_GET_TYPE = 3;
+  
+  public static native long create(int paramInt1, int paramInt2, int paramInt3, long paramLong)
+    throws Exception;
+  
+  public static native int shutdown(long paramLong, int paramInt);
+  
+  public static native int close(long paramLong);
+  
+  public static native void destroy(long paramLong);
+  
+  public static native int bind(long paramLong1, long paramLong2);
+  
+  public static native int listen(long paramLong, int paramInt);
+  
+  public static native long accept(long paramLong)
+    throws Exception;
+  
+  public static native int acceptfilter(long paramLong, String paramString1, String paramString2);
+  
+  public static native boolean atmark(long paramLong);
+  
+  public static native int connect(long paramLong1, long paramLong2);
+  
+  public static native int send(long paramLong, byte[] paramArrayOfByte, int paramInt1, int paramInt2);
+  
+  public static native int sendb(long paramLong, ByteBuffer paramByteBuffer, int paramInt1, int paramInt2);
+  
+  public static native int sendbb(long paramLong, int paramInt1, int paramInt2);
+  
+  public static native int sendv(long paramLong, byte[][] paramArrayOfByte);
+  
+  public static native int sendto(long paramLong1, long paramLong2, int paramInt1, byte[] paramArrayOfByte, int paramInt2, int paramInt3);
+  
+  public static native int recv(long paramLong, byte[] paramArrayOfByte, int paramInt1, int paramInt2);
+  
+  public static native int recvt(long paramLong1, byte[] paramArrayOfByte, int paramInt1, int paramInt2, long paramLong2);
+  
+  public static native int recvb(long paramLong, ByteBuffer paramByteBuffer, int paramInt1, int paramInt2);
+  
+  public static native int recvbb(long paramLong, int paramInt1, int paramInt2);
+  
+  public static native int recvbt(long paramLong1, ByteBuffer paramByteBuffer, int paramInt1, int paramInt2, long paramLong2);
+  
+  public static native int recvbbt(long paramLong1, int paramInt1, int paramInt2, long paramLong2);
+  
+  public static native int recvFrom(long paramLong1, long paramLong2, int paramInt1, byte[] paramArrayOfByte, int paramInt2, int paramInt3);
+  
+  public static native int optSet(long paramLong, int paramInt1, int paramInt2);
+  
+  public static native int optGet(long paramLong, int paramInt)
+    throws Exception;
+  
+  public static native int timeoutSet(long paramLong1, long paramLong2);
+  
+  public static native long timeoutGet(long paramLong)
+    throws Exception;
+  
+  public static native long sendfile(long paramLong1, long paramLong2, byte[][] paramArrayOfByte1, byte[][] paramArrayOfByte2, long paramLong3, long paramLong4, int paramInt);
+  
+  public static native long sendfilen(long paramLong1, long paramLong2, long paramLong3, long paramLong4, int paramInt);
+  
+  public static native long pool(long paramLong)
+    throws Exception;
+  
+  private static native long get(long paramLong, int paramInt);
+  
+  public static native void setsbb(long paramLong, ByteBuffer paramByteBuffer);
+  
+  public static native void setrbb(long paramLong, ByteBuffer paramByteBuffer);
+  
+  public static native int dataSet(long paramLong, String paramString, Object paramObject);
+  
+  public static native Object dataGet(long paramLong, String paramString);
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Socket.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Status.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Status.java
new file mode 100644
index 0000000..eab790a
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Status.java
@@ -0,0 +1,270 @@
+/*     */ package org.apache.tomcat.jni;
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */ public class Status
+/*     */ {
+/*     */   public static final int APR_OS_START_ERROR = 20000;
+/*     */   
+/*     */ 
+/*     */ 
+/*     */ 
+/*     */   public static final int APR_OS_ERRSPACE_SIZE = 50000;
+/*     */   
+/*     */ 
+/*     */ 
+/*     */   public static final int APR_OS_START_STATUS = 70000;
+/*     */   
+/*     */ 
+/*     */ 
+/*     */   public static final int APR_OS_START_USERERR = 120000;
+/*     */   
+/*     */ 
+/*     */ 
+/*     */   public static final int APR_OS_START_USEERR = 120000;
+/*     */   
+/*     */ 
+/*     */ 
+/*     */   public static final int APR_OS_START_CANONERR = 620000;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_OS_START_EAIERR = 670000;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_OS_START_SYSERR = 720000;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_SUCCESS = 0;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ENOSTAT = 20001;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ENOPOOL = 20002;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EBADDATE = 20004;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EINVALSOCK = 20005;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ENOPROC = 20006;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ENOTIME = 20007;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ENODIR = 20008;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ENOLOCK = 20009;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ENOPOLL = 20010;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ENOSOCKET = 20011;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ENOTHREAD = 20012;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ENOTHDKEY = 20013;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EGENERAL = 20014;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ENOSHMAVAIL = 20015;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EBADIP = 20016;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EBADMASK = 20017;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EDSOOPEN = 20019;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EABSOLUTE = 20020;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ERELATIVE = 20021;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EINCOMPLETE = 20022;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EABOVEROOT = 20023;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EBADPATH = 20024;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EPATHWILD = 20025;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ESYMNOTFOUND = 20026;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EPROC_UNKNOWN = 20027;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ENOTENOUGHENTROPY = 20028;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_INCHILD = 70001;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_INPARENT = 70002;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_DETACH = 70003;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_NOTDETACH = 70004;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_CHILD_DONE = 70005;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_CHILD_NOTDONE = 70006;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_TIMEUP = 70007;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_INCOMPLETE = 70008;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_BADCH = 70012;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_BADARG = 70013;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EOF = 70014;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_NOTFOUND = 70015;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ANONYMOUS = 70019;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_FILEBASED = 70020;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_KEYBASED = 70021;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EINIT = 70022;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_ENOTIMPL = 70023;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EMISMATCH = 70024;
+/*     */   
+/*     */ 
+/*     */   public static final int APR_EBUSY = 70025;
+/*     */   
+/*     */ 
+/*     */   public static final int TIMEUP = 120001;
+/*     */   
+/*     */ 
+/*     */   public static final int EAGAIN = 120002;
+/*     */   
+/*     */ 
+/*     */   public static final int EINTR = 120003;
+/*     */   
+/*     */ 
+/*     */   public static final int EINPROGRESS = 120004;
+/*     */   
+/*     */ 
+/*     */   public static final int ETIMEDOUT = 120005;
+/*     */   
+/*     */ 
+/*     */ 
+/*     */   private static native boolean is(int paramInt1, int paramInt2);
+/*     */   
+/*     */ 
+/*     */ 
+/* 197 */   public static final boolean APR_STATUS_IS_ENOSTAT(int s) { return is(s, 1); }
+/* 198 */   public static final boolean APR_STATUS_IS_ENOPOOL(int s) { return is(s, 2); }
+/*     */   
+/* 200 */   public static final boolean APR_STATUS_IS_EBADDATE(int s) { return is(s, 4); }
+/* 201 */   public static final boolean APR_STATUS_IS_EINVALSOCK(int s) { return is(s, 5); }
+/* 202 */   public static final boolean APR_STATUS_IS_ENOPROC(int s) { return is(s, 6); }
+/* 203 */   public static final boolean APR_STATUS_IS_ENOTIME(int s) { return is(s, 7); }
+/* 204 */   public static final boolean APR_STATUS_IS_ENODIR(int s) { return is(s, 8); }
+/* 205 */   public static final boolean APR_STATUS_IS_ENOLOCK(int s) { return is(s, 9); }
+/* 206 */   public static final boolean APR_STATUS_IS_ENOPOLL(int s) { return is(s, 10); }
+/* 207 */   public static final boolean APR_STATUS_IS_ENOSOCKET(int s) { return is(s, 11); }
+/* 208 */   public static final boolean APR_STATUS_IS_ENOTHREAD(int s) { return is(s, 12); }
+/* 209 */   public static final boolean APR_STATUS_IS_ENOTHDKEY(int s) { return is(s, 13); }
+/* 210 */   public static final boolean APR_STATUS_IS_EGENERAL(int s) { return is(s, 14); }
+/* 211 */   public static final boolean APR_STATUS_IS_ENOSHMAVAIL(int s) { return is(s, 15); }
+/* 212 */   public static final boolean APR_STATUS_IS_EBADIP(int s) { return is(s, 16); }
+/* 213 */   public static final boolean APR_STATUS_IS_EBADMASK(int s) { return is(s, 17); }
+/*     */   
+/* 215 */   public static final boolean APR_STATUS_IS_EDSOPEN(int s) { return is(s, 19); }
+/* 216 */   public static final boolean APR_STATUS_IS_EABSOLUTE(int s) { return is(s, 20); }
+/* 217 */   public static final boolean APR_STATUS_IS_ERELATIVE(int s) { return is(s, 21); }
+/* 218 */   public static final boolean APR_STATUS_IS_EINCOMPLETE(int s) { return is(s, 22); }
+/* 219 */   public static final boolean APR_STATUS_IS_EABOVEROOT(int s) { return is(s, 23); }
+/* 220 */   public static final boolean APR_STATUS_IS_EBADPATH(int s) { return is(s, 24); }
+/* 221 */   public static final boolean APR_STATUS_IS_EPATHWILD(int s) { return is(s, 25); }
+/* 222 */   public static final boolean APR_STATUS_IS_ESYMNOTFOUND(int s) { return is(s, 26); }
+/* 223 */   public static final boolean APR_STATUS_IS_EPROC_UNKNOWN(int s) { return is(s, 27); }
+/* 224 */   public static final boolean APR_STATUS_IS_ENOTENOUGHENTROPY(int s) { return is(s, 28); }
+/*     */   
+/*     */ 
+/*     */ 
+/*     */ 
+/* 229 */   public static final boolean APR_STATUS_IS_INCHILD(int s) { return is(s, 51); }
+/* 230 */   public static final boolean APR_STATUS_IS_INPARENT(int s) { return is(s, 52); }
+/* 231 */   public static final boolean APR_STATUS_IS_DETACH(int s) { return is(s, 53); }
+/* 232 */   public static final boolean APR_STATUS_IS_NOTDETACH(int s) { return is(s, 54); }
+/* 233 */   public static final boolean APR_STATUS_IS_CHILD_DONE(int s) { return is(s, 55); }
+/* 234 */   public static final boolean APR_STATUS_IS_CHILD_NOTDONE(int s) { return is(s, 56); }
+/* 235 */   public static final boolean APR_STATUS_IS_TIMEUP(int s) { return is(s, 57); }
+/* 236 */   public static final boolean APR_STATUS_IS_INCOMPLETE(int s) { return is(s, 58); }
+/*     */   
+/*     */ 
+/*     */ 
+/* 240 */   public static final boolean APR_STATUS_IS_BADCH(int s) { return is(s, 62); }
+/* 241 */   public static final boolean APR_STATUS_IS_BADARG(int s) { return is(s, 63); }
+/* 242 */   public static final boolean APR_STATUS_IS_EOF(int s) { return is(s, 64); }
+/* 243 */   public static final boolean APR_STATUS_IS_NOTFOUND(int s) { return is(s, 65); }
+/*     */   
+/*     */ 
+/*     */ 
+/* 247 */   public static final boolean APR_STATUS_IS_ANONYMOUS(int s) { return is(s, 69); }
+/* 248 */   public static final boolean APR_STATUS_IS_FILEBASED(int s) { return is(s, 70); }
+/* 249 */   public static final boolean APR_STATUS_IS_KEYBASED(int s) { return is(s, 71); }
+/* 250 */   public static final boolean APR_STATUS_IS_EINIT(int s) { return is(s, 72); }
+/* 251 */   public static final boolean APR_STATUS_IS_ENOTIMPL(int s) { return is(s, 73); }
+/* 252 */   public static final boolean APR_STATUS_IS_EMISMATCH(int s) { return is(s, 74); }
+/* 253 */   public static final boolean APR_STATUS_IS_EBUSY(int s) { return is(s, 75); }
+/*     */   
+/*     */ 
+/* 256 */   public static final boolean APR_STATUS_IS_EAGAIN(int s) { return is(s, 90); }
+/* 257 */   public static final boolean APR_STATUS_IS_ETIMEDOUT(int s) { return is(s, 91); }
+/* 258 */   public static final boolean APR_STATUS_IS_ECONNABORTED(int s) { return is(s, 92); }
+/* 259 */   public static final boolean APR_STATUS_IS_ECONNRESET(int s) { return is(s, 93); }
+/* 260 */   public static final boolean APR_STATUS_IS_EINPROGRESS(int s) { return is(s, 94); }
+/* 261 */   public static final boolean APR_STATUS_IS_EINTR(int s) { return is(s, 95); }
+/* 262 */   public static final boolean APR_STATUS_IS_ENOTSOCK(int s) { return is(s, 96); }
+/* 263 */   public static final boolean APR_STATUS_IS_EINVAL(int s) { return is(s, 97); }
+/*     */ }
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Status.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Stdlib.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Stdlib.java
new file mode 100644
index 0000000..b600c68
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Stdlib.java
@@ -0,0 +1,28 @@
+package org.apache.tomcat.jni;
+
+public class Stdlib
+{
+  public static native boolean memread(byte[] paramArrayOfByte, long paramLong, int paramInt);
+  
+  public static native boolean memwrite(long paramLong, byte[] paramArrayOfByte, int paramInt);
+  
+  public static native boolean memset(long paramLong, int paramInt1, int paramInt2);
+  
+  public static native long malloc(int paramInt);
+  
+  public static native long realloc(long paramLong, int paramInt);
+  
+  public static native long calloc(long paramLong, int paramInt);
+  
+  public static native void free(long paramLong);
+  
+  public static native int getpid();
+  
+  public static native int getppid();
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Stdlib.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Thread.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Thread.java
new file mode 100644
index 0000000..ef7bf1c
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Thread.java
@@ -0,0 +1,12 @@
+package org.apache.tomcat.jni;
+
+public class Thread
+{
+  public static native long current();
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Thread.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Time.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Time.java
new file mode 100644
index 0000000..6dde339
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/Time.java
@@ -0,0 +1,58 @@
+/*    */ package org.apache.tomcat.jni;
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ public class Time
+/*    */ {
+/*    */   public static final long APR_USEC_PER_SEC = 1000000L;
+/*    */   
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */   public static final long APR_MSEC_PER_USEC = 1000L;
+/*    */   
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */ 
+/*    */   public static long sec(long t)
+/*    */   {
+/* 36 */     return t / 1000000L;
+/*    */   }
+/*    */   
+/*    */ 
+/*    */   public static long msec(long t)
+/*    */   {
+/* 42 */     return t / 1000L;
+/*    */   }
+/*    */   
+/*    */   public static native long now();
+/*    */   
+/*    */   public static native String rfc822(long paramLong);
+/*    */   
+/*    */   public static native String ctime(long paramLong);
+/*    */   
+/*    */   public static native void sleep(long paramLong);
+/*    */ }
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\Time.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file
diff --git a/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/User.java b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/User.java
new file mode 100644
index 0000000..c41c625
--- /dev/null
+++ b/src/tomcat-apr-5.5.23-sources/org/apache/tomcat/jni/User.java
@@ -0,0 +1,38 @@
+package org.apache.tomcat.jni;
+
+public class User
+{
+  public static native long uidCurrent(long paramLong)
+    throws Error;
+  
+  public static native long gidCurrent(long paramLong)
+    throws Error;
+  
+  public static native long uid(String paramString, long paramLong)
+    throws Error;
+  
+  public static native long usergid(String paramString, long paramLong)
+    throws Error;
+  
+  public static native long gid(String paramString, long paramLong)
+    throws Error;
+  
+  public static native String username(long paramLong1, long paramLong2)
+    throws Error;
+  
+  public static native String groupname(long paramLong1, long paramLong2)
+    throws Error;
+  
+  public static native int uidcompare(long paramLong1, long paramLong2);
+  
+  public static native int gidcompare(long paramLong1, long paramLong2);
+  
+  public static native String homepath(String paramString, long paramLong)
+    throws Error;
+}
+
+
+/* Location:              C:\Users\lgoldstein\.m2\repository\tomcat\tomcat-apr\5.5.23\tomcat-apr-5.5.23.jar!\org\apache\tomcat\jni\User.class
+ * Java compiler version: 2 (46.0)
+ * JD-Core Version:       0.7.1
+ */
\ No newline at end of file


[mina-sshd] 01/06: [SSHD-946] Supporting 'encrypt-then-MAC' mode

Posted by lg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

lgoldstein pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mina-sshd.git

commit 06eeff80a7ca2fe7d6b9cfa96f5c081a6ce8c49e
Author: Lyor Goldstein <lg...@apache.org>
AuthorDate: Sun Oct 13 11:54:08 2019 +0300

    [SSHD-946] Supporting 'encrypt-then-MAC' mode
---
 CHANGES.md                                         |   7 +
 README.md                                          |   5 +-
 .../sshd/cli/client/SshClientCliSupport.java       |   3 +-
 .../java/org/apache/sshd/common/SshConstants.java  |   3 +-
 .../apache/sshd/common/kex/KexProposalOption.java  |  17 ++
 .../java/org/apache/sshd/common/mac/BaseMac.java   |  18 ++-
 .../org/apache/sshd/common/mac/BuiltinMacs.java    |  53 +++++--
 .../org/apache/sshd/common/mac/MacInformation.java |   4 +
 .../org/apache/sshd/common/util/buffer/Buffer.java |  18 ++-
 .../sshd/common/util/buffer/ByteArrayBuffer.java   |   5 +
 .../apache/sshd/util/test/JUnitTestSupport.java    |   8 +
 .../java/org/apache/sshd/common/BaseBuilder.java   |   7 +-
 .../org/apache/sshd/common/io/PacketWriter.java    |  22 ++-
 .../common/session/helpers/AbstractSession.java    | 174 ++++++++++++++-------
 .../sshd/common/session/helpers/SessionHelper.java |   3 +-
 .../sshd/common/compression/CompressionTest.java   |   6 +-
 .../apache/sshd/common/mac/EncryptThenMacTest.java | 141 +++++++++++++++++
 .../{MacTest.java => MacCompatibilityTest.java}    |  21 ++-
 .../apache/sshd/server/auth/WelcomeBannerTest.java |   5 +-
 19 files changed, 419 insertions(+), 101 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 0f48121..73664a9 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -37,6 +37,9 @@ the standard does not specifically specify the behavior regarding symbolic links
 * `Signature` methods accept a `SessionContext` argument representing the session context
 of their invocation (if any)
 
+* Default MAC(s) list is set according to the [ssh_config(5)](https://www.freebsd.org/cgi/man.cgi?query=ssh_config&sektion=5)
+order as **first** ones, where the supported MAC(s) that do no appear in it come last.
+
 ## Minor code helpers
 
 * `SessionListener` supports `sessionPeerIdentificationReceived` method that is invoked once successful
@@ -57,6 +60,8 @@ the message type=30 (old request).
 
 * `AbstractSignature#doInitSignature` is now provided also with the `Key` instance for which it is invoked.
 
+* The `MacInformation` interface has an extra `isEncryptThenMac` method (default=_false_) to enable distinction of this mode.
+
 ## Behavioral changes and enhancements
 
 * [SSHD-926](https://issues.apache.org/jira/browse/SSHD-930) - Add support for OpenSSH 'lsetstat@openssh.com' SFTP protocol extension.
@@ -77,6 +82,8 @@ exchange via properties.
 
 * [SSHD-945](https://issues.apache.org/jira/browse/SSHD-945) - Added sshd-contrib code that uses SHA1 with DSA regardless of its key length
 
+* [SSHD-946](https://issues.apache.org/jira/browse/SSHD-946) - Supporting 'encrypt-then-MAC' mode.
+
 * [SSHD-947](https://issues.apache.org/jira/browse/SSHD-947) - Added configuration allowing the user to specify whether client should wait
 for the server's identification before sending KEX-INIT message.
 
diff --git a/README.md b/README.md
index ac35e7b..f6d5399 100644
--- a/README.md
+++ b/README.md
@@ -47,8 +47,9 @@ based applications requiring SSH support.
 ## Implemented/available support
 
 * **Ciphers**: aes128cbc, aes128ctr, aes192cbc, aes192ctr, aes256cbc, aes256ctr, arcfour128, arcfour256, blowfishcbc, tripledescbc
-* **Digests**: md5, sha1, sha224, sha384, sha512
-* **Macs**: hmacmd5, hmacmd596, hmacsha1, hmacsha196, hmacsha256, hmacsha512
+* **Digests**: md5, sha1, sha224, sha256, sha384, sha512
+* **Macs**: hmacmd5, hmacmd596, hmacsha1, hmacsha196, hmacsha256, hmacsha512, hmac-sha2-256-etm@openssh.com
+, hmac-sha2-512-etm@openssh.com, hmac-sha1-etm@openssh.com
 * **Key exchange**: diffie-hellman-group1-sha1, diffie-hellman-group-exchange-sha256, diffie-hellman-group14-sha1, diffie-hellman-group14-sha256
 , diffie-hellman-group15-sha512, diffie-hellman-group16-sha512, diffie-hellman-group17-sha512, diffie-hellman-group18-sha512
 , ecdh-sha2-nistp256, ecdh-sha2-nistp384, ecdh-sha2-nistp521
diff --git a/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java b/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java
index 3d52b5f..ca1919b 100644
--- a/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java
+++ b/sshd-cli/src/main/java/org/apache/sshd/cli/client/SshClientCliSupport.java
@@ -681,7 +681,8 @@ public abstract class SshClientCliSupport extends CliSupport {
              : setupMacs(ConfigFileReaderSupport.MACS_CONFIG_PROP, argVal, null, stderr);
     }
 
-    public static List<NamedFactory<Mac>> setupMacs(String argName, String argVal, List<NamedFactory<Mac>> current, PrintStream stderr) {
+    public static List<NamedFactory<Mac>> setupMacs(
+            String argName, String argVal, List<NamedFactory<Mac>> current, PrintStream stderr) {
         if (GenericUtils.size(current) > 0) {
             showError(stderr, argName + " option value re-specified: " + NamedResource.getNames(current));
             return null;
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/SshConstants.java b/sshd-common/src/main/java/org/apache/sshd/common/SshConstants.java
index 7e73edf..06f7b05 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/SshConstants.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/SshConstants.java
@@ -122,7 +122,8 @@ public final class SshConstants {
 
     // Some more constants
     public static final int SSH_EXTENDED_DATA_STDERR = 1;   // see RFC4254 section 5.2
-    public static final int SSH_PACKET_HEADER_LEN = 5;  // 32-bit length + 8-bit pad length
+    // 32-bit length + 8-bit pad length
+    public static final int SSH_PACKET_HEADER_LEN = Integer.BYTES + Byte.BYTES;
     /*
      * See https://tools.ietf.org/html/rfc4253#section-6.1:
      *
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/kex/KexProposalOption.java b/sshd-common/src/main/java/org/apache/sshd/common/kex/KexProposalOption.java
index ae20311..752b41e 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/kex/KexProposalOption.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/kex/KexProposalOption.java
@@ -19,6 +19,7 @@
 
 package org.apache.sshd.common.kex;
 
+import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.EnumSet;
@@ -42,6 +43,22 @@ public enum KexProposalOption {
     C2SLANG(Constants.PROPOSAL_LANG_CTOS, "languages (client to server)"),
     S2CLANG(Constants.PROPOSAL_LANG_STOC, "languages (server to client)");
 
+    public static final Collection<KexProposalOption> CIPHER_PROPOSALS =
+        Collections.unmodifiableSet(
+            EnumSet.of(KexProposalOption.C2SENC, KexProposalOption.S2CENC));
+
+    public static final Collection<KexProposalOption> MAC_PROPOSALS =
+        Collections.unmodifiableSet(
+            EnumSet.of(KexProposalOption.C2SMAC, KexProposalOption.S2CMAC));
+
+    public static final Collection<KexProposalOption> COMPRESSION_PROPOSALS =
+        Collections.unmodifiableSet(
+            EnumSet.of(KexProposalOption.C2SCOMP, KexProposalOption.S2CCOMP));
+
+    public static final Collection<KexProposalOption> LANGUAGE_PROPOSALS =
+        Collections.unmodifiableSet(
+            EnumSet.of(KexProposalOption.C2SLANG, KexProposalOption.S2CLANG));
+
     /**
      * Compares values according to {@link KexProposalOption#getProposalIndex()}
      */
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/mac/BaseMac.java b/sshd-common/src/main/java/org/apache/sshd/common/mac/BaseMac.java
index e1681d4..036d46f 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/mac/BaseMac.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/mac/BaseMac.java
@@ -33,32 +33,39 @@ public class BaseMac implements Mac {
     private final int defbsize;
     private final int bsize;
     private final byte[] tmp;
+    private final boolean etmMode;
     private javax.crypto.Mac mac;
     private String s;
 
-    public BaseMac(String algorithm, int bsize, int defbsize) {
+    public BaseMac(String algorithm, int bsize, int defbsize, boolean etmMode) {
         this.algorithm = algorithm;
         this.bsize = bsize;
         this.defbsize = defbsize;
         this.tmp = new byte[defbsize];
+        this.etmMode = etmMode;
     }
 
     @Override
-    public final String getAlgorithm() {
+    public String getAlgorithm() {
         return algorithm;
     }
 
     @Override
-    public final int getBlockSize() {
+    public int getBlockSize() {
         return bsize;
     }
 
     @Override
-    public final int getDefaultBlockSize() {
+    public int getDefaultBlockSize() {
         return defbsize;
     }
 
     @Override
+    public boolean isEncryptThenMac() {
+        return etmMode;
+    }
+
+    @Override
     public void init(byte[] key) throws Exception {
         if (key.length > defbsize) {
             byte[] tmp = new byte[defbsize];
@@ -102,7 +109,8 @@ public class BaseMac implements Mac {
         synchronized (this) {
             if (s == null) {
                 s = getClass().getSimpleName() + "[" + getAlgorithm() + "] - "
-                    + " block=" + getBlockSize() + "/" + getDefaultBlockSize() + " bytes";
+                    + " block=" + getBlockSize() + "/" + getDefaultBlockSize() + " bytes"
+                    + ", encrypt-then-mac=" + isEncryptThenMac();
             }
         }
 
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java b/sshd-common/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java
index 3c7beaa..a393082 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java
@@ -46,11 +46,29 @@ public enum BuiltinMacs implements MacFactory {
     hmacmd5(Constants.HMAC_MD5, "HmacMD5", 16, 16),
     hmacmd596(Constants.HMAC_MD5_96, "HmacMD5", 12, 16),
     hmacsha1(Constants.HMAC_SHA1, "HmacSHA1", 20, 20),
+    hmacsha1etm(Constants.ETM_HMAC_SHA1, "HmacSHA1", 20, 20) {
+        @Override
+        public boolean isEncryptThenMac() {
+            return true;
+        }
+    },
     hmacsha196(Constants.HMAC_SHA1_96, "HmacSHA1", 12, 20),
     /** See <A HREF="https://tools.ietf.org/html/rfc6668">RFC 6668</A> */
     hmacsha256(Constants.HMAC_SHA2_256, "HmacSHA256", 32, 32),
+    hmacsha256etm(Constants.ETM_HMAC_SHA2_256, "HmacSHA256", 32, 32) {
+        @Override
+        public boolean isEncryptThenMac() {
+            return true;
+        }
+    },
     /** See <A HREF="https://tools.ietf.org/html/rfc6668">RFC 6668</A> */
-    hmacsha512(Constants.HMAC_SHA2_512, "HmacSHA512", 64, 64);
+    hmacsha512(Constants.HMAC_SHA2_512, "HmacSHA512", 64, 64),
+    hmacsha512etm(Constants.ETM_HMAC_SHA2_512, "HmacSHA512", 64, 64) {
+        @Override
+        public boolean isEncryptThenMac() {
+            return true;
+        }
+    };
 
     public static final Set<BuiltinMacs> VALUES =
         Collections.unmodifiableSet(EnumSet.allOf(BuiltinMacs.class));
@@ -72,7 +90,7 @@ public enum BuiltinMacs implements MacFactory {
 
     @Override
     public Mac create() {
-        return new BaseMac(getAlgorithm(), getBlockSize(), getDefaultBlockSize());
+        return new BaseMac(getAlgorithm(), getBlockSize(), getDefaultBlockSize(), isEncryptThenMac());
     }
 
     @Override
@@ -116,10 +134,12 @@ public enum BuiltinMacs implements MacFactory {
      */
     public static void registerExtension(MacFactory extension) {
         String name = Objects.requireNonNull(extension, "No extension provided").getName();
-        ValidateUtils.checkTrue(fromFactoryName(name) == null, "Extension overrides built-in: %s", name);
+        ValidateUtils.checkTrue(
+            fromFactoryName(name) == null, "Extension overrides built-in: %s", name);
 
         synchronized (EXTENSIONS) {
-            ValidateUtils.checkTrue(!EXTENSIONS.containsKey(name), "Extension overrides existing: %s", name);
+            ValidateUtils.checkTrue(
+                !EXTENSIONS.containsKey(name), "Extension overrides existing: %s", name);
             EXTENSIONS.put(name, extension);
         }
     }
@@ -130,7 +150,8 @@ public enum BuiltinMacs implements MacFactory {
      */
     public static NavigableSet<MacFactory> getRegisteredExtensions() {
         synchronized (EXTENSIONS) {
-            return GenericUtils.asSortedSet(NamedResource.BY_NAME_COMPARATOR, EXTENSIONS.values());
+            return GenericUtils.asSortedSet(
+                NamedResource.BY_NAME_COMPARATOR, EXTENSIONS.values());
         }
     }
 
@@ -152,8 +173,9 @@ public enum BuiltinMacs implements MacFactory {
 
     /**
      * @param s The {@link Enum}'s name - ignored if {@code null}/empty
-     * @return The matching {@link org.apache.sshd.common.mac.BuiltinMacs} whose {@link Enum#name()} matches
-     * (case <U>insensitive</U>) the provided argument - {@code null} if no match
+     * @return The matching {@link org.apache.sshd.common.mac.BuiltinMacs}
+     * whose {@link Enum#name()} matches (case <U>insensitive</U>) the provided
+     * argument - {@code null} if no match
      */
     public static BuiltinMacs fromString(String s) {
         if (GenericUtils.isEmpty(s)) {
@@ -193,8 +215,7 @@ public enum BuiltinMacs implements MacFactory {
     }
 
     /**
-     * @param macs A comma-separated list of MACs' names - ignored
-     *             if {@code null}/empty
+     * @param macs A comma-separated list of MACs' names - ignored if {@code null}/empty
      * @return A {@link ParseResult} containing the successfully parsed
      * factories and the unknown ones. <B>Note:</B> it is up to caller to
      * ensure that the lists do not contain duplicates
@@ -204,7 +225,9 @@ public enum BuiltinMacs implements MacFactory {
     }
 
     public static ParseResult parseMacsList(String... macs) {
-        return parseMacsList(GenericUtils.isEmpty((Object[]) macs) ? Collections.emptyList() : Arrays.asList(macs));
+        return parseMacsList(GenericUtils.isEmpty((Object[]) macs)
+            ? Collections.emptyList()
+            : Arrays.asList(macs));
     }
 
     public static ParseResult parseMacsList(Collection<String> macs) {
@@ -250,8 +273,10 @@ public enum BuiltinMacs implements MacFactory {
         }
     }
 
-    public static final class ParseResult extends NamedFactoriesListParseResult<Mac, MacFactory> {
-        public static final ParseResult EMPTY = new ParseResult(Collections.emptyList(), Collections.emptyList());
+    public static final class ParseResult
+            extends NamedFactoriesListParseResult<Mac, MacFactory> {
+        public static final ParseResult EMPTY =
+            new ParseResult(Collections.emptyList(), Collections.emptyList());
 
         public ParseResult(List<MacFactory> parsed, List<String> unsupported) {
             super(parsed, unsupported);
@@ -266,6 +291,10 @@ public enum BuiltinMacs implements MacFactory {
         public static final String HMAC_SHA2_256 = "hmac-sha2-256";
         public static final String HMAC_SHA2_512 = "hmac-sha2-512";
 
+        public static final String ETM_HMAC_SHA1 = "hmac-sha1-etm@openssh.com";
+        public static final String ETM_HMAC_SHA2_256 = "hmac-sha2-256-etm@openssh.com";
+        public static final String ETM_HMAC_SHA2_512 = "hmac-sha2-512-etm@openssh.com";
+
         private Constants() {
             throw new UnsupportedOperationException("No instance allowed");
         }
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/mac/MacInformation.java b/sshd-common/src/main/java/org/apache/sshd/common/mac/MacInformation.java
index 07a9321..7d5f6a1 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/mac/MacInformation.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/mac/MacInformation.java
@@ -37,4 +37,8 @@ public interface MacInformation extends AlgorithmNameProvider {
      * @return The &quot;natural&quot; MAC block size in bytes
      */
     int getDefaultBlockSize();
+
+    default boolean isEncryptThenMac() {
+        return false;
+    }
 }
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java b/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
index ee2901f..bb29204 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
@@ -114,6 +114,15 @@ public abstract class Buffer implements Readable {
     public abstract byte[] array();
 
     /**
+     * @param pos A position in the <U>raw</U> underlying data bytes
+     * @return The byte at that position
+     */
+    public byte rawByte(int pos) {
+        byte[] data = array();
+        return data[pos];
+    }
+
+    /**
      * &quot;Shift&quot; the internal data so that reading starts from
      * position zero.
      */
@@ -221,7 +230,8 @@ public abstract class Buffer implements Readable {
     }
 
     public void dumpHex(SimplifiedLog logger, Level level, String prefix, PropertyResolver resolver) {
-        BufferUtils.dumpHex(logger, level, prefix, resolver, BufferUtils.DEFAULT_HEX_SEPARATOR, array(), rpos(), available());
+        BufferUtils.dumpHex(
+            logger, level, prefix, resolver, BufferUtils.DEFAULT_HEX_SEPARATOR, array(), rpos(), available());
     }
 
     /*======================
@@ -482,9 +492,9 @@ public abstract class Buffer implements Readable {
 
     public KeyPair getKeyPair() throws SshException {
         try {
-            final PublicKey pub;
-            final PrivateKey prv;
-            final String keyAlg = getString();
+            PublicKey pub;
+            PrivateKey prv;
+            String keyAlg = getString();
             if (KeyPairProvider.SSH_RSA.equals(keyAlg)) {
                 BigInteger e = getMPInt();
                 BigInteger n = getMPInt();
diff --git a/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java b/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java
index bb9ff8c..e0dee96 100644
--- a/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java
+++ b/sshd-common/src/main/java/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java
@@ -158,6 +158,11 @@ public class ByteArrayBuffer extends Buffer {
     }
 
     @Override
+    public byte rawByte(int pos) {
+        return data[pos];
+    }
+
+    @Override
     public void compact() {
         int avail = available();
         if (avail > 0) {
diff --git a/sshd-common/src/test/java/org/apache/sshd/util/test/JUnitTestSupport.java b/sshd-common/src/test/java/org/apache/sshd/util/test/JUnitTestSupport.java
index 9d57473..aa1e16b 100644
--- a/sshd-common/src/test/java/org/apache/sshd/util/test/JUnitTestSupport.java
+++ b/sshd-common/src/test/java/org/apache/sshd/util/test/JUnitTestSupport.java
@@ -576,6 +576,14 @@ public abstract class JUnitTestSupport extends Assert {
         return false;
     }
 
+    /* ---------------------------------------------------------------------------- */
+
+    public static void outputDebugMessage(String format, Object o) {
+        if (OUTPUT_DEBUG_MESSAGES) {
+            outputDebugMessage(String.format(format, o));
+        }
+    }
+
     public static void outputDebugMessage(String format, Object... args) {
         if (OUTPUT_DEBUG_MESSAGES) {
             outputDebugMessage(String.format(format, args));
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java b/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java
index 904726c..484cc88 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/BaseBuilder.java
@@ -116,10 +116,13 @@ public class BaseBuilder<T extends AbstractFactoryManager, S extends BaseBuilder
     public static final List<BuiltinMacs> DEFAULT_MAC_PREFERENCE =
         Collections.unmodifiableList(
             Arrays.asList(
-                BuiltinMacs.hmacmd5,
-                BuiltinMacs.hmacsha1,
+                BuiltinMacs.hmacsha256etm,
+                BuiltinMacs.hmacsha512etm,
+                BuiltinMacs.hmacsha1etm,
                 BuiltinMacs.hmacsha256,
                 BuiltinMacs.hmacsha512,
+                BuiltinMacs.hmacsha1,
+                BuiltinMacs.hmacmd5,
                 BuiltinMacs.hmacsha196,
                 BuiltinMacs.hmacmd596
             ));
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/PacketWriter.java b/sshd-core/src/main/java/org/apache/sshd/common/io/PacketWriter.java
index 42cda19..59f66b0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/PacketWriter.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/PacketWriter.java
@@ -24,8 +24,6 @@ import java.nio.channels.Channel;
 import org.apache.sshd.common.util.buffer.Buffer;
 
 /**
- * TODO Add javadoc
- *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 public interface PacketWriter extends Channel {
@@ -40,4 +38,24 @@ public interface PacketWriter extends Channel {
      * @throws IOException if an error occurred when encoding sending the packet
      */
     IoWriteFuture writePacket(Buffer buffer) throws IOException;
+
+    /**
+     * @param len The packet payload size
+     * @param blockSize The cipher block size
+     * @param etmMode Whether using &quot;encrypt-then-MAC&quot; mode
+     * @return The required padding length
+     */
+    static int calculatePadLength(int len, int blockSize, boolean etmMode) {
+        len++;  // the pad length
+        if (!etmMode) {
+            len += Integer.BYTES;
+        }
+
+        int pad = (-len) & (blockSize - 1);
+        if (pad < blockSize) {
+            pad += blockSize;
+        }
+
+        return pad;
+    }
 }
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
index 27e87a8..241162e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/AbstractSession.java
@@ -39,6 +39,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.logging.Level;
 
 import org.apache.sshd.common.Closeable;
 import org.apache.sshd.common.Factory;
@@ -61,6 +62,7 @@ import org.apache.sshd.common.future.KeyExchangeFuture;
 import org.apache.sshd.common.future.SshFutureListener;
 import org.apache.sshd.common.io.IoSession;
 import org.apache.sshd.common.io.IoWriteFuture;
+import org.apache.sshd.common.io.PacketWriter;
 import org.apache.sshd.common.kex.KexProposalOption;
 import org.apache.sshd.common.kex.KexState;
 import org.apache.sshd.common.kex.KeyExchange;
@@ -1030,24 +1032,24 @@ public abstract class AbstractSession extends SessionHelper {
     }
 
     /**
-     * Encode a buffer into the SSH protocol.
-     * This method need to be called into a synchronized block around encodeLock
+     * Encode a buffer into the SSH protocol. <B>Note:</B> This method must be called
+     * inside a {@code synchronized} block using {@code encodeLock}.
      *
      * @param buffer the buffer to encode
      * @return The encoded buffer - may be different than original if input
      * buffer does not have enough room for {@link SshConstants#SSH_PACKET_HEADER_LEN},
-     * in which a substitute buffer will be created and used.
+     * in which case a substitute buffer will be created and used.
      * @throws IOException if an exception occurs during the encoding process
      */
     protected Buffer encode(Buffer buffer) throws IOException {
         try {
             // Check that the packet has some free space for the header
             int curPos = buffer.rpos();
+            int cmd = buffer.rawByte(curPos) & 0xFF;  // usually the 1st byte is an SSH opcode
             if (curPos < SshConstants.SSH_PACKET_HEADER_LEN) {
-                byte[] data = buffer.array();
-                int cmd = data[curPos] & 0xFF;  // usually the 1st byte is an SSH opcode
-                log.warn("encode({}) command={} performance cost: available buffer packet header length ({}) below min. required ({})",
-                     this, SshConstants.getCommandMessageName(cmd), curPos, SshConstants.SSH_PACKET_HEADER_LEN);
+                log.warn("encode({}) command={}[{}] performance cost: available buffer packet header length ({}) below min. required ({})",
+                     this, cmd, SshConstants.getCommandMessageName(cmd),
+                     curPos, SshConstants.SSH_PACKET_HEADER_LEN);
                 Buffer nb = new ByteArrayBuffer(buffer.available() + Long.SIZE, false);
                 nb.wpos(SshConstants.SSH_PACKET_HEADER_LEN);
                 nb.putBuffer(buffer);
@@ -1057,57 +1059,63 @@ public abstract class AbstractSession extends SessionHelper {
 
             // Grab the length of the packet (excluding the 5 header bytes)
             int len = buffer.available();
+            if (log.isDebugEnabled()) {
+                log.debug("encode({}) packet #{} sending command={}[{}] len={}",
+                    this, seqo, cmd, SshConstants.getCommandMessageName(cmd), len);
+            }
+
             int off = curPos - SshConstants.SSH_PACKET_HEADER_LEN;
             // Debug log the packet
-            if (log.isTraceEnabled()) {
-                buffer.dumpHex(getSimplifiedLogger(), "encode(" + this + ") packet #" + seqo, this);
+            boolean traceEnabled = log.isTraceEnabled();
+            if (traceEnabled) {
+                buffer.dumpHex(getSimplifiedLogger(), Level.FINEST, "encode(" + this + ") packet #" + seqo, this);
             }
 
             // Compress the packet if needed
             if ((outCompression != null)
                     && outCompression.isCompressionExecuted()
                     && (isAuthenticated() || (!outCompression.isDelayed()))) {
+                int oldLen = len;
                 outCompression.compress(buffer);
                 len = buffer.available();
+                if (traceEnabled) {
+                    log.trace("encode({}) packet #{} command={}[{}] compressed {} -> {}",
+                        this, seqo, cmd, SshConstants.getCommandMessageName(cmd), oldLen, len);
+                }
             }
 
             // Compute padding length
-            int bsize = outCipherSize;
+            boolean etmMode = (outMac == null) ? false : outMac.isEncryptThenMac();
+            int pad = PacketWriter.calculatePadLength(len, outCipherSize, etmMode);
             int oldLen = len;
-            len += SshConstants.SSH_PACKET_HEADER_LEN;
-            int pad = (-len) & (bsize - 1);
-            if (pad < bsize) {
-                pad += bsize;
+            len = len + pad + Byte.BYTES /* the pad length byte */;
+
+            if (traceEnabled) {
+                log.trace("encode({}) packet #{} command={}[{}] len={}, pad={}, mac={}",
+                    this, seqo, cmd, SshConstants.getCommandMessageName(cmd), len, pad, outMac);
             }
-            len = len + pad - 4;
+
             // Write 5 header bytes
             buffer.wpos(off);
             buffer.putInt(len);
             buffer.putByte((byte) pad);
-            // Fill padding
+            // Make sure enough room for padding and then fill it
             buffer.wpos(off + oldLen + SshConstants.SSH_PACKET_HEADER_LEN + pad);
             synchronized (random) {
                 random.fill(buffer.array(), buffer.wpos() - pad, pad);
             }
 
-            // Compute mac
-            if (outMac != null) {
-                int macSize = outMac.getBlockSize();
-                int l = buffer.wpos();
-                buffer.wpos(l + macSize);
-                outMac.updateUInt(seqo);
-                outMac.update(buffer.array(), off, l);
-                outMac.doFinal(buffer.array(), l);
+            if (etmMode) {
+                // Do not encrypt the length field
+                encryptOutgoingBuffer(buffer, off + Integer.BYTES, len);
+                appendOutgoingMac(buffer, off, len);
+            } else {
+                appendOutgoingMac(buffer, off, len);
+                encryptOutgoingBuffer(buffer, off, len + Integer.BYTES);
             }
-            // Encrypt packet, excluding mac
-            if (outCipher != null) {
-                outCipher.update(buffer.array(), off, len + 4);
 
-                int blocksCount = (len + 4) / outCipher.getCipherBlockSize();
-                outBlocksCount.addAndGet(Math.max(1, blocksCount));
-            }
             // Increment packet id
-            seqo = (seqo + 1) & 0xffffffffL;
+            seqo = (seqo + 1L) & 0x0ffffffffL;
             // Update stats
             outPacketsCount.incrementAndGet();
             outBytesCount.addAndGet(len);
@@ -1121,6 +1129,33 @@ public abstract class AbstractSession extends SessionHelper {
         }
     }
 
+    protected void appendOutgoingMac(Buffer buf, int offset, int len) throws Exception {
+        if (outMac == null) {
+            return;
+        }
+
+        int macSize = outMac.getBlockSize();
+        int l = buf.wpos();
+        // ensure enough room for MAC in outgoing buffer
+        buf.wpos(l + macSize);
+        // Include sequence number
+        outMac.updateUInt(seqo);
+        // Include the length field in the MAC calculation
+        outMac.update(buf.array(), offset, len + Integer.BYTES);
+        // Append MAC to end of packet
+        outMac.doFinal(buf.array(), l);
+    }
+
+    protected void encryptOutgoingBuffer(Buffer buf, int offset, int len) throws Exception {
+        if (outCipher == null) {
+            return;
+        }
+        outCipher.update(buf.array(), offset, len);
+
+        int blocksCount = len / outCipher.getCipherBlockSize();
+        outBlocksCount.addAndGet(Math.max(1, blocksCount));
+    }
+
     /**
      * Decode the incoming buffer and handle packets as needed.
      *
@@ -1129,14 +1164,16 @@ public abstract class AbstractSession extends SessionHelper {
     protected void decode() throws Exception {
         // Decoding loop
         for (;;) {
+            boolean etmMode = (inMac == null) ? false : inMac.isEncryptThenMac();
             // Wait for beginning of packet
             if (decoderState == 0) {
                 // The read position should always be 0 at this point because we have compacted this buffer
                 assert decoderBuffer.rpos() == 0;
+                int minBufLen = etmMode ? Integer.BYTES : inCipherSize;
                 // If we have received enough bytes, start processing those
-                if (decoderBuffer.available() > inCipherSize) {
+                if (decoderBuffer.available() > minBufLen) {
                     // Decrypt the first bytes
-                    if (inCipher != null) {
+                    if ((inCipher != null) && (!etmMode)) {
                         inCipher.update(decoderBuffer.array(), 0, inCipherSize);
 
                         int blocksCount = inCipherSize / inCipher.getCipherBlockSize();
@@ -1151,7 +1188,7 @@ public abstract class AbstractSession extends SessionHelper {
                     if ((decoderLength < SshConstants.SSH_PACKET_HEADER_LEN)
                             || (decoderLength > (8 * SshConstants.SSH_REQUIRED_PAYLOAD_PACKET_LENGTH_SUPPORT))) {
                         log.warn("decode({}) Error decoding packet(invalid length): {}", this, decoderLength);
-                        decoderBuffer.dumpHex(getSimplifiedLogger(), "decode(" + this + ") invalid length packet", this);
+                        decoderBuffer.dumpHex(getSimplifiedLogger(), Level.FINEST, "decode(" + this + ") invalid length packet", this);
                         throw new SshException(SshConstants.SSH2_DISCONNECT_PROTOCOL_ERROR,
                                 "Invalid packet length: " + decoderLength);
                     }
@@ -1163,35 +1200,36 @@ public abstract class AbstractSession extends SessionHelper {
                 }
                 // We have received the beginning of the packet
             } else if (decoderState == 1) {
-                // The read position should always be 4 at this point
-                assert decoderBuffer.rpos() == 4;
-                int macSize = inMac != null ? inMac.getBlockSize() : 0;
+                // The read position should always be after reading the packet length at this point
+                assert decoderBuffer.rpos() == Integer.BYTES;
+                int macSize = (inMac != null) ? inMac.getBlockSize() : 0;
                 // Check if the packet has been fully received
                 if (decoderBuffer.available() >= (decoderLength + macSize)) {
                     byte[] data = decoderBuffer.array();
-                    // Decrypt the remaining of the packet
-                    if (inCipher != null) {
-                        int updateLen = decoderLength + 4 - inCipherSize;
-                        inCipher.update(data, inCipherSize, updateLen);
+                    if (etmMode) {
+                        validateIncomingMac(data, 0, decoderLength + Integer.BYTES);
 
-                        int blocksCount = updateLen / inCipher.getCipherBlockSize();
-                        inBlocksCount.addAndGet(Math.max(1, blocksCount));
-                    }
-                    // Check the mac of the packet
-                    if (inMac != null) {
-                        // Update mac with packet id
-                        inMac.updateUInt(seqi);
-                        // Update mac with packet data
-                        inMac.update(data, 0, decoderLength + 4);
-                        // Compute mac result
-                        inMac.doFinal(inMacResult, 0);
-                        // Check the computed result with the received mac (just after the packet data)
-                        if (!BufferUtils.equals(inMacResult, 0, data, decoderLength + 4, macSize)) {
-                            throw new SshException(SshConstants.SSH2_DISCONNECT_MAC_ERROR, "MAC Error");
+                        if (inCipher != null) {
+                            inCipher.update(data, Integer.BYTES, decoderLength);
+
+                            int blocksCount = decoderLength / inCipher.getCipherBlockSize();
+                            inBlocksCount.addAndGet(Math.max(1, blocksCount));
+                        }
+                    } else {
+                        // Decrypt the remaining of the packet
+                        if (inCipher != null) {
+                            int updateLen = decoderLength + Integer.BYTES - inCipherSize;
+                            inCipher.update(data, inCipherSize, updateLen);
+
+                            int blocksCount = updateLen / inCipher.getCipherBlockSize();
+                            inBlocksCount.addAndGet(Math.max(1, blocksCount));
                         }
+
+                        validateIncomingMac(data, 0, decoderLength + Integer.BYTES);
                     }
+
                     // Increment incoming packet sequence number
-                    seqi = (seqi + 1) & 0xffffffffL;
+                    seqi = (seqi + 1L) & 0x0ffffffffL;
                     // Get padding
                     int pad = decoderBuffer.getUByte();
                     Buffer packet;
@@ -1210,12 +1248,12 @@ public abstract class AbstractSession extends SessionHelper {
                         inCompression.uncompress(decoderBuffer, uncompressBuffer);
                         packet = uncompressBuffer;
                     } else {
-                        decoderBuffer.wpos(decoderLength + 4 - pad);
+                        decoderBuffer.wpos(decoderLength + Integer.BYTES - pad);
                         packet = decoderBuffer;
                     }
 
                     if (log.isTraceEnabled()) {
-                        packet.dumpHex(getSimplifiedLogger(), "decode(" + this + ") packet #" + seqi, this);
+                        packet.dumpHex(getSimplifiedLogger(), Level.FINEST, "decode(" + this + ") packet #" + seqi, this);
                     }
 
                     // Update stats
@@ -1224,7 +1262,7 @@ public abstract class AbstractSession extends SessionHelper {
                     // Process decoded packet
                     handleMessage(packet);
                     // Set ready to handle next packet
-                    decoderBuffer.rpos(decoderLength + 4 + macSize);
+                    decoderBuffer.rpos(decoderLength + Integer.BYTES + macSize);
                     decoderBuffer.wpos(wpos);
                     decoderBuffer.compact();
                     decoderState = 0;
@@ -1236,6 +1274,24 @@ public abstract class AbstractSession extends SessionHelper {
         }
     }
 
+    protected void validateIncomingMac(byte[] data, int offset, int len) throws Exception {
+        if (inMac == null) {
+            return;
+        }
+
+        // Update mac with packet id
+        inMac.updateUInt(seqi);
+        // Update mac with packet data
+        inMac.update(data, offset, len);
+        // Compute mac result
+        inMac.doFinal(inMacResult, 0);
+
+        // Check the computed result with the received mac (just after the packet data)
+        if (!BufferUtils.equals(inMacResult, 0, data, offset + len, inMac.getBlockSize())) {
+            throw new SshException(SshConstants.SSH2_DISCONNECT_MAC_ERROR, "MAC Error");
+        }
+    }
+
     /**
      * Read the other side identification.
      * This method is specific to the client or server side, but both should call
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java
index b9ed2f1..3a24647 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/helpers/SessionHelper.java
@@ -921,7 +921,8 @@ public abstract class SessionHelper extends AbstractKexFactoryManager implements
         return proposal;
     }
 
-    protected void signalNegotiationStart(Map<KexProposalOption, String> c2sOptions, Map<KexProposalOption, String> s2cOptions) {
+    protected void signalNegotiationStart(
+            Map<KexProposalOption, String> c2sOptions, Map<KexProposalOption, String> s2cOptions) {
         try {
             invokeSessionSignaller(l -> {
                 signalNegotiationStart(l, c2sOptions, s2cOptions);
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/compression/CompressionTest.java b/sshd-core/src/test/java/org/apache/sshd/common/compression/CompressionTest.java
index a05b05f..e0fbedb 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/compression/CompressionTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/compression/CompressionTest.java
@@ -28,7 +28,7 @@ import java.util.List;
 
 import org.apache.sshd.common.channel.Channel;
 import org.apache.sshd.common.kex.KexProposalOption;
-import org.apache.sshd.common.mac.MacTest;
+import org.apache.sshd.common.mac.MacCompatibilityTest;
 import org.apache.sshd.common.session.Session;
 import org.apache.sshd.common.session.SessionListener;
 import org.apache.sshd.server.SshServer;
@@ -97,8 +97,8 @@ public class CompressionTest extends BaseTestSupport {
     public static void setupClientAndServer() throws Exception {
         JSchLogger.init();
 
-        sshd = CoreTestSupportUtils.setupTestServer(MacTest.class);
-        sshd.setKeyPairProvider(CommonTestSupportUtils.createTestHostKeyProvider(MacTest.class));
+        sshd = CoreTestSupportUtils.setupTestServer(MacCompatibilityTest.class);
+        sshd.setKeyPairProvider(CommonTestSupportUtils.createTestHostKeyProvider(MacCompatibilityTest.class));
         sshd.start();
         port = sshd.getPort();
     }
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/mac/EncryptThenMacTest.java b/sshd-core/src/test/java/org/apache/sshd/common/mac/EncryptThenMacTest.java
new file mode 100644
index 0000000..794d308
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/common/mac/EncryptThenMacTest.java
@@ -0,0 +1,141 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.common.mac;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.sshd.client.SshClient;
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.kex.KexProposalOption;
+import org.apache.sshd.server.SshServer;
+import org.apache.sshd.util.test.BaseTestSupport;
+import org.apache.sshd.util.test.CommonTestSupportUtils;
+import org.apache.sshd.util.test.CoreTestSupportUtils;
+import org.apache.sshd.util.test.JUnit4ClassRunnerWithParametersFactory;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+import org.junit.runners.Parameterized.UseParametersRunnerFactory;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@RunWith(Parameterized.class)   // see https://github.com/junit-team/junit/wiki/Parameterized-tests
+@UseParametersRunnerFactory(JUnit4ClassRunnerWithParametersFactory.class)
+public class EncryptThenMacTest extends BaseTestSupport {
+    private static SshServer sshd;
+    private static int port;
+    private static SshClient client;
+
+    private final MacFactory factory;
+
+    public EncryptThenMacTest(MacFactory factory) {
+        this.factory = factory;
+    }
+
+    @BeforeClass
+    public static void setupClientAndServer() throws Exception {
+        sshd = CoreTestSupportUtils.setupTestServer(EncryptThenMacTest.class);
+        sshd.setKeyPairProvider(CommonTestSupportUtils.createTestHostKeyProvider(EncryptThenMacTest.class));
+        sshd.start();
+        port = sshd.getPort();
+
+        client = CoreTestSupportUtils.setupTestClient(EncryptThenMacTest.class);
+        client.start();
+    }
+
+    @AfterClass
+    public static void tearDownClientAndServer() throws Exception {
+        if (sshd != null) {
+            try {
+                sshd.stop(true);
+            } finally {
+                sshd = null;
+            }
+        }
+
+        if (client != null) {
+            try {
+                client.stop();
+            } finally {
+                client = null;
+            }
+        }
+    }
+
+    @Parameters(name = "{0}")
+    public static Collection<Object[]> parameters() {
+        List<Object[]> ret = new ArrayList<>();
+        for (MacFactory f : BuiltinMacs.VALUES) {
+            if (!f.isSupported()) {
+                outputDebugMessage("Skip unsupported MAC %s", f);
+                continue;
+            }
+
+            // We want only encrypt-then-mac mode
+            if (!f.isEncryptThenMac()) {
+                outputDebugMessage("Skip Mac-Then-Encrypt %s", f);
+                continue;
+            }
+
+            ret.add(new Object[]{f});
+        }
+
+        return ret;
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        sshd.setMacFactories(Collections.singletonList(factory));
+        client.setMacFactories(Collections.singletonList(factory));
+    }
+
+    @Test
+    public void testClientConnection() throws Exception {
+        try (ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port)
+                    .verify(7L, TimeUnit.SECONDS)
+                    .getSession()) {
+            session.addPasswordIdentity(getCurrentTestName());
+            session.auth().verify(11L, TimeUnit.SECONDS);
+
+            String expected = factory.getName();
+            for (KexProposalOption opt : KexProposalOption.MAC_PROPOSALS) {
+                String actual = session.getNegotiatedKexParameter(opt);
+                assertEquals("Mismatched " + opt + " negotiation", expected, actual);
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "[" + factory + "]";
+    }
+}
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/mac/MacTest.java b/sshd-core/src/test/java/org/apache/sshd/common/mac/MacCompatibilityTest.java
similarity index 91%
rename from sshd-core/src/test/java/org/apache/sshd/common/mac/MacTest.java
rename to sshd-core/src/test/java/org/apache/sshd/common/mac/MacCompatibilityTest.java
index 3ea363b..9a687f2 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/mac/MacTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/mac/MacCompatibilityTest.java
@@ -55,14 +55,14 @@ import ch.ethz.ssh2.Connection;
 import ch.ethz.ssh2.ConnectionInfo;
 
 /**
- * Test MAC algorithms.
+ * Test MAC algorithms with other known implementations.
  *
  * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
  */
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 @RunWith(Parameterized.class)   // see https://github.com/junit-team/junit/wiki/Parameterized-tests
 @UseParametersRunnerFactory(JUnit4ClassRunnerWithParametersFactory.class)
-public class MacTest extends BaseTestSupport {
+public class MacCompatibilityTest extends BaseTestSupport {
     private static final Collection<String> GANYMEDE_MACS =
         Collections.unmodifiableSet(
             GenericUtils.asSortedSet(String.CASE_INSENSITIVE_ORDER, Connection.getAvailableMACs()));
@@ -73,7 +73,7 @@ public class MacTest extends BaseTestSupport {
     private final MacFactory factory;
     private final String jschMacClass;
 
-    public MacTest(MacFactory factory, String jschMacClass) {
+    public MacCompatibilityTest(MacFactory factory, String jschMacClass) {
         this.factory = factory;
         this.jschMacClass = jschMacClass;
     }
@@ -83,7 +83,13 @@ public class MacTest extends BaseTestSupport {
         List<Object[]> ret = new ArrayList<>();
         for (MacFactory f : BuiltinMacs.VALUES) {
             if (!f.isSupported()) {
-                System.out.println("Skip unsupported MAC " + f);
+                outputDebugMessage("Skip unsupported MAC %s", f);
+                continue;
+            }
+
+            // None of the implementations we use support encrypt-then-mac mode
+            if (f.isEncryptThenMac()) {
+                outputDebugMessage("Skip Encrypt-Then-Mac %s", f);
                 continue;
             }
 
@@ -116,8 +122,8 @@ public class MacTest extends BaseTestSupport {
     public static void setupClientAndServer() throws Exception {
         JSchLogger.init();
 
-        sshd = CoreTestSupportUtils.setupTestServer(MacTest.class);
-        sshd.setKeyPairProvider(CommonTestSupportUtils.createTestHostKeyProvider(MacTest.class));
+        sshd = CoreTestSupportUtils.setupTestServer(MacCompatibilityTest.class);
+        sshd.setKeyPairProvider(CommonTestSupportUtils.createTestHostKeyProvider(MacCompatibilityTest.class));
         sshd.start();
         port = sshd.getPort();
     }
@@ -180,7 +186,8 @@ public class MacTest extends BaseTestSupport {
         try {
             conn.setClient2ServerMACs(new String[]{macName});
 
-            ConnectionInfo info = conn.connect(null, (int) TimeUnit.SECONDS.toMillis(5L), (int) TimeUnit.SECONDS.toMillis(11L));
+            ConnectionInfo info = conn.connect(null,
+                (int) TimeUnit.SECONDS.toMillis(5L), (int) TimeUnit.SECONDS.toMillis(11L));
             outputDebugMessage("Connected: kex=%s, key-type=%s, c2senc=%s, s2cenc=%s, c2mac=%s, s2cmac=%s",
                     info.keyExchangeAlgorithm, info.serverHostKeyAlgorithm,
                     info.clientToServerCryptoAlgorithm, info.serverToClientCryptoAlgorithm,
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/auth/WelcomeBannerTest.java b/sshd-core/src/test/java/org/apache/sshd/server/auth/WelcomeBannerTest.java
index 4ae73b6..f3a5400 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/auth/WelcomeBannerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/auth/WelcomeBannerTest.java
@@ -90,8 +90,9 @@ public class WelcomeBannerTest extends BaseTestSupport {
 
     @Test
     public void testSimpleBanner() throws Exception {
-        final String expectedWelcome = "Welcome to SSHD WelcomeBannerTest";
-        PropertyResolverUtils.updateProperty(sshd, ServerAuthenticationManager.WELCOME_BANNER, expectedWelcome);
+        String expectedWelcome = "Welcome to SSHD WelcomeBannerTest";
+        PropertyResolverUtils.updateProperty(
+            sshd, ServerAuthenticationManager.WELCOME_BANNER, expectedWelcome);
         testBanner(expectedWelcome);
     }