@Test
  public void testFileStoreReport() throws Exception {
    Path targetPath = detectTargetFolder().toPath();
    Path lclSftp =
        Utils.resolve(
            targetPath,
            SftpConstants.SFTP_SUBSYSTEM_NAME,
            getClass().getSimpleName(),
            getCurrentTestName());
    Path parentPath = targetPath.getParent();
    FileStore store = Files.getFileStore(lclSftp.getRoot());
    final String queryPath = Utils.resolveRelativeRemotePath(parentPath, lclSftp);
    final SpaceAvailableExtensionInfo expected = new SpaceAvailableExtensionInfo(store);
    sshd.setSubsystemFactories(
        Arrays.<NamedFactory<Command>>asList(
            new SftpSubsystemFactory() {
              @Override
              public Command create() {
                return new SftpSubsystem(
                    getExecutorService(), isShutdownOnExit(), getUnsupportedAttributePolicy()) {
                  @Override
                  protected SpaceAvailableExtensionInfo doSpaceAvailable(int id, String path)
                      throws IOException {
                    if (!queryPath.equals(path)) {
                      throw new StreamCorruptedException(
                          "Mismatched query paths: expected=" + queryPath + ", actual=" + path);
                    }

                    return expected;
                  }
                };
              }
            }));

    try (SshClient client = SshClient.setUpDefaultClient()) {
      client.start();

      try (ClientSession session =
          client
              .connect(getCurrentTestName(), "localhost", port)
              .verify(7L, TimeUnit.SECONDS)
              .getSession()) {
        session.addPasswordIdentity(getCurrentTestName());
        session.auth().verify(5L, TimeUnit.SECONDS);

        try (SftpClient sftp = session.createSftpClient()) {
          SpaceAvailableExtension ext = assertExtensionCreated(sftp, SpaceAvailableExtension.class);
          SpaceAvailableExtensionInfo actual = ext.available(queryPath);
          assertEquals("Mismatched information", expected, actual);
        }
      } finally {
        client.stop();
      }
    }
  }
Example #2
0
  @Test
  public void testBuiltinCipherSession() throws Exception {
    Assume.assumeTrue(
        "No internal support for " + builtInCipher.getName(),
        builtInCipher.isSupported() && checkCipher(jschCipher.getName()));

    try (SshServer sshd = SshServer.setUpDefaultServer()) {
      sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
      sshd.setCipherFactories(
          Arrays.<NamedFactory<org.apache.sshd.common.cipher.Cipher>>asList(builtInCipher));
      sshd.setShellFactory(new EchoShellFactory());
      sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
      sshd.start();

      try {
        runJschTest(sshd.getPort());
      } finally {
        sshd.stop(true);
      }
    }
  }
Example #3
0
/**
 * Test Cipher algorithms.
 *
 * @author <a href="mailto:[email protected]">Apache MINA SSHD Project</a>
 */
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@RunWith(Parameterized.class) // see https://github.com/junit-team/junit/wiki/Parameterized-tests
public class CipherTest extends BaseTestSupport {
  private static final Integer NUM_LOADTEST_ROUNDS = Integer.valueOf(100000);

  /*
   * NOTE !!! order is important since we build from it the C2S/S2C ciphers proposal
   */
  private static final List<Object[]> PARAMETERS =
      Collections.unmodifiableList(
          Arrays.asList(
              new Object[] {
                BuiltinCiphers.aes128cbc, com.jcraft.jsch.jce.AES128CBC.class, NUM_LOADTEST_ROUNDS
              },
              new Object[] {
                BuiltinCiphers.tripledescbc,
                com.jcraft.jsch.jce.TripleDESCBC.class,
                NUM_LOADTEST_ROUNDS
              },
              new Object[] {
                BuiltinCiphers.blowfishcbc,
                com.jcraft.jsch.jce.BlowfishCBC.class,
                NUM_LOADTEST_ROUNDS
              },
              new Object[] {
                BuiltinCiphers.aes192cbc, com.jcraft.jsch.jce.AES192CBC.class, NUM_LOADTEST_ROUNDS
              },
              new Object[] {
                BuiltinCiphers.aes256cbc, com.jcraft.jsch.jce.AES256CBC.class, NUM_LOADTEST_ROUNDS
              }));

  @SuppressWarnings("synthetic-access")
  private static final List<NamedResource> TEST_CIPHERS =
      Collections.unmodifiableList(
          new ArrayList<NamedResource>(PARAMETERS.size()) {
            private static final long serialVersionUID = 1L; // we're not serializing it

            {
              for (Object[] params : PARAMETERS) {
                add((NamedResource) params[0]);
              }

              add(BuiltinCiphers.none);
            }
          });

