first commit

This commit is contained in:
s.golasch
2023-08-01 13:49:46 +02:00
commit 1fc239fd54
20238 changed files with 3112246 additions and 0 deletions

18
build/node_modules/ssh2/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,18 @@
sudo: false
language: cpp
notifications:
email: false
env:
matrix:
- TRAVIS_NODE_VERSION="0.10"
- TRAVIS_NODE_VERSION="0.12"
- TRAVIS_NODE_VERSION="4"
- TRAVIS_NODE_VERSION="6"
- TRAVIS_NODE_VERSION="7"
install:
- rm -rf ~/.nvm && git clone https://github.com/creationix/nvm.git ~/.nvm && source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION
- node --version
- npm --version
- npm install
- ssh -V
script: npm test

19
build/node_modules/ssh2/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright Brian White. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to
deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.

1053
build/node_modules/ssh2/README.md generated vendored Normal file

File diff suppressed because it is too large Load Diff

243
build/node_modules/ssh2/examples/server-chat.js generated vendored Normal file
View File

@@ -0,0 +1,243 @@
// **BEFORE RUNNING THIS SCRIPT:**
// 1. The server portion is best run on non-Windows systems because they have
// terminfo databases which are needed to properly work with different
// terminal types of client connections
// 2. Install `blessed`: `npm install blessed`
// 3. Create a server host key in this same directory and name it `host.key`
var fs = require('fs');
var blessed = require('blessed');
var Server = require('ssh2').Server;
var RE_SPECIAL = /[\x00-\x1F\x7F]+|(?:\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K])/g;
var MAX_MSG_LEN = 128;
var MAX_NAME_LEN = 10;
var PROMPT_NAME = 'Enter a nickname to use (max ' + MAX_NAME_LEN + ' chars): ';
var users = [];
function formatMessage(msg, output) {
var output = output;
output.parseTags = true;
msg = output._parseTags(msg);
output.parseTags = false;
return msg;
}
function userBroadcast(msg, source) {
var sourceMsg = '> ' + msg;
var name = '{cyan-fg}{bold}' + source.name + '{/}';
msg = ': ' + msg;
for (var i = 0; i < users.length; ++i) {
var user = users[i];
var output = user.output;
if (source === user)
output.add(sourceMsg);
else
output.add(formatMessage(name, output) + msg);
}
}
function localMessage(msg, source) {
var output = source.output;
output.add(formatMessage(msg, output));
}
function noop(v) {}
new Server({
hostKeys: [fs.readFileSync('host.key')],
}, function(client) {
var stream;
var name;
client.on('authentication', function(ctx) {
var nick = ctx.username;
var prompt = PROMPT_NAME;
var lowered;
// Try to use username as nickname
if (nick.length > 0 && nick.length <= MAX_NAME_LEN) {
lowered = nick.toLowerCase();
var ok = true;
for (var i = 0; i < users.length; ++i) {
if (users[i].name.toLowerCase() === lowered) {
ok = false;
prompt = 'That nickname is already in use.\n' + PROMPT_NAME;
break;
}
}
if (ok) {
name = nick;
return ctx.accept();
}
} else if (nick.length === 0)
prompt = 'A nickname is required.\n' + PROMPT_NAME;
else
prompt = 'That nickname is too long.\n' + PROMPT_NAME;
if (ctx.method !== 'keyboard-interactive')
return ctx.reject(['keyboard-interactive']);
ctx.prompt(prompt, function retryPrompt(answers) {
if (answers.length === 0)
return ctx.reject(['keyboard-interactive']);
nick = answers[0];
if (nick.length > MAX_NAME_LEN) {
return ctx.prompt('That nickname is too long.\n' + PROMPT_NAME,
retryPrompt);
} else if (nick.length === 0) {
return ctx.prompt('A nickname is required.\n' + PROMPT_NAME,
retryPrompt);
}
lowered = nick.toLowerCase();
for (var i = 0; i < users.length; ++i) {
if (users[i].name.toLowerCase() === lowered) {
return ctx.prompt('That nickname is already in use.\n' + PROMPT_NAME,
retryPrompt);
}
}
name = nick;
ctx.accept();
});
}).on('ready', function() {
var rows;
var cols;
var term;
client.once('session', function(accept, reject) {
accept().once('pty', function(accept, reject, info) {
rows = info.rows;
cols = info.cols;
term = info.term;
accept && accept();
}).on('window-change', function(accept, reject, info) {
rows = info.rows;
cols = info.cols;
if (stream) {
stream.rows = rows;
stream.columns = cols;
stream.emit('resize');
}
accept && accept();
}).once('shell', function(accept, reject) {
stream = accept();
users.push(stream);
stream.name = name;
stream.rows = rows || 24;
stream.columns = cols || 80;
stream.isTTY = true;
stream.setRawMode = noop;
stream.on('error', noop);
var screen = new blessed.screen({
autoPadding: true,
smartCSR: true,
program: new blessed.program({
input: stream,
output: stream
}),
terminal: term || 'ansi'
});
screen.title = 'SSH Chatting as ' + name;
// Disable local echo
screen.program.attr('invisible', true);
var output = stream.output = new blessed.log({
screen: screen,
top: 0,
left: 0,
width: '100%',
bottom: 2,
scrollOnInput: true
})
screen.append(output);
screen.append(new blessed.box({
screen: screen,
height: 1,
bottom: 1,
left: 0,
width: '100%',
type: 'line',
ch: '='
}));
var input = new blessed.textbox({
screen: screen,
bottom: 0,
height: 1,
width: '100%',
inputOnFocus: true
});
screen.append(input);
input.focus();
// Local greetings
localMessage('{blue-bg}{white-fg}{bold}Welcome to SSH Chat!{/}\n'
+ 'There are {bold}'
+ (users.length - 1)
+ '{/} other user(s) connected.\n'
+ 'Type /quit or /exit to exit the chat.',
stream);
// Let everyone else know that this user just joined
for (var i = 0; i < users.length; ++i) {
var user = users[i];
var output = user.output;
if (user === stream)
continue;
output.add(formatMessage('{green-fg}*** {bold}', output)
+ name
+ formatMessage('{/bold} has joined the chat{/}', output));
}
screen.render();
// XXX This fake resize event is needed for some terminals in order to
// have everything display correctly
screen.program.emit('resize');
// Read a line of input from the user
input.on('submit', function(line) {
input.clearValue();
screen.render();
if (!input.focused)
input.focus();
line = line.replace(RE_SPECIAL, '').trim();
if (line.length > MAX_MSG_LEN)
line = line.substring(0, MAX_MSG_LEN);
if (line.length > 0) {
if (line === '/quit' || line === '/exit')
stream.end();
else
userBroadcast(line, stream);
}
});
});
});
}).on('end', function() {
if (stream !== undefined) {
spliceOne(users, users.indexOf(stream));
// Let everyone else know that this user just left
for (var i = 0; i < users.length; ++i) {
var user = users[i];
var output = user.output;
output.add(formatMessage('{magenta-fg}*** {bold}', output)
+ name
+ formatMessage('{/bold} has left the chat{/}', output));
}
}
}).on('error', function(err) {
// Ignore errors
});
}).listen(0, function() {
console.log('Listening on port ' + this.address().port);
});
function spliceOne(list, index) {
for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)
list[i] = list[k];
list.pop();
}

View File

@@ -0,0 +1,96 @@
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);
});

506
build/node_modules/ssh2/lib/Channel.js generated vendored Normal file
View File

