2016-07-09 104 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會議是非常有用的。