http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/compression/Compression.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/compression/Compression.java b/sshd-core/src/main/java/org/apache/sshd/common/compression/Compression.java index 95294da..38ea52f 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/compression/Compression.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/compression/Compression.java @@ -20,7 +20,7 @@ package org.apache.sshd.common.compression; import java.io.IOException; -import org.apache.sshd.common.util.Buffer; +import org.apache.sshd.common.util.buffer.Buffer; /** * Interface used to compress the stream of data between the
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/compression/CompressionZlib.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/compression/CompressionZlib.java b/sshd-core/src/main/java/org/apache/sshd/common/compression/CompressionZlib.java index 5e9a56c..4b50c3b 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/compression/CompressionZlib.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/compression/CompressionZlib.java @@ -23,7 +23,7 @@ import java.util.zip.DataFormatException; import java.util.zip.Deflater; import java.util.zip.Inflater; -import org.apache.sshd.common.util.Buffer; +import org.apache.sshd.common.util.buffer.Buffer; /** * ZLib based Compression. http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java b/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java index cb68ea4..458b483 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java @@ -40,9 +40,10 @@ import org.apache.sshd.common.io.IoAcceptor; import org.apache.sshd.common.io.IoHandler; import org.apache.sshd.common.io.IoSession; import org.apache.sshd.common.session.ConnectionService; -import org.apache.sshd.common.util.Buffer; import org.apache.sshd.common.util.CloseableUtils; import org.apache.sshd.common.util.Readable; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.buffer.ByteArrayBuffer; /** * TODO Add javadoc @@ -68,6 +69,7 @@ public class DefaultTcpipForwarder extends CloseableUtils.AbstractInnerCloseable // TcpIpForwarder implementation // + @Override public synchronized SshdSocketAddress startLocalPortForwarding(SshdSocketAddress local, SshdSocketAddress remote) throws IOException { if (local == null) { throw new IllegalArgumentException("Local address is null"); @@ -89,12 +91,14 @@ public class DefaultTcpipForwarder extends CloseableUtils.AbstractInnerCloseable return bound; } + @Override public synchronized void stopLocalPortForwarding(SshdSocketAddress local) throws IOException { if (localToRemote.remove(local.getPort()) != null && acceptor != null) { acceptor.unbind(local.toInetSocketAddress()); } } + @Override public synchronized SshdSocketAddress startRemotePortForwarding(SshdSocketAddress remote, SshdSocketAddress local) throws IOException { Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_GLOBAL_REQUEST); buffer.putString("tcpip-forward"); @@ -111,6 +115,7 @@ public class DefaultTcpipForwarder extends CloseableUtils.AbstractInnerCloseable return new SshdSocketAddress(remote.getHostName(), port); } + @Override public synchronized void stopRemotePortForwarding(SshdSocketAddress remote) throws IOException { if (remoteToLocal.remove(remote.getPort()) != null) { Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_GLOBAL_REQUEST); @@ -122,6 +127,7 @@ public class DefaultTcpipForwarder extends CloseableUtils.AbstractInnerCloseable } } + @Override public synchronized SshdSocketAddress startDynamicPortForwarding(SshdSocketAddress local) throws IOException { if (local == null) { throw new IllegalArgumentException("Local address is null"); @@ -141,6 +147,7 @@ public class DefaultTcpipForwarder extends CloseableUtils.AbstractInnerCloseable return bound; } + @Override public synchronized void stopDynamicPortForwarding(SshdSocketAddress local) throws IOException { Closeable obj = dynamicLocal.remove(local.getPort()); if (obj != null) { @@ -149,10 +156,12 @@ public class DefaultTcpipForwarder extends CloseableUtils.AbstractInnerCloseable } } + @Override public synchronized SshdSocketAddress getForwardedPort(int remotePort) { return remoteToLocal.get(remotePort); } + @Override public synchronized SshdSocketAddress localPortForwardingRequested(SshdSocketAddress local) throws IOException { if (local == null) { throw new IllegalArgumentException("Local address is null"); @@ -169,6 +178,7 @@ public class DefaultTcpipForwarder extends CloseableUtils.AbstractInnerCloseable return bound; } + @Override public synchronized void localPortForwardingCancelled(SshdSocketAddress local) throws IOException { if (localForwards.remove(local) && acceptor != null) { acceptor.unbind(local.toInetSocketAddress()); @@ -209,6 +219,7 @@ public class DefaultTcpipForwarder extends CloseableUtils.AbstractInnerCloseable } } + @Override public String toString() { return getClass().getSimpleName() + "[" + session + "]"; } @@ -219,6 +230,7 @@ public class DefaultTcpipForwarder extends CloseableUtils.AbstractInnerCloseable class StaticIoHandler implements IoHandler { + @Override public void sessionCreated(final IoSession session) throws Exception { final TcpipClientChannel channel; int localPort = ((InetSocketAddress) session.getLocalAddress()).getPort(); @@ -231,6 +243,7 @@ public class DefaultTcpipForwarder extends CloseableUtils.AbstractInnerCloseable session.setAttribute(TcpipClientChannel.class, channel); service.registerChannel(channel); channel.open().addListener(new SshFutureListener<OpenFuture>() { + @Override public void operationComplete(OpenFuture future) { Throwable t = future.getException(); if (t != null) { @@ -241,6 +254,7 @@ public class DefaultTcpipForwarder extends CloseableUtils.AbstractInnerCloseable }); } + @Override public void sessionClosed(IoSession session) throws Exception { TcpipClientChannel channel = (TcpipClientChannel) session.getAttribute(TcpipClientChannel.class); if (channel != null) { @@ -249,15 +263,17 @@ public class DefaultTcpipForwarder extends CloseableUtils.AbstractInnerCloseable } } + @Override public void messageReceived(IoSession session, Readable message) throws Exception { TcpipClientChannel channel = (TcpipClientChannel) session.getAttribute(TcpipClientChannel.class); - Buffer buffer = new Buffer(); + Buffer buffer = new ByteArrayBuffer(); buffer.putBuffer(message); channel.waitFor(ClientChannel.OPENED | ClientChannel.CLOSED, Long.MAX_VALUE); channel.getInvertedIn().write(buffer.array(), buffer.rpos(), buffer.available()); channel.getInvertedIn().flush(); } + @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { cause.printStackTrace(); session.close(false); http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/forward/SocksProxy.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/forward/SocksProxy.java b/sshd-core/src/main/java/org/apache/sshd/common/forward/SocksProxy.java index bbe4fe7..a009144 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/forward/SocksProxy.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/forward/SocksProxy.java @@ -30,8 +30,9 @@ import org.apache.sshd.common.future.SshFutureListener; import org.apache.sshd.common.io.IoHandler; import org.apache.sshd.common.io.IoSession; import org.apache.sshd.common.session.ConnectionService; -import org.apache.sshd.common.util.Buffer; import org.apache.sshd.common.util.CloseableUtils; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.buffer.ByteArrayBuffer; /** * SOCKS proxy server, supporting simple socks4/5 protocols. @@ -47,12 +48,14 @@ public class SocksProxy extends CloseableUtils.AbstractCloseable implements IoHa this.service = service; } + @Override public void sessionCreated(IoSession session) throws Exception { if (isClosing()) { throw new SshException("SocksProxy is closing or closed"); } } + @Override public void sessionClosed(IoSession session) throws Exception { Proxy proxy = proxies.remove(session); if (proxy != null) { @@ -60,8 +63,9 @@ public class SocksProxy extends CloseableUtils.AbstractCloseable implements IoHa } } + @Override public void messageReceived(final IoSession session, org.apache.sshd.common.util.Readable message) throws Exception { - Buffer buffer = new Buffer(message.available()); + Buffer buffer = new ByteArrayBuffer(message.available()); buffer.putBuffer(message); Proxy proxy = proxies.get(session); if (proxy == null) { @@ -80,6 +84,7 @@ public class SocksProxy extends CloseableUtils.AbstractCloseable implements IoHa } } + @Override public void exceptionCaught(IoSession ioSession, Throwable cause) throws Exception { log.warn("Exception caught, closing socks proxy", cause); ioSession.close(false); @@ -142,6 +147,7 @@ public class SocksProxy extends CloseableUtils.AbstractCloseable implements IoHa channel = new TcpipClientChannel(TcpipClientChannel.Type.Direct, session, remote); service.registerChannel(channel); channel.open().addListener(new SshFutureListener<OpenFuture>() { + @Override public void operationComplete(OpenFuture future) { onChannelOpened(future); } @@ -152,7 +158,7 @@ public class SocksProxy extends CloseableUtils.AbstractCloseable implements IoHa } protected void onChannelOpened(OpenFuture future) { - Buffer buffer = new Buffer(8); + Buffer buffer = new ByteArrayBuffer(8); buffer.putByte((byte) 0x00); Throwable t = future.getException(); if (t != null) { @@ -201,7 +207,7 @@ public class SocksProxy extends CloseableUtils.AbstractCloseable implements IoHa for (int i = 0; i < nbAuthMethods; i++) { foundNoAuth |= authMethods[i] == 0; } - buffer = new Buffer(8); + buffer = new ByteArrayBuffer(8); buffer.putByte((byte) 0x05); buffer.putByte((byte) (foundNoAuth ? 0x00 : 0xFF)); session.write(buffer); @@ -248,6 +254,7 @@ public class SocksProxy extends CloseableUtils.AbstractCloseable implements IoHa channel = new TcpipClientChannel(TcpipClientChannel.Type.Direct, session, remote); service.registerChannel(channel); channel.open().addListener(new SshFutureListener<OpenFuture>() { + @Override public void operationComplete(OpenFuture future) { onChannelOpened(future); } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/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 0d95acf..cb93049 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 @@ -29,12 +29,9 @@ import org.apache.sshd.common.SshConstants; import org.apache.sshd.common.SshException; import org.apache.sshd.common.SshdSocketAddress; import org.apache.sshd.common.channel.ChannelOutputStream; -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.io.IoSession; -import org.apache.sshd.common.util.Buffer; -import org.apache.sshd.common.util.CloseableUtils; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.buffer.ByteArrayBuffer; /** * TODO Add javadoc @@ -64,6 +61,7 @@ public class TcpipClientChannel extends AbstractClientChannel { return openFuture; } + @Override public synchronized OpenFuture open() throws IOException { InetSocketAddress src = null, dst = null; switch (typeEnum) { @@ -107,10 +105,11 @@ public class TcpipClientChannel extends AbstractClientChannel { return builder().sequential(serverSession, super.getInnerCloseable()).build(); } + @Override protected synchronized void doWriteData(byte[] data, int off, int len) throws IOException { // Make sure we copy the data as the incoming buffer may be reused - Buffer buf = new Buffer(data, off, len); - buf = new Buffer(buf.getCompactData()); + Buffer buf = new ByteArrayBuffer(data, off, len); + buf = new ByteArrayBuffer(buf.getCompactData()); localWindow.consumeAndCheck(len); serverSession.write(buf); } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipServerChannel.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipServerChannel.java b/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipServerChannel.java index f2e0925..a828de6 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipServerChannel.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/forward/TcpipServerChannel.java @@ -37,8 +37,9 @@ import org.apache.sshd.common.io.IoConnector; import org.apache.sshd.common.io.IoHandler; import org.apache.sshd.common.io.IoSession; import org.apache.sshd.common.io.IoWriteFuture; -import org.apache.sshd.common.util.Buffer; import org.apache.sshd.common.util.Readable; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.buffer.ByteArrayBuffer; import org.apache.sshd.server.channel.AbstractServerChannel; import org.apache.sshd.server.channel.OpenChannelException; @@ -51,10 +52,12 @@ public class TcpipServerChannel extends AbstractServerChannel { public static class DirectTcpipFactory implements NamedFactory<Channel> { + @Override public String getName() { return "direct-tcpip"; } + @Override public Channel create() { return new TcpipServerChannel(Type.Direct); } @@ -62,10 +65,12 @@ public class TcpipServerChannel extends AbstractServerChannel { public static class ForwardedTcpipFactory implements NamedFactory<Channel> { + @Override public String getName() { return "forwarded-tcpip"; } + @Override public Channel create() { return new TcpipServerChannel(Type.Forwarded); } @@ -85,6 +90,7 @@ public class TcpipServerChannel extends AbstractServerChannel { this.type = type; } + @Override protected OpenFuture doInit(Buffer buffer) { final OpenFuture f = new DefaultOpenFuture(this); @@ -111,21 +117,25 @@ public class TcpipServerChannel extends AbstractServerChannel { // TODO: revisit for better threading. Use async io ? out = new ChannelOutputStream(this, remoteWindow, log, SshConstants.SSH_MSG_CHANNEL_DATA); IoHandler handler = new IoHandler() { + @Override public void messageReceived(IoSession session, Readable message) throws Exception { if (isClosing()) { log.debug("Ignoring write to channel {} in CLOSING state", id); } else { - Buffer buffer = new Buffer(); + Buffer buffer = new ByteArrayBuffer(); buffer.putBuffer(message); out.write(buffer.array(), buffer.rpos(), buffer.available()); out.flush(); } } + @Override public void sessionCreated(IoSession session) throws Exception { } + @Override public void sessionClosed(IoSession session) throws Exception { close(false); } + @Override public void exceptionCaught(IoSession ioSession, Throwable cause) throws Exception { close(true); } @@ -134,6 +144,7 @@ public class TcpipServerChannel extends AbstractServerChannel { .createConnector(handler); IoConnectFuture future = connector.connect(address.toInetSocketAddress()); future.addListener(new SshFutureListener<IoConnectFuture>() { + @Override public void operationComplete(IoConnectFuture future) { if (future.isConnected()) { ioSession = future.getSession(); @@ -176,19 +187,23 @@ public class TcpipServerChannel extends AbstractServerChannel { }.start(); } + @Override public CloseFuture close(boolean immediately) { return super.close(immediately).addListener(new SshFutureListener<CloseFuture>() { + @Override public void operationComplete(CloseFuture sshFuture) { closeImmediately0(); } }); } + @Override protected void doWriteData(byte[] data, int off, final int len) throws IOException { // Make sure we copy the data as the incoming buffer may be reused - Buffer buf = new Buffer(data, off, len); - buf = new Buffer(buf.getCompactData()); + Buffer buf = new ByteArrayBuffer(data, off, len); + buf = new ByteArrayBuffer(buf.getCompactData()); ioSession.write(buf).addListener(new SshFutureListener<IoWriteFuture>() { + @Override public void operationComplete(IoWriteFuture future) { try { localWindow.consumeAndCheck(len); @@ -199,6 +214,7 @@ public class TcpipServerChannel extends AbstractServerChannel { }); } + @Override protected void doWriteExtendedData(byte[] data, int off, int len) throws IOException { throw new UnsupportedOperationException(type + "Tcpip channel does not support extended data"); } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/io/IoInputStream.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoInputStream.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoInputStream.java index c585b67..d61419c 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoInputStream.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoInputStream.java @@ -19,7 +19,7 @@ package org.apache.sshd.common.io; import org.apache.sshd.common.Closeable; -import org.apache.sshd.common.util.Buffer; +import org.apache.sshd.common.util.buffer.Buffer; public interface IoInputStream extends Closeable { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/io/IoOutputStream.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoOutputStream.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoOutputStream.java index f2b8994..104d5fb 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoOutputStream.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoOutputStream.java @@ -19,7 +19,7 @@ package org.apache.sshd.common.io; import org.apache.sshd.common.Closeable; -import org.apache.sshd.common.util.Buffer; +import org.apache.sshd.common.util.buffer.Buffer; public interface IoOutputStream extends Closeable { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/io/IoReadFuture.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoReadFuture.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoReadFuture.java index d4f07a9..ebf9c20 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoReadFuture.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoReadFuture.java @@ -20,7 +20,7 @@ package org.apache.sshd.common.io; import org.apache.sshd.common.SshException; import org.apache.sshd.common.future.SshFuture; -import org.apache.sshd.common.util.Buffer; +import org.apache.sshd.common.util.buffer.Buffer; public interface IoReadFuture extends SshFuture<IoReadFuture> { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/io/IoSession.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/IoSession.java b/sshd-core/src/main/java/org/apache/sshd/common/io/IoSession.java index caccfca..0158064 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/IoSession.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/IoSession.java @@ -22,7 +22,7 @@ import java.net.SocketAddress; import org.apache.sshd.common.Closeable; import org.apache.sshd.common.future.CloseFuture; -import org.apache.sshd.common.util.Buffer; +import org.apache.sshd.common.util.buffer.Buffer; public interface IoSession extends Closeable { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSession.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSession.java b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSession.java index ed8f380..64d245c 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSession.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSession.java @@ -31,8 +31,8 @@ import org.apache.sshd.common.future.DefaultSshFuture; import org.apache.sshd.common.io.IoService; import org.apache.sshd.common.io.IoSession; import org.apache.sshd.common.io.IoWriteFuture; -import org.apache.sshd.common.util.Buffer; import org.apache.sshd.common.util.CloseableUtils; +import org.apache.sshd.common.util.buffer.Buffer; /** */ http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSupport.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSupport.java b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSupport.java index f9259f4..9b623e5 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSupport.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/io/mina/MinaSupport.java @@ -19,8 +19,8 @@ package org.apache.sshd.common.io.mina; import org.apache.mina.core.buffer.IoBuffer; -import org.apache.sshd.common.util.Buffer; import org.apache.sshd.common.util.Readable; +import org.apache.sshd.common.util.buffer.Buffer; public class MinaSupport { http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/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 9822c2d..a0ceaf0 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 @@ -39,9 +39,9 @@ import org.apache.sshd.common.io.IoHandler; import org.apache.sshd.common.io.IoService; import org.apache.sshd.common.io.IoSession; import org.apache.sshd.common.io.IoWriteFuture; -import org.apache.sshd.common.util.Buffer; import org.apache.sshd.common.util.CloseableUtils; import org.apache.sshd.common.util.Readable; +import org.apache.sshd.common.util.buffer.Buffer; /** */ http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/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 6a709df..26f589e 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 @@ -37,8 +37,8 @@ import org.apache.sshd.common.SshConstants; import org.apache.sshd.common.SshException; import org.apache.sshd.common.TcpipForwarder; import org.apache.sshd.common.future.SshFutureListener; -import org.apache.sshd.common.util.Buffer; import org.apache.sshd.common.util.CloseableUtils; +import org.apache.sshd.common.util.buffer.Buffer; import org.apache.sshd.server.channel.OpenChannelException; import org.apache.sshd.server.x11.X11ForwardSupport; http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/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 0903c39..378cce6 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 @@ -61,17 +61,18 @@ import org.apache.sshd.common.future.SshFuture; import org.apache.sshd.common.future.SshFutureListener; import org.apache.sshd.common.io.IoSession; import org.apache.sshd.common.io.IoWriteFuture; -import org.apache.sshd.common.util.Buffer; -import org.apache.sshd.common.util.BufferUtils; import org.apache.sshd.common.util.CloseableUtils; import org.apache.sshd.common.util.EventListenerUtils; import org.apache.sshd.common.util.Readable; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.buffer.BufferUtils; +import org.apache.sshd.common.util.buffer.ByteArrayBuffer; /** * The AbstractSession handles all the basic SSH protocol such as key exchange, authentication, * encoding and decoding. Both server side and client side sessions should inherit from this * abstract class. Some basic packet processing methods are defined but the actual call to these - * methods should be done from the {@link #handleMessage(org.apache.sshd.common.util.Buffer)} + * methods should be done from the {@link #handleMessage(org.apache.sshd.common.util.buffer.Buffer)} * method, which is dependant on the state and side of this session. * * TODO: if there is any very big packet, decoderBuffer and uncompressBuffer will get quite big @@ -139,7 +140,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea protected Compression inCompression; protected long seqi; protected long seqo; - protected Buffer decoderBuffer = new Buffer(); + protected Buffer decoderBuffer = new ByteArrayBuffer(); protected Buffer uncompressBuffer; protected int decoderState; protected int decoderLength; @@ -228,10 +229,12 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea ioSession.setAttribute(SESSION, session); } + @Override public String getServerVersion() { return serverVersion; } + @Override public String getClientVersion() { return clientVersion; } @@ -250,6 +253,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea * * @return the mina session */ + @Override public IoSession getIoSession() { return ioSession; } @@ -259,10 +263,12 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea * * @return the factory manager for this session */ + @Override public FactoryManager getFactoryManager() { return factoryManager; } + @Override public String getNegotiatedKexParameter(int paramType) { if ((paramType < 0) || (negotiated == null) || (paramType >= negotiated.length)) { return null; @@ -447,6 +453,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea * * @param t the exception to process */ + @Override public void exceptionCaught(Throwable t) { // Ignore exceptions that happen while closing synchronized (lock) { @@ -488,6 +495,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea return currentService != null ? new Service[] { currentService } : new Service[0]; } + @Override public <T extends Service> T getService(Class<T> clazz) { for (Service s : getServices()) { if (clazz.isInstance(s)) { @@ -506,6 +514,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea * @return a future that can be used to check when the packet has actually been sent * @throws java.io.IOException if an error occured when encoding sending the packet */ + @Override public IoWriteFuture writePacket(Buffer buffer) throws IOException { // While exchanging key, queue high level packets if (kexState.get() != KEX_STATE_DONE) { @@ -571,6 +580,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea * @return <code>true</code> if the request was successful, <code>false</code> otherwise. * @throws java.io.IOException if an error occured when encoding sending the packet */ + @Override public Buffer request(Buffer buffer) throws IOException { synchronized (requestLock) { try { @@ -585,6 +595,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea } } + @Override public Buffer createBuffer(byte cmd) { return createBuffer(cmd, 0); } @@ -597,10 +608,11 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea * @param len estimated number of bytes the buffer will hold, 0 if unknown. * @return a new buffer ready for write */ + @Override public Buffer createBuffer(byte cmd, int len) { Buffer buffer; if (len <= 0) { - buffer = new Buffer(); + buffer = new ByteArrayBuffer(); } else { // Since the caller claims to know how many bytes they will need // increase their request to account for our headers/footers if @@ -616,7 +628,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea if (outMac != null) { len += outMac.getBlockSize(); } - buffer = new Buffer(new byte[Math.max(len, Buffer.DEFAULT_SIZE)], false); + buffer = new ByteArrayBuffer(new byte[Math.max(len, ByteArrayBuffer.DEFAULT_SIZE)], false); } buffer.rpos(5); buffer.wpos(5); @@ -637,7 +649,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea if (buffer.rpos() < 5) { log.warn("Performance cost: when sending a packet, ensure that " + "5 bytes are available in front of the buffer"); - Buffer nb = new Buffer(); + Buffer nb = new ByteArrayBuffer(); nb.wpos(5); nb.putBuffer(buffer); buffer = nb; @@ -763,7 +775,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea // Decompress if needed if (inCompression != null && (authed || !inCompression.isDelayed())) { if (uncompressBuffer == null) { - uncompressBuffer = new Buffer(); + uncompressBuffer = new ByteArrayBuffer(); } else { uncompressBuffer.clear(); } @@ -803,13 +815,13 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea protected void sendIdentification(String ident) { log.debug("Send identification: {}", ident); byte[] data = (ident + "\r\n").getBytes(); - ioSession.write(new Buffer(data)); + ioSession.write(new ByteArrayBuffer(data)); } /** * Read the other side identification. * This method is specific to the client or server side, but both should call - * {@link #doReadIdentification(org.apache.sshd.common.util.Buffer,boolean)} and + * {@link #doReadIdentification(org.apache.sshd.common.util.buffer.Buffer,boolean)} and * store the result in the needed property. * * @param buffer the buffer containing the remote identification @@ -983,7 +995,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea System.arraycopy(H, 0, sessionId, 0, H.length); } - Buffer buffer = new Buffer(); + Buffer buffer = new ByteArrayBuffer(); buffer.putMPInt(K); buffer.putRawBytes(H); buffer.putByte((byte) 0x41); @@ -1079,7 +1091,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea */ private byte[] resizeKey(byte[] E, int blockSize, Digest hash, byte[] K, byte[] H) throws Exception { while (blockSize > E.length) { - Buffer buffer = new Buffer(); + Buffer buffer = new ByteArrayBuffer(); buffer.putMPInt(K); buffer.putRawBytes(H); buffer.putRawBytes(E); @@ -1111,6 +1123,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea // Write the packet with a timeout to ensure a timely close of the session // in case the consumer does not read packets anymore. writePacket(buffer, disconnectTimeoutMs, TimeUnit.MILLISECONDS).addListener(new SshFutureListener<IoWriteFuture>() { + @Override public void operationComplete(IoWriteFuture future) { close(true); } @@ -1188,7 +1201,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea protected void requestSuccess(Buffer buffer) throws Exception{ synchronized (requestResult) { - requestResult.set(new Buffer(buffer.getCompactData())); + requestResult.set(new ByteArrayBuffer(buffer.getCompactData())); resetIdleTimeout(); requestResult.notify(); } @@ -1209,6 +1222,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea * @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 { String v = factoryManager.getProperties().get(name); @@ -1239,6 +1253,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea * @param key the key of the attribute; must not be null. * @return <tt>null</tt> if there is no attribute with the specified key */ + @Override @SuppressWarnings("unchecked") public <T> T getAttribute(AttributeKey<T> key) { return (T)attributes.get(key); @@ -1251,11 +1266,13 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea * @param value the value of the attribute; must not be null. * @return The old value of the attribute. <tt>null</tt> if it is new. */ + @Override @SuppressWarnings("unchecked") public <T, E extends T> T setAttribute(AttributeKey<T> key, E value) { return (T)attributes.put(key, value); } + @Override public String getUsername() { return username; } @@ -1267,6 +1284,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea /** * {@inheritDoc} */ + @Override public void addListener(SessionListener listener) { if (listener == null) { throw new IllegalArgumentException(); @@ -1277,6 +1295,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea /** * {@inheritDoc} */ + @Override public void removeListener(SessionListener listener) { this.listeners.remove(listener); } @@ -1288,6 +1307,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea /** * {@inheritDoc} */ + @Override public SshFuture reExchangeKeys() throws IOException { if (kexState.compareAndSet(KEX_STATE_DONE, KEX_STATE_INIT)) { log.info("Initiating key re-exchange"); @@ -1331,6 +1351,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea } } + @Override public void resetIdleTimeout() { this.idleTimeoutTimestamp = System.currentTimeMillis() + idleTimeoutMs; } @@ -1339,6 +1360,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea * Check if timeout has occurred. * @return */ + @Override public TimeoutStatus getTimeoutStatus() { return timeoutStatus.get(); } @@ -1347,6 +1369,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea * What is timeout value in milliseconds for authentication stage * @return */ + @Override public long getAuthTimeout() { return authTimeoutMs; } @@ -1355,6 +1378,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea * What is timeout value in milliseconds for communication * @return */ + @Override public long getIdleTimeout() { return idleTimeoutMs; } @@ -1376,6 +1400,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea return buffer; } + @Override public void verify() throws SshException { try { await(); @@ -1388,10 +1413,12 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea } } + @Override public boolean isWritten() { return getValue() instanceof Boolean; } + @Override public Throwable getException() { Object v = getValue(); return v instanceof Throwable ? (Throwable) v : null; @@ -1408,6 +1435,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea setValue(cause); } + @Override public void operationComplete(IoWriteFuture future) { if (future.isWritten()) { setWritten(); @@ -1417,6 +1445,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea } } + @Override public String toString() { return getClass().getSimpleName() + "[" + getUsername() + "@" + getIoSession().getRemoteAddress() + "]"; } http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java index 5801801..2fdef4e 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureECDSA.java @@ -20,7 +20,9 @@ package org.apache.sshd.common.signature; import java.io.IOException; import java.math.BigInteger; -import org.apache.sshd.common.util.Buffer; + +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.buffer.ByteArrayBuffer; /** * Signature algorithm for EC keys using ECDSA. There @@ -61,7 +63,7 @@ public class SignatureECDSA extends AbstractSignature { BigInteger s = new BigInteger(sArray); // Write the <r,s> to its own types writer. - Buffer rsBuf = new Buffer(); + Buffer rsBuf = new ByteArrayBuffer(); rsBuf.putMPInt(r); rsBuf.putMPInt(s); @@ -72,7 +74,7 @@ public class SignatureECDSA extends AbstractSignature { public boolean verify(byte[] sig) throws Exception { sig = extractSig(sig); - Buffer rsBuf = new Buffer(sig); + Buffer rsBuf = new ByteArrayBuffer(sig); byte[] rArray = rsBuf.getMPIntAsBytes(); byte[] sArray = rsBuf.getMPIntAsBytes(); http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/util/Buffer.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/Buffer.java b/sshd-core/src/main/java/org/apache/sshd/common/util/Buffer.java deleted file mode 100644 index 9697bb3..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/util/Buffer.java +++ /dev/null @@ -1,577 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.sshd.common.util; - -import java.math.BigInteger; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.security.KeyFactory; -import java.security.KeyPair; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.PrivateKey; -import java.security.PublicKey; -import java.security.interfaces.DSAPrivateKey; -import java.security.interfaces.DSAPublicKey; -import java.security.interfaces.ECPrivateKey; -import java.security.interfaces.ECPublicKey; -import java.security.interfaces.RSAPrivateCrtKey; -import java.security.interfaces.RSAPublicKey; -import java.security.spec.DSAPrivateKeySpec; -import java.security.spec.DSAPublicKeySpec; -import java.security.spec.ECParameterSpec; -import java.security.spec.ECPoint; -import java.security.spec.ECPrivateKeySpec; -import java.security.spec.ECPublicKeySpec; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.RSAPrivateCrtKeySpec; -import java.security.spec.RSAPublicKeySpec; - -import org.apache.sshd.common.KeyPairProvider; -import org.apache.sshd.common.SshConstants; -import org.apache.sshd.common.SshException; -import org.apache.sshd.common.cipher.ECCurves; - -/** - * TODO Add javadoc - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public final class Buffer implements Readable { - - public static final int DEFAULT_SIZE = 256; - public static final int MAX_LEN = 65536; - - private byte[] data; - private int rpos; - private int wpos; - - public Buffer() { - this(DEFAULT_SIZE); - } - - public Buffer(int size) { - this(new byte[getNextPowerOf2(size)], false); - } - - public Buffer(byte[] data) { - this(data, 0, data.length, true); - } - - public Buffer(byte[] data, boolean read) { - this(data, 0, data.length, read); - } - - public Buffer(byte[] data, int off, int len) { - this(data, off, len, true); - } - - public Buffer(byte[] data, int off, int len, boolean read) { - this.data = data; - this.rpos = off; - this.wpos = (read ? len : 0) + off; - } - - @Override - public String toString() { - return "Buffer [rpos=" + rpos + ", wpos=" + wpos + ", size=" + data.length + "]"; - } - - /*====================== - Global methods - ======================*/ - - public int rpos() { - return rpos; - } - - public void rpos(int rpos) { - this.rpos = rpos; - } - - public int wpos() { - return wpos; - } - - public void wpos(int wpos) { - ensureCapacity(wpos - this.wpos); - this.wpos = wpos; - } - - public int available() { - return wpos - rpos; - } - - public int capacity() { - return data.length - wpos; - } - - public byte[] array() { - return data; - } - - public void compact() { - if (available() > 0) { - System.arraycopy(data, rpos, data, 0, wpos - rpos); - } - wpos -= rpos; - rpos = 0; - } - - public byte[] getCompactData() { - int l = available(); - if (l > 0) { - byte[] b = new byte[l]; - System.arraycopy(data, rpos, b, 0, l); - return b; - } else { - return new byte[0]; - } - } - - public void clear() { - rpos = 0; - wpos = 0; - } - - public String printHex() { - return BufferUtils.printHex(array(), rpos(), available()); - } - - /*====================== - Read methods - ======================*/ - - public byte getByte() { - ensureAvailable(1); - return data[rpos++]; - } - - public int getInt() { - return (int) getUInt(); - } - - public long getUInt() - { - ensureAvailable(4); - long l = ((data[rpos++] << 24) & 0xff000000L)| - ((data[rpos++] << 16) & 0x00ff0000L)| - ((data[rpos++] << 8) & 0x0000ff00L)| - ((data[rpos++] ) & 0x000000ffL); - return l; - } - - public long getLong() - { - ensureAvailable(8); - long l = (((long) data[rpos++] << 56) & 0xff00000000000000L)| - (((long) data[rpos++] << 48) & 0x00ff000000000000L)| - (((long) data[rpos++] << 40) & 0x0000ff0000000000L)| - (((long) data[rpos++] << 32) & 0x000000ff00000000L)| - (((long) data[rpos++] << 24) & 0x00000000ff000000L)| - (((long) data[rpos++] << 16) & 0x0000000000ff0000L)| - (((long) data[rpos++] << 8) & 0x000000000000ff00L)| - (((long) data[rpos++] ) & 0x00000000000000ffL); - return l; - } - - public boolean getBoolean() { - return getByte() != 0; - } - - public String getString() { - return getString(StandardCharsets.UTF_8); - } - - public String getString(Charset charset) { - int len = getInt(); - if (len < 0) { - throw new IllegalStateException("Bad item length: " + len); - } - ensureAvailable(len); - String s = new String(data, rpos, len, charset); - rpos += len; - return s; - } - - public byte[] getStringAsBytes() { - return getBytes(); - } - - public BigInteger getMPInt() { - return new BigInteger(getMPIntAsBytes()); - } - - public byte[] getMPIntAsBytes() { - return getBytes(); - } - - public byte[] getBytes() { - int len = getInt(); - if (len < 0) { - throw new IllegalStateException("Bad item length: " + len); - } - ensureAvailable(len); - byte[] b = new byte[len]; - getRawBytes(b); - return b; - } - - public void getRawBytes(byte[] buf) { - getRawBytes(buf, 0, buf.length); - } - - public void getRawBytes(byte[] buf, int off, int len) { - ensureAvailable(len); - System.arraycopy(data, rpos, buf, off, len); - rpos += len; - } - - public PublicKey getPublicKey() throws SshException { - int ow = wpos; - int len = getInt(); - wpos = rpos + len; - try { - return getRawPublicKey(); - } finally { - wpos = ow; - } - } - - public PublicKey getRawPublicKey() throws SshException { - try { - PublicKey key; - String keyAlg = getString(); - if (KeyPairProvider.SSH_RSA.equals(keyAlg)) { - BigInteger e = getMPInt(); - BigInteger n = getMPInt(); - KeyFactory keyFactory = SecurityUtils.getKeyFactory("RSA"); - key = keyFactory.generatePublic(new RSAPublicKeySpec(n, e)); - } else if (KeyPairProvider.SSH_DSS.equals(keyAlg)) { - BigInteger p = getMPInt(); - BigInteger q = getMPInt(); - BigInteger g = getMPInt(); - BigInteger y = getMPInt(); - KeyFactory keyFactory = SecurityUtils.getKeyFactory("DSA"); - key = keyFactory.generatePublic(new DSAPublicKeySpec(y, p, q, g)); - } else if (KeyPairProvider.ECDSA_SHA2_NISTP256.equals(keyAlg)) { - key = getRawECKey("nistp256", ECCurves.EllipticCurves.nistp256); - } else if (KeyPairProvider.ECDSA_SHA2_NISTP384.equals(keyAlg)) { - key = getRawECKey("nistp384", ECCurves.EllipticCurves.nistp384); - } else if (KeyPairProvider.ECDSA_SHA2_NISTP521.equals(keyAlg)) { - key = getRawECKey("nistp521", ECCurves.EllipticCurves.nistp521); - } else { - throw new IllegalStateException("Unsupported algorithm: " + keyAlg); - } - return key; - } catch (InvalidKeySpecException e) { - throw new SshException(e); - } catch (NoSuchAlgorithmException e) { - throw new SshException(e); - } catch (NoSuchProviderException e) { - throw new SshException(e); - } - } - - private PublicKey getRawECKey(String expectedCurve, ECParameterSpec spec) throws InvalidKeySpecException, - SshException, NoSuchAlgorithmException, NoSuchProviderException { - String curveName = getString(); - if (!expectedCurve.equals(curveName)) { - throw new InvalidKeySpecException("Curve name does not match expected: " + curveName + " vs " - + expectedCurve); - } - ECPoint w = ECCurves.decodeECPoint(getStringAsBytes(), spec.getCurve()); - KeyFactory keyFactory = SecurityUtils.getKeyFactory("EC"); - return keyFactory.generatePublic(new ECPublicKeySpec(w, spec)); - } - - public KeyPair getKeyPair() throws SshException { - try { - PublicKey pub; - PrivateKey prv; - String keyAlg = getString(); - if (KeyPairProvider.SSH_RSA.equals(keyAlg)) { - BigInteger e = getMPInt(); - BigInteger n = getMPInt(); - BigInteger d = getMPInt(); - BigInteger qInv = getMPInt(); - BigInteger q = getMPInt(); - BigInteger p = getMPInt(); - BigInteger dP = d.remainder(p.subtract(BigInteger.valueOf(1))); - BigInteger dQ = d.remainder(q.subtract(BigInteger.valueOf(1))); - KeyFactory keyFactory = SecurityUtils.getKeyFactory("RSA"); - pub = keyFactory.generatePublic(new RSAPublicKeySpec(n, e)); - prv = keyFactory.generatePrivate(new RSAPrivateCrtKeySpec(n, e, d, p, q, dP, dQ, qInv)); - } else if (KeyPairProvider.SSH_DSS.equals(keyAlg)) { - BigInteger p = getMPInt(); - BigInteger q = getMPInt(); - BigInteger g = getMPInt(); - BigInteger y = getMPInt(); - BigInteger x = getMPInt(); - KeyFactory keyFactory = SecurityUtils.getKeyFactory("DSA"); - pub = keyFactory.generatePublic(new DSAPublicKeySpec(y, p, q, g)); - prv = keyFactory.generatePrivate(new DSAPrivateKeySpec(x, p, q, g)); - } else if (KeyPairProvider.ECDSA_SHA2_NISTP256.equals(keyAlg)) { - return extractEC("nistp256", ECCurves.EllipticCurves.nistp256); - } else if (KeyPairProvider.ECDSA_SHA2_NISTP384.equals(keyAlg)) { - return extractEC("nistp384", ECCurves.EllipticCurves.nistp384); - } else if (KeyPairProvider.ECDSA_SHA2_NISTP521.equals(keyAlg)) { - return extractEC("nistp521", ECCurves.EllipticCurves.nistp521); - } else { - throw new IllegalStateException("Unsupported algorithm: " + keyAlg); - } - return new KeyPair(pub, prv); - } catch (InvalidKeySpecException e) { - throw new SshException(e); - } catch (NoSuchAlgorithmException e) { - throw new SshException(e); - } catch (NoSuchProviderException e) { - throw new SshException(e); - } - } - - private KeyPair extractEC(String expectedCurveName, ECParameterSpec spec) throws NoSuchAlgorithmException, - NoSuchProviderException, InvalidKeySpecException, SshException { - String curveName = getString(); - byte[] groupBytes = getStringAsBytes(); - BigInteger exponent = getMPInt(); - - if (!expectedCurveName.equals(curveName)) { - throw new SshException("Expected curve " + expectedCurveName + " but was " + curveName); - } - - ECPoint group = ECCurves.decodeECPoint(groupBytes, spec.getCurve()); - if (group == null) { - throw new InvalidKeySpecException("Couldn't decode EC group"); - } - - KeyFactory keyFactory = SecurityUtils.getKeyFactory("EC"); - PublicKey pubKey = keyFactory.generatePublic(new ECPublicKeySpec(group, spec)); - PrivateKey privKey = keyFactory.generatePrivate(new ECPrivateKeySpec(exponent, spec)); - return new KeyPair(pubKey, privKey); - } - - private void ensureAvailable(int a) { - if (available() < a) { - throw new BufferException("Underflow"); - } - } - - /*====================== - Write methods - ======================*/ - - public void putByte(byte b) { - ensureCapacity(1); - data[wpos++] = b; - } - - public void putBuffer(Readable buffer) { - putBuffer(buffer, true); - } - - public int putBuffer(Readable buffer, boolean expand) { - int r = expand ? buffer.available() : Math.min(buffer.available(), capacity()); - ensureCapacity(r); - buffer.getRawBytes(data, wpos, r); - wpos += r; - return r; - } - - /** - * Writes 16 bits - * @param i - */ - public void putShort(int i) { - ensureCapacity(2); - data[wpos++] = (byte) (i >> 8); - data[wpos++] = (byte) (i ); - } - - /** - * Writes 32 bits - * @param i - */ - public void putInt(long i) { - ensureCapacity(4); - data[wpos++] = (byte) (i >> 24); - data[wpos++] = (byte) (i >> 16); - data[wpos++] = (byte) (i >> 8); - data[wpos++] = (byte) (i ); - } - - /** - * Writes 64 bits - * @param i - */ - public void putLong(long i) { - ensureCapacity(8); - data[wpos++] = (byte) (i >> 56); - data[wpos++] = (byte) (i >> 48); - data[wpos++] = (byte) (i >> 40); - data[wpos++] = (byte) (i >> 32); - data[wpos++] = (byte) (i >> 24); - data[wpos++] = (byte) (i >> 16); - data[wpos++] = (byte) (i >> 8); - data[wpos++] = (byte) (i ); - } - - public void putBoolean(boolean b) { - putByte(b ? (byte) 1 : (byte) 0); - } - - public void putBytes(byte[] b) { - putBytes(b, 0, b.length); - } - - public void putBytes(byte[] b, int off, int len) { - putInt(len); - ensureCapacity(len); - System.arraycopy(b, off, data, wpos, len); - wpos += len; - } - - public void putString(String string) { - putString(string, Charset.defaultCharset()); - } - - public void putString(String string, Charset charset) { - putString(string.getBytes(charset)); - } - - public void putString(byte[] str) { - putInt(str.length); - putRawBytes(str); - } - - public void putMPInt(BigInteger bi) { - putMPInt(bi.toByteArray()); - } - - public void putMPInt(byte[] foo) { - int i = foo.length; - if ((foo[0] & 0x80) != 0) { - i++; - putInt(i); - putByte((byte)0); - } else { - putInt(i); - } - putRawBytes(foo); - } - - public void putRawBytes(byte[] d) { - putRawBytes(d, 0, d.length); - } - - public void putRawBytes(byte[] d, int off, int len) { - ensureCapacity(len); - System.arraycopy(d, off, data, wpos, len); - wpos += len; - } - - public void putPublicKey(PublicKey key) { - int ow = wpos; - putInt(0); - int ow1 = wpos; - putRawPublicKey(key); - int ow2 = wpos; - wpos = ow; - putInt(ow2 - ow1); - wpos = ow2; - } - - public void putRawPublicKey(PublicKey key) { - if (key instanceof RSAPublicKey) { - putString(KeyPairProvider.SSH_RSA); - putMPInt(((RSAPublicKey) key).getPublicExponent()); - putMPInt(((RSAPublicKey) key).getModulus()); - } else if (key instanceof DSAPublicKey) { - putString(KeyPairProvider.SSH_DSS); - putMPInt(((DSAPublicKey) key).getParams().getP()); - putMPInt(((DSAPublicKey) key).getParams().getQ()); - putMPInt(((DSAPublicKey) key).getParams().getG()); - putMPInt(((DSAPublicKey) key).getY()); - } else if (key instanceof ECPublicKey) { - ECPublicKey ecKey = (ECPublicKey) key; - ECParameterSpec ecParams = ecKey.getParams(); - String curveName = ECCurves.getCurveName(ecParams); - putString(ECCurves.ECDSA_SHA2_PREFIX + curveName); - putString(curveName); - putBytes(ECCurves.encodeECPoint(ecKey.getW(), ecParams.getCurve())); - } else { - throw new IllegalStateException("Unsupported algorithm: " + key.getAlgorithm()); - } - } - - public void putKeyPair(KeyPair key) { - if (key.getPrivate() instanceof RSAPrivateCrtKey) { - putString(KeyPairProvider.SSH_RSA); - putMPInt(((RSAPublicKey) key.getPublic()).getPublicExponent()); - putMPInt(((RSAPublicKey) key.getPublic()).getModulus()); - putMPInt(((RSAPrivateCrtKey) key.getPrivate()).getPrivateExponent()); - putMPInt(((RSAPrivateCrtKey) key.getPrivate()).getCrtCoefficient()); - putMPInt(((RSAPrivateCrtKey) key.getPrivate()).getPrimeQ()); - putMPInt(((RSAPrivateCrtKey) key.getPrivate()).getPrimeP()); - } else if (key.getPublic() instanceof DSAPublicKey) { - putString(KeyPairProvider.SSH_DSS); - putMPInt(((DSAPublicKey) key.getPublic()).getParams().getP()); - putMPInt(((DSAPublicKey) key.getPublic()).getParams().getQ()); - putMPInt(((DSAPublicKey) key.getPublic()).getParams().getG()); - putMPInt(((DSAPublicKey) key.getPublic()).getY()); - putMPInt(((DSAPrivateKey) key.getPrivate()).getX()); - } else if (key.getPublic() instanceof ECPublicKey) { - ECPublicKey ecPub = (ECPublicKey) key.getPublic(); - ECPrivateKey ecPriv = (ECPrivateKey) key.getPrivate(); - ECParameterSpec ecParams = ecPub.getParams(); - String curveName = ECCurves.getCurveName(ecParams); - - putString(ECCurves.ECDSA_SHA2_PREFIX + curveName); - putString(curveName); - putString(ECCurves.encodeECPoint(ecPub.getW(), ecParams.getCurve())); - putMPInt(ecPriv.getS()); - } else { - throw new IllegalStateException("Unsupported algorithm: " + key.getPublic().getAlgorithm()); - } - } - - private void ensureCapacity(int capacity) { - if (data.length - wpos < capacity) { - int cw = wpos + capacity; - byte[] tmp = new byte[getNextPowerOf2(cw)]; - System.arraycopy(data, 0, tmp, 0, data.length); - data = tmp; - } - } - - public static class BufferException extends RuntimeException { - public BufferException(String message) { - super(message); - } - } - - private static int getNextPowerOf2(int i) { - int j = 1; - while (j < i) { - j <<= 1; - } - return j; - } - -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/util/BufferUtils.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/BufferUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/BufferUtils.java deleted file mode 100644 index dde95e6..0000000 --- a/sshd-core/src/main/java/org/apache/sshd/common/util/BufferUtils.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.sshd.common.util; - -/** - * TODO Add javadoc - * - * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> - */ -public class BufferUtils { - - public static String printHex(byte[] array) { - return printHex(array, 0, array.length); - } - - public static String printHex(byte[] array, int offset, int len) { - return printHex(array, offset, len, ' '); - } - - public static String printHex(byte[] array, int offset, int len, char sep) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < len; i++) { - byte b = array[offset + i]; - if (sb.length() > 0) { - sb.append(sep); - } - sb.append(digits[(b >> 4) & 0x0F]); - sb.append(digits[b & 0x0F]); - } - return sb.toString(); - } - - public static boolean equals(byte[] a1, byte[] a2) { - if (a1.length != a2.length) { - return false; - } - return equals(a1, 0, a2, 0, a1.length); - } - - public static boolean equals(byte[] a1, int a1Offset, byte[] a2, int a2Offset, int length) { - if (a1.length < a1Offset + length || a2.length < a2Offset + length) { - return false; - } - while (length-- > 0) { - if (a1[a1Offset++] != a2[a2Offset++]) { - return false; - } - } - return true; - } - - final static char[] digits = { - '0' , '1' , '2' , '3' , '4' , '5' , - '6' , '7' , '8' , '9' , 'a' , 'b' , - 'c' , 'd' , 'e' , 'f' - }; -} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java index ebc600a..0fad1b7 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java @@ -36,6 +36,7 @@ import java.util.TreeSet; * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> */ public class GenericUtils { + public static final byte[] EMPTY_BYTE_ARRAY={ }; public static final String[] EMPTY_STRING_ARRAY={ }; public static final Object[] EMPTY_OBJECT_ARRAY={ }; http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/util/KeyUtils.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/KeyUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/KeyUtils.java index 6c7800a..d86c024 100644 --- a/sshd-core/src/main/java/org/apache/sshd/common/util/KeyUtils.java +++ b/sshd-core/src/main/java/org/apache/sshd/common/util/KeyUtils.java @@ -30,6 +30,9 @@ import org.apache.sshd.common.Digest; import org.apache.sshd.common.KeyPairProvider; import org.apache.sshd.common.cipher.ECCurves; import org.apache.sshd.common.digest.BuiltinDigests; +import org.apache.sshd.common.util.buffer.Buffer; +import org.apache.sshd.common.util.buffer.BufferUtils; +import org.apache.sshd.common.util.buffer.ByteArrayBuffer; /** * Utility class for keys @@ -46,7 +49,7 @@ public class KeyUtils { */ public static String getFingerPrint(PublicKey key) { try { - Buffer buffer = new Buffer(); + Buffer buffer = new ByteArrayBuffer(); buffer.putRawPublicKey(key); Digest md5 = BuiltinDigests.md5.create(); md5.init(); http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java new file mode 100644 index 0000000..93d006c --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java @@ -0,0 +1,489 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sshd.common.util.buffer; + +import java.math.BigInteger; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.security.KeyFactory; +import java.security.KeyPair; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.PublicKey; +import java.security.interfaces.DSAParams; +import java.security.interfaces.DSAPrivateKey; +import java.security.interfaces.DSAPublicKey; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; +import java.security.interfaces.RSAPrivateCrtKey; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.DSAPrivateKeySpec; +import java.security.spec.DSAPublicKeySpec; +import java.security.spec.ECParameterSpec; +import java.security.spec.ECPoint; +import java.security.spec.ECPrivateKeySpec; +import java.security.spec.ECPublicKeySpec; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.RSAPrivateCrtKeySpec; +import java.security.spec.RSAPublicKeySpec; + +import org.apache.sshd.common.KeyPairProvider; +import org.apache.sshd.common.SshException; +import org.apache.sshd.common.cipher.ECCurves; +import org.apache.sshd.common.util.GenericUtils; +import org.apache.sshd.common.util.Readable; +import org.apache.sshd.common.util.SecurityUtils; + +/** + * Provides an abstract message buffer for encoding SSH messages + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +public abstract class Buffer implements Readable { + + // TODO use Long.BYTES in JDK-8 + protected final byte[] workBuf = new byte[Long.SIZE / Byte.SIZE]; + + protected Buffer() { + super(); + } + + /*====================== + Global methods + ======================*/ + + public abstract int rpos(); + public abstract void rpos(int rpos); + + public abstract int wpos(); + + public abstract void wpos(int wpos); + + public abstract int capacity(); + public abstract byte[] array(); + + public abstract void compact(); + + public byte[] getCompactData() { + int l = available(); + if (l > 0) { + byte[] b = new byte[l]; + System.arraycopy(array(), rpos(), b, 0, l); + return b; + } else { + return GenericUtils.EMPTY_BYTE_ARRAY; + } + } + + public abstract void clear(); + + public String printHex() { + return BufferUtils.printHex(array(), rpos(), available()); + } + + /*====================== + Read methods + ======================*/ + + public byte getByte() { + // TODO use Byte.BYTES for JDK-8 + ensureAvailable(Byte.SIZE / Byte.SIZE); + getRawBytes(workBuf, 0, Byte.SIZE / Byte.SIZE); + return workBuf[0]; + } + + public int getInt() { + return (int) getUInt(); + } + + public long getUInt() { + // TODO use Integer.BYTES for JDK-8 + ensureAvailable(Integer.SIZE / Byte.SIZE); + getRawBytes(workBuf, 0, Integer.SIZE / Byte.SIZE); + long l = ((workBuf[0] << 24) & 0xff000000L)| + ((workBuf[1] << 16) & 0x00ff0000L)| + ((workBuf[2] << 8) & 0x0000ff00L)| + ((workBuf[3] ) & 0x000000ffL); + return l; + } + + public long getLong() { + // TODO use Long.BYTES for JDK-8 + ensureAvailable(Long.SIZE / Byte.SIZE); + getRawBytes(workBuf, 0, Long.SIZE / Byte.SIZE); + @SuppressWarnings("cast") + long l = (((long) workBuf[0] << 56) & 0xff00000000000000L)| + (((long) workBuf[1] << 48) & 0x00ff000000000000L)| + (((long) workBuf[2] << 40) & 0x0000ff0000000000L)| + (((long) workBuf[3] << 32) & 0x000000ff00000000L)| + (((long) workBuf[4] << 24) & 0x00000000ff000000L)| + (((long) workBuf[5] << 16) & 0x0000000000ff0000L)| + (((long) workBuf[6] << 8) & 0x000000000000ff00L)| + (((long) workBuf[7] ) & 0x00000000000000ffL); + return l; + } + + public boolean getBoolean() { + return getByte() != 0; + } + + public String getString() { + return getString(StandardCharsets.UTF_8); + } + + public abstract String getString(Charset charset); + + public byte[] getStringAsBytes() { + return getBytes(); + } + + public BigInteger getMPInt() { + return new BigInteger(getMPIntAsBytes()); + } + + public byte[] getMPIntAsBytes() { + return getBytes(); + } + + public byte[] getBytes() { + int len = getInt(); + if (len < 0) { + throw new BufferException("Bad item length: " + len); + } + ensureAvailable(len); + byte[] b = new byte[len]; + getRawBytes(b); + return b; + } + + public void getRawBytes(byte[] buf) { + getRawBytes(buf, 0, buf.length); + } + + public PublicKey getPublicKey() throws SshException { + int ow = wpos(); + int len = getInt(); + wpos(rpos() + len); + try { + return getRawPublicKey(); + } finally { + wpos(ow); + } + } + + public PublicKey getRawPublicKey() throws SshException { + try { + PublicKey key; + String keyAlg = getString(); + if (KeyPairProvider.SSH_RSA.equals(keyAlg)) { + BigInteger e = getMPInt(); + BigInteger n = getMPInt(); + KeyFactory keyFactory = SecurityUtils.getKeyFactory("RSA"); + key = keyFactory.generatePublic(new RSAPublicKeySpec(n, e)); + } else if (KeyPairProvider.SSH_DSS.equals(keyAlg)) { + BigInteger p = getMPInt(); + BigInteger q = getMPInt(); + BigInteger g = getMPInt(); + BigInteger y = getMPInt(); + KeyFactory keyFactory = SecurityUtils.getKeyFactory("DSA"); + key = keyFactory.generatePublic(new DSAPublicKeySpec(y, p, q, g)); + } else if (KeyPairProvider.ECDSA_SHA2_NISTP256.equals(keyAlg)) { + key = getRawECKey("nistp256", ECCurves.EllipticCurves.nistp256); + } else if (KeyPairProvider.ECDSA_SHA2_NISTP384.equals(keyAlg)) { + key = getRawECKey("nistp384", ECCurves.EllipticCurves.nistp384); + } else if (KeyPairProvider.ECDSA_SHA2_NISTP521.equals(keyAlg)) { + key = getRawECKey("nistp521", ECCurves.EllipticCurves.nistp521); + } else { + throw new NoSuchAlgorithmException("Unsupported raw public algorithm: " + keyAlg); + } + return key; + } catch (GeneralSecurityException e) { + throw new SshException(e); + } + } + + protected PublicKey getRawECKey(String expectedCurve, ECParameterSpec spec) throws GeneralSecurityException, SshException { + String curveName = getString(); + if (!expectedCurve.equals(curveName)) { + throw new InvalidKeySpecException("Curve name does not match expected: " + curveName + " vs " + + expectedCurve); + } + ECPoint w = ECCurves.decodeECPoint(getStringAsBytes(), spec.getCurve()); + KeyFactory keyFactory = SecurityUtils.getKeyFactory("EC"); + return keyFactory.generatePublic(new ECPublicKeySpec(w, spec)); + } + + public KeyPair getKeyPair() throws SshException { + try { + PublicKey pub; + PrivateKey prv; + String keyAlg = getString(); + if (KeyPairProvider.SSH_RSA.equals(keyAlg)) { + BigInteger e = getMPInt(); + BigInteger n = getMPInt(); + BigInteger d = getMPInt(); + BigInteger qInv = getMPInt(); + BigInteger q = getMPInt(); + BigInteger p = getMPInt(); + BigInteger dP = d.remainder(p.subtract(BigInteger.valueOf(1))); + BigInteger dQ = d.remainder(q.subtract(BigInteger.valueOf(1))); + KeyFactory keyFactory = SecurityUtils.getKeyFactory("RSA"); + pub = keyFactory.generatePublic(new RSAPublicKeySpec(n, e)); + prv = keyFactory.generatePrivate(new RSAPrivateCrtKeySpec(n, e, d, p, q, dP, dQ, qInv)); + } else if (KeyPairProvider.SSH_DSS.equals(keyAlg)) { + BigInteger p = getMPInt(); + BigInteger q = getMPInt(); + BigInteger g = getMPInt(); + BigInteger y = getMPInt(); + BigInteger x = getMPInt(); + KeyFactory keyFactory = SecurityUtils.getKeyFactory("DSA"); + pub = keyFactory.generatePublic(new DSAPublicKeySpec(y, p, q, g)); + prv = keyFactory.generatePrivate(new DSAPrivateKeySpec(x, p, q, g)); + } else if (KeyPairProvider.ECDSA_SHA2_NISTP256.equals(keyAlg)) { + return extractEC("nistp256", ECCurves.EllipticCurves.nistp256); + } else if (KeyPairProvider.ECDSA_SHA2_NISTP384.equals(keyAlg)) { + return extractEC("nistp384", ECCurves.EllipticCurves.nistp384); + } else if (KeyPairProvider.ECDSA_SHA2_NISTP521.equals(keyAlg)) { + return extractEC("nistp521", ECCurves.EllipticCurves.nistp521); + } else { + throw new NoSuchAlgorithmException("Unsupported key pair algorithm: " + keyAlg); + } + return new KeyPair(pub, prv); + } catch (GeneralSecurityException e) { + throw new SshException(e); + } + } + + protected KeyPair extractEC(String expectedCurveName, ECParameterSpec spec) throws GeneralSecurityException, SshException { + String curveName = getString(); + byte[] groupBytes = getStringAsBytes(); + BigInteger exponent = getMPInt(); + + if (!expectedCurveName.equals(curveName)) { + throw new SshException("Expected curve " + expectedCurveName + " but was " + curveName); + } + + ECPoint group = ECCurves.decodeECPoint(groupBytes, spec.getCurve()); + if (group == null) { + throw new InvalidKeySpecException("Couldn't decode EC group"); + } + + KeyFactory keyFactory = SecurityUtils.getKeyFactory("EC"); + PublicKey pubKey = keyFactory.generatePublic(new ECPublicKeySpec(group, spec)); + PrivateKey privKey = keyFactory.generatePrivate(new ECPrivateKeySpec(exponent, spec)); + return new KeyPair(pubKey, privKey); + } + + public void ensureAvailable(int a) throws BufferException { + if (available() < a) { + throw new BufferException("Underflow"); + } + } + + /*====================== + Write methods + ======================*/ + + public void putByte(byte b) { + // TODO use Byte.BYTES in JDK-8 + ensureCapacity(Byte.SIZE / Byte.SIZE); + workBuf[0] = b; + putRawBytes(workBuf, 0, Byte.SIZE / Byte.SIZE); + } + + public void putBuffer(Readable buffer) { + putBuffer(buffer, true); + } + + public abstract int putBuffer(Readable buffer, boolean expand); + + /** + * Writes 16 bits + * @param i + */ + public void putShort(int i) { + // TODO use Short.BYTES for JDK-8 + ensureCapacity(Short.SIZE / Byte.SIZE); + workBuf[0] = (byte) (i >> 8); + workBuf[1] = (byte) (i ); + putRawBytes(workBuf, 0, Short.SIZE / Byte.SIZE); + } + + /** + * Writes 32 bits + * @param i + */ + public void putInt(long i) { + // TODO use Integer.BYTES for JDK-8 + ensureCapacity(Integer.SIZE / Byte.SIZE); + workBuf[0] = (byte) (i >> 24); + workBuf[1] = (byte) (i >> 16); + workBuf[2] = (byte) (i >> 8); + workBuf[3] = (byte) (i ); + putRawBytes(workBuf, 0, Integer.SIZE / Byte.SIZE); + } + + /** + * Writes 64 bits + * @param i + */ + public void putLong(long i) { + // TODO use Long.BYTES for JDK-8 + ensureCapacity(Long.SIZE / Byte.SIZE); + workBuf[0] = (byte) (i >> 56); + workBuf[1] = (byte) (i >> 48); + workBuf[2] = (byte) (i >> 40); + workBuf[3] = (byte) (i >> 32); + workBuf[4] = (byte) (i >> 24); + workBuf[5] = (byte) (i >> 16); + workBuf[6] = (byte) (i >> 8); + workBuf[7] = (byte) (i ); + putRawBytes(workBuf, 0, Long.SIZE / Byte.SIZE); + } + + public void putBoolean(boolean b) { + putByte(b ? (byte) 1 : (byte) 0); + } + + public void putBytes(byte[] b) { + putBytes(b, 0, b.length); + } + + public void putBytes(byte[] b, int off, int len) { + putInt(len); + putRawBytes(b, off, len); + } + + public void putString(String string) { + putString(string, StandardCharsets.UTF_8); + } + + public void putString(String string, Charset charset) { + putBytes(string.getBytes(charset)); + } + + public void putMPInt(BigInteger bi) { + putMPInt(bi.toByteArray()); + } + + public void putMPInt(byte[] foo) { + int i = foo.length; + if ((foo[0] & 0x80) != 0) { + i++; + putInt(i); + putByte((byte)0); + } else { + putInt(i); + } + putRawBytes(foo); + } + + public void putRawBytes(byte[] d) { + putRawBytes(d, 0, d.length); + } + + public abstract void putRawBytes(byte[] d, int off, int len); + + public void putPublicKey(PublicKey key) { + int ow = wpos(); + putInt(0); + int ow1 = wpos(); + putRawPublicKey(key); + int ow2 = wpos(); + wpos(ow); + putInt(ow2 - ow1); + wpos(ow2); + } + + public void putRawPublicKey(PublicKey key) { + if (key instanceof RSAPublicKey) { + RSAPublicKey rsaPub = (RSAPublicKey) key; + + putString(KeyPairProvider.SSH_RSA); + putMPInt(rsaPub.getPublicExponent()); + putMPInt(rsaPub.getModulus()); + } else if (key instanceof DSAPublicKey) { + DSAPublicKey dsaPub = (DSAPublicKey) key; + DSAParams dsaParams = dsaPub.getParams(); + + putString(KeyPairProvider.SSH_DSS); + putMPInt(dsaParams.getP()); + putMPInt(dsaParams.getQ()); + putMPInt(dsaParams.getG()); + putMPInt(dsaPub.getY()); + } else if (key instanceof ECPublicKey) { + ECPublicKey ecKey = (ECPublicKey) key; + ECParameterSpec ecParams = ecKey.getParams(); + String curveName = ECCurves.getCurveName(ecParams); + putString(ECCurves.ECDSA_SHA2_PREFIX + curveName); + putString(curveName); + putBytes(ECCurves.encodeECPoint(ecKey.getW(), ecParams.getCurve())); + } else { + throw new BufferException("Unsupported raw public key algorithm: " + key.getAlgorithm()); + } + } + + public void putKeyPair(KeyPair kp) { + PublicKey pubKey = kp.getPublic(); + PrivateKey prvKey = kp.getPrivate(); + if (prvKey instanceof RSAPrivateCrtKey) { + RSAPublicKey rsaPub = (RSAPublicKey) pubKey; + RSAPrivateCrtKey rsaPrv = (RSAPrivateCrtKey) prvKey; + + putString(KeyPairProvider.SSH_RSA); + putMPInt(rsaPub.getPublicExponent()); + putMPInt(rsaPub.getModulus()); + putMPInt(rsaPrv.getPrivateExponent()); + putMPInt(rsaPrv.getCrtCoefficient()); + putMPInt(rsaPrv.getPrimeQ()); + putMPInt(rsaPrv.getPrimeP()); + } else if (pubKey instanceof DSAPublicKey) { + DSAPublicKey dsaPub = (DSAPublicKey) pubKey; + DSAParams dsaParams = dsaPub.getParams(); + DSAPrivateKey dsaPrv = (DSAPrivateKey) prvKey; + + putString(KeyPairProvider.SSH_DSS); + putMPInt(dsaParams.getP()); + putMPInt(dsaParams.getQ()); + putMPInt(dsaParams.getG()); + putMPInt(dsaPub.getY()); + putMPInt(dsaPrv.getX()); + } else if (pubKey instanceof ECPublicKey) { + ECPublicKey ecPub = (ECPublicKey) pubKey; + ECPrivateKey ecPriv = (ECPrivateKey) prvKey; + ECParameterSpec ecParams = ecPub.getParams(); + String curveName = ECCurves.getCurveName(ecParams); + + putString(ECCurves.ECDSA_SHA2_PREFIX + curveName); + putString(curveName); + putBytes(ECCurves.encodeECPoint(ecPub.getW(), ecParams.getCurve())); + putMPInt(ecPriv.getS()); + } else { + throw new BufferException("Unsupported key pair algorithm: " + kp.getPublic().getAlgorithm()); + } + } + + protected abstract void ensureCapacity(int capacity); + protected abstract int size(); + + @Override + public String toString() { + return "Buffer [rpos=" + rpos() + ", wpos=" + wpos() + ", size=" + size() + "]"; + } +} http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9f0bb1bc/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/BufferException.java ---------------------------------------------------------------------- diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/BufferException.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/BufferException.java new file mode 100644 index 0000000..e8d298d --- /dev/null +++ b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/BufferException.java @@ -0,0 +1,30 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.sshd.common.util.buffer; + +/** + * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a> + */ +public class BufferException extends RuntimeException { + private static final long serialVersionUID = 658645233475011039L; + + public BufferException(String message) { + super(message); + } +} \ No newline at end of file