@@ -0,0 +1,506 @@
var inherits = require('util').inherits;
var DuplexStream = require('stream').Duplex;
var ReadableStream = require('stream').Readable;
var WritableStream = require('stream').Writable;
var STDERR = require('ssh2-streams').constants.CHANNEL_EXTENDED_DATATYPE.STDERR;
var PACKET_SIZE = 32 * 1024;
var MAX_WINDOW = 1 * 1024 * 1024;
var WINDOW_THRESHOLD = MAX_WINDOW / 2;
var CUSTOM_EVENTS = [
'CHANNEL_EOF',
'CHANNEL_CLOSE',
'CHANNEL_DATA',
'CHANNEL_EXTENDED_DATA',
'CHANNEL_WINDOW_ADJUST',
'CHANNEL_SUCCESS',
'CHANNEL_FAILURE',
'CHANNEL_REQUEST'
];
var CUSTOM_EVENTS_LEN = CUSTOM_EVENTS.length;
function Channel(info, client, opts) {
var streamOpts = {
highWaterMark: MAX_WINDOW,
allowHalfOpen: (!opts || (opts && opts.allowHalfOpen !== false))
};
this.allowHalfOpen = streamOpts.allowHalfOpen;
DuplexStream.call(this, streamOpts);
var self = this;
var server = opts && opts.server;
this.server = server;
this.type = info.type;
this.subtype = undefined;
/*
incoming and outgoing contain these properties:
{
id: undefined,
window: undefined,
packetSize: undefined,
state: 'closed'
}
*/
var incoming = this.incoming = info.incoming;
var incomingId = incoming.id;
var outgoing = this.outgoing = info.outgoing;
var callbacks = this._callbacks = [];
var exitCode;
var exitSignal;
var exitDump;
var exitDesc;
var exitLang;
this._client = client;
this._hasX11 = false;
var channels = client._channels;
var sshstream = client._sshstream;
function ondrain() {
if (self._waitClientDrain) {
self._waitClientDrain = false;
if (!self._waitWindow) {
if (self._chunk)
self._write(self._chunk, null, self._chunkcb);
else if (self._chunkcb)
self._chunkcb();
else if (self._chunkErr)
self.stderr._write(self._chunkErr, null, self._chunkcbErr);
else if (self._chunkcbErr)
self._chunkcbErr();
}
}
}
client._sock.on('drain', ondrain);
sshstream.once('CHANNEL_EOF:' + incomingId, function() {
if (incoming.state === 'closed' || incoming.state === 'eof')
return;
incoming.state = 'eof';
if (self.readable)
self.push(null);
if (!server && self.stderr.readable)
self.stderr.push(null);
}).once('CHANNEL_CLOSE:' + incomingId, function() {
if (incoming.state === 'closed')
return;
incoming.state = 'closed';
if (self.readable)
self.push(null);
if (server && self.stderr.writable)
self.stderr.end();
else if (!server && self.stderr.readable)
self.stderr.push(null);
if (outgoing.state === 'open' || outgoing.state === 'eof')
self.close();
if (outgoing.state === 'closing')
outgoing.state = 'closed';
delete channels[incomingId];
var state = self._writableState;
client._sock.removeListener('drain', ondrain);
if (!state.ending && !state.finished)
self.end();
// Take care of any outstanding channel requests
self._callbacks = [];
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](true);
callbacks = self._callbacks;
if (!server) {
// align more with node child processes, where the close event gets the
// same arguments as the exit event
if (!self.readable) {
if (exitCode === null) {
self.emit('close', exitCode, exitSignal, exitDump, exitDesc,
exitLang);
} else
self.emit('close', exitCode);
} else {
self.once('end', function() {
if (exitCode === null) {
self.emit('close', exitCode, exitSignal, exitDump, exitDesc,
exitLang);
} else
self.emit('close', exitCode);
});
}
if (!self.stderr.readable)
self.stderr.emit('close');
else {
self.stderr.once('end', function() {
self.stderr.emit('close');
});
}
} else { // Server mode
if (!self.readable)
self.emit('close');
else {
self.once('end', function() {
self.emit('close');
});
}
}
for (var i = 0; i < CUSTOM_EVENTS_LEN; ++i)
sshstream.removeAllListeners(CUSTOM_EVENTS[i] + ':' + incomingId);
}).on('CHANNEL_DATA:' + incomingId, function(data) {
// the remote party should not be sending us data if there is no window
// space available ...
if (incoming.window === 0)
return;
incoming.window -= data.length;
if (!self.push(data)) {
self._waitChanDrain = true;
return;
}
if (incoming.window <= WINDOW_THRESHOLD)
windowAdjust(self);
}).on('CHANNEL_WINDOW_ADJUST:' + incomingId, function(amt) {
// the server is allowing us to send `amt` more bytes of data
outgoing.window += amt;
if (self._waitWindow) {
self._waitWindow = false;
if (!self._waitClientDrain) {
if (self._chunk)
self._write(self._chunk, null, self._chunkcb);
else if (self._chunkcb)
self._chunkcb();
else if (self._chunkErr)
self.stderr._write(self._chunkErr, null, self._chunkcbErr);
else if (self._chunkcbErr)
self._chunkcbErr();
}
}
}).on('CHANNEL_SUCCESS:' + incomingId, function() {
if (server) {
sshstream._kalast = Date.now();
sshstream._kacnt = 0;
} else
client._resetKA();
if (callbacks.length)
callbacks.shift()(false);
}).on('CHANNEL_FAILURE:' + incomingId, function() {
if (server) {
sshstream._kalast = Date.now();
sshstream._kacnt = 0;
} else
client._resetKA();
if (callbacks.length)
callbacks.shift()(true);
}).on('CHANNEL_REQUEST:' + incomingId, function(info) {
if (!server) {
if (info.request === 'exit-status') {
self.emit('exit', exitCode = info.code);
return;
} else if (info.request === 'exit-signal') {
self.emit('exit',
exitCode = null,
exitSignal = 'SIG' + info.signal,
exitDump = info.coredump,
exitDesc = info.description,
exitLang = info.lang);
return;
}
}
// keepalive request? OpenSSH will send one as a channel request if there
// is a channel open
if (info.wantReply)
sshstream.channelFailure(outgoing.id);
});
this.stdin = this.stdout = this;
if (server)
this.stderr = new ServerStderr(this);
else {
this.stderr = new ReadableStream(streamOpts);
this.stderr._read = function(n) {
if (self._waitChanDrain) {
self._waitChanDrain = false;
if (incoming.window <= WINDOW_THRESHOLD)
windowAdjust(self);
}
};
sshstream.on('CHANNEL_EXTENDED_DATA:' + incomingId,
function(type, data) {
// the remote party should not be sending us data if there is no window
// space available ...
if (incoming.window === 0)
return;
incoming.window -= data.length;
if (!self.stderr.push(data)) {
self._waitChanDrain = true;
return;
}
if (incoming.window <= WINDOW_THRESHOLD)
windowAdjust(self);
}
);
}
// outgoing data
this._waitClientDrain = false; // Client stream-level backpressure
this._waitWindow = false; // SSH-level backpressure
// incoming data
this._waitChanDrain = false; // Channel Readable side backpressure
this._chunk = undefined;
this._chunkcb = undefined;
this._chunkErr = undefined;
this._chunkcbErr = undefined;
function onFinish() {
self.eof();
if (server || (!server && !self.allowHalfOpen))
self.close();
self.writable = false;
}
this.on('finish', onFinish)
.on('prefinish', onFinish); // for node v0.11+
function onEnd() {
self.readable = false;
}
this.on('end', onEnd)
.on('close', onEnd);
}
inherits(Channel, DuplexStream);
Channel.prototype.eof = function() {
var ret = true;
var outgoing = this.outgoing;
if (outgoing.state === 'open') {
outgoing.state = 'eof';
ret = this._client._sshstream.channelEOF(outgoing.id);
}
return ret;
};
Channel.prototype.close = function() {
var ret = true;
var outgoing = this.outgoing;
if (outgoing.state === 'open' || outgoing.state === 'eof') {
outgoing.state = 'closing';
ret = this._client._sshstream.channelClose(outgoing.id);
}
return ret;
};
Channel.prototype._read = function(n) {
if (this._waitChanDrain) {
this._waitChanDrain = false;
if (this.incoming.window <= WINDOW_THRESHOLD)
windowAdjust(this);
}
};
Channel.prototype._write = function(data, encoding, cb) {
var sshstream = this._client._sshstream;
var outgoing = this.outgoing;
var packetSize = outgoing.packetSize;
var id = outgoing.id;
var window = outgoing.window;
var len = data.length;
var p = 0;
var ret;
var buf;
var sliceLen;
if (outgoing.state !== 'open')
return;
while (len - p > 0 && window > 0) {
sliceLen = len - p;
if (sliceLen > window)
sliceLen = window;
if (sliceLen > packetSize)
sliceLen = packetSize;
ret = sshstream.channelData(id, data.slice(p, p + sliceLen));
p += sliceLen;
window -= sliceLen;
if (!ret) {
this._waitClientDrain = true;
this._chunk = undefined;
this._chunkcb = cb;
break;
}
}
outgoing.window = window;
if (len - p > 0) {
if (window === 0)
this._waitWindow = true;
if (p > 0) {
// partial
buf = new Buffer(len - p);
data.copy(buf, 0, p);
this._chunk = buf;
} else
this._chunk = data;
this._chunkcb = cb;
return;
}
if (!this._waitClientDrain)
cb();
};
Channel.prototype.destroy = function() {
this.end();
};
// session type-specific methods
Channel.prototype.setWindow = function(rows, cols, height, width) {
if (this.server)
throw new Error('Client-only method called in server mode');
if (this.type === 'session'
&& (this.subtype === 'shell' || this.subtype === 'exec')
&& this.writable
&& this.outgoing.state === 'open') {
return this._client._sshstream.windowChange(this.outgoing.id,
rows,
cols,
height,
width);
}
return true;
};
Channel.prototype.signal = function(signalName) {
if (this.server)
throw new Error('Client-only method called in server mode');
if (this.type === 'session'
&& this.writable
&& this.outgoing.state === 'open')
return this._client._sshstream.signal(this.outgoing.id, signalName);
return true;
};
Channel.prototype.exit = function(name, coreDumped, msg) {
if (!this.server)
throw new Error('Server-only method called in client mode');
if (this.type === 'session'
&& this.writable
&& this.outgoing.state === 'open') {
if (typeof name === 'number')
return this._client._sshstream.exitStatus(this.outgoing.id, name);
else {
return this._client._sshstream.exitSignal(this.outgoing.id,
name,
coreDumped,
msg);
}
}
return true;
};
Channel.MAX_WINDOW = MAX_WINDOW;
Channel.PACKET_SIZE = PACKET_SIZE;
function windowAdjust(self) {
if (self.outgoing.state !== 'open')
return true;
var amt = MAX_WINDOW - self.incoming.window;
if (amt <= 0)
return true;
self.incoming.window += amt;
return self._client._sshstream.channelWindowAdjust(self.outgoing.id, amt);
}
function ServerStderr(channel) {
WritableStream.call(this, { highWaterMark: MAX_WINDOW });
this._channel = channel;
}
inherits(ServerStderr, WritableStream);
ServerStderr.prototype._write = function(data, encoding, cb) {
var channel = this._channel;
var sshstream = channel._client._sshstream;
var outgoing = channel.outgoing;
var packetSize = outgoing.packetSize;
var id = outgoing.id;
var window = outgoing.window;
var len = data.length;
var p = 0;
var ret;
var buf;
var sliceLen;
if (channel.outgoing.state !== 'open')
return;
while (len - p > 0 && window > 0) {
sliceLen = len - p;
if (sliceLen > window)
sliceLen = window;
if (sliceLen > packetSize)
sliceLen = packetSize;
ret = sshstream.channelExtData(id, data.slice(p, p + sliceLen), STDERR);
p += sliceLen;
window -= sliceLen;
if (!ret) {
channel._waitClientDrain = true;
channel._chunkErr = undefined;
channel._chunkcbErr = cb;
break;
}
}
outgoing.window = window;
if (len - p > 0) {
if (window === 0)
channel._waitWindow = true;
if (p > 0) {
// partial
buf = new Buffer(len - p);
data.copy(buf, 0, p);
channel._chunkErr = buf;
} else
channel._chunkErr = data;
channel._chunkcbErr = cb;
return;
}
if (!channel._waitClientDrain)
cb();
};
module.exports = Channel;

