hexo/node_modules/ssh2/examples/sftp-server-download-only.js

97 lines
3.8 KiB
JavaScript
Raw Normal View History

2023-10-03 11:14:36 +08:00
var constants = require('constants');
var fs = require('fs');
var ssh2 = require('ssh2');
var OPEN_MODE = ssh2.SFTP_OPEN_MODE;
var STATUS_CODE = ssh2.SFTP_STATUS_CODE;
new ssh2.Server({
hostKeys: [fs.readFileSync('host.key')]
}, function(client) {
console.log('Client connected!');
client.on('authentication', function(ctx) {
if (ctx.method === 'password'
&& ctx.username === 'foo'
&& ctx.password === 'bar')
ctx.accept();
else
ctx.reject(['password']);
}).on('ready', function() {
console.log('Client authenticated!');
client.on('session', function(accept, reject) {
var session = accept();
session.on('sftp', function(accept, reject) {
console.log('Client SFTP session');
var openFiles = {};
var handleCount = 0;
// `sftpStream` is an `SFTPStream` instance in server mode
// see: https://github.com/mscdex/ssh2-streams/blob/master/SFTPStream.md
var sftpStream = accept();
sftpStream.on('OPEN', function(reqid, filename, flags, attrs) {
console.log('OPEN', filename);
// only allow opening /tmp/foo.txt for writing
if (filename !== '/tmp/foo.txt' || !(flags & OPEN_MODE.READ))
return sftpStream.status(reqid, STATUS_CODE.FAILURE);
// create a fake handle to return to the client, this could easily
// be a real file descriptor number for example if actually opening
// the file on the disk
var handle = new Buffer(4);
openFiles[handleCount] = { read: false };
handle.writeUInt32BE(handleCount++, 0, true);
sftpStream.handle(reqid, handle);
console.log('Opening file for read')
}).on('READ', function(reqid, handle, offset, length) {
if (handle.length !== 4 || !openFiles[handle.readUInt32BE(0, true)])
return sftpStream.status(reqid, STATUS_CODE.FAILURE);
// fake the read
var state = openFiles[handle.readUInt32BE(0, true)];
if (state.read)
sftpStream.status(reqid, STATUS_CODE.EOF);
else {
state.read = true;
sftpStream.data(reqid, 'bar');
console.log('Read from file at offset %d, length %d', offset, length);
}
}).on('CLOSE', function(reqid, handle) {
var fnum;
if (handle.length !== 4 || !openFiles[(fnum = handle.readUInt32BE(0, true))])
return sftpStream.status(reqid, STATUS_CODE.FAILURE);
delete openFiles[fnum];
sftpStream.status(reqid, STATUS_CODE.OK);
console.log('Closing file');
}).on('REALPATH', function(reqid, path) {
var name = [{
filename: '/tmp/foo.txt',
longname: '-rwxrwxrwx 1 foo foo 3 Dec 8 2009 foo.txt',
attrs: {}
}];
sftpStream.name(reqid, name);
}).on('STAT', onSTAT)
.on('LSTAT', onSTAT);
function onSTAT(reqid, path) {
if (path !== '/tmp/foo.txt')
return sftpStream.status(reqid, STATUS_CODE.FAILURE);
var mode = constants.S_IFREG; // Regular file
mode |= constants.S_IRWXU; // read, write, execute for user
mode |= constants.S_IRWXG; // read, write, execute for group
mode |= constants.S_IRWXO; // read, write, execute for other
sftpStream.attrs(reqid, {
mode: mode,
uid: 0,
gid: 0,
size: 3,
atime: Date.now(),
mtime: Date.now()
});
}
});
});
}).on('end', function() {
console.log('Client disconnected');
});
}).listen(0, '127.0.0.1', function() {
console.log('Listening on port ' + this.address().port);
});