1

i want to start a Sftp server by embedding it in my java code . when i start the Sftp server and then start the client , the exception throws .

my server code

public class EmbeddedSftpServer  {
    public static  final String SERVER_BASE_DIR = System.getProperty("user.dir") + File.separator + "src";
  //  public static  final String SERVER_KEYSTORE = SERVER_BASE_DIR + File.separator + "resources" + File.separator + "ftpserver.jks";
    public static  final String SERVER_KEYSTORE= "C:\\Users\\y73wang\\IdeaProjects\\SFTPServer\\src\\main\\resources\\ftpserver.jks";
    //public static  final String SERVER_USERS = SERVER_BASE_DIR + File.separator + "resources" + File.separator + "users.properties";
    public static  final String SERVER_USERS ="C:\\Users\\y73wang\\IdeaProjects\\SFTPServer\\src\\main\\resources\\users.properties";
    //public static  final String USER_HOME_DIR = SERVER_BASE_DIR + File.separator + "SftpHomeDir" ;
    public static  final String USER_HOME_DIR = "D:\\TEST";
    public static  final String SAMPLE_FILE = "test.txt";
    public static  final String ADMIN = "admin";
    public static  final String PASSWORD = "password";
    public static  final int DEFAULT_PORT =8009;
    private final FtpServer server;

    public static EmbeddedSftpServer createDefaultServer() throws Exception {
        return  new EmbeddedSftpServer(DEFAULT_PORT,ADMIN,PASSWORD,true);
    }
    public EmbeddedSftpServer( int port, String username, String password, boolean implicitSsl ) throws Exception {
        this.server = createServer( port, username, password, implicitSsl );
    }

    private FtpServer createServer( int port, String username, String password, boolean implicitSsl ) throws FtpException {
        ListenerFactory factory = new ListenerFactory();
        factory.setPort( port );
        if ( implicitSsl ) {
            SslConfigurationFactory ssl = new SslConfigurationFactory();
            ssl.setKeystoreFile( new File( SERVER_KEYSTORE ) );
            ssl.setKeystorePassword( PASSWORD );
            // set the SSL configuration for the listener
            factory.setSslConfiguration( ssl.createSslConfiguration() );
            factory.setImplicitSsl( true );
        }

        FtpServerFactory serverFactory = new FtpServerFactory();
        // replace the default listener
        serverFactory.addListener( "default", factory.createListener() );

        PropertiesUserManagerFactory userManagerFactory = new PropertiesUserManagerFactory();

        userManagerFactory.setFile( new File( SERVER_USERS ) );
        UserManager userManager = userManagerFactory.createUserManager();
        if ( !userManager.doesExist( username ) ) {
            BaseUser user = new BaseUser();
            user.setName( username );
            user.setPassword( password );
            user.setEnabled( true );
            user.setHomeDirectory( USER_HOME_DIR );
            user.setAuthorities( Collections.<Authority>singletonList( new WritePermission() ) );
            userManager.save( user );
        }

        serverFactory.setUserManager( userManager );
        return serverFactory.createServer();
    }
    public void start() throws FtpException {
        server.start();
    }
    public void stop(){
        if (server != null){
            server.stop();
        }
    }
   public static  void main(String[] args) throws Exception {
       EmbeddedSftpServer sftpServer = new EmbeddedSftpServer(DEFAULT_PORT,"admin","admin",true);
       sftpServer.start();
   }
}

user.properties:

# Password is "admin"
ftpserver.user.admin.userpassword=21232F297A57A5A743894A0E4A801FC3
ftpserver.user.admin.homedirectory=D:/test
ftpserver.user.admin.enableflag=true
ftpserver.user.admin.writepermission=true
ftpserver.user.admin.maxloginnumber=10
ftpserver.user.admin.maxloginperip=10
ftpserver.user.admin.idletime=0
ftpserver.user.admin.uploadrate=0
ftpserver.user.admin.downloadrate=0