145
build/node_modules/ssh2/lib/SFTPWrapper.js generated vendored Normal file
View File

@@ -0,0 +1,145 @@
// This wrapper class is used to retain backwards compatibility with
// pre-v0.4 ssh2. If it weren't for `read()` and `write()` being used by the
// streams2/3 API, we could just pass the SFTPStream directly to the end user...
var inherits = require('util').inherits,
EventEmitter = require('events').EventEmitter;
function SFTPWrapper(stream) {
var self = this;
EventEmitter.call(this);
this._stream = stream;
stream.on('error', function(err) {
self.emit('error', err);
}).on('end', function() {
self.emit('end');
}).on('close', function() {
self.emit('close');
}).on('continue', function() {
self.emit('continue');
});
}
inherits(SFTPWrapper, EventEmitter);
// stream-related methods to pass on
SFTPWrapper.prototype.end = function() {
return this._stream.end();
};
// SFTPStream client methods
SFTPWrapper.prototype.createReadStream = function(path, options) {
return this._stream.createReadStream(path, options);
};
SFTPWrapper.prototype.createWriteStream = function(path, options) {
return this._stream.createWriteStream(path, options);
};
SFTPWrapper.prototype.open = function(path, flags, attrs, cb) {
return this._stream.open(path, flags, attrs, cb);
};
SFTPWrapper.prototype.close = function(handle, cb) {
return this._stream.close(handle, cb);
};
SFTPWrapper.prototype.read = function(handle, buf, off, len, position, cb) {
return this._stream.readData(handle, buf, off, len, position, cb);
};
SFTPWrapper.prototype.write = function(handle, buf, off, len, position, cb) {
return this._stream.writeData(handle, buf, off, len, position, cb);
};
SFTPWrapper.prototype.fastGet = function(remotePath, localPath, opts, cb) {
return this._stream.fastGet(remotePath, localPath, opts, cb);
};
SFTPWrapper.prototype.fastPut = function(localPath, remotePath, opts, cb) {
return this._stream.fastPut(localPath, remotePath, opts, cb);
};
SFTPWrapper.prototype.readFile = function(path, options, callback_) {
return this._stream.readFile(path, options, callback_);
};
SFTPWrapper.prototype.writeFile = function(path, data, options, callback_) {
return this._stream.writeFile(path, data, options, callback_);
};
SFTPWrapper.prototype.appendFile = function(path, data, options, callback_) {
return this._stream.appendFile(path, data, options, callback_);
};
SFTPWrapper.prototype.exists = function(path, cb) {
return this._stream.exists(path, cb);
};
SFTPWrapper.prototype.unlink = function(filename, cb) {
return this._stream.unlink(filename, cb);
};
SFTPWrapper.prototype.rename = function(oldPath, newPath, cb) {
return this._stream.rename(oldPath, newPath, cb);
};
SFTPWrapper.prototype.mkdir = function(path, attrs, cb) {
return this._stream.mkdir(path, attrs, cb);
};
SFTPWrapper.prototype.rmdir = function(path, cb) {
return this._stream.rmdir(path, cb);
};
SFTPWrapper.prototype.readdir = function(where, opts, cb) {
return this._stream.readdir(where, opts, cb);
};
SFTPWrapper.prototype.fstat = function(handle, cb) {
return this._stream.fstat(handle, cb);
};
SFTPWrapper.prototype.stat = function(path, cb) {
return this._stream.stat(path, cb);
};
SFTPWrapper.prototype.lstat = function(path, cb) {
return this._stream.lstat(path, cb);
};
SFTPWrapper.prototype.opendir = function(path, cb) {
return this._stream.opendir(path, cb);
};
SFTPWrapper.prototype.setstat = function(path, attrs, cb) {
return this._stream.setstat(path, attrs, cb);
};
SFTPWrapper.prototype.fsetstat = function(handle, attrs, cb) {
return this._stream.fsetstat(handle, attrs, cb);
};
SFTPWrapper.prototype.futimes = function(handle, atime, mtime, cb) {
return this._stream.futimes(handle, atime, mtime, cb);
};
SFTPWrapper.prototype.utimes = function(path, atime, mtime, cb) {
return this._stream.utimes(path, atime, mtime, cb);
};
SFTPWrapper.prototype.fchown = function(handle, uid, gid, cb) {
return this._stream.fchown(handle, uid, gid, cb);
};
SFTPWrapper.prototype.chown = function(path, uid, gid, cb) {
return this._stream.chown(path, uid, gid, cb);
};
SFTPWrapper.prototype.fchmod = function(handle, mode, cb) {
return this._stream.fchmod(handle, mode, cb);
};
SFTPWrapper.prototype.chmod = function(path, mode, cb) {
return this._stream.chmod(path, mode, cb);
};
SFTPWrapper.prototype.readlink = function(path, cb) {
return this._stream.readlink(path, cb);
};
SFTPWrapper.prototype.symlink = function(targetPath, linkPath, cb) {
return this._stream.symlink(targetPath, linkPath, cb);
};
SFTPWrapper.prototype.realpath = function(path, cb) {
return this._stream.realpath(path, cb);
};
// extended requests
SFTPWrapper.prototype.ext_openssh_rename = function(oldPath, newPath, cb) {
return this._stream.ext_openssh_rename(oldPath, newPath, cb);
};
SFTPWrapper.prototype.ext_openssh_statvfs = function(path, cb) {
return this._stream.ext_openssh_statvfs(path, cb);
};
SFTPWrapper.prototype.ext_openssh_fstatvfs = function(handle, cb) {
return this._stream.ext_openssh_fstatvfs(handle, cb);
};
SFTPWrapper.prototype.ext_openssh_hardlink = function(oldPath, newPath, cb) {
return this._stream.ext_openssh_hardlink(oldPath, newPath, cb);
};
SFTPWrapper.prototype.ext_openssh_fsync = function(handle, cb) {
return this._stream.ext_openssh_fsync(handle, cb);
};
module.exports = SFTPWrapper;

412
build/node_modules/ssh2/lib/agent.js generated vendored Normal file
View File

