mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-07 15:50:57 +03:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
42dddc7f7e | ||
|
|
f1b3dbb102 | ||
|
|
f83bf2cd3f | ||
|
|
be11cbb848 | ||
|
|
43b0599e1f | ||
|
|
b218186cae | ||
|
|
184236c3d5 | ||
|
|
cb1d773659 | ||
|
|
378665cb46 | ||
|
|
a5272dc413 | ||
|
|
60552fd001 | ||
|
|
ef082c668a | ||
|
|
e66386eb1c | ||
|
|
0937ec9800 | ||
|
|
4b2f42804e | ||
|
|
01765d24d2 | ||
|
|
1a2351c5ee | ||
|
|
1cec011401 | ||
|
|
52338c13cb | ||
|
|
09cf21f61a | ||
|
|
04c2e7b6b8 | ||
|
|
822f196dd8 | ||
|
|
a88a574b10 |
@@ -2,4 +2,7 @@ Shikhar Bhushan <shikhar@schmizz.net>
|
||||
Cyril Ledru <cledru@keynectis.net>
|
||||
Incendium <incendium@gmail.com>
|
||||
Philip Langdale <philipl@cloudera.com>
|
||||
Adar Dembo <adar@cloudera.com>
|
||||
Adar Dembo <adar@cloudera.com>
|
||||
Ioannis Canellos <iocanel@gmail.com>
|
||||
Neil Prosser <neil.prosser@gmail.com>
|
||||
hierynomus <jeroen@hierynomus.com>
|
||||
|
||||
9
pom.xml
9
pom.xml
@@ -6,7 +6,7 @@
|
||||
<groupId>net.schmizz</groupId>
|
||||
<artifactId>sshj</artifactId>
|
||||
<packaging>bundle</packaging>
|
||||
<version>0.5.0</version>
|
||||
<version>0.6.1</version>
|
||||
|
||||
<name>sshj</name>
|
||||
<description>SSHv2 library for Java</description>
|
||||
@@ -75,6 +75,12 @@
|
||||
<version>0.9.29</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mockito</groupId>
|
||||
<artifactId>mockito-all</artifactId>
|
||||
<version>1.9.0-rc1</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
|
||||
@@ -163,6 +169,7 @@
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<version>2.3.5</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
|
||||
@@ -91,7 +91,7 @@ public class DefaultConfig
|
||||
|
||||
private final Logger log = LoggerFactory.getLogger(getClass());
|
||||
|
||||
private static final String VERSION = "SSHJ_0_4_1";
|
||||
private static final String VERSION = "SSHJ_0_6_0";
|
||||
|
||||
public DefaultConfig() {
|
||||
setVersion(VERSION);
|
||||
|
||||
@@ -364,37 +364,41 @@ public abstract class AbstractChannel
|
||||
stream.receive(buf.array(), buf.rpos(), len);
|
||||
}
|
||||
|
||||
protected synchronized Event<ConnectionException> sendChannelRequest(String reqType, boolean wantReply,
|
||||
Buffer.PlainBuffer reqSpecific)
|
||||
protected Event<ConnectionException> sendChannelRequest(String reqType, boolean wantReply,
|
||||
Buffer.PlainBuffer reqSpecific)
|
||||
throws TransportException {
|
||||
log.info("Sending channel request for `{}`", reqType);
|
||||
trans.write(
|
||||
newBuffer(Message.CHANNEL_REQUEST)
|
||||
.putString(reqType)
|
||||
.putBoolean(wantReply)
|
||||
.putBuffer(reqSpecific)
|
||||
);
|
||||
synchronized (chanReqResponseEvents) {
|
||||
trans.write(
|
||||
newBuffer(Message.CHANNEL_REQUEST)
|
||||
.putString(reqType)
|
||||
.putBoolean(wantReply)
|
||||
.putBuffer(reqSpecific)
|
||||
);
|
||||
|
||||
Event<ConnectionException> responseEvent = null;
|
||||
if (wantReply) {
|
||||
responseEvent = new Event<ConnectionException>("chan#" + id + " / " + "chanreq for " + reqType, ConnectionException.chainer, lock);
|
||||
chanReqResponseEvents.add(responseEvent);
|
||||
Event<ConnectionException> responseEvent = null;
|
||||
if (wantReply) {
|
||||
responseEvent = new Event<ConnectionException>("chan#" + id + " / " + "chanreq for " + reqType,
|
||||
ConnectionException.chainer);
|
||||
chanReqResponseEvents.add(responseEvent);
|
||||
}
|
||||
return responseEvent;
|
||||
}
|
||||
return responseEvent;
|
||||
}
|
||||
|
||||
private synchronized void gotResponse(boolean success)
|
||||
private void gotResponse(boolean success)
|
||||
throws ConnectionException {
|
||||
final Event<ConnectionException> responseEvent = chanReqResponseEvents.poll();
|
||||
if (responseEvent != null) {
|
||||
if (success)
|
||||
responseEvent.set();
|
||||
else
|
||||
responseEvent.deliverError(new ConnectionException("Request failed"));
|
||||
} else
|
||||
throw new ConnectionException(
|
||||
DisconnectReason.PROTOCOL_ERROR,
|
||||
"Received response to channel request when none was requested");
|
||||
synchronized (chanReqResponseEvents) {
|
||||
final Event<ConnectionException> responseEvent = chanReqResponseEvents.poll();
|
||||
if (responseEvent != null) {
|
||||
if (success)
|
||||
responseEvent.set();
|
||||
else
|
||||
responseEvent.deliverError(new ConnectionException("Request failed"));
|
||||
} else
|
||||
throw new ConnectionException(DisconnectReason.PROTOCOL_ERROR,
|
||||
"Received response to channel request when none was requested");
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void gotEOF()
|
||||
|
||||
@@ -51,12 +51,13 @@ public abstract class Window {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void consume(int dec) {
|
||||
public void consume(int dec)
|
||||
throws ConnectionException {
|
||||
synchronized (lock) {
|
||||
log.debug("Consuming by " + dec + " down to " + size);
|
||||
size -= dec;
|
||||
if (size < 0)
|
||||
throw new SSHRuntimeException("Window consumed to below 0");
|
||||
throw new ConnectionException("Window consumed to below 0");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +89,14 @@ public abstract class Window {
|
||||
}
|
||||
}
|
||||
|
||||
public void consume(int howMuch) {
|
||||
try {
|
||||
super.consume(howMuch);
|
||||
} catch (ConnectionException e) {
|
||||
throw new SSHRuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Controls how much data remote end can send before an adjustment notification from us is required. */
|
||||
|
||||
@@ -74,7 +74,7 @@ public class FileMode {
|
||||
}
|
||||
|
||||
public int getTypeMask() {
|
||||
return mask & 0770000;
|
||||
return mask & 0170000;
|
||||
}
|
||||
|
||||
public int getPermissionsMask() {
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package net.schmizz.sshj.sftp;
|
||||
|
||||
import net.schmizz.sshj.xfer.LocalDestFile;
|
||||
import net.schmizz.sshj.xfer.LocalSourceFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -178,10 +181,22 @@ public class StatefulSFTPClient
|
||||
super.get(cwdify(source), dest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void get(String source, LocalDestFile dest)
|
||||
throws IOException {
|
||||
super.get(cwdify(source), dest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(String source, String dest)
|
||||
throws IOException {
|
||||
super.put(source, cwdify(dest));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(LocalSourceFile source, String dest)
|
||||
throws IOException {
|
||||
super.put(source, cwdify(dest));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -58,10 +58,9 @@ public class BouncyCastleRandom
|
||||
|
||||
}
|
||||
|
||||
private final RandomGenerator random;
|
||||
private final RandomGenerator random = new VMPCRandomGenerator();
|
||||
|
||||
public BouncyCastleRandom() {
|
||||
random = new VMPCRandomGenerator();
|
||||
byte[] seed = new SecureRandom().generateSeed(8);
|
||||
random.addSeedMaterial(seed);
|
||||
}
|
||||
|
||||
@@ -58,11 +58,7 @@ public class JCERandom
|
||||
}
|
||||
|
||||
private byte[] tmp = new byte[16];
|
||||
private SecureRandom random = null;
|
||||
|
||||
public JCERandom() {
|
||||
random = new SecureRandom();
|
||||
}
|
||||
private final SecureRandom random = new SecureRandom();
|
||||
|
||||
/**
|
||||
* Fill the given byte-array with random bytes from this PRNG.
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package net.schmizz.sshj.xfer.scp;
|
||||
|
||||
import net.schmizz.sshj.common.IOUtils;
|
||||
import net.schmizz.sshj.xfer.LocalFileFilter;
|
||||
import net.schmizz.sshj.xfer.LocalSourceFile;
|
||||
import net.schmizz.sshj.xfer.scp.SCPEngine.Arg;
|
||||
|
||||
@@ -28,8 +29,9 @@ import java.util.List;
|
||||
public final class SCPUploadClient {
|
||||
|
||||
private final SCPEngine engine;
|
||||
private LocalFileFilter uploadFilter;
|
||||
|
||||
SCPUploadClient(SCPEngine engine) {
|
||||
SCPUploadClient(SCPEngine engine) {
|
||||
this.engine = engine;
|
||||
}
|
||||
|
||||
@@ -45,7 +47,11 @@ public final class SCPUploadClient {
|
||||
return engine.getExitStatus();
|
||||
}
|
||||
|
||||
private synchronized void startCopy(LocalSourceFile sourceFile, String targetPath)
|
||||
public void setUploadFilter(LocalFileFilter uploadFilter) {
|
||||
this.uploadFilter = uploadFilter;
|
||||
}
|
||||
|
||||
private synchronized void startCopy(LocalSourceFile sourceFile, String targetPath)
|
||||
throws IOException {
|
||||
List<Arg> args = new LinkedList<Arg>();
|
||||
args.add(Arg.SINK);
|
||||
@@ -75,7 +81,7 @@ public final class SCPUploadClient {
|
||||
throws IOException {
|
||||
preserveTimeIfPossible(f);
|
||||
engine.sendMessage("D0" + getPermString(f) + " 0 " + f.getName());
|
||||
for (LocalSourceFile child : f.getChildren(null))
|
||||
for (LocalSourceFile child : f.getChildren(uploadFilter))
|
||||
process(child);
|
||||
engine.sendMessage("E");
|
||||
}
|
||||
|
||||
23
src/test/java/net/schmizz/sshj/sftp/FileModeTest.java
Normal file
23
src/test/java/net/schmizz/sshj/sftp/FileModeTest.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package net.schmizz.sshj.sftp;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.hamcrest.core.IsEqual.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
public class FileModeTest {
|
||||
|
||||
@Test
|
||||
public void shouldDetectDirectoryWithLinuxMask() {
|
||||
FileMode fileMode = new FileMode(040755);
|
||||
assertThat(fileMode.toString(), equalTo("[mask=40755]"));
|
||||
assertThat(fileMode.getType(), equalTo(FileMode.Type.DIRECTORY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDetectDirectoryWithAixUnixMask() {
|
||||
FileMode fileMode = new FileMode(0240755);
|
||||
assertThat(fileMode.toString(), equalTo("[mask=240755]"));
|
||||
assertThat(fileMode.getType(), equalTo(FileMode.Type.DIRECTORY));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package net.schmizz.sshj.xfer.scp;
|
||||
|
||||
import net.schmizz.sshj.xfer.FileSystemFile;
|
||||
import net.schmizz.sshj.xfer.LocalFileFilter;
|
||||
import net.schmizz.sshj.xfer.LocalSourceFile;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.mockito.verification.VerificationMode;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.mockito.Matchers.endsWith;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isA;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
public class SCPUploadClientTest {
|
||||
|
||||
private SCPEngine engine;
|
||||
private SCPUploadClient scpUploadClient;
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder temp = new TemporaryFolder();
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
engine = mock(SCPEngine.class);
|
||||
scpUploadClient = new SCPUploadClient(engine);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldOnlySendFilterAcceptedFilesFromDirectory() throws IOException {
|
||||
scpUploadClient.setUploadFilter(new LocalFileFilter() {
|
||||
@Override
|
||||
public boolean accept(LocalSourceFile file) {
|
||||
return !file.getName().contains("not-");
|
||||
}
|
||||
});
|
||||
|
||||
File dir = temp.newFolder("filtered-scp-upload");
|
||||
new File(dir, "not-sent.txt").createNewFile();
|
||||
new File(dir, "sent.txt").createNewFile();
|
||||
|
||||
int copy = scpUploadClient.copy(new FileSystemFile(dir), "/tmp");
|
||||
verify(engine).startedDir("filtered-scp-upload");
|
||||
verify(engine).startedFile(eq("sent.txt"), isA(Long.class));
|
||||
verify(engine, times(1)).startedFile(isA(String.class), isA(Long.class));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user