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/10/06 07:23:00 UTC
[3/4] mina-sshd git commit: [SSHD-566] Allow specific properties
overrides per session and channel
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/PropertyResolverUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/PropertyResolverUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/PropertyResolverUtils.java
new file mode 100644
index 0000000..4760a48
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/PropertyResolverUtils.java
@@ -0,0 +1,375 @@
+/*
+ * 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;
+
+import java.util.Map;
+import java.util.Objects;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public final class PropertyResolverUtils {
+
+ private PropertyResolverUtils() {
+ throw new UnsupportedOperationException("No instance allowed");
+ }
+
+ /**
+ * @param resolver The {@link PropertyResolver} instance - ignored if {@code null}
+ * @param name The property name
+ * @param defaultValue The default value to return if the specified property
+ * does not exist in the properties map
+ * @return The resolved property
+ * @throws NumberFormatException if malformed value
+ * @see #toLong(Object, long)
+ */
+ public static long getLongProperty(PropertyResolver resolver, String name, long defaultValue) {
+ return toLong(resolvePropertyValue(resolver, name), defaultValue);
+ }
+
+ public static long getLongProperty(Map<String, ?> props, String name, long defaultValue) {
+ return toLong(resolvePropertyValue(props, name), defaultValue);
+ }
+
+ /**
+ * Converts a generic object value to a {@code long} if possible:
+ * <UL>
+ * <LI>
+ * If value is {@code null} the default is returned
+ * </LI>
+ *
+ * <LI>
+ * If value is a {@link Number} then its {@link Number#longValue()} is returned
+ * </LI>
+ *
+ * <LI>
+ * Otherwise, the value's {@link #toString()} is parsed as a {@code long}
+ * </LI>
+ * </UL>
+ *
+ * @param value The resolved value - may be {@code null}
+ * @param defaultValue The default to use if {@code null} resolved value
+ * @return The resolved value
+ * @throws NumberFormatException if malformed value
+ * @see Long#parseLong(String)
+ */
+ public static long toLong(Object value, long defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ } else if (value instanceof Number) {
+ return ((Number) value).longValue();
+ } else { // we parse the string in case it is not a valid long value
+ return Long.parseLong(value.toString());
+ }
+ }
+
+ /**
+ * @param resolver The {@link PropertyResolver} instance - ignored if {@code null}
+ * @param name The property name
+ * @return The {@link Long} value or {@code null} if property not found
+ * @throws NumberFormatException if malformed value
+ * @see #toLong(Object)
+ */
+ public static Long getLong(PropertyResolver resolver, String name) {
+ return toLong(resolvePropertyValue(resolver, name));
+ }
+
+ public static Long getLong(Map<String, ?> props, String name) {
+ return toLong(resolvePropertyValue(props, name));
+ }
+
+ /**
+ * Converts a generic object into a {@link Long}:
+ * <UL>
+ * <LI>
+ * If the value is {@code null} then returns {@code null}.
+ * </LI>
+ *
+ * <LI>
+ * If the value is already a {@link Long} then it is returned as such.
+ * </LI>
+
+ * <LI>
+ * If value is a {@link Number} then its {@link Number#longValue()} is
+ * wrapped as a {@link Long}
+ * </LI>
+ *
+ * <LI>
+ * Otherwise, the value's {@link #toString()} is parsed as a {@link Long}
+ * </LI>
+ * </UL>
+ *
+ * @param value The resolved value - may be {@code null}
+ * @return The {@link Long} value or {@code null} if property not found
+ * @throws NumberFormatException if malformed value
+ * @see Long#valueOf(long)
+ * @see Long#valueOf(String)
+ */
+ public static Long toLong(Object value) {
+ if (value == null) {
+ return null;
+ } else if (value instanceof Long) {
+ return (Long) value;
+ } else if (value instanceof Number) {
+ return Long.valueOf(((Number) value).longValue());
+ } else { // we parse the string in case it is not a valid long value
+ return Long.valueOf(value.toString());
+ }
+ }
+
+ public static Object updateProperty(PropertyResolver resolver, String name, long value) {
+ return updateProperty(resolver.getProperties(), name, value);
+ }
+
+ public static Object updateProperty(Map<String, Object> props, String name, long value) {
+ return updateProperty(props, name, Long.valueOf(value));
+ }
+
+ public static int getIntProperty(PropertyResolver resolver, String name, int defaultValue) {
+ return toInteger(resolvePropertyValue(resolver, name), defaultValue);
+ }
+
+ public static int getIntProperty(Map<String, ?> props, String name, int defaultValue) {
+ return toInteger(resolvePropertyValue(props, name), defaultValue);
+ }
+
+ public static int toInteger(Object value, int defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ } else if (value instanceof Number) {
+ return ((Number) value).intValue();
+ } else { // we parse the string in case this is NOT an integer
+ return Integer.parseInt(value.toString());
+ }
+ }
+
+ public static Integer getInteger(PropertyResolver resolver, String name) {
+ return toInteger(resolvePropertyValue(resolver, name));
+ }
+
+ public static Integer getInteger(Map<String, ?> props, String name) {
+ return toInteger(resolvePropertyValue(props, name));
+ }
+
+ public static Integer toInteger(Object value) {
+ if (value == null) {
+ return null;
+ } else if (value instanceof Integer) {
+ return (Integer) value;
+ } else if (value instanceof Number) {
+ return Integer.valueOf(((Number) value).intValue());
+ } else { // we parse the string in case this is NOT an integer
+ return Integer.valueOf(value.toString());
+ }
+ }
+
+ public static Object updateProperty(PropertyResolver resolver, String name, int value) {
+ return updateProperty(resolver.getProperties(), name, value);
+ }
+
+ public static Object updateProperty(Map<String, Object> props, String name, int value) {
+ return updateProperty(props, name, Integer.valueOf(value));
+ }
+
+ public static boolean getBooleanProperty(PropertyResolver resolver, String name, boolean defaultValue) {
+ return toBoolean(getObject(resolver, name), defaultValue);
+ }
+
+ public static boolean getBooleanProperty(Map<String, ?> props, String name, boolean defaultValue) {
+ return toBoolean(getObject(props, name), defaultValue);
+ }
+
+ public static boolean toBoolean(Object value, boolean defaultValue) {
+ if (value == null) {
+ return defaultValue;
+ } else {
+ return toBoolean(value).booleanValue();
+ }
+ }
+
+ public static Boolean getBoolean(PropertyResolver resolver, String name) {
+ return toBoolean(resolvePropertyValue(resolver, name));
+ }
+
+ public static Boolean getBoolean(Map<String, ?> props, String name) {
+ return toBoolean(resolvePropertyValue(props, name));
+ }
+
+ public static Boolean toBoolean(Object value) {
+ if (value == null) {
+ return null;
+ } else if (value instanceof Boolean) {
+ return (Boolean) value;
+ } else {
+ return Boolean.valueOf(value.toString());
+ }
+ }
+
+ public static Object updateProperty(PropertyResolver resolver, String name, boolean value) {
+ return updateProperty(resolver.getProperties(), name, value);
+ }
+
+ public static Object updateProperty(Map<String, Object> props, String name, boolean value) {
+ return updateProperty(props, name, Boolean.valueOf(value));
+ }
+
+ /**
+ * @param resolver The {@link PropertyResolver} to use - ignored if {@code null}
+ * @param name The property name
+ * @param defaultValue The default value to return if property not set or empty
+ * @return The set value (if not {@code null}/empty) or default one
+ */
+ public static String getStringProperty(PropertyResolver resolver, String name, String defaultValue) {
+ String value = getString(resolver, name);
+ if (GenericUtils.isEmpty(value)) {
+ return defaultValue;
+ } else {
+ return value;
+ }
+ }
+ public static String getStringProperty(Map<String, ?> props, String name, String defaultValue) {
+ Object value = resolvePropertyValue(props, name);
+ if (value == null) {
+ return defaultValue;
+ } else {
+ return Objects.toString(value);
+ }
+ }
+
+ public static String getString(PropertyResolver resolver, String name) {
+ Object value = getObject(resolver, name);
+ return Objects.toString(value, null);
+ }
+
+ public static String getString(Map<String, ?> props, String name) {
+ Object value = getObject(props, name);
+ return Objects.toString(value, null);
+ }
+
+ public static Object getObject(PropertyResolver resolver, String name) {
+ return resolvePropertyValue(resolver, name);
+ }
+
+
+ // for symmetrical reasons...
+ public static Object getObject(Map<String, ?> props, String name) {
+ return resolvePropertyValue(props, name);
+ }
+
+ public static Object resolvePropertyValue(Map<String, ?> props, String name) {
+ String key = ValidateUtils.checkNotNullAndNotEmpty(name, "No property name");
+ return GenericUtils.isEmpty(props) ? null : props.get(key);
+ }
+
+ /**
+ * @param resolver The {@link PropertyResolver} instance
+ * @param name The property name
+ * @param value The new value - if {@code null} or an empty {@link CharSequence}
+ * the property is <U>removed</U>
+ * @return The previous value - {@code null} if none
+ */
+ public static Object updateProperty(PropertyResolver resolver, String name, Object value) {
+ return updateProperty(resolver.getProperties(), name, value);
+ }
+
+ public static Object updateProperty(Map<String, Object> props, String name, Object value) {
+ String key = ValidateUtils.checkNotNullAndNotEmpty(name, "No property name");
+ if ((value == null) || ((value instanceof CharSequence) && GenericUtils.isEmpty((CharSequence) value))) {
+ return props.remove(key);
+ } else {
+ return props.put(key, value);
+ }
+ }
+
+ /**
+ * Unwinds the resolvers hierarchy until found one with a non-{@code null} value
+ * for the requested property or reached top.
+ *
+ * @param resolver The {@link PropertyResolver} to start from - ignored if {@code null}
+ * @param name The requested property name
+ * @return The found value or {@code null}
+ */
+ public static Object resolvePropertyValue(PropertyResolver resolver, String name) {
+ String key = ValidateUtils.checkNotNullAndNotEmpty(name, "No property name");
+ for (PropertyResolver r = resolver; r != null; r = r.getParentPropertyResolver()) {
+ Map<String, ?> props = r.getProperties();
+ Object value = GenericUtils.isEmpty(props) ? null : props.get(key);
+ if (value != null) {
+ return value;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Unwinds the resolvers hierarchy until found one with a non-{@code null} value
+ * for the requested property or reached top.
+ *
+ * @param resolver The {@link PropertyResolver} to start from - ignored if {@code null}
+ * @param name The requested property name
+ * @return The found properties {@link Map} or {@code null}
+ */
+ public static Map<String, Object> resolvePropertiesSource(PropertyResolver resolver, String name) {
+ String key = ValidateUtils.checkNotNullAndNotEmpty(name, "No property name");
+ for (PropertyResolver r = resolver; r != null; r = r.getParentPropertyResolver()) {
+ Map<String, Object> props = r.getProperties();
+ Object value = GenericUtils.isEmpty(props) ? null : props.get(key);
+ if (value != null) {
+ return props;
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Wraps a {@link Map} into a {@link PropertyResolver} so it can be used
+ * with these utilities
+ *
+ * @param props The properties map - may be {@code null}/empty if no properties
+ * are updated
+ * @return The resolver wrapper
+ */
+ public static PropertyResolver toPropertyResolver(final Map<String, Object> props) {
+ return toPropertyResolver(props, null);
+ }
+
+ public static PropertyResolver toPropertyResolver(final Map<String, Object> props, final PropertyResolver parent) {
+ return new PropertyResolver() {
+ @Override
+ public PropertyResolver getParentPropertyResolver() {
+ return parent;
+ }
+
+ @Override
+ public Map<String, Object> getProperties() {
+ return props;
+ }
+
+ @Override
+ public String toString() {
+ return Objects.toString(props);
+ }
+ };
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
index 2e70c49..ea579e1 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
@@ -22,6 +22,8 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
@@ -30,7 +32,8 @@ import java.util.concurrent.atomic.AtomicReference;
import org.apache.sshd.common.Closeable;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolver;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.future.CloseFuture;
import org.apache.sshd.common.future.DefaultCloseFuture;
@@ -59,11 +62,6 @@ public abstract class AbstractChannel
extends AbstractInnerCloseable
implements Channel, ExecutorServiceConfigurer {
- public static final int DEFAULT_WINDOW_SIZE = 0x200000;
- public static final int DEFAULT_PACKET_SIZE = 0x8000;
-
- public static final long DEFAULT_CHANNEL_CLOSE_TIMEOUT = TimeUnit.SECONDS.toMillis(5L);
-
/**
* Default growth factor function used to resize response buffers
*/
@@ -78,7 +76,6 @@ public abstract class AbstractChannel
protected final Window localWindow;
protected final Window remoteWindow;
protected ConnectionService service;
- protected Session session;
protected int id;
protected int recipient;
protected final AtomicBoolean eof = new AtomicBoolean(false);
@@ -91,6 +88,9 @@ public abstract class AbstractChannel
protected final Collection<ChannelListener> channelListeners = new CopyOnWriteArraySet<>();
protected final ChannelListener channelListenerProxy;
+ private Session session;
+ private final Map<String, Object> properties = new ConcurrentHashMap<>();
+
protected AbstractChannel(boolean client) {
this("", client);
}
@@ -132,6 +132,11 @@ public abstract class AbstractChannel
}
@Override
+ public PropertyResolver getParentPropertyResolver() {
+ return getSession();
+ }
+
+ @Override
public ExecutorService getExecutorService() {
return executor;
}
@@ -304,32 +309,35 @@ public abstract class AbstractChannel
if (immediately) {
gracefulFuture.setClosed();
} else if (!gracefulFuture.isClosed()) {
- log.debug("Send SSH_MSG_CHANNEL_CLOSE on channel {}", AbstractChannel.this);
+ final Channel channel = AbstractChannel.this;
+ log.debug("Send SSH_MSG_CHANNEL_CLOSE on channel {}", channel);
+
Session s = getSession();
Buffer buffer = s.createBuffer(SshConstants.SSH_MSG_CHANNEL_CLOSE, Short.SIZE);
buffer.putInt(getRecipient());
+
try {
- long timeout = FactoryManagerUtils.getLongProperty(getSession(), FactoryManager.CHANNEL_CLOSE_TIMEOUT, DEFAULT_CHANNEL_CLOSE_TIMEOUT);
- session.writePacket(buffer, timeout, TimeUnit.MILLISECONDS).addListener(new SshFutureListener<IoWriteFuture>() {
+ long timeout = PropertyResolverUtils.getLongProperty(channel, FactoryManager.CHANNEL_CLOSE_TIMEOUT, FactoryManager.DEFAULT_CHANNEL_CLOSE_TIMEOUT);
+ s.writePacket(buffer, timeout, TimeUnit.MILLISECONDS).addListener(new SshFutureListener<IoWriteFuture>() {
@SuppressWarnings("synthetic-access")
@Override
public void operationComplete(IoWriteFuture future) {
if (future.isWritten()) {
- log.debug("Message SSH_MSG_CHANNEL_CLOSE written on channel {}", AbstractChannel.this);
+ log.debug("Message SSH_MSG_CHANNEL_CLOSE written on channel {}", channel);
if (gracefulState.compareAndSet(GracefulState.Opened, GracefulState.CloseSent)) {
// Waiting for CLOSE message to come back from the remote side
} else if (gracefulState.compareAndSet(GracefulState.CloseReceived, GracefulState.Closed)) {
gracefulFuture.setClosed();
}
} else {
- log.debug("Failed to write SSH_MSG_CHANNEL_CLOSE on channel {}", AbstractChannel.this);
- AbstractChannel.this.close(true);
+ log.debug("Failed to write SSH_MSG_CHANNEL_CLOSE on channel {}", channel);
+ channel.close(true);
}
}
});
} catch (IOException e) {
- log.debug("Exception caught while writing SSH_MSG_CHANNEL_CLOSE packet on channel " + AbstractChannel.this, e);
- AbstractChannel.this.close(true);
+ log.debug("Exception caught while writing SSH_MSG_CHANNEL_CLOSE packet on channel " + channel, e);
+ channel.close(true);
}
}
@@ -471,8 +479,13 @@ public abstract class AbstractChannel
writePacket(buffer);
}
+ @Override
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
protected void configureWindow() {
- localWindow.init(getSession());
+ localWindow.init(this);
}
protected void sendWindowAdjust(int len) throws IOException {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java
index dc93b96..20436c8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/Channel.java
@@ -22,6 +22,7 @@ import java.io.IOException;
import org.apache.sshd.client.future.OpenFuture;
import org.apache.sshd.common.Closeable;
+import org.apache.sshd.common.PropertyResolver;
import org.apache.sshd.common.future.CloseFuture;
import org.apache.sshd.common.session.ConnectionService;
import org.apache.sshd.common.session.Session;
@@ -33,7 +34,7 @@ import org.apache.sshd.common.util.buffer.Buffer;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface Channel extends ChannelListenerManager, Closeable {
+public interface Channel extends ChannelListenerManager, PropertyResolver, Closeable {
/**
* @return Local channel identifier
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelOutputStream.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelOutputStream.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelOutputStream.java
index a2c4ace..0ba9c39 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelOutputStream.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelOutputStream.java
@@ -23,7 +23,7 @@ import java.io.InterruptedIOException;
import java.io.OutputStream;
import java.nio.channels.Channel;
import java.util.concurrent.TimeUnit;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.util.ValidateUtils;
@@ -55,7 +55,7 @@ public class ChannelOutputStream extends OutputStream implements Channel {
private boolean noDelay;
public ChannelOutputStream(AbstractChannel channel, Window remoteWindow, Logger log, byte cmd) {
- this(channel, remoteWindow, FactoryManagerUtils.getLongProperty(channel, WAIT_FOR_SPACE_TIMEOUT, DEFAULT_WAIT_FOR_SPACE_TIMEOUT), log, cmd);
+ this(channel, remoteWindow, PropertyResolverUtils.getLongProperty(channel, WAIT_FOR_SPACE_TIMEOUT, DEFAULT_WAIT_FOR_SPACE_TIMEOUT), log, cmd);
}
public ChannelOutputStream(AbstractChannel channel, Window remoteWindow, long maxWaitTimeout, Logger log, byte cmd) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelPipedInputStream.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelPipedInputStream.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelPipedInputStream.java
index a01b955..61c5ec9 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelPipedInputStream.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/ChannelPipedInputStream.java
@@ -29,7 +29,8 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolver;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
@@ -40,8 +41,6 @@ import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public class ChannelPipedInputStream extends InputStream implements ChannelPipedSink {
- public static final long DEFAULT_TIMEOUT = 0L;
-
private final Window localWindow;
private final Buffer buffer = new ByteArrayBuffer();
private final byte[] b = new byte[1];
@@ -60,9 +59,13 @@ public class ChannelPipedInputStream extends InputStream implements ChannelPiped
private long timeout;
- public ChannelPipedInputStream(Window localWindow) {
+ public ChannelPipedInputStream(PropertyResolver resolver, Window localWindow) {
+ this(localWindow, PropertyResolverUtils.getLongProperty(resolver, FactoryManager.WINDOW_TIMEOUT, FactoryManager.DEFAULT_WINDOW_TIMEOUT));
+ }
+
+ public ChannelPipedInputStream(Window localWindow, long windowTimeout) {
this.localWindow = ValidateUtils.checkNotNull(localWindow, "No local window provided");
- this.timeout = FactoryManagerUtils.getLongProperty(localWindow.getProperties(), FactoryManager.WINDOW_TIMEOUT, DEFAULT_TIMEOUT);
+ this.timeout = windowTimeout;
}
@Override
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/channel/Window.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/Window.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/Window.java
index 0094b9d..08d8ed7 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/channel/Window.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/Window.java
@@ -28,8 +28,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
-import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.PropertyResolver;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.util.Predicate;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.logging.AbstractLoggingBean;
@@ -43,7 +43,7 @@ import org.apache.sshd.common.util.logging.AbstractLoggingBean;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public class Window extends AbstractLoggingBean implements java.nio.channels.Channel {
+public class Window extends AbstractLoggingBean implements java.nio.channels.Channel, PropertyResolver {
/**
* Default {@link Predicate} used to test if space became available
*/
@@ -65,7 +65,7 @@ public class Window extends AbstractLoggingBean implements java.nio.channels.Cha
private int maxSize;
private int packetSize;
- private Map<String, ?> props = Collections.<String, Object>emptyMap();
+ private Map<String, Object> props = Collections.<String, Object>emptyMap();
public Window(AbstractChannel channel, Object lock, boolean client, boolean local) {
this.channel = ValidateUtils.checkNotNull(channel, "No channel provided");
@@ -73,10 +73,16 @@ public class Window extends AbstractLoggingBean implements java.nio.channels.Cha
this.suffix = ": " + (client ? "client" : "server") + " " + (local ? "local " : "remote") + " window";
}
- public Map<String, ?> getProperties() {
+ @Override
+ public Map<String, Object> getProperties() {
return props;
}
+ @Override
+ public PropertyResolver getParentPropertyResolver() {
+ return channel;
+ }
+
public int getSize() {
synchronized (lock) {
return sizeHolder.get();
@@ -91,21 +97,13 @@ public class Window extends AbstractLoggingBean implements java.nio.channels.Cha
return packetSize;
}
- public void init(Session session) {
- init(session.getFactoryManager());
- }
-
- public void init(FactoryManager manager) {
- init(manager.getProperties());
- }
-
- public void init(Map<String, ?> props) {
- init(FactoryManagerUtils.getIntProperty(props, FactoryManager.WINDOW_SIZE, AbstractChannel.DEFAULT_WINDOW_SIZE),
- FactoryManagerUtils.getIntProperty(props, FactoryManager.MAX_PACKET_SIZE, AbstractChannel.DEFAULT_PACKET_SIZE),
- props);
+ public void init(PropertyResolver resolver) {
+ init(PropertyResolverUtils.getIntProperty(resolver, FactoryManager.WINDOW_SIZE, FactoryManager.DEFAULT_WINDOW_SIZE),
+ PropertyResolverUtils.getIntProperty(resolver, FactoryManager.MAX_PACKET_SIZE, FactoryManager.DEFAULT_MAX_PACKET_SIZE),
+ resolver.getProperties());
}
- public void init(int size, int packetSize, Map<String, ?> props) {
+ public void init(int size, int packetSize, Map<String, Object> props) {
ValidateUtils.checkTrue(size >= 0, "Illegal initial size: %d", size);
ValidateUtils.checkTrue(packetSize > 0, "Illegal packet size: %d", packetSize);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java b/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java
index 07b1d90..6fbe333 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipClientChannel.java
@@ -30,6 +30,7 @@ import org.apache.sshd.common.SshException;
import org.apache.sshd.common.SshdSocketAddress;
import org.apache.sshd.common.channel.ChannelOutputStream;
import org.apache.sshd.common.io.IoSession;
+import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
@@ -86,6 +87,7 @@ public class TcpipClientChannel extends AbstractClientChannel {
openFuture = new DefaultOpenFuture(lock);
log.debug("Send SSH_MSG_CHANNEL_OPEN on channel {}", this);
+ Session session = getSession();
Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_OPEN);
buffer.putString(type);
buffer.putInt(id);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/io/AbstractIoServiceFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/AbstractIoServiceFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/io/AbstractIoServiceFactory.java
index bb1742e..73a91ca 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/AbstractIoServiceFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/AbstractIoServiceFactory.java
@@ -23,7 +23,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.util.closeable.AbstractCloseable;
import org.apache.sshd.common.util.threads.ExecutorServiceCarrier;
@@ -77,7 +77,7 @@ public abstract class AbstractIoServiceFactory extends AbstractCloseable impleme
}
public static int getNioWorkers(FactoryManager manager) {
- int nb = FactoryManagerUtils.getIntProperty(manager, FactoryManager.NIO_WORKERS, FactoryManager.DEFAULT_NIO_WORKERS);
+ int nb = PropertyResolverUtils.getIntProperty(manager, FactoryManager.NIO_WORKERS, FactoryManager.DEFAULT_NIO_WORKERS);
if (nb > 0) {
return nb;
} else {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaAcceptor.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaAcceptor.java b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaAcceptor.java
index f25d8ee..bfd87f6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaAcceptor.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaAcceptor.java
@@ -31,7 +31,7 @@ import org.apache.mina.core.service.IoService;
import org.apache.mina.transport.socket.nio.NioSession;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
/**
*/
@@ -48,8 +48,8 @@ public class MinaAcceptor extends MinaService implements org.apache.sshd.common.
public MinaAcceptor(FactoryManager manager, org.apache.sshd.common.io.IoHandler handler, IoProcessor<NioSession> ioProcessor) {
super(manager, handler, ioProcessor);
- backlog = FactoryManagerUtils.getIntProperty(manager, FactoryManager.SOCKET_BACKLOG, DEFAULT_BACKLOG);
- reuseAddress = FactoryManagerUtils.getBooleanProperty(manager, FactoryManager.SOCKET_REUSEADDR, DEFAULT_REUSE_ADDRESS);
+ backlog = PropertyResolverUtils.getIntProperty(manager, FactoryManager.SOCKET_BACKLOG, DEFAULT_BACKLOG);
+ reuseAddress = PropertyResolverUtils.getBooleanProperty(manager, FactoryManager.SOCKET_REUSEADDR, DEFAULT_REUSE_ADDRESS);
}
protected IoAcceptor createAcceptor() {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java
index 1455518..654c0b0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaService.java
@@ -32,7 +32,7 @@ import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSession;
import org.apache.sshd.common.Closeable;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.util.closeable.AbstractCloseable;
/**
@@ -151,11 +151,11 @@ public abstract class MinaService extends AbstractCloseable implements org.apach
}
protected Integer getInteger(String property) {
- return FactoryManagerUtils.getInteger(manager, property);
+ return PropertyResolverUtils.getInteger(manager, property);
}
protected Boolean getBoolean(String property) {
- return FactoryManagerUtils.getBoolean(manager, property);
+ return PropertyResolverUtils.getBoolean(manager, property);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
index f12bc4a..836f41d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
@@ -32,7 +32,7 @@ import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.future.CloseFuture;
import org.apache.sshd.common.io.IoAcceptor;
import org.apache.sshd.common.io.IoHandler;
@@ -48,7 +48,7 @@ public class Nio2Acceptor extends Nio2Service implements IoAcceptor {
public Nio2Acceptor(FactoryManager manager, IoHandler handler, AsynchronousChannelGroup group) {
super(manager, handler, group);
channels = new ConcurrentHashMap<SocketAddress, AsynchronousServerSocketChannel>();
- backlog = FactoryManagerUtils.getIntProperty(manager, FactoryManager.SOCKET_BACKLOG, DEFAULT_BACKLOG);
+ backlog = PropertyResolverUtils.getIntProperty(manager, FactoryManager.SOCKET_BACKLOG, DEFAULT_BACKLOG);
}
@Override
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java
index 7d4f1db..ba1494c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Service.java
@@ -30,7 +30,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.sshd.common.Closeable;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.io.IoHandler;
import org.apache.sshd.common.io.IoService;
import org.apache.sshd.common.io.IoSession;
@@ -78,7 +78,7 @@ public abstract class Nio2Service extends AbstractInnerCloseable implements IoSe
}
protected <T> void setOption(NetworkChannel socket, String property, SocketOption<T> option, T defaultValue) throws IOException {
- String valStr = FactoryManagerUtils.getString(manager, property);
+ String valStr = PropertyResolverUtils.getString(manager, property);
T val = defaultValue;
if (!GenericUtils.isEmpty(valStr)) {
Class<T> type = option.type();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
index 9f5f09c..d37403d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
@@ -31,7 +31,7 @@ import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.future.CloseFuture;
import org.apache.sshd.common.io.IoHandler;
import org.apache.sshd.common.io.IoService;
@@ -179,7 +179,7 @@ public class Nio2Session extends AbstractCloseable implements IoSession {
}
public void startReading() {
- startReading(FactoryManagerUtils.getIntProperty(manager, FactoryManager.NIO2_READ_BUFFER_SIZE, DEFAULT_READBUF_SIZE));
+ startReading(PropertyResolverUtils.getIntProperty(manager, FactoryManager.NIO2_READ_BUFFER_SIZE, DEFAULT_READBUF_SIZE));
}
public void startReading(int bufSize) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java
index 584d3b1..6cbb376 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java
@@ -30,7 +30,6 @@ import org.apache.sshd.common.util.logging.AbstractLoggingBean;
*/
public abstract class AbstractDHKeyExchange extends AbstractLoggingBean implements KeyExchange {
- protected AbstractSession session;
protected byte[] v_s;
protected byte[] v_c;
protected byte[] i_s;
@@ -41,6 +40,8 @@ public abstract class AbstractDHKeyExchange extends AbstractLoggingBean implemen
protected byte[] k;
protected byte[] h;
+ private AbstractSession session;
+
protected AbstractDHKeyExchange() {
super();
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/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 8f00b8d..65d7e64 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
@@ -30,8 +30,8 @@ import org.apache.sshd.client.channel.AbstractClientChannel;
import org.apache.sshd.client.future.OpenFuture;
import org.apache.sshd.common.Closeable;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.channel.Channel;
@@ -48,20 +48,6 @@ import org.apache.sshd.common.util.closeable.AbstractInnerCloseable;
import org.apache.sshd.server.channel.OpenChannelException;
import org.apache.sshd.server.x11.X11ForwardSupport;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_CHANNEL_CLOSE;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_CHANNEL_DATA;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_CHANNEL_EOF;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_CHANNEL_EXTENDED_DATA;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_CHANNEL_FAILURE;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_CHANNEL_OPEN;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_CHANNEL_OPEN_CONFIRMATION;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_CHANNEL_OPEN_FAILURE;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_CHANNEL_REQUEST;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_CHANNEL_WINDOW_ADJUST;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_GLOBAL_REQUEST;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_REQUEST_FAILURE;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_REQUEST_SUCCESS;
-
/**
* Base implementation of ConnectionService.
*
@@ -147,7 +133,7 @@ public abstract class AbstractConnectionService extends AbstractInnerCloseable i
@Override
public int registerChannel(Channel channel) throws IOException {
- int maxChannels = FactoryManagerUtils.getIntProperty(session, MAX_CONCURRENT_CHANNELS_PROP, DEFAULT_MAX_CHANNELS);
+ int maxChannels = PropertyResolverUtils.getIntProperty(session, MAX_CONCURRENT_CHANNELS_PROP, DEFAULT_MAX_CHANNELS);
int curSize = channels.size();
if (curSize > maxChannels) {
throw new IllegalStateException("Currently active channels (" + curSize + ") at max.: " + maxChannels);
@@ -182,43 +168,43 @@ public abstract class AbstractConnectionService extends AbstractInnerCloseable i
@Override
public void process(int cmd, Buffer buffer) throws Exception {
switch (cmd) {
- case SSH_MSG_CHANNEL_OPEN:
+ case SshConstants.SSH_MSG_CHANNEL_OPEN:
channelOpen(buffer);
break;
- case SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
+ case SshConstants.SSH_MSG_CHANNEL_OPEN_CONFIRMATION:
channelOpenConfirmation(buffer);
break;
- case SSH_MSG_CHANNEL_OPEN_FAILURE:
+ case SshConstants.SSH_MSG_CHANNEL_OPEN_FAILURE:
channelOpenFailure(buffer);
break;
- case SSH_MSG_CHANNEL_REQUEST:
+ case SshConstants.SSH_MSG_CHANNEL_REQUEST:
channelRequest(buffer);
break;
- case SSH_MSG_CHANNEL_DATA:
+ case SshConstants.SSH_MSG_CHANNEL_DATA:
channelData(buffer);
break;
- case SSH_MSG_CHANNEL_EXTENDED_DATA:
+ case SshConstants.SSH_MSG_CHANNEL_EXTENDED_DATA:
channelExtendedData(buffer);
break;
- case SSH_MSG_CHANNEL_FAILURE:
+ case SshConstants.SSH_MSG_CHANNEL_FAILURE:
channelFailure(buffer);
break;
- case SSH_MSG_CHANNEL_WINDOW_ADJUST:
+ case SshConstants.SSH_MSG_CHANNEL_WINDOW_ADJUST:
channelWindowAdjust(buffer);
break;
- case SSH_MSG_CHANNEL_EOF:
+ case SshConstants.SSH_MSG_CHANNEL_EOF:
channelEof(buffer);
break;
- case SSH_MSG_CHANNEL_CLOSE:
+ case SshConstants.SSH_MSG_CHANNEL_CLOSE:
channelClose(buffer);
break;
- case SSH_MSG_GLOBAL_REQUEST:
+ case SshConstants.SSH_MSG_GLOBAL_REQUEST:
globalRequest(buffer);
break;
- case SSH_MSG_REQUEST_SUCCESS:
+ case SshConstants.SSH_MSG_REQUEST_SUCCESS:
requestSuccess(buffer);
break;
- case SSH_MSG_REQUEST_FAILURE:
+ case SshConstants.SSH_MSG_REQUEST_FAILURE:
requestFailure(buffer);
break;
default:
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/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 4108949..11ca6f8 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
@@ -37,9 +37,10 @@ import java.util.concurrent.atomic.AtomicReference;
import org.apache.sshd.common.Closeable;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.PropertyResolver;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.Service;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.SshException;
@@ -60,6 +61,7 @@ import org.apache.sshd.common.mac.Mac;
import org.apache.sshd.common.random.Random;
import org.apache.sshd.common.util.EventListenerUtils;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.Pair;
import org.apache.sshd.common.util.Readable;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
@@ -166,12 +168,9 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
protected final AtomicReference<Buffer> requestResult = new AtomicReference<>();
protected final Map<AttributeKey<?>, Object> attributes = new ConcurrentHashMap<>();
- // Session timeout
- protected long authTimeoutTimestamp;
- protected long idleTimeoutTimestamp;
- protected long authTimeoutMs = TimeUnit.MINUTES.toMillis(2); // 2 minutes in milliseconds
- protected long idleTimeoutMs = TimeUnit.MINUTES.toMillis(10); // 10 minutes in milliseconds
- protected long disconnectTimeoutMs = TimeUnit.SECONDS.toMillis(10); // 10 seconds in milliseconds
+ // Session timeout measurements
+ protected long authTimeoutStart = System.currentTimeMillis();
+ protected long idleTimeoutStart = System.currentTimeMillis();
protected final AtomicReference<TimeoutStatus> timeoutStatus = new AtomicReference<>(TimeoutStatus.NoTimeout);
//
@@ -190,6 +189,7 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
* The factory manager used to retrieve factories of Ciphers, Macs and other objects
*/
private final FactoryManager factoryManager;
+ private final Map<String, Object> properties = new ConcurrentHashMap<>();
/**
* Create a new session.
@@ -198,7 +198,7 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
* @param factoryManager the factory manager
* @param ioSession the underlying MINA session
*/
- public AbstractSession(boolean isServer, FactoryManager factoryManager, IoSession ioSession) {
+ protected AbstractSession(boolean isServer, FactoryManager factoryManager, IoSession ioSession) {
this.isServer = isServer;
this.factoryManager = ValidateUtils.checkNotNull(factoryManager, "No factory manager provided", GenericUtils.EMPTY_OBJECT_ARRAY);
this.ioSession = ioSession;
@@ -207,11 +207,7 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
sessionListenerProxy = EventListenerUtils.proxyWrapper(SessionListener.class, loader, sessionListeners);
channelListenerProxy = EventListenerUtils.proxyWrapper(ChannelListener.class, loader, channelListeners);
- random = factoryManager.getRandomFactory().create();
- authTimeoutMs = getLongProperty(FactoryManager.AUTH_TIMEOUT, authTimeoutMs);
- authTimeoutTimestamp = System.currentTimeMillis() + authTimeoutMs;
- idleTimeoutMs = getLongProperty(FactoryManager.IDLE_TIMEOUT, idleTimeoutMs);
- disconnectTimeoutMs = getLongProperty(FactoryManager.DISCONNECT_TIMEOUT, disconnectTimeoutMs);
+ random = ValidateUtils.checkNotNull(factoryManager.getRandomFactory(), "No random factory").create();
}
/**
@@ -287,6 +283,16 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
}
@Override
+ public PropertyResolver getParentPropertyResolver() {
+ return getFactoryManager();
+ }
+
+ @Override
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ @Override
public String getNegotiatedKexParameter(KexProposalOption paramType) {
if (paramType == null) {
return null;
@@ -1260,9 +1266,10 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
Buffer buffer = createBuffer(SshConstants.SSH_MSG_DISCONNECT, msg.length() + Short.SIZE);
buffer.putInt(reason);
buffer.putString(msg);
- buffer.putString(""); // language...
+ buffer.putString(""); // TODO configure language...
// Write the packet with a timeout to ensure a timely close of the session
// in case the consumer does not read packets anymore.
+ long disconnectTimeoutMs = PropertyResolverUtils.getLongProperty(this, FactoryManager.DISCONNECT_TIMEOUT, FactoryManager.DEFAULT_DISCONNECT_TIMEOUT);
writePacket(buffer, disconnectTimeoutMs, TimeUnit.MILLISECONDS).addListener(new SshFutureListener<IoWriteFuture>() {
@Override
public void operationComplete(IoWriteFuture future) {
@@ -1375,36 +1382,6 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
}
/**
- * 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
- */
- @Override
- public int getIntProperty(String name, int defaultValue) {
- try {
- return FactoryManagerUtils.getIntProperty(factoryManager, name, defaultValue);
- } catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("getIntProperty(" + name + ") failed (" + e.getClass().getSimpleName() + ") to retrieve: " + e.getMessage());
- }
- return defaultValue;
- }
- }
-
- public long getLongProperty(String name, long defaultValue) {
- try {
- return FactoryManagerUtils.getLongProperty(factoryManager, name, defaultValue);
- } catch (Exception e) {
- if (log.isDebugEnabled()) {
- log.debug("getLongProperty(" + name + ") failed (" + e.getClass().getSimpleName() + ") to retrieve: " + e.getMessage());
- }
- return defaultValue;
- }
- }
-
- /**
* Returns the value of the user-defined attribute of this session.
*
* @param key the key of the attribute; must not be null.
@@ -1611,54 +1588,92 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
* timed out, a DISCONNECT message will be sent.
*
* @throws IOException If failed to check
+ * @see #checkAuthenticationTimeout(long, long)
+ * @see #checkIdleTimeout(long, long)
*/
protected void checkForTimeouts() throws IOException {
- if (!isClosing()) {
- long now = System.currentTimeMillis();
- if ((!authed) && (authTimeoutMs > 0L) && (now > authTimeoutTimestamp)) {
- timeoutStatus.set(TimeoutStatus.AuthTimeout);
- disconnect(SshConstants.SSH2_DISCONNECT_PROTOCOL_ERROR, "Session has timed out waiting for authentication after " + authTimeoutMs + " ms.");
- }
- if ((idleTimeoutMs > 0) && (idleTimeoutTimestamp > 0L) && (now > idleTimeoutTimestamp)) {
- timeoutStatus.set(TimeoutStatus.AuthTimeout);
- disconnect(SshConstants.SSH2_DISCONNECT_PROTOCOL_ERROR, "User session has timed out idling after " + idleTimeoutMs + " ms.");
- }
+ if (isClosing()) {
+ log.debug("checkForTimeouts({}) session closing", this);
+ return;
}
+
+ long now = System.currentTimeMillis();
+ Pair<TimeoutStatus, String> result = checkAuthenticationTimeout(now, getAuthTimeout());
+ if (result == null) {
+ result = checkIdleTimeout(now, getIdleTimeout());
+ }
+
+ TimeoutStatus status = (result == null) ? TimeoutStatus.NoTimeout : result.getFirst();
+ if ((status == null) || TimeoutStatus.NoTimeout.equals(status)) {
+ return;
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("checkForTimeouts({}) disconnect - reason={}", this, status);
+ }
+
+ timeoutStatus.set(status);
+ disconnect(SshConstants.SSH2_DISCONNECT_PROTOCOL_ERROR, result.getSecond());
}
- @Override
- public void resetIdleTimeout() {
- this.idleTimeoutTimestamp = System.currentTimeMillis() + idleTimeoutMs;
+ /**
+ * Checks if authentication timeout expired
+ *
+ * @param now The current time in millis
+ * @param authTimeoutMs The configured timeout in millis - if non-positive
+ * then no timeout
+ * @return A {@link Pair} specifying the timeout status and disconnect reason
+ * message if timeout expired, {@code null} or {@link TimeoutStatus#NoTimeout}
+ * if no timeout occurred
+ * @see #getAuthTimeout()
+ */
+ protected Pair<TimeoutStatus, String> checkAuthenticationTimeout(long now, long authTimeoutMs) {
+ long authDiff = now - authTimeoutStart;
+ if ((!authed) && (authTimeoutMs > 0L) && (authDiff > authTimeoutMs)) {
+ return new Pair<TimeoutStatus, String>(TimeoutStatus.AuthTimeout, "Session has timed out waiting for authentication after " + authTimeoutMs + " ms.");
+ } else {
+ return null;
+ }
}
/**
- * Check if timeout has occurred.
+ * Checks if idle timeout expired
*
- * @return The {@link TimeoutStatus}
+ * @param now The current time in millis
+ * @param authTimeoutMs The configured timeout in millis - if non-positive
+ * then no timeout
+ * @return A {@link Pair} specifying the timeout status and disconnect reason
+ * message if timeout expired, {@code null} or {@link TimeoutStatus#NoTimeout}
+ * if no timeout occurred
+ * @see #getIdleTimeout()
*/
+ protected Pair<TimeoutStatus, String> checkIdleTimeout(long now, long idleTimeoutMs) {
+ long idleDiff = now - idleTimeoutStart;
+ if ((idleTimeoutMs > 0L) && (idleDiff > idleTimeoutMs)) {
+ return new Pair<TimeoutStatus, String>(TimeoutStatus.IdleTimeout, "User session has timed out idling after " + idleTimeoutMs + " ms.");
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void resetIdleTimeout() {
+ this.idleTimeoutStart = System.currentTimeMillis();
+ }
+
@Override
public TimeoutStatus getTimeoutStatus() {
return timeoutStatus.get();
}
- /**
- * What is timeout value in milliseconds for authentication stage
- *
- * @return The timeout value in milliseconds for authentication stage
- */
@Override
public long getAuthTimeout() {
- return authTimeoutMs;
+ return PropertyResolverUtils.getLongProperty(this, FactoryManager.AUTH_TIMEOUT, FactoryManager.DEFAULT_AUTH_TIMEOUT);
}
- /**
- * What is timeout value in milliseconds for communication
- *
- * @return The timeout value in milliseconds for communication
- */
@Override
public long getIdleTimeout() {
- return idleTimeoutMs;
+ return PropertyResolverUtils.getLongProperty(this, FactoryManager.IDLE_TIMEOUT, FactoryManager.DEFAULT_IDLE_TIMEOUT);
}
@Override
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/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
index bd60783..3f04862 100644
--- 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
@@ -23,6 +23,7 @@ import java.util.concurrent.TimeUnit;
import org.apache.sshd.common.Closeable;
import org.apache.sshd.common.FactoryManager;
+import org.apache.sshd.common.PropertyResolver;
import org.apache.sshd.common.Service;
import org.apache.sshd.common.auth.UsernameHolder;
import org.apache.sshd.common.channel.ChannelListenerManager;
@@ -39,7 +40,12 @@ import org.apache.sshd.common.util.buffer.Buffer;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface Session extends SessionListenerManager, ChannelListenerManager, Closeable, UsernameHolder {
+public interface Session
+ extends SessionListenerManager,
+ ChannelListenerManager,
+ PropertyResolver,
+ Closeable,
+ UsernameHolder {
/**
* Timeout status.
@@ -47,7 +53,7 @@ public interface Session extends SessionListenerManager, ChannelListenerManager,
enum TimeoutStatus {
NoTimeout,
AuthTimeout,
- IdleTimeout
+ IdleTimeout;
}
/**
@@ -102,15 +108,6 @@ public interface Session extends SessionListenerManager, ChannelListenerManager,
String getNegotiatedKexParameter(KexProposalOption 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.
*
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
index 29b03ea..ca806fd 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
@@ -19,6 +19,7 @@
package org.apache.sshd.server;
import java.util.List;
+import java.util.concurrent.TimeUnit;
import org.apache.sshd.common.Factory;
import org.apache.sshd.common.FactoryManager;
@@ -38,13 +39,16 @@ import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
*/
public interface ServerFactoryManager extends FactoryManager, KeyPairProviderHolder {
/**
- * Key used to retrieve the value of the maximum concurrent open session count per username
+ * Key used to retrieve the value of the maximum concurrent open session count per username.
+ * If not set, then unlimited
*/
String MAX_CONCURRENT_SESSIONS = "max-concurrent-sessions";
+
/**
* Key used to retrieve the value of the server identification string if not default.
*/
String SERVER_IDENTIFICATION = "server-identification";
+
/**
* Key used to retrieve the value in the configuration properties map
* of the maximum number of failed authentication requests before the
@@ -96,10 +100,16 @@ public interface ServerFactoryManager extends FactoryManager, KeyPairProviderHol
* Key used to configure the timeout used when receiving a close request
* on a channel to wait until the command cleanly exits after setting
* an EOF on the input stream. In milliseconds.
+ * @see #DEFAULT_COMMAND_EXIT_TIMEOUT
*/
String COMMAND_EXIT_TIMEOUT = "command-exit-timeout";
/**
+ * Default {@link #COMMAND_EXIT_TIMEOUT} if not set
+ */
+ long DEFAULT_COMMAND_EXIT_TIMEOUT = TimeUnit.SECONDS.toMillis(5L);
+
+ /**
* Key re-exchange will be automatically performed after the session
* has sent or received the given amount of bytes.
* The default value is 1 gigabyte.
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/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
index 8d1d152..55d5a5a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
@@ -32,8 +32,8 @@ 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.PropertyResolverUtils;
import org.apache.sshd.common.ServiceFactory;
import org.apache.sshd.common.io.IoAcceptor;
import org.apache.sshd.common.io.IoServiceFactory;
@@ -465,7 +465,7 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
SshServer sshd = SshServer.setUpDefaultServer();
Map<String, Object> props = sshd.getProperties();
- FactoryManagerUtils.updateProperty(props, ServerFactoryManager.WELCOME_BANNER, "Welcome to SSHD\n");
+ PropertyResolverUtils.updateProperty(sshd, ServerFactoryManager.WELCOME_BANNER, "Welcome to SSHD\n");
props.putAll(options);
sshd.setPort(port);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/DefaultKeyboardInteractiveAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/DefaultKeyboardInteractiveAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/DefaultKeyboardInteractiveAuthenticator.java
index 71283ff..0e3f971 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/DefaultKeyboardInteractiveAuthenticator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/DefaultKeyboardInteractiveAuthenticator.java
@@ -21,7 +21,7 @@ package org.apache.sshd.server.auth.keyboard;
import java.util.List;
-import org.apache.sshd.common.FactoryManagerUtils;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
@@ -96,22 +96,22 @@ public class DefaultKeyboardInteractiveAuthenticator
}
protected String getInteractionName(ServerSession session) {
- return FactoryManagerUtils.getStringProperty(session, KB_INTERACTIVE_NAME_PROP, DEFAULT_KB_INTERACTIVE_NAME);
+ return PropertyResolverUtils.getStringProperty(session, KB_INTERACTIVE_NAME_PROP, DEFAULT_KB_INTERACTIVE_NAME);
}
protected String getInteractionInstruction(ServerSession session) {
- return FactoryManagerUtils.getStringProperty(session, KB_INTERACTIVE_INSTRUCTION_PROP, DEFAULT_KB_INTERACTIVE_INSTRUCTION);
+ return PropertyResolverUtils.getStringProperty(session, KB_INTERACTIVE_INSTRUCTION_PROP, DEFAULT_KB_INTERACTIVE_INSTRUCTION);
}
protected String getInteractionLanguage(ServerSession session) {
- return FactoryManagerUtils.getStringProperty(session, KB_INTERACTIVE_LANG_PROP, DEFAULT_KB_INTERACTIVE_LANG);
+ return PropertyResolverUtils.getStringProperty(session, KB_INTERACTIVE_LANG_PROP, DEFAULT_KB_INTERACTIVE_LANG);
}
protected String getInteractionPrompt(ServerSession session) {
- return FactoryManagerUtils.getStringProperty(session, KB_INTERACTIVE_PROMPT_PROP, DEFAULT_KB_INTERACTIVE_PROMPT);
+ return PropertyResolverUtils.getStringProperty(session, KB_INTERACTIVE_PROMPT_PROP, DEFAULT_KB_INTERACTIVE_PROMPT);
}
protected boolean isInteractionPromptEchoEnabled(ServerSession session) {
- return FactoryManagerUtils.getBooleanProperty(session, KB_INTERACTIVE_ECHO_PROMPT_PROP, DEFAULT_KB_INTERACTIVE_ECHO_PROMPT);
+ return PropertyResolverUtils.getBooleanProperty(session, KB_INTERACTIVE_ECHO_PROMPT_PROP, DEFAULT_KB_INTERACTIVE_ECHO_PROMPT);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java
index 9aa5426..095d164 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java
@@ -96,6 +96,7 @@ public abstract class AbstractServerChannel extends AbstractChannel implements S
log.debug("Send SSH_MSG_CHANNEL_REQUEST exit-status on channel {}", Integer.valueOf(id));
}
+ Session session = getSession();
Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_CHANNEL_REQUEST, Long.SIZE);
buffer.putInt(recipient);
buffer.putString("exit-status");
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/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 98fe92d..31cd5c1 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
@@ -28,6 +28,7 @@ import java.util.Set;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.apache.sshd.agent.SshAgent;
@@ -35,8 +36,8 @@ import org.apache.sshd.agent.SshAgentFactory;
import org.apache.sshd.common.Closeable;
import org.apache.sshd.common.Factory;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.channel.AbstractChannelRequestHandler;
import org.apache.sshd.common.channel.Channel;
@@ -48,6 +49,7 @@ import org.apache.sshd.common.file.FileSystemFactory;
import org.apache.sshd.common.future.CloseFuture;
import org.apache.sshd.common.future.DefaultCloseFuture;
import org.apache.sshd.common.future.SshFutureListener;
+import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
@@ -76,8 +78,6 @@ import org.apache.sshd.server.x11.X11ForwardSupport;
*/
public class ChannelSession extends AbstractServerChannel {
- public static final long DEFAULT_COMMAND_EXIT_TIMEOUT = 5000;
-
protected static class StandardEnvironment implements Environment {
private final Map<Signal, Set<SignalListener>> listeners;
@@ -240,13 +240,17 @@ public class ChannelSession extends AbstractServerChannel {
}
};
- FactoryManager manager = getSession().getFactoryManager();
- long timeout = FactoryManagerUtils.getLongProperty(manager, ServerFactoryManager.COMMAND_EXIT_TIMEOUT, DEFAULT_COMMAND_EXIT_TIMEOUT);
+ ChannelSession channel = ChannelSession.this;
+ long timeout = PropertyResolverUtils.getLongProperty(
+ channel, ServerFactoryManager.COMMAND_EXIT_TIMEOUT, ServerFactoryManager.DEFAULT_COMMAND_EXIT_TIMEOUT);
if (log.isDebugEnabled()) {
- log.debug("Wait {} ms for shell to exit cleanly", Long.valueOf(timeout));
+ log.debug("Wait {} ms for shell to exit cleanly on {}", Long.valueOf(timeout), channel);
}
- manager.getScheduledExecutorService().schedule(task, timeout, TimeUnit.MILLISECONDS);
+ Session s = channel.getSession();
+ FactoryManager manager = ValidateUtils.checkNotNull(s.getFactoryManager(), "No factory manager");
+ ScheduledExecutorService scheduler = ValidateUtils.checkNotNull(manager.getScheduledExecutorService(), "No scheduling service");
+ scheduler.schedule(task, timeout, TimeUnit.MILLISECONDS);
commandExitFuture.addListener(new SshFutureListener<CloseFuture>() {
@Override
public void operationComplete(CloseFuture future) {
@@ -532,17 +536,18 @@ public class ChannelSession extends AbstractServerChannel {
protected void prepareCommand() throws IOException {
// Add the user
+ Session session = getSession();
addEnvVariable(Environment.ENV_USER, session.getUsername());
// If the shell wants to be aware of the session, let's do that
if (command instanceof SessionAware) {
- ((SessionAware) command).setSession((ServerSession) getSession());
+ ((SessionAware) command).setSession((ServerSession) session);
}
if (command instanceof ChannelSessionAware) {
((ChannelSessionAware) command).setChannelSession(this);
}
// If the shell wants to be aware of the file system, let's do that too
if (command instanceof FileSystemAware) {
- ServerFactoryManager manager = ((ServerSession) getSession()).getFactoryManager();
+ ServerFactoryManager manager = ((ServerSession) session).getFactoryManager();
FileSystemFactory factory = manager.getFileSystemFactory();
((FileSystemAware) command).setFileSystem(factory.createFileSystem(session));
}
@@ -571,7 +576,7 @@ public class ChannelSession extends AbstractServerChannel {
setDataReceiver(recv);
((AsyncCommand) command).setIoInputStream(recv.getIn());
} else {
- PipeDataReceiver recv = new PipeDataReceiver(localWindow);
+ PipeDataReceiver recv = new PipeDataReceiver(this, localWindow);
setDataReceiver(recv);
command.setInputStream(recv.getIn());
}
@@ -608,7 +613,9 @@ public class ChannelSession extends AbstractServerChannel {
}
protected boolean handleAgentForwarding(Buffer buffer) throws IOException {
+ Session session = getSession();
ValidateUtils.checkTrue(session instanceof ServerSession, "Session not a server one");
+
FactoryManager manager = session.getFactoryManager();
ForwardingFilter filter = manager.getTcpipForwardingFilter();
SshAgentFactory factory = manager.getAgentFactory();
@@ -625,7 +632,9 @@ public class ChannelSession extends AbstractServerChannel {
}
protected boolean handleX11Forwarding(Buffer buffer) throws IOException {
+ Session session = getSession();
ValidateUtils.checkTrue(session instanceof ServerSession, "Session not a server one");
+
FactoryManager manager = session.getFactoryManager();
ForwardingFilter filter = manager.getTcpipForwardingFilter();
if ((filter == null) || (!filter.canForwardX11(session))) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/server/channel/PipeDataReceiver.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/PipeDataReceiver.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/PipeDataReceiver.java
index deb1b25..0aa29a8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/PipeDataReceiver.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/PipeDataReceiver.java
@@ -22,6 +22,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import org.apache.sshd.common.PropertyResolver;
import org.apache.sshd.common.channel.ChannelPipedInputStream;
import org.apache.sshd.common.channel.ChannelPipedOutputStream;
import org.apache.sshd.common.channel.Window;
@@ -38,8 +39,8 @@ public class PipeDataReceiver extends AbstractLoggingBean implements ChannelData
private InputStream in;
private OutputStream out;
- public PipeDataReceiver(Window localWindow) {
- ChannelPipedInputStream in = new ChannelPipedInputStream(localWindow);
+ public PipeDataReceiver(PropertyResolver resolver, Window localWindow) {
+ ChannelPipedInputStream in = new ChannelPipedInputStream(resolver, localWindow);
this.in = in;
this.out = new ChannelPipedOutputStream(in);
if (log != null && log.isTraceEnabled()) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java b/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
index 29ba7f5..06b0211 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
@@ -301,6 +301,7 @@ public class TcpipServerChannel extends AbstractServerChannel {
try {
localWindow.consumeAndCheck(len);
} catch (IOException e) {
+ Session session = getSession();
session.exceptionCaught(e);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java b/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java
index 29b8e10..03ccda6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java
@@ -25,27 +25,31 @@ import org.apache.sshd.common.kex.dh.AbstractDHKeyExchange;
import org.apache.sshd.common.session.AbstractSession;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.server.session.ServerSession;
+import org.apache.sshd.server.session.ServerSessionHolder;
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public abstract class AbstractDHServerKeyExchange extends AbstractDHKeyExchange {
-
- protected ServerSession session;
+public abstract class AbstractDHServerKeyExchange extends AbstractDHKeyExchange implements ServerSessionHolder {
protected AbstractDHServerKeyExchange() {
super();
}
@Override
+ public ServerSession getServerSession() {
+ return (ServerSession) super.getSession();
+ }
+
+ @Override
public void init(AbstractSession s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
super.init(s, v_s, v_c, i_s, i_c);
ValidateUtils.checkTrue(s instanceof ServerSession, "Using a server side KeyExchange on a client");
- session = (ServerSession) s;
}
@Override
public PublicKey getServerKey() {
+ ServerSession session = getServerSession();
return ValidateUtils.checkNotNull(session.getHostKey(), "No server key pair available").getPublic();
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
index 49d8a93..87536a4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
@@ -27,9 +27,10 @@ import java.security.KeyPair;
import java.util.ArrayList;
import java.util.List;
+import org.apache.sshd.common.Factory;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.kex.DHFactory;
@@ -48,6 +49,7 @@ import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.BufferUtils;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
import org.apache.sshd.server.ServerFactoryManager;
+import org.apache.sshd.server.session.ServerSession;
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
@@ -97,8 +99,9 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
public boolean next(Buffer buffer) throws Exception {
int cmd = buffer.getUByte();
+ ServerSession session = getServerSession();
if (cmd == SshConstants.SSH_MSG_KEX_DH_GEX_REQUEST_OLD && expected == SshConstants.SSH_MSG_KEX_DH_GEX_REQUEST) {
- log.debug("Received SSH_MSG_KEX_DH_GEX_REQUEST_OLD");
+ log.debug("Received SSH_MSG_KEX_DH_GEX_REQUEST_OLD on {}", session);
oldRequest = true;
min = 1024;
prf = buffer.getInt();
@@ -113,7 +116,7 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
hash = dh.getHash();
hash.init();
- log.debug("Send SSH_MSG_KEX_DH_GEX_GROUP");
+ log.debug("Send SSH_MSG_KEX_DH_GEX_GROUP on {}", session);
buffer = session.prepareBuffer(SshConstants.SSH_MSG_KEX_DH_GEX_GROUP, BufferUtils.clear(buffer));
buffer.putMPInt(dh.getP());
buffer.putMPInt(dh.getG());
@@ -123,7 +126,7 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
return false;
}
if (cmd == SshConstants.SSH_MSG_KEX_DH_GEX_REQUEST && expected == SshConstants.SSH_MSG_KEX_DH_GEX_REQUEST) {
- log.debug("Received SSH_MSG_KEX_DH_GEX_REQUEST");
+ log.debug("Received SSH_MSG_KEX_DH_GEX_REQUEST on {}", session);
min = buffer.getInt();
prf = buffer.getInt();
max = buffer.getInt();
@@ -136,7 +139,7 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
hash = dh.getHash();
hash.init();
- log.debug("Send SSH_MSG_KEX_DH_GEX_GROUP");
+ log.debug("Send SSH_MSG_KEX_DH_GEX_GROUP on {}", session);
buffer = session.prepareBuffer(SshConstants.SSH_MSG_KEX_DH_GEX_GROUP, BufferUtils.clear(buffer));
buffer.putMPInt(dh.getP());
buffer.putMPInt(dh.getG());
@@ -151,7 +154,7 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
}
if (cmd == SshConstants.SSH_MSG_KEX_DH_GEX_INIT) {
- log.debug("Received SSH_MSG_KEX_DH_GEX_INIT");
+ log.debug("Received SSH_MSG_KEX_DH_GEX_INIT on {}", session);
e = buffer.getMPIntAsBytes();
dh.setF(e);
k = dh.getK();
@@ -199,14 +202,14 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
buffer.putBytes(sig.sign());
sigH = buffer.getCompactData();
- if (log.isDebugEnabled()) {
- log.debug("K_S: {}", BufferUtils.printHex(k_s));
- log.debug("f: {}", BufferUtils.printHex(f));
- log.debug("sigH: {}", BufferUtils.printHex(sigH));
+ if (log.isTraceEnabled()) {
+ log.trace("{}[K_S]: {}", session, BufferUtils.printHex(k_s));
+ log.trace("{}[f]: {}", session, BufferUtils.printHex(f));
+ log.trace("{}[sigH]: {}", session, BufferUtils.printHex(sigH));
}
// Send response
- log.debug("Send SSH_MSG_KEX_DH_GEX_REPLY");
+ log.debug("Send SSH_MSG_KEX_DH_GEX_REPLY on {}", session);
buffer.clear();
buffer.rpos(5);
buffer.wpos(5);
@@ -248,16 +251,22 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
log.warn("No suitable primes found, defaulting to DHG1");
return getDH(new BigInteger(DHGroupData.getP1()), new BigInteger(DHGroupData.getG()));
}
- Random random = session.getFactoryManager().getRandomFactory().create();
+
+ ServerSession session = getServerSession();
+ FactoryManager manager = ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
+ Factory<Random> factory = ValidateUtils.checkNotNull(manager.getRandomFactory(), "No random factory");
+ Random random = factory.create();
int which = random.random(selected.size());
Moduli.DhGroup group = selected.get(which);
return getDH(group.p, group.g);
}
protected List<Moduli.DhGroup> loadModuliGroups() throws IOException {
+ ServerSession session = getServerSession();
+ String moduliStr = PropertyResolverUtils.getString(session, ServerFactoryManager.MODULI_URL);
+
List<Moduli.DhGroup> groups = null;
URL moduli;
- String moduliStr = FactoryManagerUtils.getString(session, ServerFactoryManager.MODULI_URL);
if (!GenericUtils.isEmpty(moduliStr)) {
try {
moduli = new URL(moduliStr);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a9d975b6/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
index 29a807d..eaa8abb 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
@@ -35,6 +35,7 @@ import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.BufferUtils;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.apache.sshd.server.session.ServerSession;
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
@@ -85,12 +86,12 @@ public class DHGServer extends AbstractDHServerKeyExchange {
throw new SshException(SshConstants.SSH2_DISCONNECT_KEY_EXCHANGE_FAILED,
"Protocol error: expected packet " + SshConstants.SSH_MSG_KEXDH_INIT + ", got " + cmd);
}
- log.debug("Received SSH_MSG_KEXDH_INIT");
+ ServerSession session = getServerSession();
+ log.debug("Received SSH_MSG_KEXDH_INIT on {}", session);
e = buffer.getMPIntAsBytes();
dh.setF(e);
k = dh.getK();
- byte[] k_s;
KeyPair kp = ValidateUtils.checkNotNull(session.getHostKey(), "No server key pair available");
String algo = session.getNegotiatedKexParameter(KexProposalOption.SERVERKEYS);
FactoryManager manager = session.getFactoryManager();
@@ -102,7 +103,7 @@ public class DHGServer extends AbstractDHServerKeyExchange {
buffer = new ByteArrayBuffer();
buffer.putRawPublicKey(kp.getPublic());
- k_s = buffer.getCompactData();
+ byte[] k_s = buffer.getCompactData();
buffer.clear();
buffer.putBytes(v_c);
@@ -123,14 +124,14 @@ public class DHGServer extends AbstractDHServerKeyExchange {
buffer.putBytes(sig.sign());
sigH = buffer.getCompactData();
- if (log.isDebugEnabled()) {
- log.debug("K_S: {}", BufferUtils.printHex(k_s));
- log.debug("f: {}", BufferUtils.printHex(f));
- log.debug("sigH: {}", BufferUtils.printHex(sigH));
+ if (log.isTraceEnabled()) {
+ log.trace("{}[K_S]: {}", session, BufferUtils.printHex(k_s));
+ log.trace("{}[f]: {}", session, BufferUtils.printHex(f));
+ log.trace("{}[sigH]: {}", session, BufferUtils.printHex(sigH));
}
// Send response
- log.debug("Send SSH_MSG_KEXDH_REPLY");
+ log.debug("Send SSH_MSG_KEXDH_REPLY on {}", session);
buffer.clear();
buffer.rpos(5);
buffer.wpos(5);