ftpserver.user.anonymous.userpassword=
ftpserver.user.anonymous.homedirectory=D:/test
ftpserver.user.anonymous.enableflag=true
ftpserver.user.anonymous.writepermission=false
ftpserver.user.anonymous.maxloginnumber=20
ftpserver.user.anonymous.maxloginperip=2
ftpserver.user.anonymous.idletime=300
ftpserver.user.anonymous.uploadrate=4800
ftpserver.user.anonymous.downloadrate=4800

the Client code :

public class JschClient {
public void sendFile(String filename) throws JSchException, SftpException, FileNotFoundException {
    int Port =22;
    String sftphost = "127.0.0.1";
    String userName = "admin";
    String password = "admin";
    String HomeDir = "D:\\test";
    Session session =null;
    Channel channel =null;
    ChannelSftp channelSftp = null;
    JSch jSch = new JSch();
    session =jSch.getSession(userName,sftphost,8009);
    java.util.Properties config = new java.util.Properties();
    config.put("StrictHostKeyChecking","no");
    config.put("PreferredAuthentications", "password");
    session.setConfig(config);
    session.setPassword(password);
    session.connect(60000);
    channel = session.openChannel("sftp");
    channel.connect();
    channelSftp = (ChannelSftp) channel;
    ((ChannelSftp) channel).cd(HomeDir);
    File f = new File(filename);
    channelSftp.put(new FileInputStream(f),f.getName());
    channelSftp.exit();
    System.out.println("sftp Channel exited.");
    channel.disconnect();
    System.out.println("Channel disconnected.");
    session.disconnect();
    System.out.println("Host Session disconnected.");
}
public static void main(String[]agrs) throws FileNotFoundException, JSchException, SftpException {
    JschClient jschClient = new JschClient();
    jschClient.sendFile("D:\\file1.txt");
}

error log:

Exception in thread "main" com.jcraft.jsch.JSchException: connection is closed by foreign host
at com.jcraft.jsch.Session.connect(Session.java:269)
at client.JschClient.sendFile(JschClient.java:29)
at client.JschClient.main(JschClient.java:45)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

is there any wrong in my code ?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Wang Yue
  • 21
  • 1
  • 1
  • 4

4 Answers4

1

You are starting an FTP server, but connecting to it using an SFTP client.

That cannot work. The FTP and SFTP are two completely different and incompatible protocols.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
1

May be i am very late to answer your question but still if anyone needs how to connect with SFTP using jsch library.

You can use below method

   static Session session = null;
    static Channel channel = null;


public Session sftpConnection(final String value, final String sftpUser, final String sftpHost, final int sftpPort,
        final String sftpPass) {
        System.out.println("preparing the host information for sftp.");
        try {
            JSch jsch = new JSch();
            this.session = jsch.getSession(sftpUser, sftpHost, sftpPort);
            if (value.equals("puttyServer")) {
                this.session.setProxy(new ProxySOCKS5("proxy need to add", Integer.parseInt("portnumber need to add")));
            }
            this.session.setPassword(sftpPass);
            java.util.Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            this.session.setConfig(config);
            this.session.connect();
            return this.session;
        } catch (Exception ex) {
            ex.printStackTrace();
            sftpConnection(value, sftpUser, sftpHost, sftpPort, sftpPass);
        }
        return null;
    }
1

This could be the issue of whitelisting the servers. Consider there are two servers named X and Y and You are trying to connect to Y from X using Jsch SFTP. In that case, server X should be in white list of server Y.

**************CODE BLOCK of SESSION CLASS********

while(true){
        i=0;
        j=0;
        while(i<buf.buffer.length){
          **j=io.getByte();** //io.getByte() reads the key which is shared between two servers
          if(j<0)break;
          buf.buffer[i]=(byte)j; i++; 
          if(j==10)break;
        }
        if(j<0){
          throw new JSchException("connection is closed by foreign host");
        }

0

just tweak the sshd_config 'MaxStartups' count, for example 'MaxStartups 1000', and restart ssh

Rinoux
  • 11
  • 3