2016-07-09 88 views
0

我实现基于libssh SFTP服务器的NodeJS脚本(NPM安装SSH)SFTP服务器的NodeJS访问错误

var config = require('config'); 
var fs = require('fs'); 
var path = require('path'); 
var libssh = require('ssh'); 

var server; 
var options = { 
    host: 'localhost', 
    port: '3022', 
    // Get the common name of ssh_keys 
    host_key: config.get('logshipper.sftp.host_key'), 
    // Root path of SFTP folder on the machine 
    root: path.join(__dirname, config.get('logshipper.sftp.root')), 
    test_username: 'correct_username', 
    test_password: 'correct_password' 
}; 

server = libssh.createServer({ 
    hostRsaKeyFile: __dirname + '/ssh_keys/' + 'rsa_' + options.host_key, 
    hostDsaKeyFile: __dirname + '/ssh_keys/' + 'dsa_' + options.host_key 
}); 

server.on('connection', function (session) { 
    session.on('auth', function (message) { 
     // Maybe check username/password 
     return message.replyAuthSuccess(); 
    }); 

    session.on('channel', function (channel) { 
     channel.on('subsystem', function (message) { 
      if (message.subsystem == 'sftp') { 
       message.replySuccess(); 
       message.sftpAccept(); 
      } 
     }); 

     channel.on('sftp:realpath', function (message) { 
      console.log('server cmd sftp:realpath'); 
      if (message.filename == '.' || (/\/$/).test(message.filename)) { 
       message.replyName(path.join(options.root, message.filename), { 
        permissions: +libssh.Stat('777').dir() 
       }) 
      } else { 
       message.replyName(message.filename, { 
        permissions: +libssh.Stat('777').reg() 
       }) 
      } 
     }); 

     channel.on('sftp:stat', statHandle); 

     function statHandle(message) { 
      console.log('server cmd sftp:stat'); 

      var attrs = { 
       permissions: +libssh.Stat(777).dir() 
       , uid: 101 
       , gid: 202 
       , size: 100 
       , atime: Date.now() 
       , mtime: Date.now() 
      }; 

      message.replyAttr(attrs) 
     } 

     // can be handled the same way as 'stat' if you like 
     channel.on('sftp:lstat', statHandle); 

     channel.on('sftp:opendir', function (message) { 
      console.log('server cmd sftp:opendir'); 
      message.replyHandle(message.filename + '/'); 
     }); 

     var lastmsg; 
     channel.on('sftpmessage', function (message) { 
      lastmsg = message 
     }); 

     channel.on('sftp:readdir', function (message) { 
      console.log('server cmd sftp:readdir', message.handle); 

      if (lastmsg.type == 'readdir') { 
       return message.replyStatus('ok'); 
      } 

      var readPath = message.handle; 
      fs.readdir(readPath, function(err, files) { 
       if (err) { 
        console.log(err); 
        throw err; 

       } else { 
        files = files.map(function(file) { 
         return { 
          filename: file, 
          longname: file, 
          attrs: { permissions: +libssh.Stat(644).reg() } 
         }; 
        }); 
        return message.replyNames(files); 
       } 
      }); 
     }); 

     channel.on('sftp:close', function (message) { 
      console.log('server cmd sftp:close'); 
      message.replyStatus('ok'); 
     }) 
    }) 
}); 

server.listen(options.port, options.host); 
console.log('Listening on port ' + options.port); 

的Ubuntu 14.04,0.10.25的NodeJS 在sftp.root目录中我有测试 - 文件我应该可以下载到,检查它是否SFTP服务器上,等

当我使用SFTP(Ubuntu的cmd以连接到服务器,我得到):

sftp -P 3022 localhost 
Connected to localhost. 
sftp> dir 
Couldn't read directory: No error 
test-file 
sftp> 

服务器输出:

/usr/bin/node sftpServer.js 
Listening on port 3022 
server cmd sftp:realpath 
server cmd sftp:opendir 
server cmd sftp:readdir /home/MyFolder/uploads/ 
server cmd sftp:readdir /home/MyFolder/uploads/ 
server cmd sftp:close 

无法读取目录:没有错误

但它实际上是一个考验,我需要通过lftp的与此服务器的工作

lftp sftp://localhost:3022 
lftp localhost:~> dir 
ls: ls: Access failed:  
lftp localhost:~> 

我正在访问失败的错误。我试图使文件夹chmod 777或标记为根组,并没有帮助。

我希望有人会研究它,并帮助我弄清楚为什么出现这个访问错误,谢谢!

回答

1

最后的回复名称应该包含EOF标志,并且replyStatus必须具有代码SSH_FX_EOF。否则,状态被视为错误。 也许这段代码会做:

 if (lastmsg.type == 'readdir') { 
      return message.replyStatus('eof'); 
     } 

打开调试中的lftp看到协议报文,然后比较成功的不成功的VS会议是非常有用的。