Announcement

Collapse
No announcement yet.

SFTP issue with timestamps and permissions

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • SFTP issue with timestamps and permissions

    Background
    ----------------
    This one is a bit of a head scratcher. I am working with a 3rd party company that hosts the SFTP. I have no say in the server setup. They have configured it in such a way that filezilla, winscp, and Mirth all throw an error when putting a file.

    The error deals with preserving the time stamp of the file and also explicitly setting the permission. Now there are special GUI options for filezilla and winscp that you can select that will work around this error.

    I believe that the sftp option is -p that accomplishes the same thing. But i don't know how to invoke this in the sftp reader.

    I have tried settings -p in the configuration options of the sftp settings ( wrench). I have tried -p as the name and -p as a value.

    The file technically makes it but mirth throws an error thus queuing the message.

    The Question?
    ------------------
    How can I use the configuration options of sftp to not preserve the time stamp of files sent across?

    And what option is required to allow the server to apply the default permissions?

    Am I misusing the config options and instead must use a javascript writer? If so how do i pass the -p flag in code?

  • #2
    Have you tried using JavaScript Writer with JSch instead of File Writer and the preprogrammed SFTP process? There is more flexibility there.

    Comment


    • #3
      @cbarlow: No, i have not tried that yet. I haven't any experience with that option. It seems the option to pass a flag would be available in the sftp selection.

      I will begin working on your suggestion.

      Comment


      • #4
        Here is my javascript writer code. May help set you on your path.

        var ip = '127.0.0.1';
        var port = '2222';
        var user = 'user';
        var pass = 'mypass';
        var directory = 'C:/temp';
        /************************************************** ***********************/
        importPackage(com.jcraft.jsch);
        importPackage(Packages.java.io);

        var date = DateUtil.getCurrentDate('yyyy-MM-dd_HH.mm.ss');

        importPackage(com.jcraft.jsch);
        var jsch = new JSch(); //Java Secure Channel
        jsch.setConfig('StrictHostKeyChecking','no'); //Ignore the pop up for the Key
        jsch.setConfig('HashKnownHosts','no'); //Dont Hash, just move on
        var session = jsch.getSession(user,ip,port); //establish a session to the SSH server
        session.setPassword(pass); //set password
        session.setTimeout(10000); //set timeout
        session.setServerAliveInterval(0); //don't keep checking the connection
        session.connect(); //open the session
        var channel = session.openChannel('sftp'); //open an sftp channel connection
        channel.connect(); //connect to the sftp channel
        channel.cd('Elite'); //change directory
        var folder = new File(directory);
        var directoryList = folder.listFiles();
        var totalFileCount = directoryList.length;
        for (var i = 0; i < totalFileCount; i++) {
        if(directoryList[i].isFile()) {
        var file = directoryList[i];
        var fileName = file.getName();
        channel.put(file,date + '_' + fileName); //write file to current directory
        FileUtil.write(directory + '/archive/' + fileName,false,FileUtil.read(file));
        FileUtil.deleteFile(file);
        }
        }
        channel.exit(); //exit the sftp channel
        channel.disconnect(); //disconnect the sftp channel
        session.disconnect(); //disconnect the session to the SSH server

        Comment


        • #5
          I have actually built something super close to this. I would really like to keep 'StrictHostKeyChecking' set to 'yes' for security. But i cannot for the life of me figure out how to use setKnownHosts. It always replys with unknown host. I have used the RSA key in the error and I have also used the actual key returned from mySession.getHostKey().key.

          I am trying to follow the comments from this page https://dentrassi.de/2015/07/13/prog...key-with-jsch/.

          Below is what I have so far. I have yet to see the call to sftpChannel.getHome() work. And because of that I haven't even started working on the put files.


          Any idea how to manipulate the hosts file?


          Code:
          var username = 'aUserName';
          var password = 'thePassword';
          var host = 'sshftp.somePlaceOutThere.com';
          var port = 22;
          
          
          // the following key is fake. but you will get the idea there is a space after the url entry.
          
          var knownHostPublicKey = "sshftp.somePlaceOutThere.com AAAABAAAAAAAAAEAAAABIwAAAQEAxaHm6weHW2lzjnoFfruIBakFFOUB8K/5FGxBX56GjwFF1gxp7t9vK9PAAABBBBBx5k9iDf8ENeOtwzZZ0RUw/ahiin0CpaGnrW6YBYuP94WZRDWd8+LuxTHqlBGpM2K7s3C8qRSHedyci7rzozrAaOUdRlGhCivJBsw9kI0123456789BT5SV98765432165498765X/+k+/V8cuesf+zYYFi1Liq4TI/6x/HvABbvo2dj6kQZMv8Z50w8aABrKJE/N/Z8pB31hEOfyZTV+D2DTMNGh4S2nF69qyCgwiAAAAAAtdoJty+zneG6g1Efw2+MTU3tPOPx7k9UZw=="; 
          
          
          
          try{
            var mySecureConnection = new com.jcraft.jsch.JSch();
            mySecureConnection.setConfig('StrictHostKeyChecking','yes');
            mySecureConnection.setKnownHosts(new java.io.ByteArrayInputStream(knownHostPublicKey.getBytes()))
            
          logger.warn("Key Repo: " + mySecureConnection.getHostKeyRepository());
            
            var mySession = mySecureConnection.getSession(username, host, port);
            mySession.setPassword(password);
            mySession.setTimeout(15000);  
            mySession.connect();
            try{
            	logger.warn("Ok, connected to session.");
            	logger.warn("Host: " + mySession.getHost());
            	logger.warn("Key: " + mySession.getHostKey().key);
            	var sftpChannel = mySession.openChannel('sftp');
            	try{
            	  logger.warn("Channel Home:" + sftpChannel.getHome());
            	}
            	finally{
            		sftpChannel.exit();
            	}
            }
            finally{
              mySession.disconnect();
            }
          }
          catch (e){
            logger.error(e)	
          }

          Comment


          • #6
            Sorry I do not. I would have to do some googling and playing to see if I could figure it out.

            Comment


            • #7
              Solution

              I have solved the issue. And i have included the additional security. Below is the code snippets with full explanation. Much thanks to cbarlow for the example code.


              Code:
              var username = "aUsername";
              var password = "ThePassword";
              var host = "sshftp.SomeWhereOutThere.com";
              var port = 22;
              
              //the following 64 bit encoded key is fake and is also the incorrect length
              var knownHostPublicKey = new java.lang.String("sshftp.SomeWhereOutThere.com,123.56.189.256 ssh-rsa AAAAB3NzaAAAc2EAAAABIwAAAQEAxaHm6weHW2lzjnoFfruIBakFFOUB8K/5FGxBX56Gj9841819p7t9vK9PcRUWE6C2x5k9iDf8ENeO818VS0CpaGnrW6YBYuP94WZRDAAA+LuxTHqlBGpM2K7s3C8qRSHedyci7rzozrAaOUdRlGhCivJBsw9kI+MeAAAAiFBkclBT5SVBLugTLix45lBIA89dE8AX/+k+/V8fYYFi1Liq4TI/6x/HvABbvo2dj6kQZMv8Z50asdfa1hEOfyZTV+D2DTMNGh4+zScues2nF69qyCgwiTeav8C84adsfy+zneG6g1Efw2+MTU3tPOPx7k9UZw==");
              The java.lang.String is very important. Java Strings have the getBytes as a member function. Second I had a poorly formed known hosts string. The host and IP are comma separated with no space. The second entry is the algorithm (ssh-rsa or ssh-des) finally the 3rd entry is the key.


              Code:
              var mySecureConnection = new com.jcraft.jsch.JSch();
              mySecureConnection.setConfig("StrictHostKeyChecking","yes");
              mySecureConnection.setConfig("HashKnownHosts", "no")
              mySecureConnection.setKnownHosts(new java.io.ByteArrayInputStream(knownHostPublicKey.getBytes()))
              Using setKnownHosts with a byteArrayInputStream will write the single host to the white list in real time. No Man-in-the-Middle attacks for me.

              Code:
                
              var mySession = mySecureConnection.getSession(username, host, port);
              mySession.setPassword(password);
              mySession.setTimeout(15000);
              mySession.setServerAliveInterval(0); 
              mySession.connect();
              try{
                var sftpChannel = mySession.openChannel('sftp');
                try{
                  sftpChannel.connect();
              Ok, my issue was I had the open/connect chain in the wrong order. It is getSession, connect that session, openChannel, then CONNECT the channel. I was missing the actual channel connection. It is 2 opens, 2 connects.

              Code:
                  try{
                    sftpChannel.cd("incoming/FilePath");
                    var inputStream = new java.io.ByteArrayInputStream(
                      connectorMessage.getRawData().getBytes(java.nio.charset.StandardCharsets.UTF_8)
                    );
                    try{
                	   sftpChannel.put(
                	     inputStream,
                           $('originalFilename')
                	   );
                	 }
              Using connectorMessage.getRawData() will pull the huge string that is the file from the source connector. getBytes will read it into the byteArraystream. Then you can dump that stream onto the sftp with the files original name.

              Code:
                	 catch (e){
                	   logger.error('I caught the file write error: ' + e.message);
                	 }
                  }
                  finally{
                    sftpChannel.exit();
                  }
                }
                finally{
                  sftpChannel.disconnect();
                }
              }
              finally{
                mySession.disconnect();
              }

              I don't even need that worthless catch message because uisng JSCH to invoke an sftp doesn't automatically try to preserve time stamps, or set permissions. So I coded around my initial issue without having to just supress the error message.

              Comment

              Working...
              X