Martin Peters created SSHD-1188:
-----------------------------------

             Summary: OpenMode and CopyMode is not honored as expected in 
version > 4 of SFTP api
                 Key: SSHD-1188
                 URL: https://issues.apache.org/jira/browse/SSHD-1188
             Project: MINA SSHD
          Issue Type: Bug
    Affects Versions: 2.5.1
            Reporter: Martin Peters


When calling 
{code:java}
sftpClient.write(remoteFileName, OpenMode.Create, OpenMode.Write, 
OpenMode.Exclusive);{code}
I expect the operation to succeed if no file with that name exists and fail if 
a file with that name exists. This works as expected when using a 
SftpVersionSelector to force version 3 or 4. Version 5 or 6 will overwrite the 
existing file.

 

Similarly I expect the line below to fail when newName already exists.
{code:java}
sftpClient.rename(oldName, newName);
{code}
This works as expected in version 3 or 4. In version 5 or 6 the existing file 
is overwritten.

I expect the following line which is not supported in version 3 or 4 to fail 
when the newName file already exists when using 5 or 6 but it still overwrites 
any existing file:
{code:java}
sftpClient.rename(oldName, newName, CopyMode.Atomic);
{code}
 

I'm using 2.5 but issue seems to be the same in 2.7.

 

I have tested this using apache mina server & client, including a quick and 
dirty test to demonstrate the OpenMode issue:
{code:java}
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;

import java.io.IOException;
import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.sshd.client.SshClient;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.client.subsystem.sftp.SftpClient;
import org.apache.sshd.client.subsystem.sftp.SftpClientFactory;
import org.apache.sshd.client.subsystem.sftp.SftpVersionSelector;
import org.apache.sshd.common.file.virtualfs.VirtualFileSystemFactory;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

public class BugMVP {

   @Rule
   public TemporaryFolder testFolder = new TemporaryFolder();

   private static final String USERNAME = "username";

   private static final String PASSWORD = "password";

   private SshServer sshd;

   @Before
   public void prepare() throws IOException {
      Map<String, String> roots = new HashMap<>();
      roots.put(USERNAME, testFolder.getRoot().getAbsolutePath());

      sshd = SshServer.setUpDefaultServer();
      sshd.setFileSystemFactory(new 
VirtualFileSystemFactory(testFolder.getRoot().toPath()));
      sshd.setPort(42414);
      sshd.setSubsystemFactories(Collections.singletonList(new 
SftpSubsystemFactory()));
      sshd.setKeyPairProvider(new 
SimpleGeneratorHostKeyProvider(testFolder.newFile("hostkey.ser").toPath()));
      sshd.setPasswordAuthenticator((username, password, session) -> 
username.equals(USERNAME) && password.equals(PASSWORD));
      sshd.start();

      testFolder.newFolder("somefolder");
      testFolder.newFile("somefolder/foo.bar");
   }

   @Test
   public void testUploadingFileUsingDefaultVersion6_shouldFail() throws 
IOException {
      SshClient client = SshClient.setUpDefaultClient();
      client.start();

      ClientSession clientSession = client.connect(USERNAME, "localhost", 42414)
            .verify(Duration.ofSeconds(10))
            .getSession();

      clientSession.addPasswordIdentity(PASSWORD);
      clientSession.auth().verify(Duration.ofSeconds(10));

      SftpClientFactory factory = SftpClientFactory.instance();
      SftpClient sftpClient = factory.createSftpClient(clientSession);

      try (sftpClient; clientSession) {
         sftpClient.write("somefolder/foo.bar", SftpClient.OpenMode.Write, 
SftpClient.OpenMode.Create, SftpClient.OpenMode.Exclusive);
         assertFalse(true);
      } catch (IOException e){
         assertEquals("File/Directory already exists",e.getMessage());
      }
   }

   @Test
   public void testUploadingFileUsingV4_shouldFail() throws IOException {
      SshClient client = SshClient.setUpDefaultClient();
      client.start();

      ClientSession clientSession = client.connect(USERNAME, "localhost", 42414)
            .verify(Duration.ofSeconds(10))
            .getSession();

      clientSession.addPasswordIdentity(PASSWORD);
      clientSession.auth().verify(Duration.ofSeconds(10));

      SftpVersionSelector versionSelector = (session, initial, current, 
available) -> {
         return 4;
      };
      SftpClientFactory factory = SftpClientFactory.instance();
      SftpClient sftpClient = factory.createSftpClient(clientSession, 
versionSelector);

      try (sftpClient; clientSession) {
         sftpClient.write("somefolder/foo.bar", SftpClient.OpenMode.Write, 
SftpClient.OpenMode.Create, SftpClient.OpenMode.Exclusive);
         assertFalse(true);
      } catch (IOException e){
         assertEquals("File/Directory already exists",e.getMessage());
      }
   }

}
{code}
 



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to