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 2015/06/08 13:30:15 UTC

[2/6] mina-sshd git commit: [SSHD-483] Move classes from org.apache.sshd to their rightful location - common, client or server

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/random/BouncyCastleRandom.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/random/BouncyCastleRandom.java b/sshd-core/src/main/java/org/apache/sshd/common/random/BouncyCastleRandom.java
index eb5967a..acf69d5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/random/BouncyCastleRandom.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/random/BouncyCastleRandom.java
@@ -21,7 +21,6 @@ package org.apache.sshd.common.random;
 import java.security.SecureRandom;
 
 import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.Random;
 import org.bouncycastle.crypto.prng.RandomGenerator;
 import org.bouncycastle.crypto.prng.VMPCRandomGenerator;
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/random/JceRandom.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/random/JceRandom.java b/sshd-core/src/main/java/org/apache/sshd/common/random/JceRandom.java
index 9ccd351..4657abe 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/random/JceRandom.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/random/JceRandom.java
@@ -21,7 +21,6 @@ package org.apache.sshd.common.random;
 import java.security.SecureRandom;
 
 import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.Random;
 
 /**
  * A <code>Random</code> implementation using the built-in {@link SecureRandom} PRNG. 
@@ -49,24 +48,23 @@ public class JceRandom implements Random {
         public Random create() {
             return new JceRandom();
         }
-
     }
 
     private byte[] tmp = new byte[16];
-    private SecureRandom random = null;
+    private final SecureRandom random = new SecureRandom();
 
     public JceRandom() {
-      random = new SecureRandom();
+      super();
     }
 
     @Override
     public synchronized void fill(byte[] foo, int start, int len) {
-        if (start == 0 && len == foo.length) {
+        if ((start == 0) && (len == foo.length)) {
             random.nextBytes(foo);
         } else {
             synchronized (this) {
                 if (len > tmp.length) {
-                      tmp = new byte[len];
+                    tmp = new byte[len];
                 }
                 random.nextBytes(tmp);
                 System.arraycopy(tmp, 0, foo, start, len);
@@ -78,5 +76,4 @@ public class JceRandom implements Random {
     public synchronized int random(int n) {
         return random.nextInt(n);
     }
-
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/random/Random.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/random/Random.java b/sshd-core/src/main/java/org/apache/sshd/common/random/Random.java
new file mode 100644
index 0000000..e3f2c78
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/random/Random.java
@@ -0,0 +1,43 @@
+/*
+ * 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.random;
+
+/**
+ * A pseudo random number generator.
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface Random {
+
+    /**
+     * Fill part of bytes with random values.
+     *
+     * @param bytes byte array to be filled.
+     * @param start index to start filling at.
+     * @param len length of segment to fill.
+     */
+    void fill(byte[] bytes, int start, int len);
+
+    /**
+     * Returns a pseudo-random uniformly distributed {@code int}
+     * in the half-open range [0, n).
+     */
+    int random(int n);
+
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/random/SingletonRandomFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/random/SingletonRandomFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/random/SingletonRandomFactory.java
index 3146a7e..54b9575 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/random/SingletonRandomFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/random/SingletonRandomFactory.java
@@ -19,7 +19,6 @@
 package org.apache.sshd.common.random;
 
 import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.Random;
 
 /**
  * A random factory wrapper that uses a single random instance.

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/random/package.html
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/random/package.html b/sshd-core/src/main/java/org/apache/sshd/common/random/package.html
index 37e6332..0e94d7f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/random/package.html
+++ b/sshd-core/src/main/java/org/apache/sshd/common/random/package.html
@@ -19,7 +19,7 @@
 </head>
 <body>
 
-<a href="{@docRoot}/org/apache/sshd/common/Random.html"><code>Random</code></a> implementations.
+<a href="{@docRoot}/org/apache/sshd/common/random/Random.html"><code>Random</code></a> implementations.
 
 </body>
 </html>

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
index 9833411..dc6cba8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
@@ -28,14 +28,13 @@ import java.util.concurrent.atomic.AtomicInteger;
 import org.apache.sshd.agent.common.AgentForwardSupport;
 import org.apache.sshd.client.channel.AbstractClientChannel;
 import org.apache.sshd.client.future.OpenFuture;
-import org.apache.sshd.common.Channel;
 import org.apache.sshd.common.Closeable;
 import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.RequestHandler;
-import org.apache.sshd.common.Session;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.SshException;
-import org.apache.sshd.common.TcpipForwarder;
+import org.apache.sshd.common.channel.Channel;
+import org.apache.sshd.common.channel.RequestHandler;
+import org.apache.sshd.common.forward.TcpipForwarder;
 import org.apache.sshd.common.future.SshFutureListener;
 import org.apache.sshd.common.util.CloseableUtils;
 import org.apache.sshd.common.util.buffer.Buffer;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
index 62af8da..1d25411 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
@@ -41,27 +41,25 @@ import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.apache.sshd.common.Cipher;
 import org.apache.sshd.common.Closeable;
-import org.apache.sshd.common.Digest;
 import org.apache.sshd.common.FactoryManager;
 import org.apache.sshd.common.FactoryManagerUtils;
-import org.apache.sshd.common.KeyExchange;
-import org.apache.sshd.common.Mac;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.NamedResource;
-import org.apache.sshd.common.Random;
 import org.apache.sshd.common.Service;
-import org.apache.sshd.common.Session;
-import org.apache.sshd.common.SessionListener;
 import org.apache.sshd.common.SshConstants;
 import org.apache.sshd.common.SshException;
+import org.apache.sshd.common.cipher.Cipher;
 import org.apache.sshd.common.compression.Compression;
+import org.apache.sshd.common.digest.Digest;
 import org.apache.sshd.common.future.DefaultSshFuture;
 import org.apache.sshd.common.future.SshFuture;
 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.kex.KeyExchange;
+import org.apache.sshd.common.mac.Mac;
+import org.apache.sshd.common.random.Random;
 import org.apache.sshd.common.util.CloseableUtils;
 import org.apache.sshd.common.util.EventListenerUtils;
 import org.apache.sshd.common.util.Readable;
@@ -126,6 +124,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea
     protected byte[] I_S; // the payload of the factoryManager's SSH_MSG_KEXINIT
     protected KeyExchange kex;
     protected final AtomicInteger kexState = new AtomicInteger();
+    @SuppressWarnings("rawtypes")
     protected DefaultSshFuture reexchangeFuture;
 
     //
@@ -1311,10 +1310,8 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea
     	sessionListenerProxy.sessionEvent(this, event);
     }
 
-    /**
-     * {@inheritDoc}
-     */
     @Override