@@ -0,0 +1,412 @@
var Socket = require('net').Socket;
var EventEmitter = require('events').EventEmitter;
var inherits = require('util').inherits;
var path = require('path');
var fs = require('fs');
var cp = require('child_process');
var REQUEST_IDENTITIES = 11;
var IDENTITIES_ANSWER = 12;
var SIGN_REQUEST = 13;
var SIGN_RESPONSE = 14;
var FAILURE = 5;
var RE_CYGWIN_SOCK = /^\!<socket >(\d+) s ([A-Z0-9]{8}\-[A-Z0-9]{8}\-[A-Z0-9]{8}\-[A-Z0-9]{8})/;
module.exports = function(sockPath, key, keyType, data, cb) {
var sock;
var error;
var sig;
var datalen;
var keylen = 0;
var isSigning = Buffer.isBuffer(key);
var type;
var count = 0;
var siglen = 0;
var nkeys = 0;
var keys;
var comlen = 0;
var comment = false;
var accept;
var reject;
if (typeof key === 'function' && typeof keyType === 'function') {
// agent forwarding
accept = key;
reject = keyType;
} else if (isSigning) {
keylen = key.length;
datalen = data.length;
} else {
cb = key;
key = undefined;
}
function onconnect() {
var buf;
if (isSigning) {
/*
byte SSH2_AGENTC_SIGN_REQUEST
string key_blob
string data
uint32 flags
*/
var p = 9;
buf = new Buffer(4 + 1 + 4 + keylen + 4 + datalen + 4);
buf.writeUInt32BE(buf.length - 4, 0, true);
buf[4] = SIGN_REQUEST;
buf.writeUInt32BE(keylen, 5, true);
key.copy(buf, p);
buf.writeUInt32BE(datalen, p += keylen, true);
data.copy(buf, p += 4);
buf.writeUInt32BE(0, p += datalen, true);
sock.write(buf);
} else {
/*
byte SSH2_AGENTC_REQUEST_IDENTITIES
*/
sock.write(new Buffer([0, 0, 0, 1, REQUEST_IDENTITIES]));
}
}
function ondata(chunk) {
for (var i = 0, len = chunk.length; i < len; ++i) {
if (type === undefined) {
// skip over packet length
if (++count === 5) {
type = chunk[i];
count = 0;
}
} else if (type === SIGN_RESPONSE) {
/*
byte SSH2_AGENT_SIGN_RESPONSE
string signature_blob
*/
if (!sig) {
siglen <<= 8;
siglen += chunk[i];
if (++count === 4) {
sig = new Buffer(siglen);
count = 0;
}
} else {
sig[count] = chunk[i];
if (++count === siglen) {
sock.removeAllListeners('data');
return sock.destroy();
}
}
} else if (type === IDENTITIES_ANSWER) {
/*
byte SSH2_AGENT_IDENTITIES_ANSWER
uint32 num_keys
Followed by zero or more consecutive keys, encoded as:
string public key blob
string public key comment
*/
if (keys === undefined) {
nkeys <<= 8;
nkeys += chunk[i];
if (++count === 4) {
keys = new Array(nkeys);
count = 0;
if (nkeys === 0) {
sock.removeAllListeners('data');
return sock.destroy();
}
}
} else {
if (!key) {
keylen <<= 8;
keylen += chunk[i];
if (++count === 4) {
key = new Buffer(keylen);
count = 0;
}
} else if (comment === false) {
key[count] = chunk[i];
if (++count === keylen) {
keys[nkeys - 1] = key;
keylen = 0;
count = 0;
comment = true;
if (--nkeys === 0) {
key = undefined;
sock.removeAllListeners('data');
return sock.destroy();
}
}
} else if (comment === true) {
comlen <<= 8;
comlen += chunk[i];
if (++count === 4) {
count = 0;
if (comlen > 0)
comment = comlen;
else {
key = undefined;
comment = false;
}
comlen = 0;
}
} else {
// skip comments
if (++count === comment) {
comment = false;
count = 0;
key = undefined;
}
}
}
} else if (type === FAILURE) {
if (isSigning)
error = new Error('Agent unable to sign data');
else
error = new Error('Unable to retrieve list of keys from agent');
sock.removeAllListeners('data');
return sock.destroy();
}
}
}
function onerror(err) {
error = err;
}
function onclose() {
if (error)
cb(error);
else if ((isSigning && !sig) || (!isSigning && !keys))
cb(new Error('Unexpected disconnection from agent'));
else if (isSigning && sig)
cb(undefined, sig);
else if (!isSigning && keys)
cb(undefined, keys);
}
if (process.platform === 'win32') {
if (sockPath === 'pageant') {
// Pageant (PuTTY authentication agent)
sock = new PageantSock();
} else {
// cygwin ssh-agent instance
var triedCygpath = false;
fs.readFile(sockPath, function readCygsocket(err, data) {
if (err) {
if (triedCygpath)
return cb(new Error('Invalid cygwin unix socket path'));
// try using `cygpath` to convert a possible *nix-style path to the
// real Windows path before giving up ...
cp.exec('cygpath -w "' + sockPath + '"',
function(err, stdout, stderr) {
if (err || stdout.length === 0)
return cb(new Error('Invalid cygwin unix socket path'));
triedCygpath = true;
sockPath = stdout.toString().replace(/[\r\n]/g, '');
fs.readFile(sockPath, readCygsocket);
});
return;
}
var m;
if (m = RE_CYGWIN_SOCK.exec(data.toString('ascii'))) {
var port;
var secret;
var secretbuf;
var state;
var bc = 0;
var isRetrying = false;
var inbuf = [];
var credsbuf = new Buffer(12);
var i;
var j;
// use 0 for pid, uid, and gid to ensure we get an error and also
// a valid uid and gid from cygwin so that we don't have to figure it
// out ourselves
credsbuf.fill(0);
// parse cygwin unix socket file contents
port = parseInt(m[1], 10);
secret = m[2].replace(/\-/g, '');
secretbuf = new Buffer(16);
for (i = 0, j = 0; j < 32; ++i,j+=2)
secretbuf[i] = parseInt(secret.substring(j, j + 2), 16);
// convert to host order (always LE for Windows)
for (i = 0; i < 16; i += 4)
secretbuf.writeUInt32LE(secretbuf.readUInt32BE(i, true), i, true);
function _onconnect() {
bc = 0;
state = 'secret';
sock.write(secretbuf);
}
function _ondata(data) {
bc += data.length;
if (state === 'secret') {
// the secret we sent is echoed back to us by cygwin, not sure of
// the reason for that, but we ignore it nonetheless ...
if (bc === 16) {
bc = 0;
state = 'creds';
sock.write(credsbuf);
}
} else if (state === 'creds') {
// if this is the first attempt, make sure to gather the valid
// uid and gid for our next attempt
if (!isRetrying)
inbuf.push(data);
if (bc === 12) {
sock.removeListener('connect', _onconnect);
sock.removeListener('data', _ondata);
sock.removeListener('close', _onclose);
if (isRetrying) {
addSockListeners();
sock.emit('connect');
} else {
isRetrying = true;
credsbuf = Buffer.concat(inbuf);
credsbuf.writeUInt32LE(process.pid, 0, true);
sock.destroy();
tryConnect();
}
}
}
}
function _onclose() {
cb(new Error('Problem negotiating cygwin unix socket security'));
}
function tryConnect() {
sock = new Socket();
sock.once('connect', _onconnect);
sock.on('data', _ondata);
sock.once('close', _onclose);
sock.connect(port);
}
tryConnect();
} else
cb(new Error('Malformed cygwin unix socket file'));
});
return;
}
} else
sock = new Socket();
function addSockListeners() {
if (!accept && !reject) {
sock.once('connect', onconnect);
sock.on('data', ondata);
sock.once('error', onerror);
sock.once('close', onclose);
} else {
var chan;
sock.once('connect', function() {
chan = accept();
var isDone = false;
function onDone() {
if (isDone)
return;
sock.destroy();
isDone = true;
}
chan.once('end', onDone)
.once('close', onDone)
.on('data', function(data) {
sock.write(data);
});
sock.on('data', function(data) {
chan.write(data);
});
});
sock.once('close', function() {
if (!chan)
reject();
});
}
}
addSockListeners();
sock.connect(sockPath);
};
// win32 only ------------------------------------------------------------------
if (process.platform === 'win32') {
var RET_ERR_BADARGS = 10;
var RET_ERR_UNAVAILABLE = 11;
var RET_ERR_NOMAP = 12;
var RET_ERR_BINSTDIN = 13;
var RET_ERR_BINSTDOUT = 14;
var RET_ERR_BADLEN = 15;
var ERROR = {};
var EXEPATH = path.resolve(__dirname, '..', 'util/pagent.exe');
ERROR[RET_ERR_BADARGS] = new Error('Invalid pagent.exe arguments');
ERROR[RET_ERR_UNAVAILABLE] = new Error('Pageant is not running');
ERROR[RET_ERR_NOMAP] = new Error('pagent.exe could not create an mmap');
ERROR[RET_ERR_BINSTDIN] = new Error('pagent.exe could not set mode for stdin');
ERROR[RET_ERR_BINSTDOUT] = new Error('pagent.exe could not set mode for stdout');
ERROR[RET_ERR_BADLEN] = new Error('pagent.exe did not get expected input payload');
function PageantSock() {
this.proc = undefined;
this.buffer = null;
}
inherits(PageantSock, EventEmitter);
PageantSock.prototype.write = function(buf) {
if (this.buffer === null)
this.buffer = buf;
else {
this.buffer = Buffer.concat([this.buffer, buf],
this.buffer.length + buf.length);
}
// Wait for at least all length bytes
if (this.buffer.length < 4)
return;
var len = this.buffer.readUInt32BE(0, true);
// Make sure we have a full message before querying pageant
if ((this.buffer.length - 4) < len)
return;
buf = this.buffer.slice(0, 4 + len);
if (this.buffer.length > (4 + len))
this.buffer = this.buffer.slice(4 + len);
else
this.buffer = null;
var self = this;
var proc;
var hadError = false;
proc = this.proc = cp.spawn(EXEPATH, [ buf.length ]);
proc.stdout.on('data', function(data) {
self.emit('data', data);
});
proc.once('error', function(err) {
if (!hadError) {
hadError = true;
self.emit('error', err);
}
});
proc.once('close', function(code) {
self.proc = undefined;
if (ERROR[code] && !hadError) {
hadError = true;
self.emit('error', ERROR[code]);
}
self.emit('close', hadError);
});
proc.stdin.end(buf);
};
PageantSock.prototype.end = PageantSock.prototype.destroy = function() {
this.buffer = null;
if (this.proc) {
this.proc.kill();
this.proc = undefined;
}
};
PageantSock.prototype.connect = function() {
this.emit('connect');
};
}

1540
build/node_modules/ssh2/lib/client.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

76
build/node_modules/ssh2/lib/keepalivemgr.js generated vendored Normal file
View File

@@ -0,0 +1,76 @@
var spliceOne = require('./utils').spliceOne;
function Manager(interval, streamInterval, kaCountMax) {
var streams = this._streams = [];
this._timer = undefined;
this._timerInterval = interval;
this._timerfn = function() {
var now = Date.now();
for (var i = 0, len = streams.length, s, last; i < len; ++i) {
s = streams[i];
last = s._kalast;
if (last && (now - last) >= streamInterval) {
if (++s._kacnt > kaCountMax) {
var err = new Error('Keepalive timeout');
err.level = 'client-timeout';
s.emit('error', err);
s.disconnect();
spliceOne(streams, i);
--i;
len = streams.length;
} else {
s._kalast = now;
// XXX: if the server ever starts sending real global requests to the
// client, we will need to add a dummy callback here to keep the
// correct reply order
s.ping();
}
}
}
};
}
Manager.prototype.start = function() {
if (this._timer)
this.stop();
this._timer = setInterval(this._timerfn, this._timerInterval);
};
Manager.prototype.stop = function() {
if (this._timer) {
clearInterval(this._timer);
this._timer = undefined;
}
};
Manager.prototype.add = function(stream) {
var streams = this._streams,
self = this;
stream.once('end', function() {
self.remove(stream);
}).on('packet', resetKA);
streams[streams.length] = stream;
resetKA();
if (!this._timer)
this.start();
function resetKA() {
stream._kalast = Date.now();
stream._kacnt = 0;
}
};
Manager.prototype.remove = function(stream) {
var streams = this._streams,
index = streams.indexOf(stream);
if (index > -1)
spliceOne(streams, index);
if (!streams.length)
this.stop();
};
module.exports = Manager;

1157
build/node_modules/ssh2/lib/server.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

5
build/node_modules/ssh2/lib/utils.js generated vendored Normal file
View File

@@ -0,0 +1,5 @@
exports.spliceOne = function(list, index) {
for (var i = index, k = i + 1, n = list.length; k < n; i += 1, k += 1)
list[i] = list[k];
list.pop();
};

