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<MyValue> MY_KEY = new AttributeKey<MyValue>();
+ *
+ * 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 "static"
+ * 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);
+ }
+ }
+}