  private static final String CRYPT_NAMES = NamedResource.Utils.getNames(TEST_CIPHERS);

  @Parameters(name = "cipher={0}, load={2}")
  public static Collection<Object[]> parameters() {
    return PARAMETERS;
  }

  private final Random random = Utils.getRandomizerInstance();
  private final BuiltinCiphers builtInCipher;
  private final Class<? extends com.jcraft.jsch.Cipher> jschCipher;
  private final int loadTestRounds;

  public CipherTest(
      BuiltinCiphers builtInCipher,
      Class<? extends com.jcraft.jsch.Cipher> jschCipher,
      int loadTestRounds) {
    this.builtInCipher = builtInCipher;
    this.jschCipher = jschCipher;
    this.loadTestRounds = loadTestRounds;
  }

  @Test
  public void testBuiltinCipherSession() throws Exception {
    Assume.assumeTrue(
        "No internal support for " + builtInCipher.getName(),
        builtInCipher.isSupported() && checkCipher(jschCipher.getName()));

    try (SshServer sshd = SshServer.setUpDefaultServer()) {
      sshd.setKeyPairProvider(Utils.createTestHostKeyProvider());
      sshd.setCipherFactories(
          Arrays.<NamedFactory<org.apache.sshd.common.cipher.Cipher>>asList(builtInCipher));
      sshd.setShellFactory(new EchoShellFactory());
      sshd.setPasswordAuthenticator(BogusPasswordAuthenticator.INSTANCE);
      sshd.start();

      try {
        runJschTest(sshd.getPort());
      } finally {
        sshd.stop(true);
      }
    }
  }

  private void runJschTest(int port) throws Exception {
    JSchLogger.init();
    JSch sch = new JSch();
    JSch.setConfig("cipher.s2c", CRYPT_NAMES);
    JSch.setConfig("cipher.c2s", CRYPT_NAMES);
    com.jcraft.jsch.Session s = sch.getSession(getCurrentTestName(), "localhost", port);
    s.setUserInfo(new SimpleUserInfo(getCurrentTestName()));
    s.connect();

    try {
      com.jcraft.jsch.Channel c = s.openChannel("shell");
      c.connect();

      try (OutputStream os = c.getOutputStream();
          InputStream is = c.getInputStream()) {
        String expected = "this is my command\n";
        byte[] expData = expected.getBytes(StandardCharsets.UTF_8);
        byte[] actData = new byte[expData.length + Long.SIZE /* just in case */];
        for (int i = 0; i < 10; i++) {
          os.write(expData);
          os.flush();

          int len = is.read(actData);
          String actual = new String(actData, 0, len);
          assertEquals("Mismatched command at iteration " + i, expected, actual);
        }
      } finally {
        c.disconnect();
      }
    } finally {
      s.disconnect();
    }
  }

  @Test
  public void testCipherLoad() throws Exception {
    Assume.assumeTrue(
        "No internal support for " + builtInCipher.getName(), builtInCipher.isSupported());
    loadTest(builtInCipher, random, loadTestRounds);
  }

  private static void loadTest(NamedFactory<Cipher> factory, Random random, int numRounds)
      throws Exception {
    Cipher cipher = factory.create();
    byte[] key = new byte[cipher.getBlockSize()];
    byte[] iv = new byte[cipher.getIVSize()];
    random.fill(key, 0, key.length);
    random.fill(iv, 0, iv.length);
    cipher.init(Cipher.Mode.Encrypt, key, iv);

    byte[] input = new byte[BufferUtils.getNextPowerOf2(key.length)];
    random.fill(input, 0, input.length);
    long t0 = System.currentTimeMillis();
    for (int i = 0; i < numRounds; i++) {
      cipher.update(input, 0, input.length);
    }
    long t1 = System.currentTimeMillis();
    System.err.println(factory.getName() + "[" + numRounds + "]: " + (t1 - t0) + " ms");
  }

  static boolean checkCipher(String cipher) {
    try {
      Class<?> c = Class.forName(cipher);
      com.jcraft.jsch.Cipher _c = (com.jcraft.jsch.Cipher) (c.newInstance());
      _c.init(
          com.jcraft.jsch.Cipher.ENCRYPT_MODE,
          new byte[_c.getBlockSize()],
          new byte[_c.getIVSize()]);
      return true;
    } catch (Exception e) {
      System.err.println(
          "checkCipher(" + cipher + ") " + e.getClass().getSimpleName() + ": " + e.getMessage());
      return false;
    }
  }
}