71
build/node_modules/ssh2/package.json generated vendored Normal file
View File

@@ -0,0 +1,71 @@
{
"_from": "ssh2@^0.5.1",
"_id": "ssh2@0.5.5",
"_inBundle": false,
"_integrity": "sha1-x3gezS7OcwSiU89iD6taXCK7IjU=",
"_location": "/ssh2",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "ssh2@^0.5.1",
"name": "ssh2",
"escapedName": "ssh2",
"rawSpec": "^0.5.1",
"saveSpec": null,
"fetchSpec": "^0.5.1"
},
"_requiredBy": [
"/sftp-promises"
],
"_resolved": "https://registry.npmjs.org/ssh2/-/ssh2-0.5.5.tgz",
"_shasum": "c7781ecd2ece7304a253cf620fab5a5c22bb2235",
"_spec": "ssh2@^0.5.1",
"_where": "/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/sftp-promises",
"author": {
"name": "Brian White",
"email": "mscdex@mscdex.net"
},
"bugs": {
"url": "https://github.com/mscdex/ssh2/issues"
},
"bundleDependencies": false,
"dependencies": {
"ssh2-streams": "~0.1.18"
},
"deprecated": false,
"description": "SSH2 client and server modules written in pure JavaScript for node.js",
"devDependencies": {
"semver": "^5.1.0"
},
"engines": {
"node": ">=0.10.0"
},
"homepage": "https://github.com/mscdex/ssh2#readme",
"keywords": [
"ssh",
"ssh2",
"sftp",
"secure",
"shell",
"exec",
"remote",
"client"
],
"licenses": [
{
"type": "MIT",
"url": "http://github.com/mscdex/ssh2/raw/master/LICENSE"
}
],
"main": "./lib/client",
"name": "ssh2",
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/mscdex/ssh2.git"
},
"scripts": {
"test": "node test/test.js"
},
"version": "0.5.5"
}

View File

@@ -0,0 +1,26 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAz7MF4vhgw6HxNf3KtVf3VULTYgrRSlv+cCZdB1xxI1p/nGyu
/eekUn5C+mGeDS488DX5ulzicxVpL7pamc/tFNcp91MrR7PiIMK2l+bwbZJubbLj
DHhNcBklnFOSKxtmQRfuorGakpy/kXmIxF5of0xXGns6DlHRq9dGCJIXvrkqhcEb
k4n2y4aV4VOiMHdo6FrFQVPzA8DlbJP2SjIFZ/0VdK7O7eiyiqV1p1xlbTQQ5rAX
LdsshBn/GvoBOTCVupMXurn2582vgGh26Mmovj2QGzScMGUVttkMlnxUmKT/aQka
mC0vR54QOW7lyWPjAitOV0qgmtGm3/cl7W7NjwIDAQABAoIBAFxH0C+951BEXWV9
s1jLEqshG8YNxFtjcDLn+KFSoznv9Y7MgxtwlgPI8X1Jbe2xQ4X+lUwGBN7Y/nkk
NSjtxwphZtXqb+pVs/yWRoZLJzunucSnnFVoBg/uPFWuk9zvOYlmVrKWcnT9i+fY
tbl5sLgOdQzg/zRpidztssIQFti3o2jnpyrEGcepPWLkfCgqPfGmNv78BAIt/6iT
zYDB4GMSq/LnPTIOFsIOvlkZg3RCcLWeAPRC+lvFQVY+M/uJL5WIbA5il1IMMKH7
MULWpRO3lnb1JVrkZlBldK5uew6AN3tHDQOmg+C2JuIbOZ35J9dcnwsE+IptWWBj
XiFRJCECgYEA8BeuufkslureqOycaPLMkqchMTue1OxbLJFvPN+dh/cW6Lng3b8+
xAyzZrc0vccH/jl9WVHhIZ7TcKXDzSmmrtnZ/3m1c4gANGqIPwO+emL1ZzzkIKGd
FrLeBZKP4TWry9kjg4cG1SKGpcB5ngJMPXUxMZNe74tC4Hk820PkFjcCgYEA3XXn
ngRCgH9N1eKSD2daxxlBhTTSnTgjU+dDaDFQzPIhJCcS8HwyQBQmNTOSXXK9sShC
fdXAsmiBby5WEBq/K5+cXeDG2ZlFLyPovEgTUrLgraw42PYs0+A8Ls7dFk7PuMez
3G2gUPkY039JiyXKfcog9/dIRfbWCwzQ6s7TV2kCgYEArsme81cahhgg1zvCNokk
M1Omz2/HFt2nFpAeOmPVDGnu7Kh9sxGKgTF53bpclBh0kjiKL99zFYXKCoUzQYYk
CcEhemLBnYUSGRbBb5arMfAfFfR3Y+YkNaUsC0SCqILpOfMvbo57g+ipu7ufDlA/
7rIFiUDvaVap7j909W+8egsCgYEAsuc/0DBixMmSyHl7QwRcmkC15HVSu32RVIOb
ub01KAtmaH1EWJAMTCW64/mggOtjgI0kgeE/BSFVhsqo7eOdkhEj0db27OxbroRU
zF1xdrpYtRRO7D6a4iLgm3OzuQS72+tASo8pFqDUxG6sq8NAvLOgRJE4ioSoT07w
KvAgXRkCgYEAmWgcsX/BdNcKOteSDtPkys5NRtWCBz7Coxb+xXXoXz1FVegBolpY
wXVePvXTIbU8VJOLunMyH5wpmMUiJbTX9v2o/yfpsH0ci4GaAeVtqpA=
-----END RSA PRIVATE KEY-----

12
build/node_modules/ssh2/test/fixtures/id_dsa generated vendored Normal file
View File

@@ -0,0 +1,12 @@
-----BEGIN DSA PRIVATE KEY-----
MIIBuwIBAAKBgQC3/2VIGHgqHuxvhPa6rryqqLy6sQmjeSIwyrIW5F/o8W4sz/mE
0noDSW4PaoXjgPQv5egj1EByws6dMOUqLaZHNWNn+Lh/jkKlwKyhbSCAjqoWH3v3
uI1j58GO/eZ2+REijfyA0XJxdm7kqEexxbg0UpFr1F/eLBUxpLIbhhS1cwIVAKcB
B9DnAObuPJGTwYTCaIIBQDy9AoGAJicW0pIFwgoTYsIeywmUQopJ3FQ4M3eDwQ0U
T33pzWvBZFN2OsUDTFg64PNm9ow09wk042qMg168eKCUTp2iR/Y9R4xTj8dls8iv
aMGMZ/B32eURIjUREGiXYTyG1pfuB2znSvr/5pavhuz5yG9M0AJCiYiexdaQKO3N
oJp6T3ACgYEAsep79p4WljnawrJc928zGq6dLYjs+5apYhqx4vf2l3Z2u26VqVNG
i5zZkUzhWQYV3/qtEOpO43dyZTHW+d9L8ni6HbXFWRVx60WE+5WKkzkimHJ6gox2
kDvOqPudiS34KJOCEYYLEnJmK8aUZBZzWFORXkN8QgA/h9ts8AU785UCFAVXZMWq
CteWCH2HzcY2x/65dMwL
-----END DSA PRIVATE KEY-----

5
build/node_modules/ssh2/test/fixtures/id_ecdsa generated vendored Normal file
View File

@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIPMZuWP7fMsZeyC1XXVUALVebJOX7PTwmsPql9qG25SeoAoGCCqGSM49
AwEHoUQDQgAEB/B6mC5lrekKPWfGEkKpnCk08+dRnzFUg2jUHpaIrOTt4jGdvq6T
yAN57asB+PYmFyVIpi35NcmicF18qX3ayg==
-----END EC PRIVATE KEY-----

15
build/node_modules/ssh2/test/fixtures/id_rsa generated vendored Normal file
View File

@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDL0yFO4W4xbdrJk/i+CW3itPATvhRkS+x+gKmkdH739AqWYP6r
kTFAmFTw9gLJ/c2tN7ow0T0QUR9iUsv/3QzTuwsjBu0feo3CVxwMkaJTo5ks9XBo
OW0R3tyCcOLlAcQ1WjC7cv5Ifn4gXLLM+k8/y/m3u8ERtidNxbRqpQ/gPQIDAQAB
AoGABirSRC/ABNDdIOJQUXe5knWFGiPTPCGr+zvrZiV8PgZtV5WBvzE6e0jgsRXQ
icobMhWQla+PGHJL786vi4NlwuhwKcF7Pd908ofej1eeBOd1u/HQ/qsfxPdxI0zF
dcWPYgAOo9ydOMGcSx4v1zDIgFInELJzKbv64LJQD0/xhoUCQQD7KhJ7M8Nkwsr2
iKCyWTFM2M8/VKltgaiSmsNKZETashk5tKOrM3EWX4RcB/DnvHe8VNyYpC6Sd1uQ
AHwPDfxDAkEAz7+7hDybH6Cfvmr8kUOlDXiJJWXp5lP37FLzMDU6a9wTKZFnh57F
e91zRmKlQTegFet93MXaFYljRkI+4lMpfwJBAPPLbNEF973Qjq4rBMDZbs9HDDRO
+35+AqD7dGC7X1Jg2bd3rf66GiU7ZgDm/GIUQK0gOlg31bT6AniO39zFGH0CQFBh
Yd9HR8nT7xrQ8EoQPzNYGNBUf0xz3rAcZCWZ4rHK48sojEMoBkbnputrzX7PU+xH
QlqCXuAIWVXc2dHd1WcCQQDIUJHPOsgeAfTLoRRRURp/m8zZ9IpbaPTyDstPVNYe
zARW3Oa/tzPqdO6NWaetCp17u7Kb6X9np7Vz17i/4KED
-----END RSA PRIVATE KEY-----

