http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/forward/StaticDecisionForwardingFilter.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/forward/StaticDecisionForwardingFilter.java b/sshd-core/src/main/java/org/apache/sshd/server/forward/StaticDecisionForwardingFilter.java index 67b77ce..db7cba9 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/forward/StaticDecisionForwardingFilter.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/forward/StaticDecisionForwardingFilter.java @@ -35,7 +35,7 @@ public class StaticDecisionForwardingFilter extends AbstractLoggingBean implemen public StaticDecisionForwardingFilter(boolean acceptance) { this.acceptance = acceptance; } - + public final boolean isAccepted() { return acceptance; } @@ -59,12 +59,12 @@ public class StaticDecisionForwardingFilter extends AbstractLoggingBean implemen 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 + * @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) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/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 2afc135..2ac4180 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 @@ -60,7 +60,7 @@ public class TcpipServerChannel extends AbstractServerChannel { protected TcpipFactory(ForwardingFilter.Type type) { this.type = type; } - + public final ForwardingFilter.Type getType() { return type; } @@ -82,7 +82,7 @@ public class TcpipServerChannel extends AbstractServerChannel { @Override public Channel create() { - TcpipServerChannel channel = new TcpipServerChannel(getType()); + TcpipServerChannel channel = new TcpipServerChannel(getType()); channel.setExecutorService(getExecutorService()); channel.setShutdownOnExit(isShutdownOnExit()); return channel; @@ -112,7 +112,7 @@ public class TcpipServerChannel extends AbstractServerChannel { int originatorPort = buffer.getInt(); if (log.isDebugEnabled()) { log.debug("Receiving request for direct tcpip: hostToConnect={}, portToConnect={}, originatorIpAddress={}, originatorPort={}", - hostToConnect, portToConnect, originatorIpAddress, originatorPort); + hostToConnect, portToConnect, originatorIpAddress, originatorPort); } final SshdSocketAddress address; @@ -156,16 +156,19 @@ public class TcpipServerChannel extends AbstractServerChannel { out.flush(); } } + @Override public void sessionCreated(IoSession session) throws Exception { // ignored } + @Override public void sessionClosed(IoSession session) throws Exception { close(false); } + @Override - public void exceptionCaught(IoSession ioSession, Throwable cause) throws Exception { + public void exceptionCaught(IoSession session, Throwable cause) throws Exception { close(true); } }; @@ -182,9 +185,9 @@ public class TcpipServerChannel extends AbstractServerChannel { closeImmediately0(); if (future.getException() instanceof ConnectException) { f.setException(new OpenChannelException( - SshConstants.SSH_OPEN_CONNECT_FAILED, - future.getException().getMessage(), - future.getException())); + SshConstants.SSH_OPEN_CONNECT_FAILED, + future.getException().getMessage(), + future.getException())); } else { f.setException(future.getException()); } @@ -211,27 +214,26 @@ public class TcpipServerChannel extends AbstractServerChannel { ExecutorService service = getExecutorService(); // allocate a temporary executor service if none provided final ExecutorService executors = (service == null) - ? ThreadUtils.newSingleThreadExecutor("TcpIpServerChannel-ConnectorCleanup[" + getSession() + "]") - : service - ; + ? ThreadUtils.newSingleThreadExecutor("TcpIpServerChannel-ConnectorCleanup[" + getSession() + "]") + : service; // shutdown the temporary executor service if had to create it final boolean shutdown = (executors == service) ? isShutdownOnExit() : true; executors.submit(new Runnable() { - @SuppressWarnings("synthetic-access") - @Override - public void run() { - try { - connector.close(true); - } finally { - if ((executors != null) && (!executors.isShutdown()) && shutdown) { - Collection<Runnable> runners = executors.shutdownNow(); - if (log.isDebugEnabled()) { - log.debug("destroy() - shutdown executor service - runners count=" + runners.size()); - } + @SuppressWarnings("synthetic-access") + @Override + public void run() { + try { + connector.close(true); + } finally { + if ((executors != null) && (!executors.isShutdown()) && shutdown) { + Collection<Runnable> runners = executors.shutdownNow(); + if (log.isDebugEnabled()) { + log.debug("destroy() - shutdown executor service - runners count=" + runners.size()); } } } - }); + } + }); } @Override http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java index 557af0a..b68d54b 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java @@ -50,8 +50,8 @@ public class CancelTcpipForwardHandler extends AbstractLoggingBean implements Co if (log.isDebugEnabled()) { log.debug("process(" + connectionService + ")[" + request + "] " + socketAddress + " reply=" + wantReply); } - - TcpipForwarder forwarder = connectionService.getTcpipForwarder(); + + TcpipForwarder forwarder = connectionService.getTcpipForwarder(); forwarder.localPortForwardingCancelled(socketAddress); if (wantReply) { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java index 3f5dc4d..4b0f0c4 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java @@ -54,7 +54,7 @@ public class TcpipForwardHandler extends AbstractLoggingBean implements Connecti } port = bound.getPort(); - if (wantReply){ + if (wantReply) { buffer.clear(); // leave room for the SSH header buffer.ensureCapacity(5 + 1 + (Integer.SIZE / Byte.SIZE), Int2IntFunction.Utils.add(Byte.SIZE)); http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticator.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticator.java index b3a21ff..82100c8 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticator.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticator.java @@ -19,7 +19,6 @@ package org.apache.sshd.server.jaas; import java.io.IOException; - import javax.security.auth.Subject; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; @@ -44,7 +43,7 @@ public class JaasPasswordAuthenticator extends AbstractLoggingBean implements Pa public JaasPasswordAuthenticator() { this(null); } - + public JaasPasswordAuthenticator(String domain) { this.domain = domain; } @@ -59,9 +58,9 @@ public class JaasPasswordAuthenticator extends AbstractLoggingBean implements Pa @Override public boolean authenticate(String username, String password, ServerSession session) { - return authenticate(username, password); + return authenticate(username, password); } - + public boolean authenticate(final String username, final String password) { try { Subject subject = new Subject(); http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/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 52324ca..d7a68f1 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 @@ -23,7 +23,6 @@ import java.security.PublicKey; import org.apache.sshd.common.kex.dh.AbstractDHKeyExchange; import org.apache.sshd.common.session.AbstractSession; -import org.apache.sshd.common.util.GenericUtils; import org.apache.sshd.common.util.ValidateUtils; import org.apache.sshd.server.session.ServerSession; @@ -39,8 +38,8 @@ public abstract class AbstractDHServerKeyExchange extends AbstractDHKeyExchange } @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); + 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; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/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 732b22d..4a88148 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 @@ -62,6 +62,10 @@ public class DHGEXServer extends AbstractDHServerKeyExchange { protected byte expected; protected boolean oldRequest; + protected DHGEXServer(DHFactory factory) { + this.factory = ValidateUtils.checkNotNull(factory, "No factory"); + } + public static KeyExchangeFactory newFactory(final DHFactory factory) { return new KeyExchangeFactory() { @Override @@ -83,13 +87,9 @@ public class DHGEXServer extends AbstractDHServerKeyExchange { }; } - protected DHGEXServer(DHFactory factory) { - this.factory = ValidateUtils.checkNotNull(factory, "No factory"); - } - @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); + 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); expected = SshConstants.SSH_MSG_KEX_DH_GEX_REQUEST; } @@ -154,10 +154,10 @@ public class DHGEXServer extends AbstractDHServerKeyExchange { log.debug("Received SSH_MSG_KEX_DH_GEX_INIT"); e = buffer.getMPIntAsBytes(); dh.setF(e); - K = dh.getK(); + k = dh.getK(); - byte[] K_S; + byte[] k_s; KeyPair kp = ValidateUtils.checkNotNull(session.getHostKey(), "No server key pair available"); String algo = session.getNegotiatedKexParameter(KexProposalOption.SERVERKEYS); FactoryManager manager = session.getFactoryManager(); @@ -169,14 +169,14 @@ public class DHGEXServer extends AbstractDHServerKeyExchange { buffer = new ByteArrayBuffer(); buffer.putRawPublicKey(kp.getPublic()); - K_S = buffer.getCompactData(); + k_s = buffer.getCompactData(); buffer.clear(); - buffer.putBytes(V_C); - buffer.putBytes(V_S); - buffer.putBytes(I_C); - buffer.putBytes(I_S); - buffer.putBytes(K_S); + buffer.putBytes(v_c); + buffer.putBytes(v_s); + buffer.putBytes(i_c); + buffer.putBytes(i_s); + buffer.putBytes(k_s); if (oldRequest) { buffer.putInt(prf); } else { @@ -188,19 +188,19 @@ public class DHGEXServer extends AbstractDHServerKeyExchange { buffer.putMPInt(dh.getG()); buffer.putMPInt(e); buffer.putMPInt(f); - buffer.putMPInt(K); + buffer.putMPInt(k); hash.update(buffer.array(), 0, buffer.available()); - H = hash.digest(); + h = hash.digest(); byte[] sigH; buffer.clear(); - sig.update(H, 0, H.length); + sig.update(h, 0, h.length); buffer.putString(algo); buffer.putBytes(sig.sign()); sigH = buffer.getCompactData(); if (log.isDebugEnabled()) { - log.debug("K_S: {}", BufferUtils.printHex(K_S)); + log.debug("K_S: {}", BufferUtils.printHex(k_s)); log.debug("f: {}", BufferUtils.printHex(f)); log.debug("sigH: {}", BufferUtils.printHex(sigH)); } @@ -211,7 +211,7 @@ public class DHGEXServer extends AbstractDHServerKeyExchange { buffer.rpos(5); buffer.wpos(5); buffer.putByte(SshConstants.SSH_MSG_KEX_DH_GEX_REPLY); - buffer.putBytes(K_S); + buffer.putBytes(k_s); buffer.putBytes(f); buffer.putBytes(sigH); session.writePacket(buffer); @@ -270,7 +270,8 @@ public class DHGEXServer extends AbstractDHServerKeyExchange { if (groups == null) { moduliStr = "/org/apache/sshd/moduli"; try { - if ((moduli = getClass().getResource(moduliStr)) == null) { + moduli = getClass().getResource(moduliStr); + if (moduli == null) { throw new FileNotFoundException("Missing internal moduli file"); } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/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 1c433f1..a625a44 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 @@ -31,7 +31,6 @@ import org.apache.sshd.common.kex.KeyExchange; import org.apache.sshd.common.kex.KeyExchangeFactory; import org.apache.sshd.common.session.AbstractSession; import org.apache.sshd.common.signature.Signature; -import org.apache.sshd.common.util.GenericUtils; import org.apache.sshd.common.util.ValidateUtils; import org.apache.sshd.common.util.buffer.Buffer; import org.apache.sshd.common.util.buffer.BufferUtils; @@ -45,6 +44,10 @@ public class DHGServer extends AbstractDHServerKeyExchange { protected final DHFactory factory; protected AbstractDH dh; + protected DHGServer(DHFactory factory) { + this.factory = ValidateUtils.checkNotNull(factory, "No factory"); + } + public static KeyExchangeFactory newFactory(final DHFactory factory) { return new KeyExchangeFactory() { @Override @@ -66,13 +69,9 @@ public class DHGServer extends AbstractDHServerKeyExchange { }; } - protected DHGServer(DHFactory factory) { - this.factory = ValidateUtils.checkNotNull(factory, "No factory"); - } - @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); + 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); dh = factory.create(); hash = dh.getHash(); hash.init(); @@ -83,15 +82,15 @@ public class DHGServer extends AbstractDHServerKeyExchange { public boolean next(Buffer buffer) throws Exception { int cmd = buffer.getUByte(); if (cmd != SshConstants.SSH_MSG_KEXDH_INIT) { - throw new SshException(SshConstants.SSH2_DISCONNECT_KEY_EXCHANGE_FAILED, - "Protocol error: expected packet " + SshConstants.SSH_MSG_KEXDH_INIT + ", got " + cmd); + 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"); e = buffer.getMPIntAsBytes(); dh.setF(e); - K = dh.getK(); + k = dh.getK(); - byte[] K_S; + byte[] k_s; KeyPair kp = ValidateUtils.checkNotNull(session.getHostKey(), "No server key pair available"); String algo = session.getNegotiatedKexParameter(KexProposalOption.SERVERKEYS); FactoryManager manager = session.getFactoryManager(); @@ -103,29 +102,29 @@ public class DHGServer extends AbstractDHServerKeyExchange { buffer = new ByteArrayBuffer(); buffer.putRawPublicKey(kp.getPublic()); - K_S = buffer.getCompactData(); + k_s = buffer.getCompactData(); buffer.clear(); - buffer.putBytes(V_C); - buffer.putBytes(V_S); - buffer.putBytes(I_C); - buffer.putBytes(I_S); - buffer.putBytes(K_S); + buffer.putBytes(v_c); + buffer.putBytes(v_s); + buffer.putBytes(i_c); + buffer.putBytes(i_s); + buffer.putBytes(k_s); buffer.putMPInt(e); buffer.putMPInt(f); - buffer.putMPInt(K); + buffer.putMPInt(k); hash.update(buffer.array(), 0, buffer.available()); - H = hash.digest(); + h = hash.digest(); byte[] sigH; buffer.clear(); - sig.update(H, 0, H.length); + sig.update(h, 0, h.length); buffer.putString(algo); buffer.putBytes(sig.sign()); sigH = buffer.getCompactData(); if (log.isDebugEnabled()) { - log.debug("K_S: {}", BufferUtils.printHex(K_S)); + log.debug("K_S: {}", BufferUtils.printHex(k_s)); log.debug("f: {}", BufferUtils.printHex(f)); log.debug("sigH: {}", BufferUtils.printHex(sigH)); } @@ -136,7 +135,7 @@ public class DHGServer extends AbstractDHServerKeyExchange { buffer.rpos(5); buffer.wpos(5); buffer.putByte(SshConstants.SSH_MSG_KEXDH_REPLY); - buffer.putBytes(K_S); + buffer.putBytes(k_s); buffer.putBytes(f); buffer.putBytes(sigH); session.writePacket(buffer); http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/kex/Moduli.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/kex/Moduli.java b/sshd-core/src/main/java/org/apache/sshd/server/kex/Moduli.java index c9e59da..d3fd7d8 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/kex/Moduli.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/kex/Moduli.java @@ -31,7 +31,7 @@ import java.util.List; * * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ -public class Moduli { +public final class Moduli { public static final int MODULI_TYPE_SAFE = 2; public static final int MODULI_TESTS_COMPOSITE = 0x01; @@ -42,6 +42,10 @@ public class Moduli { BigInteger p; } + // Private constructor + private Moduli() { + } + public static List<DhGroup> parseModuli(URL url) throws IOException { List<DhGroup> groups = new ArrayList<DhGroup>(); try (BufferedReader r = new BufferedReader(new InputStreamReader(url.openStream()))) { @@ -81,8 +85,4 @@ public class Moduli { } } - // Private constructor - private Moduli() { - } - } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java b/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java index 87bc88b..e86e174 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java @@ -41,6 +41,7 @@ import org.apache.sshd.common.util.io.IoUtils; * {@link #loadKeys()} is called. If there is a file backing it up and the * file exists, the key is loaded from it. Otherwise a new key pair is * generated and saved (provided a path is configured and {@link #isOverwriteAllowed()} + * * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ public abstract class AbstractGeneratorHostKeyProvider extends AbstractKeyPairProvider { @@ -108,14 +109,14 @@ public abstract class AbstractGeneratorHostKeyProvider extends AbstractKeyPairPr if (keyPair == null) { if (keyPath != null) { - LinkOption[] options = IoUtils.getLinkOptions(false); + LinkOption[] options = IoUtils.getLinkOptions(false); if (Files.exists(keyPath, options) && Files.isRegularFile(keyPath, options)) { try { keyPair = readKeyPair(keyPath, IoUtils.EMPTY_OPEN_OPTIONS); - } catch(Exception e) { + } catch (Exception e) { log.warn("Failed (" + e.getClass().getSimpleName() + ")" - + " to load from " + keyPath - + ": " + e.getMessage(), + + " to load from " + keyPath + + ": " + e.getMessage(), e); } } @@ -126,19 +127,19 @@ public abstract class AbstractGeneratorHostKeyProvider extends AbstractKeyPairPr String alg = getAlgorithm(); try { keyPair = generateKeyPair(alg); - } catch(Exception e) { + } catch (Exception e) { log.warn("Failed (" + e.getClass().getSimpleName() + ")" - + " to generate " + alg + " keys: " + e.getMessage(), - e); + + " to generate " + alg + " keys: " + e.getMessage(), + e); } if ((keyPair != null) && (keyPath != null)) { try { writeKeyPair(keyPair, keyPath); - } catch(Exception e) { + } catch (Exception e) { log.warn("Failed (" + e.getClass().getSimpleName() + ")" - + " to write to " + keyPath - + ": " + e.getMessage(), + + " to write to " + keyPath + + ": " + e.getMessage(), e); } } @@ -151,16 +152,17 @@ public abstract class AbstractGeneratorHostKeyProvider extends AbstractKeyPairPr } } - protected KeyPair readKeyPair(Path keyPath, OpenOption ... options) throws IOException, GeneralSecurityException { - try(InputStream inputStream = Files.newInputStream(keyPath, options)) { + protected KeyPair readKeyPair(Path keyPath, OpenOption... options) throws IOException, GeneralSecurityException { + try (InputStream inputStream = Files.newInputStream(keyPath, options)) { return doReadKeyPair(keyPath.toString(), inputStream); } } + protected abstract KeyPair doReadKeyPair(String resourceKey, InputStream inputStream) throws IOException, GeneralSecurityException; - protected void writeKeyPair(KeyPair kp, Path keyPath, OpenOption ... options) throws IOException, GeneralSecurityException { + protected void writeKeyPair(KeyPair kp, Path keyPath, OpenOption... options) throws IOException, GeneralSecurityException { if ((!Files.exists(keyPath)) || isOverwriteAllowed()) { - try(OutputStream os = Files.newOutputStream(keyPath, options)) { + try (OutputStream os = Files.newOutputStream(keyPath, options)) { doWriteKeyPair(keyPath.toString(), kp, os); } catch (Exception e) { log.warn("Unable to write key {}: {}", path, e); @@ -169,6 +171,7 @@ public abstract class AbstractGeneratorHostKeyProvider extends AbstractKeyPairPr log.error("Overwriting key ({}) is disabled: using throwaway {}", keyPath, kp); } } + protected abstract void doWriteKeyPair(String resourceKey, KeyPair kp, OutputStream outputStream) throws IOException, GeneralSecurityException; http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/SimpleGeneratorHostKeyProvider.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/SimpleGeneratorHostKeyProvider.java b/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/SimpleGeneratorHostKeyProvider.java index fff76a8..ca811ae 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/SimpleGeneratorHostKeyProvider.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/SimpleGeneratorHostKeyProvider.java @@ -49,7 +49,7 @@ public class SimpleGeneratorHostKeyProvider extends AbstractGeneratorHostKeyProv @Override protected KeyPair doReadKeyPair(String resourceKey, InputStream inputStream) throws IOException, GeneralSecurityException { - try(ObjectInputStream r = new ObjectInputStream(inputStream)) { + try (ObjectInputStream r = new ObjectInputStream(inputStream)) { try { return (KeyPair) r.readObject(); } catch (ClassNotFoundException e) { @@ -60,7 +60,7 @@ public class SimpleGeneratorHostKeyProvider extends AbstractGeneratorHostKeyProv @Override protected void doWriteKeyPair(String resourceKey, KeyPair kp, OutputStream outputStream) throws IOException, GeneralSecurityException { - try(ObjectOutputStream w = new ObjectOutputStream(outputStream)) { + try (ObjectOutputStream w = new ObjectOutputStream(outputStream)) { w.writeObject(kp); } } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java index ddb15a7..692ffc5 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java @@ -23,7 +23,6 @@ import java.io.IOException; import org.apache.sshd.common.SshException; import org.apache.sshd.common.session.AbstractConnectionService; import org.apache.sshd.common.session.Session; -import org.apache.sshd.common.util.GenericUtils; import org.apache.sshd.common.util.ValidateUtils; /** @@ -35,7 +34,7 @@ public class ServerConnectionService extends AbstractConnectionService { protected ServerConnectionService(Session s) throws SshException { super(s); - + ValidateUtils.checkTrue(s instanceof ServerSession, "Server side service used on client side"); if (!session.isAuthenticated()) { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java index 4e07afc..02f627d 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java @@ -31,8 +31,9 @@ public interface ServerSession extends Session { /** * @return The {@link ServerFactoryManager} for this session */ - @Override ServerFactoryManager getFactoryManager(); - + @Override + ServerFactoryManager getFactoryManager(); + /** * @return The {@link KeyPair} representing the current session's used keys * on KEX @@ -41,6 +42,7 @@ public interface ServerSession extends Session { /** * Retrieve the current number of sessions active for a given username. + * * @param userName The name of the user - ignored if {@code null}/empty * @return The current number of live <code>SshSession</code> objects associated with the user */ http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionImpl.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionImpl.java b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionImpl.java index e46f4b2..1b0d501 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionImpl.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionImpl.java @@ -46,13 +46,12 @@ import org.apache.sshd.common.util.buffer.ByteArrayBuffer; import org.apache.sshd.server.ServerFactoryManager; /** - * * TODO Add javadoc * * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ public class ServerSessionImpl extends AbstractSession implements ServerSession { - protected static final long MAX_PACKETS = (1l << 31); + protected static final long MAX_PACKETS = 1L << 31; private long maxBytes = 1024 * 1024 * 1024; // 1 GB private long maxKeyInterval = 60 * 60 * 1000; // 1 hour @@ -91,11 +90,10 @@ public class ServerSessionImpl extends AbstractSession implements ServerSession if (KexState.DONE.equals(kexState.get())) { long now = System.currentTimeMillis(); if ((inPacketsCount.get() > MAX_PACKETS) - || (outPacketsCount.get() > MAX_PACKETS) - || (inBytesCount.get() > maxBytes) - || (outBytesCount.get() > maxBytes) - || ((maxKeyInterval > 0L) && ((now - lastKeyTimeValue.get()) > maxKeyInterval))) - { + || (outPacketsCount.get() > MAX_PACKETS) + || (inBytesCount.get() > maxBytes) + || (outBytesCount.get() > maxBytes) + || ((maxKeyInterval > 0L) && ((now - lastKeyTimeValue.get()) > maxKeyInterval))) { reExchangeKeys(); } } @@ -113,14 +111,14 @@ public class ServerSessionImpl extends AbstractSession implements ServerSession } @Override - protected byte[] sendKexInit(Map<KexProposalOption,String> proposal) throws IOException { + protected byte[] sendKexInit(Map<KexProposalOption, String> proposal) throws IOException { mergeProposals(serverProposal, proposal); return super.sendKexInit(proposal); } @Override protected void setKexSeed(byte... seed) { - I_S = ValidateUtils.checkNotNullAndNotEmpty(seed, "No KEX seed"); + i_s = ValidateUtils.checkNotNullAndNotEmpty(seed, "No KEX seed"); } @Override @@ -166,8 +164,9 @@ public class ServerSessionImpl extends AbstractSession implements ServerSession * Called by {@link #resolveAvailableSignaturesProposal(FactoryManager)} * if none of the provided keys is supported - last chance for the derived * implementation to do something + * * @param supported The supported key types - may be {@code null}/empty - * @param provided The available signature types - may be {@code null}/empty + * @param provided The available signature types - may be {@code null}/empty * @return The resolved proposal - {@code null} by default */ protected String resolveEmptySignaturesProposal(Iterable<String> supported, Iterable<String> provided) { @@ -201,9 +200,9 @@ public class ServerSessionImpl extends AbstractSession implements ServerSession } @Override - protected void receiveKexInit(Map<KexProposalOption,String> proposal, byte[] seed) throws IOException { + protected void receiveKexInit(Map<KexProposalOption, String> proposal, byte[] seed) throws IOException { mergeProposals(clientProposal, proposal); - I_C = seed; + i_c = seed; } @Override @@ -220,7 +219,7 @@ public class ServerSessionImpl extends AbstractSession implements ServerSession } IoService service = ioSession.getService(); - Map<?,IoSession> sessionsMap = service.getManagedSessions(); + Map<?, IoSession> sessionsMap = service.getManagedSessions(); if (GenericUtils.isEmpty(sessionsMap)) { return 0; } @@ -231,7 +230,7 @@ public class ServerSessionImpl extends AbstractSession implements ServerSession if (session == null) { continue; } - + String sessionUser = session.getUsername(); if ((!GenericUtils.isEmpty(sessionUser)) && Objects.equals(sessionUser, userName)) { totalCount++; @@ -241,12 +240,12 @@ public class ServerSessionImpl extends AbstractSession implements ServerSession return totalCount; } - /** - * Returns the session id. - * - * @return The session id. - */ - public long getId() { - return ioSession.getId(); - } + /** + * Returns the session id. + * + * @return The session id. + */ + public long getId() { + return ioSession.getId(); + } } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/session/ServerUserAuthService.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerUserAuthService.java b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerUserAuthService.java index 50b2eb6..09eceab 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerUserAuthService.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerUserAuthService.java @@ -64,11 +64,11 @@ public class ServerUserAuthService extends CloseableUtils.AbstractCloseable impl this.session = (ServerSession) s; maxAuthRequests = session.getIntProperty(ServerFactoryManager.MAX_AUTH_REQUESTS, DEFAULT_MAX_AUTH_REQUESTS); - ServerFactoryManager manager=getFactoryManager(); + ServerFactoryManager manager = getFactoryManager(); userAuthFactories = new ArrayList<>(manager.getUserAuthFactories()); // Get authentication methods authMethods = new ArrayList<>(); - + String mths = FactoryManagerUtils.getString(manager, ServerFactoryManager.AUTH_METHODS); if (GenericUtils.isEmpty(mths)) { for (NamedFactory<UserAuth> uaf : manager.getUserAuthFactories()) { @@ -88,7 +88,7 @@ public class ServerUserAuthService extends CloseableUtils.AbstractCloseable impl } } } - + if (log.isDebugEnabled()) { log.debug("Authorized authentication methods: {}", NamedResource.Utils.getNames(userAuthFactories)); } @@ -148,7 +148,7 @@ public class ServerUserAuthService extends CloseableUtils.AbstractCloseable impl log.debug("Authentication failed: {}", e.getMessage()); } } - } else { + } else { if (this.currentAuth == null) { // This should not happen throw new IllegalStateException("No current authentication mechanism for cmd=" + (cmd & 0xFF)); http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java index cf533b9..c9e6880 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/session/SessionFactory.java @@ -27,9 +27,8 @@ import org.apache.sshd.server.ServerFactoryManager; * A factory of server sessions. * This class can be used as a way to customize the creation of server sessions. * - * @see org.apache.sshd.server.SshServer#setSessionFactory(SessionFactory) - * * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + * @see org.apache.sshd.server.SshServer#setSessionFactory(SessionFactory) */ public class SessionFactory extends AbstractSessionFactory { @@ -38,7 +37,7 @@ public class SessionFactory extends AbstractSessionFactory { public SessionFactory() { super(); } - + public SessionFactory(ServerFactoryManager manager) { this.manager = manager; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/shell/InteractiveProcessShellFactory.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/InteractiveProcessShellFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/InteractiveProcessShellFactory.java index 98d7e40..054660f 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/shell/InteractiveProcessShellFactory.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/InteractiveProcessShellFactory.java @@ -23,12 +23,25 @@ import org.apache.sshd.common.util.OsUtils; /** * A simplistic interactive shell factory + * * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ public class InteractiveProcessShellFactory extends ProcessShellFactory { - // must come first due to class loading issues - private static final String[] LINUX_COMMAND = { "/bin/sh", "-i", "-l" }; - private static final String[] WINDOWS_COMMAND = { "cmd.exe" }; + + public static final InteractiveProcessShellFactory INSTANCE; + + private static final String[] LINUX_COMMAND; + private static final String[] WINDOWS_COMMAND; + + static { + LINUX_COMMAND = new String[] {"/bin/sh", "-i", "-l"}; + WINDOWS_COMMAND = new String[] {"cmd.exe"}; + INSTANCE = new InteractiveProcessShellFactory(); + } + + public InteractiveProcessShellFactory() { + super(resolveDefaultInteractiveCommand(), TtyOptions.resolveDefaultTtyOptions()); + } public static String[] resolveDefaultInteractiveCommand() { return resolveInteractiveCommand(OsUtils.isWin32()); @@ -43,9 +56,4 @@ public class InteractiveProcessShellFactory extends ProcessShellFactory { } } - public static final InteractiveProcessShellFactory INSTANCE = new InteractiveProcessShellFactory(); - - public InteractiveProcessShellFactory() { - super(resolveDefaultInteractiveCommand(), TtyOptions.resolveDefaultTtyOptions()); - } } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java index 30ab6b0..26b4a11 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShell.java @@ -40,7 +40,7 @@ public interface InvertedShell { * @param env * @throws IOException */ - void start(Map<String,String> env) throws IOException; + void start(Map<String, String> env) throws IOException; /** * Returns the output stream used to feed the shell. @@ -52,18 +52,21 @@ public interface InvertedShell { /** * Return an InputStream representing the output stream of the shell. + * * @return */ InputStream getOutputStream(); /** * Return an InputStream representing the error stream of the shell. + * * @return */ InputStream getErrorStream(); /** * Check if the underlying shell is still alive + * * @return */ boolean isAlive(); http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java index 849afd1..d678f95 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java @@ -36,13 +36,15 @@ import org.apache.sshd.server.session.ServerSession; * as a {@link Command}. This is useful when using external * processes. * When starting the shell, this wrapper will also create a thread used - * to pump the streams and also to check if the shell is alive. + * to pump the streams and also to check if the shell is alive. * * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ public class InvertedShellWrapper implements Command, SessionAware { - /** default buffer size for the IO pumps. */ + /** + * default buffer size for the IO pumps. + */ public static final int DEFAULT_BUFFER_SIZE = 8192; private final InvertedShell shell; @@ -67,9 +69,9 @@ public class InvertedShellWrapper implements Command, SessionAware { public InvertedShellWrapper(InvertedShell shell, int bufferSize) { this(shell, - ThreadUtils.newSingleThreadExecutor("shell[" + Integer.toHexString(shell.hashCode()) + "]"), - true, - bufferSize); + ThreadUtils.newSingleThreadExecutor("shell[" + Integer.toHexString(shell.hashCode()) + "]"), + true, + bufferSize); } public InvertedShellWrapper(InvertedShell shell, Executor executor, int bufferSize) { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java index be54fea..ab8a2c6 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShellFactory.java @@ -45,16 +45,16 @@ import org.apache.sshd.server.Command; */ public class ProcessShellFactory extends AbstractLoggingBean implements Factory<Command> { - public static enum TtyOptions { + public enum TtyOptions { Echo, INlCr, ICrNl, ONlCr, OCrNl; - - + public static final Set<TtyOptions> LINUX_OPTIONS = Collections.unmodifiableSet(EnumSet.of(TtyOptions.ONlCr)); + public static final Set<TtyOptions> WINDOWS_OPTIONS = Collections.unmodifiableSet(EnumSet.of(TtyOptions.Echo, TtyOptions.ICrNl, TtyOptions.ONlCr)); @@ -113,7 +113,7 @@ public class ProcessShellFactory extends AbstractLoggingBean implements Factory< @SuppressWarnings("synthetic-access") @Override - public void start(Map<String,String> env) throws IOException { + public void start(Map<String, String> env) throws IOException { String[] cmds = new String[command.length]; for (int i = 0; i < cmds.length; i++) { if ("$USER".equals(command[i])) { @@ -125,7 +125,7 @@ public class ProcessShellFactory extends AbstractLoggingBean implements Factory< ProcessBuilder builder = new ProcessBuilder(cmds); if (GenericUtils.size(env) > 0) { try { - Map<String,String> procEnv = builder.environment(); + Map<String, String> procEnv = builder.environment(); procEnv.putAll(env); } catch (Exception e) { log.warn("Could not set environment for command=" + GenericUtils.join(cmds, ' '), e); @@ -187,20 +187,25 @@ public class ProcessShellFactory extends AbstractLoggingBean implements Factory< protected class TtyFilterInputStream extends FilterInputStream { private Buffer buffer; private int lastChar; + public TtyFilterInputStream(InputStream in) { super(in); buffer = new ByteArrayBuffer(32); } + synchronized void write(int c) { buffer.putByte((byte) c); } + synchronized void write(byte[] buf, int off, int len) { buffer.putBytes(buf, off, len); } + @Override public int available() throws IOException { return super.available() + buffer.available(); } + @SuppressWarnings("synthetic-access") @Override public synchronized int read() throws IOException { @@ -223,6 +228,7 @@ public class ProcessShellFactory extends AbstractLoggingBean implements Factory< lastChar = c; return c; } + @Override public synchronized int read(byte[] b, int off, int len) throws IOException { if (buffer.available() == 0) { @@ -239,10 +245,12 @@ public class ProcessShellFactory extends AbstractLoggingBean implements Factory< protected class TtyFilterOutputStream extends FilterOutputStream { private TtyFilterInputStream echo; + public TtyFilterOutputStream(OutputStream out, TtyFilterInputStream echo) { super(out); this.echo = echo; } + @SuppressWarnings("synthetic-access") @Override public void write(int c) throws IOException { @@ -256,6 +264,7 @@ public class ProcessShellFactory extends AbstractLoggingBean implements Factory< echo.write(c); } } + @Override public void write(byte[] b, int off, int len) throws IOException { for (int i = off; i < len; i++) { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/subsystem/SubsystemFactory.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/SubsystemFactory.java b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/SubsystemFactory.java index 2a888e3..7a46f7e 100644 --- a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/SubsystemFactory.java +++ b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/SubsystemFactory.java @@ -20,19 +20,12 @@ package org.apache.sshd.server.subsystem; import org.apache.sshd.common.NamedFactory; -import org.apache.sshd.common.util.Transformer; import org.apache.sshd.server.Command; /** * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ +// CHECKSTYLE:OFF public interface SubsystemFactory extends NamedFactory<Command> { - // required because of generics issues - Transformer<SubsystemFactory,NamedFactory<Command>> FAC2NAMED=new Transformer<SubsystemFactory,NamedFactory<Command>>() { - @Override - public NamedFactory<Command> transform(SubsystemFactory input) { - return input; - } - }; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/DefaultGroupPrincipal.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/DefaultGroupPrincipal.java b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/DefaultGroupPrincipal.java new file mode 100644 index 0000000..d52b385 --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/DefaultGroupPrincipal.java @@ -0,0 +1,32 @@ +/* + * 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.subsystem.sftp; + +import java.nio.file.attribute.GroupPrincipal; + +/** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +class DefaultGroupPrincipal extends PrincipalBase implements GroupPrincipal { + + public DefaultGroupPrincipal(String name) { + super(name); + } + +} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/DefaultUserPrincipal.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/DefaultUserPrincipal.java b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/DefaultUserPrincipal.java new file mode 100644 index 0000000..1ca17d8 --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/DefaultUserPrincipal.java @@ -0,0 +1,32 @@ +/* + * 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.subsystem.sftp; + +import java.nio.file.attribute.UserPrincipal; + +/** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +class DefaultUserPrincipal extends PrincipalBase implements UserPrincipal { + + public DefaultUserPrincipal(String name) { + super(name); + } + +} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/DirectoryHandle.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/DirectoryHandle.java b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/DirectoryHandle.java new file mode 100644 index 0000000..c34d3ef --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/DirectoryHandle.java @@ -0,0 +1,94 @@ +/* + * 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.subsystem.sftp; + +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Iterator; + +/** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +class DirectoryHandle extends Handle implements Iterator<Path> { + + private boolean done; + private boolean sendDotDot; + private boolean sendDot = true; + // the directory should be read once at "open directory" + private DirectoryStream<Path> ds; + private Iterator<Path> fileList; + + public DirectoryHandle(Path file) throws IOException { + super(file); + ds = Files.newDirectoryStream(file); + + Path parent = file.getParent(); + sendDotDot = parent != null; // if no parent then no need to send ".." + fileList = ds.iterator(); + } + + public boolean isDone() { + return done; + } + + public void markDone() { + this.done = true; + // allow the garbage collector to do the job + this.fileList = null; + } + + public boolean isSendDot() { + return sendDot; + } + + public void markDotSent() { + sendDot = false; + } + + public boolean isSendDotDot() { + return sendDotDot; + } + + public void markDotDotSent() { + sendDotDot = false; + } + + @Override + public boolean hasNext() { + return fileList.hasNext(); + } + + @Override + public Path next() { + return fileList.next(); + } + + @Override + public void remove() { + throw new UnsupportedOperationException("Not allowed to remove " + toString()); + } + + @Override + public void close() throws IOException { + markDone(); // just making sure + ds.close(); + } +} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/FileHandle.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/FileHandle.java b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/FileHandle.java new file mode 100644 index 0000000..fed8805 --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/FileHandle.java @@ -0,0 +1,188 @@ +/* + * 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.subsystem.sftp; + +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.channels.FileChannel; +import java.nio.channels.FileLock; +import java.nio.file.OpenOption; +import java.nio.file.Path; +import java.nio.file.StandardOpenOption; +import java.nio.file.attribute.FileAttribute; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import static org.apache.sshd.common.subsystem.sftp.SftpConstants.ACE4_READ_ATTRIBUTES; +import static org.apache.sshd.common.subsystem.sftp.SftpConstants.ACE4_READ_DATA; +import static org.apache.sshd.common.subsystem.sftp.SftpConstants.ACE4_WRITE_ATTRIBUTES; +import static org.apache.sshd.common.subsystem.sftp.SftpConstants.ACE4_WRITE_DATA; +import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_ACCESS_DISPOSITION; +import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_APPEND_DATA; +import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_CREATE_NEW; +import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_CREATE_TRUNCATE; +import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_OPEN_EXISTING; +import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_OPEN_OR_CREATE; +import static org.apache.sshd.common.subsystem.sftp.SftpConstants.SSH_FXF_TRUNCATE_EXISTING; + +/** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +class FileHandle extends Handle { + + private final int access; + private final FileChannel fileChannel; + private long pos; + private final List<FileLock> locks = new ArrayList<>(); + + public FileHandle(SftpSubsystem sftpSubsystem, Path file, int flags, int access, Map<String, Object> attrs) throws IOException { + super(file); + this.access = access; + + Set<OpenOption> options = new HashSet<>(); + if (((access & ACE4_READ_DATA) != 0) || ((access & ACE4_READ_ATTRIBUTES) != 0)) { + options.add(StandardOpenOption.READ); + } + if (((access & ACE4_WRITE_DATA) != 0) || ((access & ACE4_WRITE_ATTRIBUTES) != 0)) { + options.add(StandardOpenOption.WRITE); + } + switch (flags & SSH_FXF_ACCESS_DISPOSITION) { + case SSH_FXF_CREATE_NEW: + options.add(StandardOpenOption.CREATE_NEW); + break; + case SSH_FXF_CREATE_TRUNCATE: + options.add(StandardOpenOption.CREATE); + options.add(StandardOpenOption.TRUNCATE_EXISTING); + break; + case SSH_FXF_OPEN_EXISTING: + break; + case SSH_FXF_OPEN_OR_CREATE: + options.add(StandardOpenOption.CREATE); + break; + case SSH_FXF_TRUNCATE_EXISTING: + options.add(StandardOpenOption.TRUNCATE_EXISTING); + break; + default: // ignored + } + if ((flags & SSH_FXF_APPEND_DATA) != 0) { + options.add(StandardOpenOption.APPEND); + } + FileAttribute<?>[] attributes = new FileAttribute<?>[attrs.size()]; + int index = 0; + for (Map.Entry<String, Object> attr : attrs.entrySet()) { + final String key = attr.getKey(); + final Object val = attr.getValue(); + attributes[index++] = new FileAttribute<Object>() { + @Override + public String name() { + return key; + } + + @Override + public Object value() { + return val; + } + }; + } + FileChannel channel; + try { + channel = FileChannel.open(file, options, attributes); + } catch (UnsupportedOperationException e) { + channel = FileChannel.open(file, options); + sftpSubsystem.setAttributes(file, attrs); + } + this.fileChannel = channel; + this.pos = 0; + } + + public final FileChannel getFileChannel() { + return fileChannel; + } + + public int getAccessMask() { + return access; + } + + public int read(byte[] data, long offset) throws IOException { + return read(data, 0, data.length, offset); + } + + public int read(byte[] data, int doff, int length, long offset) throws IOException { + FileChannel channel = getFileChannel(); + if (pos != offset) { + channel.position(offset); + pos = offset; + } + int read = channel.read(ByteBuffer.wrap(data, doff, length)); + pos += read; + return read; + } + + public void write(byte[] data, long offset) throws IOException { + write(data, 0, data.length, offset); + } + + public void write(byte[] data, int doff, int length, long offset) throws IOException { + FileChannel channel = getFileChannel(); + if (pos != offset) { + channel.position(offset); + pos = offset; + } + channel.write(ByteBuffer.wrap(data, doff, length)); + pos += length; + } + + @Override + public void close() throws IOException { + FileChannel channel = getFileChannel(); + channel.close(); + } + + public void lock(long offset, long length, int mask) throws IOException { + FileChannel channel = getFileChannel(); + long size = (length == 0L) ? channel.size() - offset : length; + FileLock lock = channel.tryLock(offset, size, false); + synchronized (locks) { + locks.add(lock); + } + } + + public boolean unlock(long offset, long length) throws IOException { + FileChannel channel = getFileChannel(); + long size = (length == 0) ? channel.size() - offset : length; + FileLock lock = null; + for (Iterator<FileLock> iterator = locks.iterator(); iterator.hasNext();) { + FileLock l = iterator.next(); + if (l.position() == offset && l.size() == size) { + iterator.remove(); + lock = l; + break; + } + } + if (lock != null) { + lock.release(); + return true; + } + return false; + } +} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/Handle.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/Handle.java b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/Handle.java new file mode 100644 index 0000000..ea0af1a --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/Handle.java @@ -0,0 +1,48 @@ +/* + * 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.subsystem.sftp; + +import java.io.IOException; +import java.nio.file.Path; +import java.util.Objects; + +/** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +abstract class Handle implements java.io.Closeable { + private Path file; + + public Handle(Path file) { + this.file = file; + } + + public Path getFile() { + return file; + } + + @Override + public void close() throws IOException { + // ignored + } + + @Override + public String toString() { + return Objects.toString(getFile()); + } +} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/InvalidHandleException.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/InvalidHandleException.java b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/InvalidHandleException.java new file mode 100644 index 0000000..cd986d3 --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/InvalidHandleException.java @@ -0,0 +1,32 @@ +/* + * 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.subsystem.sftp; + +import java.io.IOException; + +/** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +class InvalidHandleException extends IOException { + private static final long serialVersionUID = -1686077114375131889L; + + public InvalidHandleException(String handle, Handle h, Class<? extends Handle> expected) { + super(handle + "[" + h + "] is not a " + expected.getSimpleName()); + } +} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/17f2d627/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/PrincipalBase.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/PrincipalBase.java b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/PrincipalBase.java new file mode 100644 index 0000000..e61238e --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/PrincipalBase.java @@ -0,0 +1,65 @@ +/* + * 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.subsystem.sftp; + +import java.security.Principal; +import java.util.Objects; + +/** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +class PrincipalBase implements Principal { + + private final String name; + + public PrincipalBase(String name) { + if (name == null) { + throw new IllegalArgumentException("name is null"); + } + this.name = name; + } + + @Override + public final String getName() { + return name; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if ((o == null) || (getClass() != o.getClass())) { + return false; + } + + Principal that = (Principal) o; + return Objects.equals(getName(), that.getName()); + } + + @Override + public int hashCode() { + return Objects.hashCode(getName()); + } + + @Override + public String toString() { + return getName(); + } +}