+    @SuppressWarnings("rawtypes")
     public SshFuture reExchangeKeys() throws IOException {
         if (kexState.compareAndSet(KEX_STATE_DONE, KEX_STATE_INIT)) {
             log.info("Initiating key re-exchange");

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSessionFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSessionFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSessionFactory.java
index 8e16eb7..e0bdd1f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSessionFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSessionFactory.java
@@ -21,8 +21,6 @@ package org.apache.sshd.common.session;
 import java.util.List;
 import java.util.concurrent.CopyOnWriteArrayList;
 
-import org.apache.sshd.common.AbstractSessionIoHandler;
-import org.apache.sshd.common.SessionListener;
 import org.apache.sshd.common.io.IoSession;
 import org.apache.sshd.common.util.ValidateUtils;
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSessionIoHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSessionIoHandler.java b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSessionIoHandler.java
new file mode 100644
index 0000000..8f6d345
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSessionIoHandler.java
@@ -0,0 +1,60 @@
+/*
+ * 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.session;
+
+import org.apache.sshd.common.io.IoHandler;
+import org.apache.sshd.common.io.IoSession;
+import org.apache.sshd.common.util.Readable;
+
+/**
+ * TODO Add javadoc
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractSessionIoHandler implements IoHandler {
+
+    protected abstract AbstractSession createSession(IoSession ioSession) throws Exception;
+
+    @Override
+    public void sessionCreated(IoSession ioSession) throws Exception {
+        AbstractSession session = createSession(ioSession);
+        AbstractSession.attachSession(ioSession, session);
+    }
+
+    @Override
+    public void sessionClosed(IoSession ioSession) throws Exception {
+        AbstractSession.getSession(ioSession).close(true);
+    }
+
+    @Override
+    public void exceptionCaught(IoSession ioSession, Throwable cause) throws Exception {
+        AbstractSession session = AbstractSession.getSession(ioSession, true);
+        if (session != null) {
+            session.exceptionCaught(cause);
+        } else {
+            throw new IllegalStateException("No session available", cause);
+        }
+    }
+
+    @Override
+    public void messageReceived(IoSession ioSession, Readable message) throws Exception {
+        AbstractSession.getSession(ioSession).messageReceived(message);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionService.java b/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionService.java
index 58cb0f9..51d7886 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionService.java
@@ -20,9 +20,9 @@ package org.apache.sshd.common.session;
 
 import java.io.IOException;
 
-import org.apache.sshd.common.Channel;
 import org.apache.sshd.common.Service;
-import org.apache.sshd.common.TcpipForwarder;
+import org.apache.sshd.common.channel.Channel;
+import org.apache.sshd.common.forward.TcpipForwarder;
 
 /**
  * Interface implementing ssh-connection service.

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java b/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
new file mode 100644
index 0000000..ecae304
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
@@ -0,0 +1,259 @@
+/*
+ * 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.session;
+
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.sshd.common.Closeable;
+import org.apache.sshd.common.FactoryManager;
+import org.apache.sshd.common.Service;
+import org.apache.sshd.common.future.SshFuture;
+import org.apache.sshd.common.io.IoSession;
+import org.apache.sshd.common.io.IoWriteFuture;
+import org.apache.sshd.common.util.buffer.Buffer;
+
+/**
+ * Represents an SSH session
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface Session extends Closeable {
+
+    /**
+     * Timeout status.
+     */
+    enum TimeoutStatus {
+        NoTimeout,
+        AuthTimeout,
+        IdleTimeout
+    }
+
+    /**
+     * Returns the value of the user-defined attribute of this session.
+     *
+     * @param key the key of the attribute; must not be null.
+     * @return <tt>null</tt> if there is no attribute with the specified key
+     */
+    <T> T getAttribute(AttributeKey<T> key);
+
+    /**
+     * Sets a user-defined attribute.
+     *
+     * @param key   the key of the attribute; must not be null.
+     * @param value the value of the attribute; must not be null.
+     * @return The old value of the attribute.  <tt>null</tt> if it is new.
+     */
+    <T, E extends T> T setAttribute(AttributeKey<T> key, E value);
+
+    /**
+     * Retrieve the name of the user authenticated on this session
+     * or null if the session has not been authenticated yet.
+     *
+     * @return the user name.
+     */
+    String getUsername();
+
+    /**
+     * Retrieve the client version for this session.
+     *
+     * @return the client version.
+     */
+    String getClientVersion();
+
+    /**
+     * Retrieve the server version for this session.
+     *
+     * @return the server version.
+     */
+    String getServerVersion();
+
+    /**
+     * Retrieve the FactoryManager that has created this session
+     *
+     * @return the factory manager, can not be <tt>null</tt>.
+     */
+    FactoryManager getFactoryManager();
+
+    /**
+     * Retrieve one of the negotiated values during the KEX stage
+     * @param paramType The parameter type index - one of the {@link SSHConstants}
+     *  {@code PROPOSAL_XXX} values
+     * @return The negotiated parameter value - {@code null} if invalid
+     * parameter index or no negotiated value
+     */
+    String getNegotiatedKexParameter(int paramType);
+
+    /**
+     * Retrieve a configuration property as an integer
+     *
+     * @param name the name of the property
+     * @param defaultValue the default value
+     * @return the value of the configuration property or the default value if not found
+     */
+    int getIntProperty(String name, int defaultValue);
+
+    /**
+     * Create a new buffer for the specified SSH packet and reserve the needed space
+     * (5 bytes) for the packet header.
+     *
+     * @param cmd the SSH command
+     * @return a new buffer ready for write
+     */
+    Buffer createBuffer(byte cmd);
+
+    /**
+     * Create a new buffer for the specified SSH packet and reserve the needed space
+     * (5 bytes) for the packet header.
+     *
+     * @param cmd the SSH command
+     * @param estimatedSize estimated number of bytes the buffer will hold, 0 if unknown.
+     * @return a new buffer ready for write
+     */
+    Buffer createBuffer(byte cmd, int estimatedSize);
+
+    /**
+     * Encode and send the given buffer.
+     * The buffer has to have 5 bytes free at the beginning to allow the encoding to take place.
+     * Also, the write position of the buffer has to be set to the position of the last byte to write.
+     *
+     * @param buffer the buffer to encode and send
+     * @return a future that can be used to check when the packet has actually been sent
+     * @throws java.io.IOException if an error occurred when encoding sending the packet
+     */
+    IoWriteFuture writePacket(Buffer buffer) throws IOException;
+
+    /**
+     * Encode and send the given buffer with the specified timeout.
+     * If the buffer could not be written before the timeout elapses, the returned
+     * {@link org.apache.sshd.common.io.IoWriteFuture} will be set with a
+     * {@link java.util.concurrent.TimeoutException} exception to indicate a timeout.
+     *
+     * @param buffer the buffer to encode and spend
+     * @param timeout the timeout
+     * @param unit the time unit of the timeout parameter
+     * @return a future that can be used to check when the packet has actually been sent
+     * @throws java.io.IOException if an error occurred when encoding sending the packet
+     */
+    IoWriteFuture writePacket(Buffer buffer, long timeout, TimeUnit unit) throws IOException;
+
+    /**
+     * Send a global request and wait for the response.
+     * This must only be used when sending a SSH_MSG_GLOBAL_REQUEST with a result expected,
+     * else it will wait forever.
+     *
+     * @param buffer the buffer containing the global request
+     * @return the return buffer if the request was successful, <code>null</code> otherwise.
+     * @throws java.io.IOException if an error occurred when encoding sending the packet
+     */
+    Buffer request(Buffer buffer) throws IOException;
+
+    /**
+     * Handle any exceptions that occured on this session.
+     * The session will be closed and a disconnect packet will be
+     * sent before if the given exception is an
+     * {@link org.apache.sshd.common.SshException}.
+     *
+     * @param t the exception to process
+     */
+    void exceptionCaught(Throwable t);
+
+    /**
+     * Add a session |listener|.
+     *
+     * @param listener the session listener to add
+     */
+    void addListener(SessionListener listener);
+
+    /**
+     * Remove a session |listener|.
+     *
+     * @param listener the session listener to remove
+     */
+    void removeListener(SessionListener listener);
+
+    /**
+     * Initiate a new key exchange.
+     */
+    @SuppressWarnings("rawtypes")
+    SshFuture reExchangeKeys() throws IOException;
+
+    /**
+     * Get the service of the specified type.
+     * If the service is not of the specified class,
+     * an IllegalStateException will be thrown.
+     *
+     * @throws java.lang.IllegalStateException
+     */
+    <T extends Service> T getService(Class<T> clazz);
+
+    /**
+     * Returns the IoSession associated to this ssh session
+     */
+    IoSession getIoSession();
+
+    /**
+     * Type safe key for storage within the user attributes of {@link org.apache.sshd.common.session.AbstractSession}.
+     * Typically it is used as a static variable that is shared between the producer
+     * and the consumer. To further restrict access the setting or getting it from
+     * the Session you can add static get and set methods, e.g:
+     *
+     * <pre>
+     * private static final AttributeKey&lt;MyValue&gt; MY_KEY = new AttributeKey&lt;MyValue&gt;();
+     *
+     * public static MyValue getMyValue(Session s) {
+     *   return s.getAttribute(MY_KEY);
+     * }
+     *
+     * private void setMyValue(Session s, MyValue value) {
+     *   s.setAttribute(MY_KEY, value);
+     * }
+     * </pre>
+     *
+     * @param <T> type of value stored in the attribute.
+     *
+     * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+     */
+    public class AttributeKey<T> {
+        public AttributeKey() {
+            super();
+        }
+    }
+
+    public void resetIdleTimeout();
+
+    /**
+     * Check if timeout has occurred.
+     * @return the timeout status, never <code>null</code>
+     */
+    public TimeoutStatus getTimeoutStatus();
+
+    /**
+     * What is timeout value in milliseconds for authentication stage
+     * @return
+     */
+    public long getAuthTimeout();
+
+    /**
+     * What is timeout value in milliseconds for communication
+     * @return
+     */
+
+    public long getIdleTimeout();
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/session/SessionListener.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/SessionListener.java b/sshd-core/src/main/java/org/apache/sshd/common/session/SessionListener.java
new file mode 100644
index 0000000..7f5bbc2
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/SessionListener.java
@@ -0,0 +1,53 @@
+/*
+ * 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.session;
+
+import java.util.EventListener;
+
+/**
+ * Represents an interface receiving Session events.
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface SessionListener extends EventListener {
+
+    enum Event {
+        KeyEstablished, Authenticated, KexCompleted
+    }
+
+    /**
+     * A new session just been created
+     * @param session
+     */
+    void sessionCreated(Session session);
+
+    /**
+     * An event has been triggered
+     * @param session
+     * @param event
+     */
+    void sessionEvent(Session session, Event event);
+
+    /**
+     * A session has been closed
+     * @param session
+     */
+    void sessionClosed(Session session);
+
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/session/SessionTimeoutListener.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/SessionTimeoutListener.java b/sshd-core/src/main/java/org/apache/sshd/common/session/SessionTimeoutListener.java
index 60d2d69..26764a7 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/SessionTimeoutListener.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/SessionTimeoutListener.java
@@ -21,8 +21,6 @@ package org.apache.sshd.common.session;
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArraySet;
 
-import org.apache.sshd.common.Session;
-import org.apache.sshd.common.SessionListener;
 import org.apache.sshd.common.util.AbstractLoggingBean;
 
 /**

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
index f129703..66e93e4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
@@ -21,8 +21,9 @@ package org.apache.sshd.common.signature;
 import java.security.PrivateKey;
 import java.security.PublicKey;
 
-import org.apache.sshd.common.Signature;
+import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.SecurityUtils;
+import org.apache.sshd.common.util.ValidateUtils;
 
 /**
  * TODO Add javadoc
@@ -32,15 +33,20 @@ import org.apache.sshd.common.util.SecurityUtils;
 public abstract class AbstractSignature implements Signature {
 
     protected java.security.Signature signature;
-    protected String algorithm;
+    private final String algorithm;
 
     protected AbstractSignature(String algorithm) {
-        this.algorithm = algorithm;
+        this.algorithm = ValidateUtils.checkNotNullAndNotEmpty(algorithm, "No signature algorithm specified", GenericUtils.EMPTY_OBJECT_ARRAY);
+    }
+
+    @Override
+    public final String getAlgorithm() {
+        return algorithm;
     }
 
     @Override
     public void init(PublicKey pubkey, PrivateKey prvkey) throws Exception {
-        signature = SecurityUtils.getSignature(algorithm);
+        signature = SecurityUtils.getSignature(getAlgorithm());
         if (pubkey != null) {
             signature.initVerify(pubkey);
         }
@@ -73,4 +79,9 @@ public abstract class AbstractSignature implements Signature {
         }
         return sig;
     }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "[" + getAlgorithm() + "]";
+    }
 }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
index f8a7891..e77ec12 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
@@ -31,12 +31,11 @@ import java.util.Set;
 import java.util.SortedSet;
 import java.util.TreeMap;
 
-import org.apache.sshd.common.Digest;
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.NamedResource;
-import org.apache.sshd.common.Signature;
 import org.apache.sshd.common.cipher.ECCurves;
 import org.apache.sshd.common.config.NamedFactoriesListParseResult;
+import org.apache.sshd.common.digest.Digest;
 import org.apache.sshd.common.keyprovider.KeyPairProvider;
 import org.apache.sshd.common.util.GenericUtils;
 import org.apache.sshd.common.util.SecurityUtils;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/signature/Signature.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/Signature.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/Signature.java
new file mode 100644
index 0000000..3a37a5a
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/Signature.java
@@ -0,0 +1,73 @@
+/*
+ * 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.signature;
+
+import java.security.PrivateKey;
+import java.security.PublicKey;
+
+/**
+ * Signature interface for SSH used to sign or verify packets
+ * Usually wraps a javax.crypto.Signature object
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface Signature {
+    /**
+     * @return The signature algorithm name
+     */
+    String getAlgorithm();
+
+    /**
+     * Initialize this signature with the given public key and private key.
+     * If the private key is null, only signature verification can be performed.
+     *
+     * @param pubkey
+     * @param prvkey
+     * @throws Exception
+     */
+    void init(PublicKey pubkey, PrivateKey prvkey) throws Exception;
+
+    /**
+     * Update the computed signature with the given data
+     *
+     * @param H
+     * @param off
+     * @param len
+     * @throws Exception
+     */
+    void update(byte[] H, int off, int len) throws Exception;
+
+    /**
+     * Verify against the given signature
+     *
+     * @param sig
+     * @return
+     * @throws Exception
+     */
+    boolean verify(byte[] sig) throws Exception;
+
+    /**
+     * Compute the signature
+     *
+     * @return
+     * @throws Exception
+     */
+    byte[] sign() throws Exception;
+
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureFactory.java
index 99510e6..26abe3c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureFactory.java
@@ -21,7 +21,6 @@ package org.apache.sshd.common.signature;
 
 import org.apache.sshd.common.NamedFactory;
 import org.apache.sshd.common.OptionalFeature;
-import org.apache.sshd.common.Signature;
 import org.apache.sshd.common.Transformer;
 
 /**

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/signature/package.html
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/package.html b/sshd-core/src/main/java/org/apache/sshd/common/signature/package.html
index fb6d271..d1b16e4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/signature/package.html
+++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/package.html
@@ -19,7 +19,7 @@
 </head>
 <body>
 
-<a href="{@docRoot}/org/apache/sshd/common/Signature.html"><code>Signature</code></a> implementations.
+<a href="{@docRoot}/org/apache/sshd/common/signature/Signature.html"><code>Signature</code></a> implementations.
 
 </body>
 </html>

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/util/CloseableUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/CloseableUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/CloseableUtils.java
index 1deeceb..9710d57 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/CloseableUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/CloseableUtils.java
@@ -88,6 +88,7 @@ public class CloseableUtils {
             });
         }
 
+        @SuppressWarnings("rawtypes")
         public <T extends SshFuture> Builder when(SshFuture<T> future) {
             if (future != null) {
                 when(Collections.singleton(future));
@@ -95,10 +96,12 @@ public class CloseableUtils {
             return this;
         }
 
+        @SuppressWarnings("rawtypes")
         public <T extends SshFuture> Builder when(@SuppressWarnings("unchecked") SshFuture<T>... futures) {
             return when(Arrays.asList(futures));
         }
 
+        @SuppressWarnings("rawtypes")
         public <T extends SshFuture> Builder when(final Iterable<? extends SshFuture<T>> futures) {
             return close(new FuturesCloseable<T>(lock, futures));
         }

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/common/util/SttySupport.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/SttySupport.java b/sshd-core/src/main/java/org/apache/sshd/common/util/SttySupport.java
deleted file mode 100644
index 537a16f..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/SttySupport.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * 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.util;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Map;
-import java.util.StringTokenizer;
-import java.util.TreeMap;
-
-import org.apache.sshd.common.PtyMode;
-
-/**
- * Support for stty command on unix
- *
- * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
- */
-public class SttySupport {
-
-    private static String sttyCommand = System.getProperty("sshd.sttyCommand", "stty");
-    private static String ttyProps;
-    private static long ttyPropsLastFetched;
-
-    public static Map<PtyMode, Integer> getUnixPtyModes() throws IOException, InterruptedException {
-        return parsePtyModes(getTtyProps());
-    }
-
-    public static Map<PtyMode, Integer> parsePtyModes(String stty) {
-        Map<PtyMode, Integer> modes = new TreeMap<PtyMode, Integer>();
-        for (PtyMode mode : PtyMode.values()) {
-            if (mode == PtyMode.TTY_OP_ISPEED || mode == PtyMode.TTY_OP_OSPEED) {
-                // TODO ...
-            } else {
-                String str = mode.name().toLowerCase();
-                // Are we looking for a character?
-                if (str.charAt(0) == 'v') {
-                    str = str.substring(1);
-                    int v = findChar(stty, str);
-                    if (v < 0 && "reprint".equals(str)) {
-                        v = findChar(stty, "rprnt");
-                    }
-                    if (v >= 0) {
-                        modes.put(mode, Integer.valueOf(v));
-                    }
-                } else {
-                    int v = findFlag(stty, str);
-                    if (v >= 0) {
-                        modes.put(mode, Integer.valueOf(v));
-                    }
-                }
-            }
-        }
-        return modes;
-    }
-
-    private static int findFlag(String stty, String name) {
-        int cur = 0;
-        while (cur < stty.length()) {
-            int idx1 = stty.indexOf(name, cur);
-            int idx2 = idx1 + name.length();
-            if (idx1 < 0) {
-                return -1;
-            }
-            if (idx1 > 0 && Character.isLetterOrDigit(stty.charAt(idx1 - 1))
-                    || (idx2 < stty.length() && Character.isLetterOrDigit(stty.charAt(idx2)))) {
-                cur = idx2;
-                continue;
-            }
-            return idx1 == 0 ? 1 : stty.charAt(idx1 - 1) == '-' ? 0 : 1;
-        }
-        return -1;
-    }
-
-    private static int findChar(String stty, String name) {
-        int cur = 0;
-        while (cur < stty.length()) {
-            int idx1 = stty.indexOf(name, cur);
-            int idx2 = stty.indexOf('=', idx1);
-            int idx3 = stty.indexOf(';', idx1);
-            if (idx1 < 0 || idx2 < 0 || idx3 < idx2) {
-                // Invalid syntax
-                return -1;
-            }
-            if (idx1 > 0 && Character.isLetterOrDigit(stty.charAt(idx1 - 1))
-                    || (idx2 < stty.length() && Character.isLetterOrDigit(stty.charAt(idx2)))) {
-                cur = idx1 + name.length();
-                continue;
-            }
-            String val = stty.substring(idx2 + 1, idx3 < 0 ? stty.length() : idx3).trim();
-            if (val.indexOf("undef") >= 0) {
-                return -1;
-            }
-            if (val.length() == 2 && val.charAt(0) == '^') {
-                int v = (val.charAt(1) - 'A' + 129) % 128;
-                return v;
-            } else {
-                try {
-                    return Integer.parseInt(val);
-                } catch (NumberFormatException e) {
-                    // what else ?
-                }
-            }
-            return -1;
-        }
-        return -1;
-    }
-
-    /**
-     *  Returns the value of "stty size" width param.
-     *
-     *  <strong>Note</strong>: this method caches the value from the
-     *  first time it is called in order to increase speed, which means
-     *  that changing to size of the terminal will not be reflected
-     *  in the console.
-     */
-    public static int getTerminalWidth() {
-        int val = -1;
-
-        try {
-            val = getTerminalProperty("columns");
-        } catch (Exception e) {
-            // ignored
-        }
-
-        if (val == -1) {
-            val = 80;
-        }
-
-        return val;
-    }
-
-    /**
-     *  Returns the value of "stty size" height param.
-     *
-     *  <strong>Note</strong>: this method caches the value from the
-     *  first time it is called in order to increase speed, which means
-     *  that changing to size of the terminal will not be reflected
-     *  in the console.
-     */
-    public static int getTerminalHeight() {
-        int val = -1;
-
-        try {
-            val = getTerminalProperty("rows");
-        } catch (Exception e) {
-            // ignored
-        }
-
-        if (val == -1) {
-            val = 24;
-        }
-
-        return val;
-    }
-
-    private static int getTerminalProperty(String prop)
-                                    throws IOException, InterruptedException {
-        // need to be able handle both output formats:
-        // speed 9600 baud; 24 rows; 140 columns;
-        // and:
-        // speed 38400 baud; rows = 49; columns = 111; ypixels = 0; xpixels = 0;
-        for (StringTokenizer tok = new StringTokenizer(getTtyProps(), ";\n");
-                 tok.hasMoreTokens();) {
-            String str = tok.nextToken().trim();
-
-            if (str.startsWith(prop)) {
-                int index = str.lastIndexOf(" ");
-
-                return Integer.parseInt(str.substring(index).trim());
-            } else if (str.endsWith(prop)) {
-                int index = str.indexOf(" ");
-
-                return Integer.parseInt(str.substring(0, index).trim());
-            }
-        }
-
-        return -1;
-    }
-
-    public static String getTtyProps() throws IOException, InterruptedException {
-        // tty properties are cached so we don't have to worry too much about getting term widht/height
-        if (ttyProps == null || System.currentTimeMillis() - ttyPropsLastFetched > 1000) {
-            ttyProps = stty("-a");
-            ttyPropsLastFetched = System.currentTimeMillis();
-        }
-        return ttyProps;
-    }
-
-
-    /**
-     *  Execute the stty command with the specified arguments
-     *  against the current active terminal.
-     */
-    public static String stty(final String args)
-                        throws IOException, InterruptedException {
-        return exec("stty " + args + " < /dev/tty").trim();
-    }
-
-    /**
-     *  Execute the specified command and return the output
-     *  (both stdout and stderr).
-     */
-    public static String exec(final String cmd)
-                        throws IOException, InterruptedException {
-        return exec(new String[] {
-                        "sh",
-                        "-c",
-                        cmd
-                    });
-    }
-
-    /**
-     *  Execute the specified command and return the output
-     *  (both stdout and stderr).
-     */
-    private static String exec(final String[] cmd)
-                        throws IOException, InterruptedException {
-        ByteArrayOutputStream bout = new ByteArrayOutputStream();
-
-        Process p = Runtime.getRuntime().exec(cmd);
-        int c;
-        InputStream in;
-
-        in = p.getInputStream();
-
-        while ((c = in.read()) != -1) {
-            bout.write(c);
-        }
-
-        in = p.getErrorStream();
-
-        while ((c = in.read()) != -1) {
-            bout.write(c);
-        }
-
-        p.waitFor();
-
-        String result = new String(bout.toByteArray());
-
-        return result;
-    }
-
-    /**
-     *  The command to use to set the terminal options. Defaults
-     *  to "stty", or the value of the system property "jline.sttyCommand".
-     */
-    public static void setSttyCommand(String cmd) {
-        sttyCommand = cmd;
-    }
-
-    /**
-     *  The command to use to set the terminal options. Defaults
-     *  to "stty", or the value of the system property "jline.sttyCommand".
-     */
-    public static String getSttyCommand() {
-        return sttyCommand;
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/package.html
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/package.html b/sshd-core/src/main/java/org/apache/sshd/package.html
deleted file mode 100644
index 6a5ccde..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/package.html
+++ /dev/null
@@ -1,25 +0,0 @@
-<!--
-    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.
--->
-<html>
-<head>
-</head>
-<body>
-
-Defines the two main classes for the client and server side of SSH protocol support.
-
-</body>
-</html>

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/server/Environment.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/Environment.java b/sshd-core/src/main/java/org/apache/sshd/server/Environment.java
index c10bee1..01d0b96 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/Environment.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/Environment.java
@@ -21,7 +21,7 @@ package org.apache.sshd.server;
 import java.util.Collection;
 import java.util.Map;
 
-import org.apache.sshd.common.PtyMode;
+import org.apache.sshd.common.channel.PtyMode;
 
 /**
  * Interface providing access to the environment map and allowing the registration

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/server/ServerBuilder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ServerBuilder.java b/sshd-core/src/main/java/org/apache/sshd/server/ServerBuilder.java
new file mode 100644
index 0000000..93a9b37
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/ServerBuilder.java
@@ -0,0 +1,125 @@
+/*
+ * 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.server;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.sshd.common.BaseBuilder;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.Transformer;
+import org.apache.sshd.common.kex.BuiltinDHFactories;
+import org.apache.sshd.common.kex.DHFactory;
+import org.apache.sshd.common.kex.KeyExchange;
+import org.apache.sshd.server.channel.ChannelSession;
+import org.apache.sshd.server.config.keys.DefaultAuthorizedKeysAuthenticator;
+import org.apache.sshd.server.forward.TcpipServerChannel;
+import org.apache.sshd.server.global.CancelTcpipForwardHandler;
+import org.apache.sshd.server.global.KeepAliveHandler;
+import org.apache.sshd.server.global.NoMoreSessionsHandler;
+import org.apache.sshd.server.global.TcpipForwardHandler;
+import org.apache.sshd.server.kex.DHGEXServer;
+import org.apache.sshd.server.kex.DHGServer;
+
+/**
+ * SshServer builder
+ */
+public class ServerBuilder extends BaseBuilder<SshServer, ServerBuilder> {
+    public static final Transformer<DHFactory,NamedFactory<KeyExchange>>    DH2KEX = 
+            new Transformer<DHFactory, NamedFactory<KeyExchange>>() {
+                @Override
+                public NamedFactory<KeyExchange> transform(DHFactory factory) {
+                    if (factory == null) {
+                        return null;
+                    } else if (factory.isGroupExchange()) {
+                        return DHGEXServer.newFactory(factory);
+                    } else {
+                        return DHGServer.newFactory(factory);
+                    }
+                }
+            };
+
+    protected PublickeyAuthenticator pubkeyAuthenticator;
+
+    public ServerBuilder() {
+        super();
+    }
+
+    public ServerBuilder publickeyAuthenticator(PublickeyAuthenticator auth) {
+        pubkeyAuthenticator = auth;
+        return this;
+    }
+
+    @Override
+    protected ServerBuilder fillWithDefaultValues() {
+        super.fillWithDefaultValues();
+        if (keyExchangeFactories == null) {
+            keyExchangeFactories = setUpDefaultKeyExchanges(false);
+        }
+        if (channelFactories == null) {
+            channelFactories = Arrays.asList(
+                    ChannelSession.ChannelSessionFactory.INSTANCE,
+                    TcpipServerChannel.DirectTcpipFactory.INSTANCE);
+        }
+        if (globalRequestHandlers == null) {
+            globalRequestHandlers = Arrays.asList(
+                    new KeepAliveHandler(),
+                    new NoMoreSessionsHandler(),
+                    new TcpipForwardHandler(),
+                    new CancelTcpipForwardHandler());
+        }
+        if (factory == null) {
+            factory = SshServer.DEFAULT_SSH_SERVER_FACTORY;
+        }
+        
+        if (pubkeyAuthenticator == null) {
+            pubkeyAuthenticator = DefaultAuthorizedKeysAuthenticator.INSTANCE;
+        }
+
+        return me();
+    }
+
+    @Override
+    public SshServer build(boolean isFillWithDefaultValues) {
+        SshServer server = super.build(isFillWithDefaultValues);
+        server.setPublickeyAuthenticator(pubkeyAuthenticator);
+        return server;
+    }
+
+    /**
+     * @param ignoreUnsupported If {@code true} then all the default
+     * key exchanges are included, regardless of whether they are currently
+     * supported by the JCE. Otherwise, only the supported ones out of the
+     * list are included
+     * @return A {@link List} of the default {@link NamedFactory}
+     * instances of the {@link KeyExchange}s according to the preference
+     * order defined by {@link #DEFAULT_KEX_PREFERENCE}.
+     * <B>Note:</B> the list may be filtered to exclude unsupported JCE
+     * key exchanges according to the <tt>ignoreUnsupported</tt> parameter
+     * @see BuiltinDHFactories#isSupported()
+     */
+    public static List<NamedFactory<KeyExchange>> setUpDefaultKeyExchanges(boolean ignoreUnsupported) {
+        return NamedFactory.Utils.setUpTransformedFactories(ignoreUnsupported, DEFAULT_KEX_PREFERENCE, DH2KEX);
+    }
+
+    public static ServerBuilder builder() {
+        return new ServerBuilder();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
new file mode 100644
index 0000000..3281b28
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
@@ -0,0 +1,468 @@
+/*
+ * 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.server;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.sshd.common.AbstractFactoryManager;
+import org.apache.sshd.common.Closeable;
+import org.apache.sshd.common.Factory;
+import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.io.IoAcceptor;
+import org.apache.sshd.common.io.IoServiceFactory;
+import org.apache.sshd.common.io.IoSession;
+import org.apache.sshd.common.io.mina.MinaServiceFactory;
+import org.apache.sshd.common.io.nio2.Nio2ServiceFactory;
+import org.apache.sshd.common.session.AbstractSession;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.OsUtils;
+import org.apache.sshd.common.util.SecurityUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.server.auth.UserAuthKeyboardInteractive;
+import org.apache.sshd.server.auth.UserAuthPassword;
+import org.apache.sshd.server.auth.UserAuthPublicKey;
+import org.apache.sshd.server.auth.gss.GSSAuthenticator;
+import org.apache.sshd.server.auth.gss.UserAuthGSS;
+import org.apache.sshd.server.command.ScpCommandFactory;
+import org.apache.sshd.server.forward.ForwardingFilter;
+import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
+import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
+import org.apache.sshd.server.session.ServerConnectionService;
+import org.apache.sshd.server.session.ServerSession;
+import org.apache.sshd.server.session.ServerUserAuthService;
+import org.apache.sshd.server.session.SessionFactory;
+import org.apache.sshd.server.sftp.SftpSubsystemFactory;
+import org.apache.sshd.server.shell.ProcessShellFactory;
+
+/**
+ * The SshServer class is the main entry point for the server side of the SSH protocol.
+ *
+ * The SshServer has to be configured before being started.  Such configuration can be
+ * done either using a dependency injection mechanism (such as the Spring framework)
+ * or programmatically. Basic setup is usually done using the {@link #setUpDefaultServer()}
+ * method, which will known ciphers, macs, channels, etc...
+ * Besides this basic setup, a few things have to be manually configured such as the
+ * port number, {@link Factory}, the {@link org.apache.sshd.common.keyprovider.KeyPairProvider}
+ * and the {@link PasswordAuthenticator}.
+ *
+ * Some properties can also be configured using the {@link #setProperties(java.util.Map)}
+ * method.
+ *
+ * Once the SshServer instance has been configured, it can be started using the
+ * {@link #start()} method and stopped using the {@link #stop()} method.
+ *
+ * @see ServerFactoryManager
+ * @see org.apache.sshd.common.FactoryManager
+ *
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class SshServer extends AbstractFactoryManager implements ServerFactoryManager, Closeable {
+
+    public static final Factory<SshServer> DEFAULT_SSH_SERVER_FACTORY = new Factory<SshServer>() {
+        @Override
+        public SshServer create() {
+            return new SshServer();
+        }
+    };
+
+    protected IoAcceptor acceptor;
+    protected String host;
+    protected int port;
+    protected List<NamedFactory<UserAuth>> userAuthFactories;
+    protected Factory<Command> shellFactory;
+    protected SessionFactory sessionFactory;
+    protected CommandFactory commandFactory;
+    protected List<NamedFactory<Command>> subsystemFactories;
+    protected PasswordAuthenticator passwordAuthenticator;
+    protected PublickeyAuthenticator publickeyAuthenticator;
+    protected GSSAuthenticator gssAuthenticator;
+
+    public SshServer() {
+        super();
+    }
+
+    public String getHost() {
+        return host;
+    }
+
+    public void setHost(String host) {
+        this.host = host;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    /**
+     * Configure the port number to use for this SSH server.
+     *
+     * @param port the port number for this SSH server
+     */
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    @Override
+    public List<NamedFactory<UserAuth>> getUserAuthFactories() {
+        return userAuthFactories;
+    }
+
+    public void setUserAuthFactories(List<NamedFactory<UserAuth>> userAuthFactories) {
+        this.userAuthFactories = userAuthFactories;
+    }
+
+    @Override
+    public Factory<Command> getShellFactory() {
+        return shellFactory;
+    }
+
+    public void setShellFactory(Factory<Command> shellFactory) {
+        this.shellFactory = shellFactory;
+    }
+
+    public SessionFactory getSessionFactory() {
+        return sessionFactory;
+    }
+
+    public void setSessionFactory(SessionFactory sessionFactory) {
+        this.sessionFactory = sessionFactory;
+    }
+
+    @Override
+    public CommandFactory getCommandFactory() {
+        return commandFactory;
+    }
+
+    public void setCommandFactory(CommandFactory commandFactory) {
+        this.commandFactory = commandFactory;
+    }
+
+    @Override
+    public List<NamedFactory<Command>> getSubsystemFactories() {
+        return subsystemFactories;
+    }
+
+    public void setSubsystemFactories(List<NamedFactory<Command>> subsystemFactories) {
+        this.subsystemFactories = subsystemFactories;
+    }
+
+    @Override
+    public PasswordAuthenticator getPasswordAuthenticator() {
+        return passwordAuthenticator;
+    }
+
+    public void setPasswordAuthenticator(PasswordAuthenticator passwordAuthenticator) {
+        this.passwordAuthenticator = passwordAuthenticator;
+    }
+
+    @Override
+    public PublickeyAuthenticator getPublickeyAuthenticator() {
+        return publickeyAuthenticator;
+    }
+
+    public void setPublickeyAuthenticator(PublickeyAuthenticator publickeyAuthenticator) {
+        this.publickeyAuthenticator = publickeyAuthenticator;
+    }
+
+    @Override
+    public GSSAuthenticator getGSSAuthenticator() {
+      return gssAuthenticator;
+    }
+
+    public void setGSSAuthenticator(GSSAuthenticator gssAuthenticator) {
+      this.gssAuthenticator = gssAuthenticator;
+    }
+
+    @Override
+    public void setTcpipForwardingFilter(ForwardingFilter forwardingFilter) {
+        this.tcpipForwardingFilter = forwardingFilter;
+    }
+
+    @Override
+    protected void checkConfig() {
+        super.checkConfig();
+
+        ValidateUtils.checkTrue(getPort() >= 0 /* zero means not set yet */, "Bad port number: %d", Integer.valueOf(getPort()));
+
+        if (GenericUtils.isEmpty(getUserAuthFactories())) {
+            List<NamedFactory<UserAuth>> factories = new ArrayList<NamedFactory<UserAuth>>();
+            if (getPasswordAuthenticator() != null) {
+                factories.add(UserAuthPassword.UserAuthPasswordFactory.INSTANCE);
+                factories.add(UserAuthKeyboardInteractive.UserAuthKeyboardInteractiveFactory.INSTANCE);
+            }
+            if (getPublickeyAuthenticator() != null) {
+                factories.add(UserAuthPublicKey.UserAuthPublicKeyFactory.INSTANCE);
+            }
+            if (getGSSAuthenticator() != null) {
+              factories.add(UserAuthGSS.UserAuthGSSFactory.INSTANCE);
+            }
+            
+            ValidateUtils.checkTrue(factories.size() > 0, "UserAuthFactories not set", GenericUtils.EMPTY_OBJECT_ARRAY); 
+            setUserAuthFactories(factories);
+        }
+
+        ValidateUtils.checkNotNullAndNotEmpty(getChannelFactories(), "ChannelFactories not set", GenericUtils.EMPTY_OBJECT_ARRAY);
+        ValidateUtils.checkNotNull(getKeyPairProvider(), "HostKeyProvider not set", GenericUtils.EMPTY_OBJECT_ARRAY);
+        ValidateUtils.checkNotNull(getFileSystemFactory(), "FileSystemFactory not set", GenericUtils.EMPTY_OBJECT_ARRAY);
+
+        if (GenericUtils.isEmpty(getServiceFactories())) {
+            setServiceFactories(Arrays.asList(
+                    new ServerUserAuthService.Factory(),
+                    new ServerConnectionService.Factory()
+            ));
+        }
+    }
+
+    /**
+     * Start the SSH server and accept incoming exceptions on the configured port.
+     * 
+     * @throws IOException
+     */
+    public void start() throws IOException {
+        checkConfig();
+        if (sessionFactory == null) {
+            sessionFactory = createSessionFactory();
+        }
+        sessionFactory.setServer(this);
+        acceptor = createAcceptor();
+
+        setupSessionTimeout(sessionFactory);
+
+        String  hostsList=getHost();
+        if (!GenericUtils.isEmpty(hostsList)) {
+            String[] hosts = GenericUtils.split(hostsList, ',');
+            for (String host : hosts) {
+                if (log.isDebugEnabled()) {
+                    log.debug("start() - resolve bind host={}", host);
+                }
+
+                InetAddress[] inetAddresses = InetAddress.getAllByName(host);
+                for (InetAddress inetAddress : inetAddresses) {
+                    if (log.isTraceEnabled()) {
+                        log.trace("start() - bind host={} / {}", host, inetAddress);
+                    }
+
+                    acceptor.bind(new InetSocketAddress(inetAddress, port));
+                    if (port == 0) {
+                        port = ((InetSocketAddress) acceptor.getBoundAddresses().iterator().next()).getPort();
+                        log.info("start() listen on auto-allocated port=" + port);
+                    }
+                }
+            }
+        } else {
+            acceptor.bind(new InetSocketAddress(port));
+            if (port == 0) {
+                port = ((InetSocketAddress) acceptor.getBoundAddresses().iterator().next()).getPort();
+                log.info("start() listen on auto-allocated port=" + port);
+            }
+        }
+    }
+
+    /**
+     * Stop the SSH server.  This method will block until all resources are actually disposed.
+     */
+    public void stop() throws InterruptedException {
+        stop(false);
+    }
+
+    public void stop(boolean immediately) throws InterruptedException {
+        close(immediately).await();
+    }
+
+    public void open() throws IOException {
+        start();
+    }
+
+    @Override
+    protected Closeable getInnerCloseable() {
+        return builder()
+                .run(new Runnable() {
+                    @SuppressWarnings("synthetic-access")
+                    @Override
+                    public void run() {
+                        removeSessionTimeout(sessionFactory);
+                    }
+                })
+                .sequential(acceptor, ioServiceFactory)
+                .run(new Runnable() {
+                    @SuppressWarnings("synthetic-access")
+                    @Override
+                    public void run() {
+                        acceptor = null;
+                        ioServiceFactory = null;
+                        if (shutdownExecutor && (executor != null) && (!executor.isShutdown())) {
+                            try {
+                                executor.shutdownNow();
+                            } finally {
+                                executor = null;
+                            }
+                        }
+                    }
+                })
+                .build();
+    }
+
+    /**
+     * Obtain the list of active sessions.
+     */
+    public List<AbstractSession> getActiveSessions() {
+        List<AbstractSession> sessions = new ArrayList<AbstractSession>();
+        for (IoSession ioSession : acceptor.getManagedSessions().values()) {
+            AbstractSession session = AbstractSession.getSession(ioSession, true);
+            if (session != null) {
+                sessions.add(session);
+            }
+        }
+        return sessions;
+    }
+
+    protected IoAcceptor createAcceptor() {
+        return getIoServiceFactory().createAcceptor(getSessionFactory());
+    }
+
+    protected SessionFactory createSessionFactory() {
+        return new SessionFactory();
+    }
+
+    @Override
+    public String toString() {
+        return "SshServer[" + Integer.toHexString(hashCode()) + "]";
+    }
+
+    public static SshServer setUpDefaultServer() {
+        return ServerBuilder.builder().build();
+    }
+
+    /*=================================
+          Main class implementation
+     *=================================*/
+
+    public static void main(String[] args) throws Exception {
+        int port = 8000;
+        String provider;
+        boolean error = false;
+        Map<String, String> options = new LinkedHashMap<String, String>();
+
+        for (int i = 0; i < args.length; i++) {
+            if ("-p".equals(args[i])) {
+                if (i + 1 >= args.length) {
+                    System.err.println("option requires an argument: " + args[i]);
+                    break;
+                }
+                port = Integer.parseInt(args[++i]);
+            } else if ("-io".equals(args[i])) {
+                if (i + 1 >= args.length) {
+                    System.err.println("option requires an argument: " + args[i]);
+                    break;
+                }
+                provider = args[++i];
+                if ("mina".equals(provider)) {
+                    System.setProperty(IoServiceFactory.class.getName(), MinaServiceFactory.class.getName());
+                } else if ("nio2".endsWith(provider)) {
+                    System.setProperty(IoServiceFactory.class.getName(), Nio2ServiceFactory.class.getName());
+                } else {
+                    System.err.println("provider should be mina or nio2: " + args[i]);
+                    break;
+                }
+            } else if ("-o".equals(args[i])) {
+                if (i + 1 >= args.length) {
+                    System.err.println("option requires and argument: " + args[i]);
+                    error = true;
+                    break;
+                }
+                String opt = args[++i];
+                int idx = opt.indexOf('=');
+                if (idx <= 0) {
+                    System.err.println("bad syntax for option: " + opt);
+                    error = true;
+                    break;
+                }
+                options.put(opt.substring(0, idx), opt.substring(idx + 1));
+            } else if (args[i].startsWith("-")) {
+                System.err.println("illegal option: " + args[i]);
+                error = true;
+                break;
+            } else {
+                System.err.println("extra argument: " + args[i]);
+                error = true;
+                break;
+            }
+        }
+        if (error) {
+            System.err.println("usage: sshd [-p port] [-io mina|nio2] [-o option=value]");
+            System.exit(-1);
+        }
+
+        System.err.println("Starting SSHD on port " + port);
+                                                    
+        SshServer sshd = SshServer.setUpDefaultServer();
+        Map<String,Object> props = sshd.getProperties();
+        FactoryManagerUtils.updateProperty(props, ServerFactoryManager.WELCOME_BANNER, "Welcome to SSHD\n");
+        props.putAll(options);
+        sshd.setPort(port);
+
+        if (SecurityUtils.isBouncyCastleRegistered()) {
+            sshd.setKeyPairProvider(new PEMGeneratorHostKeyProvider("key.pem"));
+        } else {
+            sshd.setKeyPairProvider(new SimpleGeneratorHostKeyProvider("key.ser"));
+        }
+        if (OsUtils.isUNIX()) {
+            sshd.setShellFactory(new ProcessShellFactory(new String[] { "/bin/sh", "-i", "-l" },
+                                 EnumSet.of(ProcessShellFactory.TtyOptions.ONlCr)));
+        } else {
+            sshd.setShellFactory(new ProcessShellFactory(new String[] { "cmd.exe "},
+                                 EnumSet.of(ProcessShellFactory.TtyOptions.Echo, ProcessShellFactory.TtyOptions.ICrNl, ProcessShellFactory.TtyOptions.ONlCr)));
+        }
+        sshd.setPasswordAuthenticator(new PasswordAuthenticator() {
+            @Override
+            public boolean authenticate(String username, String password, ServerSession session) {
+                return username != null && username.equals(password);
+            }
+        });
+        sshd.setPublickeyAuthenticator(PublickeyAuthenticator.AcceptAllPublickeyAuthenticator.INSTANCE);
+        sshd.setTcpipForwardingFilter(ForwardingFilter.AcceptAllForwardingFilter.INSTANCE);
+        sshd.setCommandFactory(new ScpCommandFactory.Builder().withDelegate(new CommandFactory() {
+            @Override
+            public Command createCommand(String command) {
+                EnumSet<ProcessShellFactory.TtyOptions> ttyOptions;
+                if (OsUtils.isUNIX()) {
+                    ttyOptions = EnumSet.of(ProcessShellFactory.TtyOptions.ONlCr);
+                } else {
+                    ttyOptions = EnumSet.of(ProcessShellFactory.TtyOptions.Echo, ProcessShellFactory.TtyOptions.ICrNl, ProcessShellFactory.TtyOptions.ONlCr);
+                }
+                return new ProcessShellFactory(command.split(" "), ttyOptions).create();
+            }
+        }).build());
+        sshd.setSubsystemFactories(Arrays.<NamedFactory<Command>>asList(new SftpSubsystemFactory()));
+        sshd.start();
+
+        Thread.sleep(Long.MAX_VALUE);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/server/auth/CachingPublicKeyAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/CachingPublicKeyAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/CachingPublicKeyAuthenticator.java
index 0e0880b..c7733b4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/CachingPublicKeyAuthenticator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/CachingPublicKeyAuthenticator.java
@@ -22,8 +22,8 @@ import java.security.PublicKey;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
-import org.apache.sshd.common.Session;
-import org.apache.sshd.common.SessionListener;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.session.SessionListener;
 import org.apache.sshd.server.PublickeyAuthenticator;
 import org.apache.sshd.server.session.ServerSession;
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
index 6b7786a..913543a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
@@ -21,8 +21,8 @@ package org.apache.sshd.server.auth;
 import java.security.PublicKey;
 
 import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.Signature;
 import org.apache.sshd.common.SshConstants;
+import org.apache.sshd.common.signature.Signature;
 import org.apache.sshd.common.util.buffer.Buffer;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
 import org.apache.sshd.server.PublickeyAuthenticator;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/server/channel/AsyncDataReceiver.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/AsyncDataReceiver.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/AsyncDataReceiver.java
index fbc8396..91dde4c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/AsyncDataReceiver.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/AsyncDataReceiver.java
@@ -20,7 +20,7 @@ package org.apache.sshd.server.channel;
 
 import java.io.IOException;
 
-import org.apache.sshd.common.Channel;
+import org.apache.sshd.common.channel.Channel;
 import org.apache.sshd.common.channel.ChannelAsyncInputStream;
 import org.apache.sshd.common.io.IoInputStream;
 import org.apache.sshd.common.util.buffer.ByteArrayBuffer;

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
index dcb8c2e..74329db 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
@@ -33,17 +33,16 @@ import java.util.concurrent.TimeUnit;
 
 import org.apache.sshd.agent.SshAgent;
 import org.apache.sshd.agent.SshAgentFactory;
-import org.apache.sshd.common.Channel;
 import org.apache.sshd.common.Closeable;
 import org.apache.sshd.common.FactoryManager;
 import org.apache.sshd.common.FactoryManagerUtils;
-import org.apache.sshd.common.ForwardingFilter;
 import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.PtyMode;
-import org.apache.sshd.common.RequestHandler;
 import org.apache.sshd.common.SshConstants;
+import org.apache.sshd.common.channel.Channel;
 import org.apache.sshd.common.channel.ChannelAsyncOutputStream;
 import org.apache.sshd.common.channel.ChannelOutputStream;
+import org.apache.sshd.common.channel.PtyMode;
+import org.apache.sshd.common.channel.RequestHandler;
 import org.apache.sshd.common.file.FileSystemAware;
 import org.apache.sshd.common.file.FileSystemFactory;
 import org.apache.sshd.common.future.CloseFuture;
@@ -64,6 +63,7 @@ import org.apache.sshd.server.ServerFactoryManager;
 import org.apache.sshd.server.SessionAware;
 import org.apache.sshd.server.Signal;
 import org.apache.sshd.server.SignalListener;
+import org.apache.sshd.server.forward.ForwardingFilter;
 import org.apache.sshd.server.session.ServerSession;
 import org.apache.sshd.server.x11.X11ForwardSupport;
 
@@ -210,7 +210,6 @@ public class ChannelSession extends AbstractServerChannel {
     protected Buffer tempBuffer;
     protected final CloseFuture commandExitFuture = new DefaultCloseFuture(lock);
 
-    @SuppressWarnings("synthetic-access")
     public ChannelSession() {
         addRequestHandler(new ChannelSessionRequestHandler());
         addRequestHandler(new PuttyRequestHandler());
@@ -659,6 +658,10 @@ public class ChannelSession extends AbstractServerChannel {
     }
 
     private class ChannelSessionRequestHandler implements RequestHandler<Channel> {
+        public ChannelSessionRequestHandler() {
+            super();
+        }
+
         @Override
         public Result process(Channel channel, String request, boolean wantReply, Buffer buffer) throws Exception {
             Boolean r = handleRequest(request, buffer);

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/server/channel/PuttyRequestHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/PuttyRequestHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/PuttyRequestHandler.java
index 6df5ea7..c8b4ae3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/PuttyRequestHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/PuttyRequestHandler.java
@@ -18,8 +18,8 @@
  */
 package org.apache.sshd.server.channel;
 
-import org.apache.sshd.common.Channel;
-import org.apache.sshd.common.RequestHandler;
+import org.apache.sshd.common.channel.Channel;
+import org.apache.sshd.common.channel.RequestHandler;
 import org.apache.sshd.common.util.AbstractLoggingBean;
 import org.apache.sshd.common.util.buffer.Buffer;
 

http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9b98f342/sshd-core/src/main/java/org/apache/sshd/server/forward/ForwardingFilter.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/forward/ForwardingFilter.java b/sshd-core/src/main/java/org/apache/sshd/server/forward/ForwardingFilter.java
new file mode 100644
index 0000000..4d20ee1
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/forward/ForwardingFilter.java
@@ -0,0 +1,250 @@
+/*
+ * 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.server.forward;
+
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
+
+import org.apache.sshd.agent.SshAgent;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.SshdSocketAddress;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.util.AbstractLoggingBean;
+import org.apache.sshd.common.util.GenericUtils;
+
+/**
+ * Determines if a forwarding request will be permitted.
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface ForwardingFilter {
+    /**
+     * Determine if the session may arrange for agent forwarding.
+     * <p>
+     * This server process will open a new listen socket locally and export
+     * the address in the {@link SshAgent#SSH_AUTHSOCKET_ENV_NAME} environment
+     * variable.
+     *
+     * @param session session requesting permission to forward the agent.
+     * @return true if the agent forwarding is permitted, false if denied.
+     */
+    boolean canForwardAgent(Session session);
+
+    /**
+     * Determine if the session may arrange for X11 forwarding.
+     * <p>
+     * This server process will open a new listen socket locally and export
+     * the address in the environment so X11 clients can be tunneled to the
+     * user's X11 display server.
+     *
+     * @param session session requesting permission to forward X11 connections.
+     * @return true if the X11 forwarding is permitted, false if denied.
+     */
+    boolean canForwardX11(Session session);
+
+    /**
+     * Determine if the session may listen for inbound connections.
+     * <p>
+     * This server process will open a new listen socket on the address given
+     * by the client (usually 127.0.0.1 but may be any address).  Any inbound
+     * connections to this socket will be tunneled over the session to the
+     * client, which the client will then forward the connection to another
+     * host on the client's side of the network.
+     *
+     * @param address address the client has requested this server listen
+     *  for inbound connections on, and relay them through the client.
+     * @param session session requesting permission to listen for connections.
+     * @return true if the socket is permitted; false if it must be denied.
+     */
+    boolean canListen(SshdSocketAddress address, Session session);
+
+    /**
+     * The type of requested connection forwarding. The type's {@link #getName()}
+     * method returns the SSH request type
+     */
+    enum Type implements NamedResource { 
+        Direct("direct-tcpip"),
+        Forwarded("forwarded-tcpip");
+        
+        private final String name;
+
+        @Override
+        public final String getName() {
+            return name;
+        }
+
+        Type(String name) {
+            this.name = name;
+        }
+        
+        public static final Set<Type> VALUES = 
+                Collections.unmodifiableSet(EnumSet.allOf(Type.class));
+
+        /**
+         * @param name Either the enum name or the request - ignored if {@code null}/empty
+         * @return The matching {@link Type} value - case <U>insensitive</U>,
+         * or {@code null} if no match found
+         * @see #fromName(String)
+         * @see #fromEnumName(String)
+         */
+        public static final Type fromString(String name) {
+            if (GenericUtils.isEmpty(name)) {
+                return null;
+            }
+            
+            Type t = fromName(name);
+            if (t == null) {
+                t = fromEnumName(name);
+            }
+
+            return t;
+        }
+
+        /**
+         * @param name The request name - ignored if {@code null}/empty
+         * @return The matching {@link Type} value - case <U>insensitive</U>,
+         * or {@code null} if no match found
+         */
+        public static final Type fromName(String name) {
+            if (GenericUtils.isEmpty(name)) {
+                return null;
+            }
+            
+            for (Type t : VALUES) {
+                if (name.equalsIgnoreCase(t.getName())) {
+                    return t;
+                }
+            }
+            
+            return null;
+        }
+        
+        /**
+         * @param name The enum value name - ignored if {@code null}/empty
+         * @return The matching {@link Type} value - case <U>insensitive</U>,
+         * or {@code null} if no match found
+         */
+        public static final Type fromEnumName(String name) {
+            if (GenericUtils.isEmpty(name)) {
+                return null;
+            }
+            
+            for (Type t : VALUES) {
+                if (name.equalsIgnoreCase(t.name())) {
+                    return t;
+                }
+            }
+            
+            return null;
+        }
+    }
+
+    /**
+     * Determine if the session may create an outbound connection.
+     * <p>
+     * This server process will connect to another server listening on the
+     * address specified by the client.  Usually this is to another port on
+     * the same host (127.0.0.1) but may be to any other system this server
+     * can reach on the server's side of the network.
+     *
+     * @param type The {@link Type} of requested connection forwarding
+     * @param address address the client has requested this server listen
+     *  for inbound connections on, and relay them through the client.
+     * @param session session requesting permission to listen for connections.
+     * @return true if the socket is permitted; false if it must be denied.
+     */
+    boolean canConnect(Type type, SshdSocketAddress address, Session session);
+    
+    /**
+     * A {@link ForwardingFilter} implementation that returns the same &quot;static&quot;
+     * result for <U>all</U> the queries.
+     */
+    public static class StaticDecisionForwardingFilter extends AbstractLoggingBean implements ForwardingFilter {
+        private final boolean acceptance;
+
+        /**
+         * @param acceptance The acceptance status for <U>all</U> the queries
+         */
+        public StaticDecisionForwardingFilter(boolean acceptance) {
+            this.acceptance = acceptance;
+        }
+        
+        public final boolean isAccepted() {
+            return acceptance;
+        }
+
+        @Override
+        public boolean canForwardAgent(Session session) {
+            return checkAcceptance("auth-agent-req@openssh.com", session, SshdSocketAddress.LOCALHOST_ADDRESS);
+        }
+
+        @Override
+        public boolean canForwardX11(Session session) {
+            return checkAcceptance("x11-req", session, SshdSocketAddress.LOCALHOST_ADDRESS);
+        }
+
+        @Override
+        public boolean canListen(SshdSocketAddress address, Session session) {
+            return checkAcceptance("tcpip-forward", session, address);
+        }
+
+        @Override
+        public boolean canConnect(Type type, SshdSocketAddress address, Session session) {
+            return checkAcceptance(type.getName(), session, address);
+        }
+        
+        /**
+         * @param request The SSH request that ultimately led to this filter being consulted
+         * @param session The requesting {@link Session}
+         * @param target The request target - may be {@link SshdSocketAddress#LOCALHOST_ADDRESS}
+         * if no real target
+         * @return The (static) {@link #isAccepted()} flag
+         */
+        protected boolean checkAcceptance(String request, Session session, SshdSocketAddress target) {
+            boolean accepted = isAccepted();
+            if (log.isDebugEnabled()) {
+                log.debug("checkAcceptance(" + request + ")[" + session + "] acceptance for target=" + target + " is " + accepted);
+            }
+            return accepted;
+        }
+    }
+    
+    /**
+     * A {@link ForwardingFilter} that accepts all requests
+     */
+    public static class AcceptAllForwardingFilter extends StaticDecisionForwardingFilter {
+        public static final AcceptAllForwardingFilter INSTANCE = new AcceptAllForwardingFilter();
+
+        public AcceptAllForwardingFilter() {
+            super(true);
+        }
+    }
+
+    /**
+     * A {@link ForwardingFilter} that rejects all requests
+     */
+    public static class RejectAllForwardingFilter extends StaticDecisionForwardingFilter {
+        public static final RejectAllForwardingFilter INSTANCE = new RejectAllForwardingFilter();
+
+        public RejectAllForwardingFilter() {
+            super(false);
+        }
+    }
+}