26
build/node_modules/ssh2/test/fixtures/id_rsa.ppk generated vendored Normal file
View File

@@ -0,0 +1,26 @@
PuTTY-User-Key-File-2: ssh-rsa
Encryption: none
Comment: rsa-key-20150522
Public-Lines: 6
AAAAB3NzaC1yc2EAAAABJQAAAQB1quqP0rhl78NOLD4lj+1x5FGAqZ3aqo6GiEPz
KOaQmy86FuJMK0nHj3gUKTa/Kvaa+8PZyeu+uVseHg47YrynCOcJEEnpqvbArc8M
xMWuUnTUMrjvokGDOBBiQu4UAE4bybpgXkNHJfbrcDVgivmv3Ikn8PVIZ1rLBMLZ
6Lzn0rjPjFD0X4WqsAJW2SFiZnsjMZtVL2TWadNTyyfjjm2NCRBvd32VLohkSe9Q
BZBD6MW8YQyBKUnEF/7WNY0eehDVrfx1YqPOV1bDwFUhRaAYpLDLDR0KCAPvx7qb
8G5Cq0TIBsEr3H8ztNRcOTQoaKgn0T18M7cyS4ykoNLYW4Zx
Private-Lines: 14
AAABACyF3DZraF3sBLXLjSL4MFSblHXfUHxAiPSiQzlpa/9dUCPRTrUJddzOgHZU
yJtcXU9mLm4VDRe7wZyxbSs6Hd5WZUGzIuLLEUH8k4hKdE/MLDSdkhV7qhX5iaij
tAeRaammRoVUGXTd7rnzGx2cXnnkvkZ22VmqkQ6MLg1DTmWNfOO9cdwFGdQawf/n
yUV0nTkWsHXy5Qrozq9wRFk8eyw+pFllxqavsNftZX8VDiQt27JLZPTU4LGkH660
3gq1KhNS/l05TlXnMZGjlcPN8UEaBzmCWRezhJSttjs5Kgp1K3yDf4ozMR/HWOCj
Jq8fd3VIgli6ML8yjr/c0A0T9MUAAACBAL1/byxHiCvY/2C+/L5T+ZZq13jdZuYK
MmOFaNITgEdNGWSIFYRzhLKGXj7awQWOIW6chj470GNOfQjFL1TvXhbwfqW6esDa
kETOYQPYQHZijABcn7uurMUm/bu5x/z9gYkAfniOCI5vmvMvJ09JcZ0iUmFWDZZY
fAutBvrt+n/vAAAAgQCe9jrA51wn1/wzKmWF+2+OWFUG9usheIcEbHB8mxLguLfU
+x4i+2vLo0FtXEPAw+Bt7Tge4t0m6USiVZXtW/QKsh0kMj4mNVHFz+XXw4l1QOYv
n5TjnLepiP7majXv4GHI2eOcHkyly4sIkj4jNLYqvT86hMxW4IC+jtJEWhn/nwAA
AIEAlJ8cExu2WrWukTDJQHrVegtvdJUhNjol2wLucPuWwSxKuB8FHYwaPRYRkf3d
DkZ53hhjJZ0BVkAaQ28uqM09xKD+q1H4/r0nnbtlV4uHLl3cCD5mGrH8I/iDPJX4
fFIqCa0+n1D6RzvDqs1QIu+PGSp0K6vHOOS5fP0ZpuT025E=
Private-MAC: 4ca26008c85b901f4d2766b0924c25e527678d7e

30
build/node_modules/ssh2/test/fixtures/id_rsa_enc generated vendored Normal file
View File

@@ -0,0 +1,30 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-128-CBC,CCE70744FB28F2EFB1D74377281A780C
1WiGnqpSGXFIg+WYr7T2XN72C1YrNQ1jmRISb32TB/Rh2Zo47fjyQnv9impz8b6m
91R/qF7uCLI0fswvT5oqwn1L0vUAA0YtW/E2IQJEx5GPiaexoDJYYfu2yy036Kca
e9VtCajgrV+kycg1CknCxQKMcKXNq8Czvq66PM4Bzknek5hhdmxHxOl0QAE+8EXt
pnasOGz3szTUKkD6givwWgvDXY3BnVG46fXff99Xqgb6fx5IDbAkVKaxWIN/c81E
b0rcfyoLb7yjPgNYn9vUI6Z+24NMYUYARzb3dG5geaeX0BYb/VlCtJUsP0Rp2P2P
jl+cdvBKaeOvA9gPo/jAtSOFexQRs7AzKzoOLYU1fokd8HhqxOKAljn9ujmEqif7
qcimk2s7ff6tSSlxtRzDP+Uq9d1u5tyaONRV2lwj+GdP1gRoOmdZL5chdvoAi0I8
5eMf58hEuN2d4h4FryO6z7K+XQ9oo6/N/xHU0U/t2Pco9oY2L6oWMDxKwbfPhaD5
CcoEElsK4XFArYDielEq9Y1sXaEuwR5I0ksDDsANp74r9Bhcqz60gJa6hVz0ouEU
QA67wV9+TRmulKRxwANvqxQwqPuxqcTPeJjXSUN/ZCaDwYmI+d1poxMx2fQzT82M
onlgOWq+3HbCotyoeFpCameymwDQzmrYdMBr7oWLgnOrxmJ89zDc6+jkHFgQJvnU
atyeVDqe866ZvvIGWS+r/EsDjV3cTW/cJvdsC+5BpnoXoVF4LqxE3LFbEbQBvqio
4enCZpspQSMOJra37vSofbD+DyI5Wd+y8SBmfDLjyDFhT0spW9aN99uFqSc3UElA
SAmnFmpYBFEQrRGpvpu5sC0c/YjZeRXr0/F1xPpIT1SWzpRsbcsWRBDzWjLOKWQx
8ytwc2QS7eKedfqkPWpYKW0Qtps+XgnGWA6PBX42IYhLsKANRfhFXQv5LPqLNNOn
3EsG9pd+0dBpfxFQfyyAKAUuvpJNgJ6kNx8VSj8Ppj8lyUdGa9YucgB02m7gHC9U
A4YyJsIcjo6IcrjM+ez1govRRS0nE8AUb8ups9tn8mdBwqcPCrgcJhV7JkOYNJYh
NAh0vgmneOq8LSVs2SRaL3uuLNbjh1LR9iViwbIY8kMQXkiXa2/V+PFwt5oqeX5f
2x3yzCeGBiQW10InyBBnKutbPD85R4YJhQ55bOMDSFfGGqwOU1QURiO1NUzf9n/2
+E8VE7J/IQoO0TrJpC+EV0ROKME9W6+AvEFdmdIigbq3bkdEgSixyLnrhV8V8T4N
nbKlLoqfXt8DmT+h8XPzgsu0Fq/PNi6xBaiUsaN9tK6OP2ZVjr9ihbeLTI0rcKDr
XX2cWPvTcboRLt+S4wmqchMf7Kxa2PfX5Tf+KCcdZNQO4YqS23wQZgk61kuOQCsS
uOop+ICI7yWZkjqCOzGOeHLl/7FyFeprsFDIwD1g20y9bzibbJlbQPhwXSalqDQT
MWLH3rdFuvgLH7ujtjxSakES+VzkOhbnmb/Wypbl1D7P7GT2seau16EEGQDhDzcJ
Q4d/BjR2WqqxmC79MOAvUWAu6fZQjPD30/gYPGpMaEuiLrDlzDqvf+oi4A9+EtRL
-----END RSA PRIVATE KEY-----

12
build/node_modules/ssh2/test/fixtures/ssh_host_dsa_key generated vendored Normal file
View File

@@ -0,0 +1,12 @@
-----BEGIN DSA PRIVATE KEY-----
MIIBuwIBAAKBgQDEK+daQ7RuajwxkmBmogb0iUSi/w2RYKuvC2EiviBu3S2s9Bfq
gROKscAnURrxpTOa+iYeI7hRzfuX0qFmnFwXIjKJBjqBdg9r76UR5UNytnWQkJ5x
lxsZThMeAMw38SvmRMw15kkgxycKGqu4yvNLGyVwN02bPVjLcEVLWLCM1wIVAK50
5JqF0nmGXFkcmNtxR24/mNXTAoGBAIc2p8C8b08OTQPmfZI+Wq8a+CuEr5R36bMW
TAs5etqmO2aVo5zvR0MnTjoS2ZDbuznDG9RiSuIB+ivr/daEwi+K+Ha8pZfYjXCG
ldzvmr5I4x8rkH3zyn7BADnc+/q3pa8AnZvTme5eNsxn1Pu/rmC/8KKnhmzRggqP
N8ORhoQQAoGAMCvoMcsDAui2d/WVpgHZZEFlxfbf4dPUPYb5zf2xOiMG9OK+Cbv3
NaLZwk/Hd2g4L3nwTKDASxfmRcrbuaOg/d7aDjQ2mJz18Js4IjY34QpgLspGCNX/
6rJSQ+ov1Z2Etr95N4Tzm3qpxW5BH9TTgaC/ntb9NRqIzNPCvAHXmlcCFBxgZpyb
4GUgmqhTOMtmBkJ7QpL9
-----END DSA PRIVATE KEY-----

View File

@@ -0,0 +1,5 @@
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEICrdbIIYmW/XTK9hxaQZZ56IGwG0NhqD2eppYUJNZsECoAoGCCqGSM49
AwEHoUQDQgAEa+MuLv++3ft5HPFIsM2hQnmHPF12q08/MaHoGud4yqp3evyomjZN
xbsSb39fv8t6XX1u1rm5oHQcBV5Mqomaeg==
-----END EC PRIVATE KEY-----

15
build/node_modules/ssh2/test/fixtures/ssh_host_rsa_key generated vendored Normal file
View File

@@ -0,0 +1,15 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQC57UB/5H0M+t+mopksrltCCIXghryzofJjau+8tuMT9CG6ta3S
O9aKApJUUG/xtc88giVhB7HFABX/oob+jrkSthR8s/whULC8E+GhvOBjHydRUZIs
aPYOMBb42HcbOsgq3li/hwOcDk0vY00hZDKCum9BgvRAb7dPEkw2dmiCQQIDAQAB
AoGAMG+HOwoaLbR5aR64yrQNYBF6Vvii1iUdURr9o2r9kygpVUuZIcim5kMvPbnK
v+w+NaQt+q4XeJvCH1uG0W/69FwnphfaOVmCCUtsoJ6sU3fWr9x59MtKL2Llh8xR
50lz6R+eDXoYRDq245hG9BFn/bu0vtqQqx06mlZJcjaRocECQQDjdYFmr+DSww3x
VNx0G0DUkaQZZ+iqZiT3Zund2pcBB4aLiewOrqj0GFct4+YNzgxIXPejmS0eSokN
N2lC3NxZAkEA0UGjN5TG5/LEK3zcYtx2kpXryenrYORo1n2L/WPMZ0mjLQyd4LJr
ibfgVUfwX/kV3vgGYLwjpgcaTiMsecv4KQJAYMmMgZSPdz+WvD1e/WznXkyG5mSn
xXJngnrhQw0TulVodBIBR5IcxJli510VdIRcB6K/oXa5ky0mOmB8wv3WKQJBAKEF
PxE//KbzWhyUogm4180IbD4dMDCI0ltqlFRRfTJlqZi6wqnq4XFB+u/kwYU4aKoA
dPfvDgduI8HIsyqt17ECQDI/HC8PiYsDIOyVpQuQdIAsbGmoavK7X1MVEWR2nj9t
7BbUVFSnVKynL4TWIJZ6xP8WQwkDBQc5WjognHDaUTQ=
-----END RSA PRIVATE KEY-----

2135
build/node_modules/ssh2/test/test-client-server.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

459
build/node_modules/ssh2/test/test-openssh.js generated vendored Normal file
View File

@@ -0,0 +1,459 @@
var Server = require('../lib/server');
var utils = require('ssh2-streams').utils;
var semver = require('semver');
var fs = require('fs');
var crypto = require('crypto');
var path = require('path');
var join = path.join;
var assert = require('assert');
var spawn = require('child_process').spawn;
var exec = require('child_process').exec;
var t = -1;
var group = path.basename(__filename, '.js') + '/';
var fixturesdir = join(__dirname, 'fixtures');
var CLIENT_TIMEOUT = 5000;
var USER = 'nodejs';
var HOST_KEY_RSA = fs.readFileSync(join(fixturesdir, 'ssh_host_rsa_key'));
var HOST_KEY_DSA = fs.readFileSync(join(fixturesdir, 'ssh_host_dsa_key'));
var HOST_KEY_ECDSA = fs.readFileSync(join(fixturesdir, 'ssh_host_ecdsa_key'));
var CLIENT_KEY_RSA_PATH = join(fixturesdir, 'id_rsa');
var CLIENT_KEY_RSA = fs.readFileSync(CLIENT_KEY_RSA_PATH);
var CLIENT_KEY_RSA_PUB = utils.genPublicKey(utils.parseKey(CLIENT_KEY_RSA));
var CLIENT_KEY_DSA_PATH = join(fixturesdir, 'id_dsa');
var CLIENT_KEY_DSA = fs.readFileSync(CLIENT_KEY_DSA_PATH);
var CLIENT_KEY_DSA_PUB = utils.genPublicKey(utils.parseKey(CLIENT_KEY_DSA));
if (semver.gte(process.version, '5.2.0')) {
var CLIENT_KEY_ECDSA_PATH = join(fixturesdir, 'id_ecdsa');
var CLIENT_KEY_ECDSA = fs.readFileSync(CLIENT_KEY_ECDSA_PATH);
var CLIENT_KEY_ECDSA_PUB = utils.genPublicKey(
utils.parseKey(CLIENT_KEY_ECDSA)
);
}
var opensshVer;
var DEBUG = false;
// Fix file modes to avoid OpenSSH client complaints about keys' permissions
fs.readdirSync(fixturesdir).forEach(function(file) {
fs.chmodSync(join(fixturesdir, file), '0600');
});
var tests = [
{ run: function() {
var what = this.what;
var server;
server = setup(
this,
{ privateKeyPath: CLIENT_KEY_RSA_PATH },
{ hostKeys: [HOST_KEY_RSA] }
);
server.on('connection', function(conn) {
conn.on('authentication', function(ctx) {
if (ctx.method === 'none')
return ctx.reject();
assert(ctx.method === 'publickey',
makeMsg(what, 'Unexpected auth method: ' + ctx.method));
assert(ctx.username === USER,
makeMsg(what, 'Unexpected username: ' + ctx.username));
assert(ctx.key.algo === 'ssh-rsa',
makeMsg(what, 'Unexpected key algo: ' + ctx.key.algo));
assert.deepEqual(CLIENT_KEY_RSA_PUB.public,
ctx.key.data,
makeMsg(what, 'Public key mismatch'));
if (ctx.signature) {
var verifier = crypto.createVerify('RSA-SHA1');
var pem = CLIENT_KEY_RSA_PUB.publicOrig;
verifier.update(ctx.blob);
assert(verifier.verify(pem, ctx.signature),
makeMsg(what, 'Could not verify PK signature'));
ctx.accept();
} else
ctx.accept();
}).on('ready', function() {
conn.on('session', function(accept, reject) {
var session = accept();
if (session) {
session.on('exec', function(accept, reject) {
var stream = accept();
if (stream) {
stream.exit(0);
stream.end();
}
}).on('pty', function(accept, reject) {
accept && accept();
});
}
});
});
});
},
what: 'Authenticate with an RSA key'
},
{ run: function() {
var what = this.what;
var server;
server = setup(
this,
{ privateKeyPath: CLIENT_KEY_DSA_PATH },
{ hostKeys: [HOST_KEY_RSA] }
);
server.on('connection', function(conn) {
conn.on('authentication', function(ctx) {
if (ctx.method === 'none')
return ctx.reject();
assert(ctx.method === 'publickey',
makeMsg(what, 'Unexpected auth method: ' + ctx.method));
assert(ctx.username === USER,
makeMsg(what, 'Unexpected username: ' + ctx.username));
assert(ctx.key.algo === 'ssh-dss',
makeMsg(what, 'Unexpected key algo: ' + ctx.key.algo));
assert.deepEqual(CLIENT_KEY_DSA_PUB.public,
ctx.key.data,
makeMsg(what, 'Public key mismatch'));
if (ctx.signature) {
var verifier = crypto.createVerify('DSA-SHA1');
var pem = CLIENT_KEY_DSA_PUB.publicOrig;
verifier.update(ctx.blob);
assert(verifier.verify(pem, ctx.signature),
makeMsg(what, 'Could not verify PK signature'));
ctx.accept();
} else
ctx.accept();
}).on('ready', function() {
conn.on('session', function(accept, reject) {
var session = accept();
if (session) {
session.on('exec', function(accept, reject) {
var stream = accept();
if (stream) {
stream.exit(0);
stream.end();
}
}).on('pty', function(accept, reject) {
accept && accept();
});
}
});
});
});
},
what: 'Authenticate with a DSA key'
},
{ run: function() {
if (semver.lt(process.version, '5.2.0'))
return next();
var what = this.what;
var server;
server = setup(
this,
{ privateKeyPath: CLIENT_KEY_ECDSA_PATH },
{ hostKeys: [HOST_KEY_RSA] }
);
server.on('connection', function(conn) {
conn.on('authentication', function(ctx) {
if (ctx.method === 'none')
return ctx.reject();
assert(ctx.method === 'publickey',
makeMsg(what, 'Unexpected auth method: ' + ctx.method));
assert(ctx.username === USER,
makeMsg(what, 'Unexpected username: ' + ctx.username));
assert(ctx.key.algo === 'ecdsa-sha2-nistp256',
makeMsg(what, 'Unexpected key algo: ' + ctx.key.algo));
assert.deepEqual(CLIENT_KEY_ECDSA_PUB.public,
ctx.key.data,
makeMsg(what, 'Public key mismatch'));
if (ctx.signature) {
var verifier = crypto.createVerify('sha256');
var pem = CLIENT_KEY_ECDSA_PUB.publicOrig;
verifier.update(ctx.blob);
assert(verifier.verify(pem, ctx.signature),
makeMsg(what, 'Could not verify PK signature'));
ctx.accept();
} else
ctx.accept();
}).on('ready', function() {
conn.on('session', function(accept, reject) {
var session = accept();
if (session) {
session.on('exec', function(accept, reject) {
var stream = accept();
if (stream) {
stream.exit(0);
stream.end();
}
}).on('pty', function(accept, reject) {
accept && accept();
});
}
});
});
});
},
what: 'Authenticate with a ECDSA key'
},
{ run: function() {
var server;
server = setup(
this,
{ privateKeyPath: CLIENT_KEY_RSA_PATH },
{ hostKeys: [HOST_KEY_DSA] }
);
server.on('connection', function(conn) {
conn.on('authentication', function(ctx) {
ctx.accept();
}).on('ready', function() {
conn.on('session', function(accept, reject) {
var session = accept();
if (session) {
session.on('exec', function(accept, reject) {
var stream = accept();
if (stream) {
stream.exit(0);
stream.end();
}
}).on('pty', function(accept, reject) {
accept && accept();
});
}
});
});
});
},
what: 'Server with DSA host key'
},
{ run: function() {
if (semver.lt(process.version, '5.2.0'))
return next();
var server;
server = setup(
this,
{ privateKeyPath: CLIENT_KEY_RSA_PATH },
{ hostKeys: [HOST_KEY_ECDSA] }
);
server.on('connection', function(conn) {
conn.on('authentication', function(ctx) {
ctx.accept();
}).on('ready', function() {
conn.on('session', function(accept, reject) {
var session = accept();
if (session) {
session.on('exec', function(accept, reject) {
var stream = accept();
if (stream) {
stream.exit(0);
stream.end();
}
}).on('pty', function(accept, reject) {
accept && accept();
});
}
});
});
});
},
what: 'Server with ECDSA host key'
},
{ run: function() {
var server;
var what = this.what;
server = setup(
this,
{ privateKeyPath: CLIENT_KEY_RSA_PATH },
{ hostKeys: [HOST_KEY_RSA] }
);
server.on('_child', function(childProc) {
childProc.stderr.once('data', function(data) {
childProc.stdin.end();
});
childProc.stdin.write('ping');
}).on('connection', function(conn) {
conn.on('authentication', function(ctx) {
ctx.accept();
}).on('ready', function() {
conn.on('session', function(accept, reject) {
var session = accept();
assert(session, makeMsg(what, 'Missing session'));
session.on('exec', function(accept, reject) {
var stream = accept();
assert(stream, makeMsg(what, 'Missing exec stream'));
stream.stdin.on('data', function(data) {
stream.stdout.write('pong on stdout');
stream.stderr.write('pong on stderr');
}).on('end', function() {
stream.stdout.write('pong on stdout');
stream.stderr.write('pong on stderr');
stream.exit(0);
stream.close();
});
}).on('pty', function(accept, reject) {
accept && accept();
});
});
});
});
},
what: 'Server closes stdin too early'
},
];
function setup(self, clientcfg, servercfg) {
self.state = {
serverReady: false,
clientClose: false,
serverClose: false
};
var client;
var server = new Server(servercfg);
server.on('error', onError)
.on('connection', function(conn) {
conn.on('error', onError)
.on('ready', onReady);
server.close();
})
.on('close', onClose);
function onError(err) {
var which = (arguments.length >= 3 ? 'client' : 'server');
assert(false, makeMsg(self.what, 'Unexpected ' + which + ' error: ' + err));
}
function onReady() {
assert(!self.state.serverReady,
makeMsg(self.what, 'Received multiple ready events for server'));
self.state.serverReady = true;
self.onReady && self.onReady();
}
function onClose() {
if (arguments.length >= 3) {
assert(!self.state.clientClose,
makeMsg(self.what, 'Received multiple close events for client'));
self.state.clientClose = true;
} else {
assert(!self.state.serverClose,
makeMsg(self.what, 'Received multiple close events for server'));
self.state.serverClose = true;
}
if (self.state.clientClose && self.state.serverClose)
next();
}
process.nextTick(function() {
server.listen(0, 'localhost', function() {
var cmd = 'ssh';
var args = ['-o', 'UserKnownHostsFile=/dev/null',
'-o', 'StrictHostKeyChecking=no',
'-o', 'CheckHostIP=no',
'-o', 'ConnectTimeout=3',
'-o', 'GlobalKnownHostsFile=/dev/null',
'-o', 'GSSAPIAuthentication=no',
'-o', 'IdentitiesOnly=yes',
'-o', 'BatchMode=yes',
'-o', 'VerifyHostKeyDNS=no',
'-vvvvvv',
'-T',
'-o', 'KbdInteractiveAuthentication=no',
'-o', 'HostbasedAuthentication=no',
'-o', 'PasswordAuthentication=no',
'-o', 'PubkeyAuthentication=yes',
'-o', 'PreferredAuthentications=publickey'];
if (clientcfg.privateKeyPath)
args.push('-o', 'IdentityFile=' + clientcfg.privateKeyPath);
if (!/^[0-6]\./.test(opensshVer)) {
// OpenSSH 7.0+ disables DSS/DSA host (and user) key support by
// default, so we explicitly enable it here
args.push('-o', 'HostKeyAlgorithms=+ssh-dss');
}
args.push('-p', server.address().port.toString(),
'-l', USER,
'localhost',
'uptime');
client = spawn(cmd, args);
server.emit('_child', client);
if (DEBUG) {
client.stdout.pipe(process.stdout);
client.stderr.pipe(process.stderr);
} else {
client.stdout.resume();
client.stderr.resume();
}
client.on('error', function(err) {
onError(err, null, null);
}).on('exit', function(code) {
clearTimeout(client.timer);
if (code !== 0)
return onError(new Error('Non-zero exit code ' + code), null, null);
onClose(null, null, null);
});
client.timer = setTimeout(function() {
assert(false, makeMsg(self.what, 'Client timeout'));
}, CLIENT_TIMEOUT);
});
});
return server;
}
function next() {
if (Array.isArray(process._events.exit))
process._events.exit = process._events.exit[1];
if (++t === tests.length)
return;
var v = tests[t];
v.run.call(v);
}
function makeMsg(what, msg) {
return '[' + group + what + ']: ' + msg;
}
process.once('uncaughtException', function(err) {
if (t > -1 && !/(?:^|\n)AssertionError: /i.test(''+err))
console.log(makeMsg(tests[t].what, 'Unexpected Exception:'));
throw err;
});
process.once('exit', function() {
assert(t === tests.length,
makeMsg('_exit',
'Only finished ' + t + '/' + tests.length + ' tests'));
});
// Get OpenSSH client version first
exec('ssh -V', function(err, stdout, stderr) {
if (err) {
console.log('OpenSSH client is required for these tests');
process.exitCode = 5;
return;
}
var re = /^OpenSSH_([\d\.]+)/;
var m = re.exec(stdout.toString());
if (!m || !m[1]) {
m = re.exec(stderr.toString());
if (!m || !m[1]) {
console.log('OpenSSH client is required for these tests');
process.exitCode = 5;
return;
}
}
opensshVer = m[1];
next();
});

22
build/node_modules/ssh2/test/test.js generated vendored Normal file
View File

@@ -0,0 +1,22 @@
var spawn = require('child_process').spawn,
join = require('path').join;
var files = require('fs').readdirSync(__dirname).filter(function(f) {
return (f.substr(0, 5) === 'test-');
}).map(function(f) {
return join(__dirname, f);
}),
f = -1;
function next() {
if (++f < files.length) {
spawn(process.argv[0], [ files[f] ], { stdio: 'inherit' })
.on('exit', function(code) {
if (code === 0)
process.nextTick(next);
else
process.exit(code);
});
}
}
next();

2
build/node_modules/ssh2/util/build_pagent.bat generated vendored Normal file
View File

@@ -0,0 +1,2 @@
@cl /Ox pagent.c User32.lib
@del /Q *.obj

88
build/node_modules/ssh2/util/pagent.c generated vendored Normal file
View File

@@ -0,0 +1,88 @@
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#define AGENT_COPYDATA_ID 0x804e50ba
#define AGENT_MAX_MSGLEN 8192
#define GET_32BIT_MSB_FIRST(cp) \
(((unsigned long)(unsigned char)(cp)[0] << 24) | \
((unsigned long)(unsigned char)(cp)[1] << 16) | \
((unsigned long)(unsigned char)(cp)[2] << 8) | \
((unsigned long)(unsigned char)(cp)[3]))
#define GET_32BIT(cp) GET_32BIT_MSB_FIRST(cp)
#define RET_ERR_BADARGS 10
#define RET_ERR_UNAVAILABLE 11
#define RET_ERR_NOMAP 12
#define RET_ERR_BINSTDIN 13
#define RET_ERR_BINSTDOUT 14
#define RET_ERR_BADLEN 15
#define RET_NORESPONSE 1
#define RET_RESPONSE 0
int main (int argc, const char* argv[]) {
HWND hwnd;
char *mapname;
HANDLE filemap;
unsigned char *p, *ret;
int id, retlen, inlen, n, rmode, r = RET_NORESPONSE;
COPYDATASTRUCT cds;
void *in;
if (argc < 2)
return RET_ERR_BADARGS;
hwnd = FindWindow("Pageant", "Pageant");
if (!hwnd)
return RET_ERR_UNAVAILABLE;
rmode = _setmode(_fileno(stdin), _O_BINARY);
if (rmode == -1)
return RET_ERR_BINSTDIN;
rmode = _setmode(_fileno(stdout), _O_BINARY);
if (rmode == -1)
return RET_ERR_BINSTDOUT;
inlen = atoi(argv[1]);
in = malloc(inlen);
n = fread(in, 1, inlen, stdin);
if (n != inlen) {
free(in);
return RET_ERR_BADLEN;
}
mapname = malloc(32);
n = sprintf(mapname, "PageantRequest%08x", (unsigned)GetCurrentThreadId());
filemap = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
0, AGENT_MAX_MSGLEN, mapname);
if (filemap == NULL || filemap == INVALID_HANDLE_VALUE) {
free(in);
free(mapname);
return RET_ERR_NOMAP;
}
p = MapViewOfFile(filemap, FILE_MAP_WRITE, 0, 0, 0);
memcpy(p, in, inlen);
cds.dwData = AGENT_COPYDATA_ID;
cds.cbData = 1 + n;
cds.lpData = mapname;
id = SendMessage(hwnd, WM_COPYDATA, (WPARAM) NULL, (LPARAM) &cds);
if (id > 0) {
r = RET_RESPONSE;
retlen = 4 + GET_32BIT(p);
fwrite(p, 1, retlen, stdout);
}
free(in);
free(mapname);
UnmapViewOfFile(p);
CloseHandle(filemap);
return r;
}

BIN
build/node_modules/ssh2/util/pagent.exe generated vendored Normal file

Binary file not shown.