fix port,io.of privateKey
This commit is contained in:
parent
49fc526c08
commit
3537565ffe
11 changed files with 1034 additions and 3263 deletions
36
README.md
36
README.md
|
|
@ -221,6 +221,42 @@ Clicking `Start logging` on the status bar will log all data to the client. A `D
|
|||
# Example:
|
||||
|
||||
http://localhost:2222/ssh/host/192.168.1.1?port=2244&header=My%20Header&color=red
|
||||
http://127.0.0.1:2222/ssh/host/165.149.12.16?host=165.149.12.16&user=root&port=54321
|
||||
|
||||
# how use
|
||||
```
|
||||
WebSSH2/app#cat config.json|grep privateKey
|
||||
"privateKey":"/.ssh/id_rsa",
|
||||
# create privateKey
|
||||
$ ssh-keygen -t rsa
|
||||
# cp ~/.ssh/id_rsa.pub to server ~/.ssh/authorized_keys
|
||||
# server:
|
||||
chmod 600 ~/.ssh/authorized_keys
|
||||
```
|
||||
|
||||
# Tips
|
||||
* If you want to add custom JavaScript to the browser client you can either modify `./src/client.html` and add a **<script>** element, modify `./src/index.js` directly, or check out `webpack.*.js` and add your custom javascript file to a task there (best option).
|
||||
|
||||
# how build webssh2.bundle.js
|
||||
```
|
||||
cd WebSSH2/app
|
||||
# modify:
|
||||
client/src/js/index.js
|
||||
npm install compression-webpack-plugin --save-dev
|
||||
npm install --save-dev mini-css-extract-plugin
|
||||
npm i --save '@fortawesome/fontawesome'
|
||||
npm i --save '@fortawesome/fontawesome-free-solid'
|
||||
npm i --save 'xterm'
|
||||
npm i --save 'xterm' 'socket.io-client' 'style-loader'
|
||||
npm i --save 'css-loader'
|
||||
npm install --save-dev webpack-cli
|
||||
npm install --save-dev webpack
|
||||
npm install --save-dev webpack-merge
|
||||
npm install --save-dev uglifyjs-webpack-plugin
|
||||
npm install --save-dev clean-webpack-plugin
|
||||
npm install --save-dev copy-webpack-plugin
|
||||
npm install --save-dev 'extract-text-webpack-plugin'
|
||||
npm install --save '@fortawesome/fontawesome-svg-core' '@fortawesome/free-solid-svg-icons'
|
||||
npm install --save acorn chokidar estraverse inflight ms querystring-es3 string-width acorn-dynamic-import chownr esutils inherits nanomatch randombytes strip-ansi after chrome-trace-event events ini neo-async randomfill strip-eof ajv cipher-base evp_bytestokey interpret nice-try readable-stream style-loader ajv-errors class-utils execa invert-kv node-libs-browser readdirp supports-color ajv-keywords clean-webpack-plugin expand-brackets is-accessor-descriptor normalize-path regenerate tapable ansi-regex cliui expand-tilde isarray npm-run-path regex-not terser ansi-styles code-point-at extend-shallow is-binary-path number-is-nan regexpu-core terser-webpack-plugin anymatch collection-visit extglob is-buffer object-component regjsgen through2 aproba color-convert extract-text-webpack-plugin is-data-descriptor object-copy regjsparser timers-browserify arraybuffer.slice color-name fast-deep-equal is-descriptor object.pick remove-trailing-separator to-array array-union commander fast-json-stable-stringify isexe object-visit repeat-element to-arraybuffer array-uniq commondir fastparse is-extendable once repeat-string to-object-path array-unique component-bind figgy-pudding is-extglob os-browserify require-directory to-regex arr-diff component-emitter fill-range is-fullwidth-code-point os-locale require-main-filename to-regex-range arr-flatten component-inherit find-cache-dir is-glob pako resolve-cwd tslib arr-union compression-webpack-plugin find-up is-number parallel-transform resolve-dir tty-browserify asn1.js concat-map findup-sync isobject parse-asn1 resolve-from typedarray assert concat-stream flush-write-stream is-plain-object parse-passwd resolve-url uglify-js assign-symbols console-browserify for-in is-stream parseqs ret uglifyjs-webpack-plugin async constants-browserify @fortawesome is-windows parseuri rimraf union-value async-each copy-concurrently fragment-cache jsesc pascalcase ripemd160 unique-filename async-limiter copy-descriptor from2 json5 path-browserify run-queue unique-slug atob copy-webpack-plugin fs.realpath json-parse-better-errors path-dirname safe-buffer unset-value babel-code-frame core-util-is fs-write-stream-atomic json-schema-traverse path-exists safe-regex upath backo2 create-ecdh get-caller-file js-tokens path-is-absolute schema-utils uri-js balanced-match create-hash get-stream kind-of path-key semver urix base create-hmac get-value lcid path-type serialize-javascript url base64-arraybuffer cross-spawn glob lightercollective pbkdf2 set-blocking use base64-js crypto-browserify global-modules loader-runner p-defer setimmediate util better-assert cssesc global-modules-path loader-utils p-finally set-value util-deprecate big.js css-loader global-prefix locate-path pify sha.js v8-compile-cache binary-extensions css-selector-tokenizer globby lodash p-is-promise shebang-command vm-browserify blob cyclist glob-parent lodash.debounce pkg-dir shebang-regex watchpack bluebird date-now graceful-fs lru-cache p-limit signal-exit @webassemblyjs bn.js decamelize has-ansi make-dir p-locate slash webpack brace-expansion decode-uri-component has-binary2 map-age-cleaner posix-character-classes snapdragon webpack-cli braces define-property has-cors map-cache postcss snapdragon-node webpack-merge brorand des.js has-flag map-visit postcss-modules-extract-imports snapdragon-util webpack-sources browserify-aes detect-file hash-base md5.js postcss-modules-local-by-default socket.io-client which browserify-cipher diffie-hellman hash.js mem postcss-modules-scope socket.io-parser which-module browserify-des dir-glob has-value memory-fs postcss-modules-values source-list-map worker-farm browserify-rsa domain-browser has-values micromatch postcss-value-parser source-map wrap-ansi browserify-sign duplexify hmac-drbg miller-rabin process source-map-resolve wrappy browserify-zlib elliptic homedir-polyfill mimic-fn process-nextick-args source-map-support ws buffer emojis-list https-browserify mini-css-extract-plugin promise-inflight source-map-url xmlhttprequest-ssl buffer-from end-of-stream icss-replace-symbols minimalistic-assert prr split-string xtend buffer-xor engine.io-client icss-utils minimalistic-crypto-utils pseudomap ssri xterm builtin-status-codes engine.io-parser ieee754 minimatch p-try static-extend @xtuc cacache enhanced-resolve iferr minimist public-encrypt stream-browserify y18n cache-base errno ignore mississippi pump stream-each yallist callsite escape-string-regexp import-local mixin-deep pumpify stream-http yargs camelcase eslint-scope imurmurhash mkdirp punycode stream-shift yargs-parser chalk esrecurse indexof move-concurrently querystring string_decoder yeast
|
||||
npm run build
|
||||
```
|
||||
|
|
@ -20,6 +20,10 @@
|
|||
<div id="status"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// your server io.of(Thepath)
|
||||
var g_szPath = "/ssh"
|
||||
</script>
|
||||
<script src="/webssh2.bundle.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -20,6 +20,10 @@
|
|||
<div id="status"></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// your server io.of(Thepath)
|
||||
var g_szPath = "/ssh"
|
||||
</script>
|
||||
<script src="/webssh2.bundle.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
|
|
@ -37,16 +37,16 @@ function resizeScreen () {
|
|||
term.fit()
|
||||
socket.emit('resize', { cols: term.cols, rows: term.rows })
|
||||
}
|
||||
|
||||
var szPath = g_szPath || null;
|
||||
if (document.location.pathname) {
|
||||
var parts = document.location.pathname.split('/')
|
||||
var base = parts.slice(0, parts.length - 1).join('/') + '/'
|
||||
var resource = base.substring(1) + 'socket.io'
|
||||
socket = io.connect(null, {
|
||||
socket = io.connect(szPath, {
|
||||
resource: resource
|
||||
})
|
||||
} else {
|
||||
socket = io.connect()
|
||||
socket = io.connect(szPath)
|
||||
}
|
||||
|
||||
term.on('data', function (data) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"privateKey":"/.ssh/id_rsa",
|
||||
"listen": {
|
||||
"ip": "0.0.0.0",
|
||||
"port": 2222
|
||||
|
|
|
|||
19
app/index.js
19
app/index.js
|
|
@ -7,9 +7,26 @@
|
|||
* Bill Church - https://github.com/billchurch/WebSSH2 - May 2017
|
||||
*
|
||||
*/
|
||||
var path = require('path')
|
||||
var express = require('express')
|
||||
var app = express()
|
||||
var compression = require('compression')
|
||||
var nodeRoot = path.dirname(require.main.filename)
|
||||
var expressOptions = require('./server/expressOptions')
|
||||
|
||||
// static files
|
||||
var publicPath = path.join(nodeRoot, 'client', 'public')
|
||||
app.use(express.static(publicPath, expressOptions))
|
||||
|
||||
// express
|
||||
app.use(compression({ level: 9 }))
|
||||
var server = require('http').Server(app)
|
||||
var io = require('socket.io')(server, { serveClient: false })
|
||||
|
||||
app.disable('x-powered-by')
|
||||
|
||||
var config = require('./server/app').config
|
||||
var server = require('./server/app').server
|
||||
require('./server/app').mySSH(app,io.of("/ssh"))
|
||||
|
||||
server.listen({ host: config.listen.ip, port: config.listen.port
|
||||
})
|
||||
|
|
|
|||
3857
app/package-lock.json
generated
3857
app/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -27,6 +27,9 @@
|
|||
"url": "https://github.com/billchurch/WebSSH2/issues"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome": "^1.1.8",
|
||||
"@fortawesome/fontawesome-free-solid": "^5.0.13",
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.12",
|
||||
"basic-auth": "^2.0.1",
|
||||
"colors": "^1.3.2",
|
||||
"compression": "^1.7.3",
|
||||
|
|
@ -36,6 +39,7 @@
|
|||
"morgan": "^1.9.1",
|
||||
"read-config": "^2.0.0",
|
||||
"socket.io": "^2.1.1",
|
||||
"socket.io-client": "^2.2.0",
|
||||
"ssh2": "^0.6.1",
|
||||
"validator": "^10.9.0"
|
||||
},
|
||||
|
|
@ -49,6 +53,32 @@
|
|||
"standard": "standard --verbose --fix | snazzy",
|
||||
"cleanmac": "find . -name '.DS_Store' -type f -delete"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.5.0",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.6.3",
|
||||
"ajv": "^6.5.5",
|
||||
"bithound": "^1.7.0",
|
||||
"clean-webpack-plugin": "^0.1.19",
|
||||
"compression-webpack-plugin": "^2.0.0",
|
||||
"copy-webpack-plugin": "^4.6.0",
|
||||
"css-loader": "^1.0.1",
|
||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||
"file-loader": "^2.0.0",
|
||||
"mini-css-extract-plugin": "^0.5.0",
|
||||
"nodemon": "^1.18.6",
|
||||
"postcss-discard-comments": "^4.0.1",
|
||||
"snazzy": "^8.0.0",
|
||||
"snyk": "^1.108.2",
|
||||
"standard": "^12.0.1",
|
||||
"style-loader": "^0.23.1",
|
||||
"uglifyjs-webpack-plugin": "^2.1.1",
|
||||
"url-loader": "^1.1.2",
|
||||
"webpack": "^4.28.4",
|
||||
"webpack-cli": "^3.2.1",
|
||||
"webpack-merge": "^4.2.1",
|
||||
"webpack-stream": "^5.1.1",
|
||||
"xterm": "^3.10.1"
|
||||
},
|
||||
"standard": {
|
||||
"ignore": [
|
||||
"client/public/webssh2.bundle.js",
|
||||
|
|
@ -58,27 +88,5 @@
|
|||
"build/*",
|
||||
"workspace/*"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fortawesome/fontawesome-svg-core": "^1.2.12",
|
||||
"@fortawesome/free-solid-svg-icons": "^5.6.3",
|
||||
"clean-webpack-plugin": "^1.0.0",
|
||||
"copy-webpack-plugin": "^4.6.0",
|
||||
"cross-env": "^5.2.0",
|
||||
"css-loader": "^2.1.0",
|
||||
"extract-text-webpack-plugin": "^4.0.0-beta.0",
|
||||
"file-loader": "^3.0.1",
|
||||
"nodaemon": "0.0.5",
|
||||
"postcss-discard-comments": "^4.0.1",
|
||||
"snazzy": "^8.0.0",
|
||||
"standard": "^12.0.1",
|
||||
"style-loader": "^0.23.1",
|
||||
"uglifyjs-webpack-plugin": "^2.1.1",
|
||||
"url-loader": "^1.1.2",
|
||||
"webpack": "^4.28.4",
|
||||
"webpack-cli": "^3.2.1",
|
||||
"webpack-merge": "^4.2.1",
|
||||
"webpack-stream": "^5.2.1",
|
||||
"xterm": "^3.10.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@ var nodeRoot = path.dirname(require.main.filename)
|
|||
var configPath = path.join(nodeRoot, 'config.json')
|
||||
var publicPath = path.join(nodeRoot, 'client', 'public')
|
||||
console.log('WebSSH2 service reading config from: ' + configPath)
|
||||
var config = require('read-config')(configPath)
|
||||
var express = require('express')
|
||||
var config = require('read-config')(configPath),
|
||||
fs = require('fs'),
|
||||
os = require('os');
|
||||
var logger = require('morgan')
|
||||
var session = require('express-session')({
|
||||
secret: config.session.secret,
|
||||
|
|
@ -18,40 +19,61 @@ var session = require('express-session')({
|
|||
saveUninitialized: false,
|
||||
unset: 'destroy'
|
||||
})
|
||||
var app = express()
|
||||
var compression = require('compression')
|
||||
var server = require('http').Server(app)
|
||||
|
||||
|
||||
var myutil = require('./util')
|
||||
var validator = require('validator')
|
||||
var io = require('socket.io')(server, { serveClient: false })
|
||||
|
||||
var socket = require('./socket')
|
||||
var expressOptions = require('./expressOptions')
|
||||
|
||||
// express
|
||||
app.use(compression({ level: 9 }))
|
||||
app.use(session)
|
||||
app.use(myutil.basicAuth)
|
||||
if (config.accesslog) app.use(logger('common'))
|
||||
app.disable('x-powered-by')
|
||||
|
||||
// static files
|
||||
app.use(express.static(publicPath, expressOptions))
|
||||
|
||||
app.get('/reauth', function (req, res, next) {
|
||||
var r = req.headers.referer || '/'
|
||||
res.status(401).send('<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=' + r + '"></head><body bgcolor="#000"></body></html>')
|
||||
})
|
||||
|
||||
function mySSH(app, io)
|
||||
{
|
||||
app.use(session)
|
||||
app.get('/reauth', function (req, res, next) {
|
||||
var r = req.headers.referer || '/'
|
||||
res.status(401).send('<!DOCTYPE html><html><head><meta http-equiv="refresh" content="0; url=' + r + '"></head><body bgcolor="#000"></body></html>')
|
||||
})
|
||||
|
||||
if (config.accesslog) app.use(logger('common'))
|
||||
app.use(myutil.basicAuth)
|
||||
|
||||
// test:
|
||||
// http://127.0.0.1:2222/ssh/host/165.149.12.16?host=165.149.12.16&user=root&port=54321
|
||||
app.get('/ssh/host/:host?', function (req, res, next) {
|
||||
var szHost = req.params && req.params.host || null;
|
||||
if(req.query)
|
||||
{
|
||||
req.params = req.query;
|
||||
req.params.host = szHost || req.params.host;
|
||||
}
|
||||
// console.log(req.params);
|
||||
res.sendFile(path.join(path.join(publicPath, 'client.htm')))
|
||||
if(req.params)
|
||||
{
|
||||
if(req.params.user)
|
||||
req.session.username = req.params.user;
|
||||
if(req.params.pass)
|
||||
req.session.userpassword = req.params.pass;
|
||||
}
|
||||
if(!req.params || !req.params.host)return;
|
||||
var szKey = '';
|
||||
if(!szKey && fs.existsSync(os.userInfo().homedir + config.privateKey))
|
||||
{
|
||||
szKey = fs.readFileSync(os.userInfo().homedir + config.privateKey).toString('utf8');
|
||||
// console.log(szKey);
|
||||
}
|
||||
|
||||
// capture, assign, and validated variables
|
||||
req.session.ssh = {
|
||||
privateKey: szKey,
|
||||
host: (validator.isIP(req.params.host + '') && req.params.host) ||
|
||||
(validator.isFQDN(req.params.host) && req.params.host) ||
|
||||
(/^(([a-z]|[A-Z]|[0-9]|[!^(){}\-_~])+)?\w$/.test(req.params.host) &&
|
||||
req.params.host) || config.ssh.host,
|
||||
port: (validator.isInt(req.query.port + '', { min: 1, max: 65535 }) &&
|
||||
req.query.port) || config.ssh.port,
|
||||
port: (validator.isInt(req.params.port + '', { min: 1, max: 65535 }) &&
|
||||
req.params.port) || config.ssh.port,
|
||||
header: {
|
||||
name: req.query.header || config.header.text,
|
||||
background: req.query.headerBackground || config.header.background
|
||||
|
|
@ -100,5 +122,5 @@ io.use(function (socket, next) {
|
|||
|
||||
// bring up socket
|
||||
io.on('connection', socket)
|
||||
|
||||
module.exports = { server: server, config: config }
|
||||
}
|
||||
module.exports = { config: config,mySSH: mySSH }
|
||||
|
|
|
|||
|
|
@ -1,11 +1,10 @@
|
|||
'use strict'
|
||||
/* jshint esversion: 6, asi: true, node: true */
|
||||
// socket.js
|
||||
|
||||
// private
|
||||
var debug = require('debug')
|
||||
var debugWebSSH2 = require('debug')('WebSSH2')
|
||||
var SSH = require('ssh2').Client
|
||||
var debug = require('debug'),
|
||||
uuid = require('node-uuid'),
|
||||
redis = require("redis").createClient(),
|
||||
debugWebSSH2 = require('debug')('WebSSH2'),
|
||||
SSH = require('ssh2').Client;
|
||||
// var fs = require('fs')
|
||||
// var hostkeys = JSON.parse(fs.readFileSync('./hostkeyhashes.json', 'utf8'))
|
||||
var termCols, termRows
|
||||
|
|
@ -13,126 +12,167 @@ var menuData = '<a id="logBtn"><i class="fas fa-clipboard fa-fw"></i> Start Log<
|
|||
'<a id="downloadLogBtn"><i class="fas fa-download fa-fw"></i> Download Log</a>'
|
||||
|
||||
// public
|
||||
module.exports = function socket (socket) {
|
||||
module.exports = function socket (socket)
|
||||
{
|
||||
var oSs = socket.request.session,oSsh = oSs.ssh;
|
||||
// if websocket connection arrives without an express session, kill it
|
||||
if (!socket.request.session) {
|
||||
socket.emit('401 UNAUTHORIZED')
|
||||
debugWebSSH2('SOCKET: No Express Session / REJECTED')
|
||||
socket.disconnect(true)
|
||||
if (!socket.request.session)
|
||||
{
|
||||
socket.emit('401 UNAUTHORIZED');
|
||||
debugWebSSH2('SOCKET: No Express Session / REJECTED');
|
||||
// 如果关闭,其他监听不可用
|
||||
// console.log("不能关闭,否则其他监听不能用");
|
||||
socket.disconnect(true);
|
||||
return
|
||||
}
|
||||
var conn = new SSH()
|
||||
socket.on('geometry', function socketOnGeometry (cols, rows) {
|
||||
termCols = cols
|
||||
termRows = rows
|
||||
})
|
||||
conn.on('banner', function connOnBanner (data) {
|
||||
var conn = new SSH();
|
||||
socket.on('geometry', function socketOnGeometry (cols, rows)
|
||||
{
|
||||
termCols = cols;
|
||||
termRows = rows;
|
||||
});
|
||||
conn.on('banner', function connOnBanner (data)
|
||||
{
|
||||
// need to convert to cr/lf for proper formatting
|
||||
data = data.replace(/\r?\n/g, '\r\n')
|
||||
socket.emit('data', data.toString('utf-8'))
|
||||
})
|
||||
});
|
||||
|
||||
conn.on('ready', function connOnReady () {
|
||||
console.log('WebSSH2 Login: user=' + socket.request.session.username + ' from=' + socket.handshake.address + ' host=' + socket.request.session.ssh.host + ' port=' + socket.request.session.ssh.port + ' sessionID=' + socket.request.sessionID + '/' + socket.id + ' mrhsession=' + socket.request.session.ssh.mrhsession + ' allowreplay=' + socket.request.session.ssh.allowreplay + ' term=' + socket.request.session.ssh.term)
|
||||
conn.on('ready', function connOnReady ()
|
||||
{
|
||||
if(!oSsh.redisid)
|
||||
{
|
||||
// 记录到tags库
|
||||
var szIdTmp = "ssh" + (oSsh.redisid || uuid.v4()),oTmp = {
|
||||
id:szIdTmp,
|
||||
host:oSsh.host,
|
||||
port:oSsh.port,
|
||||
username:oSs.username,
|
||||
userpassword:oSs.userpassword,
|
||||
privateKey:oSsh.privateKey};
|
||||
var szK = [oTmp.host,oTmp.port,oTmp.username].join("_");
|
||||
if(global && (!global.oNoRpt || !global.oNoRpt[szK]))
|
||||
redis.set(szIdTmp, JSON.stringify(oTmp));
|
||||
}
|
||||
//
|
||||
console.log('WebSSH2 Login: user=' + oSs.username + ' from=' + socket.handshake.address + ' host=' + oSsh.host + ' port=' + oSsh.port + ' sessionID=' + socket.request.sessionID + '/' + socket.id + ' mrhsession=' + oSsh.mrhsession + ' allowreplay=' + oSsh.allowreplay + ' term=' + oSsh.term)
|
||||
socket.emit('menu', menuData)
|
||||
socket.emit('allowreauth', socket.request.session.ssh.allowreauth)
|
||||
socket.emit('setTerminalOpts', socket.request.session.ssh.terminal)
|
||||
socket.emit('title', 'ssh://' + socket.request.session.ssh.host)
|
||||
if (socket.request.session.ssh.header.background) socket.emit('headerBackground', socket.request.session.ssh.header.background)
|
||||
if (socket.request.session.ssh.header.name) socket.emit('header', socket.request.session.ssh.header.name)
|
||||
socket.emit('footer', 'ssh://' + socket.request.session.username + '@' + socket.request.session.ssh.host + ':' + socket.request.session.ssh.port)
|
||||
socket.emit('status', 'SSH CONNECTION ESTABLISHED')
|
||||
socket.emit('statusBackground', 'green')
|
||||
socket.emit('allowreplay', socket.request.session.ssh.allowreplay)
|
||||
socket.emit('allowreauth', oSsh.allowreauth);
|
||||
socket.emit('setTerminalOpts', oSsh.terminal);
|
||||
socket.emit('title', 'ssh://' + oSsh.host);
|
||||
if (oSsh.header.background) socket.emit('headerBackground', oSsh.header.background);
|
||||
if (oSsh.header.name) socket.emit('header', oSsh.header.name);
|
||||
socket.emit('footer', 'ssh://' + oSs.username + '@' + oSsh.host + ':' + oSsh.port);
|
||||
socket.emit('status', 'SSH CONNECTION ESTABLISHED');
|
||||
socket.emit('statusBackground', 'green');
|
||||
socket.emit('allowreplay', oSsh.allowreplay);
|
||||
conn.shell({
|
||||
term: socket.request.session.ssh.term,
|
||||
term: oSsh.term,
|
||||
cols: termCols,
|
||||
rows: termRows
|
||||
}, function connShell (err, stream) {
|
||||
if (err) {
|
||||
SSHerror('EXEC ERROR' + err)
|
||||
conn.end()
|
||||
conn.end();
|
||||
return
|
||||
}
|
||||
// poc to log commands from client
|
||||
if (socket.request.session.ssh.serverlog.client) var dataBuffer
|
||||
socket.on('data', function socketOnData (data) {
|
||||
stream.write(data)
|
||||
if (oSsh.serverlog.client) var dataBuffer
|
||||
socket.on('data', function socketOnData (data)
|
||||
{
|
||||
stream.write(data);
|
||||
// poc to log commands from client
|
||||
if (socket.request.session.ssh.serverlog.client) {
|
||||
if (data === '\r') {
|
||||
console.log('serverlog.client: ' + socket.request.session.id + '/' + socket.id + ' host: ' + socket.request.session.ssh.host + ' command: ' + dataBuffer)
|
||||
dataBuffer = undefined
|
||||
} else {
|
||||
dataBuffer = (dataBuffer) ? dataBuffer + data : data
|
||||
if (oSsh.serverlog.client)
|
||||
{
|
||||
if (data === '\r')
|
||||
{
|
||||
console.log('serverlog.client: ' + oSs.id + '/' + socket.id + ' host: ' + oSsh.host + ' command: ' + dataBuffer);
|
||||
dataBuffer = undefined;
|
||||
} else
|
||||
{
|
||||
dataBuffer = (dataBuffer) ? dataBuffer + data : data;
|
||||
}
|
||||
}
|
||||
})
|
||||
socket.on('control', function socketOnControl (controlData) {
|
||||
switch (controlData) {
|
||||
socket.on('control', function socketOnControl (controlData)
|
||||
{
|
||||
switch (controlData)
|
||||
{
|
||||
case 'replayCredentials':
|
||||
if (socket.request.session.ssh.allowreplay) {
|
||||
stream.write(socket.request.session.userpassword + '\n')
|
||||
if (oSsh.allowreplay)
|
||||
{
|
||||
stream.write(oSs.userpassword + '\n');
|
||||
}
|
||||
/* falls through */
|
||||
default:
|
||||
console.log('controlData: ' + controlData)
|
||||
console.log('controlData: ' + controlData);
|
||||
}
|
||||
})
|
||||
socket.on('resize', function socketOnResize (data) {
|
||||
stream.setWindow(data.rows, data.cols)
|
||||
socket.on('resize', function socketOnResize (data)
|
||||
{
|
||||
stream.setWindow(data.rows, data.cols);
|
||||
})
|
||||
socket.on('disconnecting', function socketOnDisconnecting (reason) { debugWebSSH2('SOCKET DISCONNECTING: ' + reason) })
|
||||
socket.on('disconnect', function socketOnDisconnect (reason) {
|
||||
debugWebSSH2('SOCKET DISCONNECT: ' + reason)
|
||||
err = { message: reason }
|
||||
SSHerror('CLIENT SOCKET DISCONNECT', err)
|
||||
conn.end()
|
||||
// socket.request.session.destroy()
|
||||
})
|
||||
socket.on('error', function socketOnError (err) {
|
||||
SSHerror('SOCKET ERROR', err)
|
||||
conn.end()
|
||||
socket.on('disconnecting', function socketOnDisconnecting (reason) { debugWebSSH2('SOCKET DISCONNECTING: ' + reason) });
|
||||
socket.on('disconnect', function socketOnDisconnect (reason)
|
||||
{
|
||||
debugWebSSH2('SOCKET DISCONNECT: ' + reason);
|
||||
err = { message: reason };
|
||||
SSHerror('CLIENT SOCKET DISCONNECT', err);
|
||||
conn.end();
|
||||
// oSs.destroy()
|
||||
})
|
||||
socket.on('error', function socketOnError (err)
|
||||
{
|
||||
SSHerror('SOCKET ERROR', err);
|
||||
conn.end();
|
||||
});
|
||||
|
||||
stream.on('data', function streamOnData (data) { socket.emit('data', data.toString('utf-8')) })
|
||||
stream.on('close', function streamOnClose (code, signal) {
|
||||
stream.on('data', function streamOnData (data) { socket.emit('data', data.toString('utf-8')) });
|
||||
stream.on('close', function streamOnClose (code, signal)
|
||||
{
|
||||
err = { message: ((code || signal) ? (((code) ? 'CODE: ' + code : '') + ((code && signal) ? ' ' : '') + ((signal) ? 'SIGNAL: ' + signal : '')) : undefined) }
|
||||
SSHerror('STREAM CLOSE', err)
|
||||
conn.end()
|
||||
SSHerror('STREAM CLOSE', err);
|
||||
conn.end();
|
||||
})
|
||||
stream.stderr.on('data', function streamStderrOnData (data) {
|
||||
console.log('STDERR: ' + data)
|
||||
stream.stderr.on('data', function streamStderrOnData (data)
|
||||
{
|
||||
console.log('STDERR: ' + data);
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
conn.on('end', function connOnEnd (err) { SSHerror('CONN END BY HOST', err) });
|
||||
conn.on('close', function connOnClose (err) { SSHerror('CONN CLOSE', err) });
|
||||
conn.on('error', function connOnError (err) { SSHerror('CONN ERROR', err) });
|
||||
conn.on('keyboard-interactive', function connOnKeyboardInteractive (name, instructions, instructionsLang, prompts, finish)
|
||||
{
|
||||
debugWebSSH2('conn.on(\'keyboard-interactive\')');
|
||||
finish([oSs.userpassword]);
|
||||
})
|
||||
|
||||
conn.on('end', function connOnEnd (err) { SSHerror('CONN END BY HOST', err) })
|
||||
conn.on('close', function connOnClose (err) { SSHerror('CONN CLOSE', err) })
|
||||
conn.on('error', function connOnError (err) { SSHerror('CONN ERROR', err) })
|
||||
conn.on('keyboard-interactive', function connOnKeyboardInteractive (name, instructions, instructionsLang, prompts, finish) {
|
||||
debugWebSSH2('conn.on(\'keyboard-interactive\')')
|
||||
finish([socket.request.session.userpassword])
|
||||
})
|
||||
if (socket.request.session.username && socket.request.session.userpassword && socket.request.session.ssh) {
|
||||
|
||||
if (oSs.username && oSsh && (oSs.userpassword || oSsh.privateKey))
|
||||
{
|
||||
// console.log('hostkeys: ' + hostkeys[0].[0])
|
||||
conn.connect({
|
||||
host: socket.request.session.ssh.host,
|
||||
port: socket.request.session.ssh.port,
|
||||
username: socket.request.session.username,
|
||||
password: socket.request.session.userpassword,
|
||||
host: oSsh.host,
|
||||
port: oSsh.port,
|
||||
username: oSs.username,
|
||||
password: oSs.userpassword,
|
||||
tryKeyboard: true,
|
||||
algorithms: socket.request.session.ssh.algorithms,
|
||||
readyTimeout: socket.request.session.ssh.readyTimeout,
|
||||
keepaliveInterval: socket.request.session.ssh.keepaliveInterval,
|
||||
keepaliveCountMax: socket.request.session.ssh.keepaliveCountMax,
|
||||
algorithms: oSsh.algorithms,
|
||||
readyTimeout: oSsh.readyTimeout,
|
||||
keepaliveInterval: oSsh.keepaliveInterval,
|
||||
keepaliveCountMax: oSsh.keepaliveCountMax,
|
||||
privateKey: oSsh.privateKey,
|
||||
debug: debug('ssh2')
|
||||
})
|
||||
} else {
|
||||
debugWebSSH2('Attempt to connect without session.username/password or session varialbles defined, potentially previously abandoned client session. disconnecting websocket client.\r\nHandshake information: \r\n ' + JSON.stringify(socket.handshake))
|
||||
socket.emit('ssherror', 'WEBSOCKET ERROR - Refresh the browser and try again')
|
||||
socket.request.session.destroy()
|
||||
socket.disconnect(true)
|
||||
debugWebSSH2('Attempt to connect without session.username/password or session varialbles defined, potentially previously abandoned client session. disconnecting websocket client.\r\nHandshake information: \r\n ' + JSON.stringify(socket.handshake));
|
||||
socket.emit('ssherror', 'WEBSOCKET ERROR - Refresh the browser and try again');
|
||||
oSs.destroy();
|
||||
// 不能关闭
|
||||
// console.log("不能关闭,否则其他监听不能用");
|
||||
socket.disconnect(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -141,33 +181,35 @@ module.exports = function socket (socket) {
|
|||
* @param {string} myFunc Function calling this function
|
||||
* @param {object} err error object or error message
|
||||
*/
|
||||
function SSHerror (myFunc, err) {
|
||||
var theError
|
||||
if (socket.request.session) {
|
||||
function SSHerror (myFunc, err)
|
||||
{
|
||||
var theError;
|
||||
if (socket.request.session)
|
||||
{
|
||||
// we just want the first error of the session to pass to the client
|
||||
socket.request.session.error = (socket.request.session.error) || ((err) ? err.message : undefined)
|
||||
theError = (socket.request.session.error) ? ': ' + socket.request.session.error : ''
|
||||
oSs.error = (oSs.error) || ((err) ? err.message : undefined);
|
||||
theError = (oSs.error) ? ': ' + oSs.error : '';
|
||||
// log unsuccessful login attempt
|
||||
if (err && (err.level === 'client-authentication')) {
|
||||
console.log('WebSSH2 ' + 'error: Authentication failure'.red.bold +
|
||||
' user=' + socket.request.session.username.yellow.bold.underline +
|
||||
' from=' + socket.handshake.address.yellow.bold.underline)
|
||||
socket.emit('allowreauth', socket.request.session.ssh.allowreauth)
|
||||
socket.emit('reauth')
|
||||
' user=' + oSs.username.yellow.bold.underline +
|
||||
' from=' + socket.handshake.address.yellow.bold.underline);
|
||||
socket.emit('allowreauth', oSsh.allowreauth);
|
||||
socket.emit('reauth');
|
||||
} else {
|
||||
console.log('WebSSH2 Logout: user=' + socket.request.session.username + ' from=' + socket.handshake.address + ' host=' + socket.request.session.ssh.host + ' port=' + socket.request.session.ssh.port + ' sessionID=' + socket.request.sessionID + '/' + socket.id + ' allowreplay=' + socket.request.session.ssh.allowreplay + ' term=' + socket.request.session.ssh.term)
|
||||
console.log('WebSSH2 Logout: user=' + oSs.username + ' from=' + socket.handshake.address + ' host=' + oSsh.host + ' port=' + oSsh.port + ' sessionID=' + socket.request.sessionID + '/' + socket.id + ' allowreplay=' + oSsh.allowreplay + ' term=' + oSsh.term)
|
||||
if (err) {
|
||||
theError = (err) ? ': ' + err.message : ''
|
||||
theError = (err) ? ': ' + err.message : '';
|
||||
console.log('WebSSH2 error' + theError)
|
||||
}
|
||||
}
|
||||
socket.emit('ssherror', 'SSH ' + myFunc + theError)
|
||||
socket.request.session.destroy()
|
||||
socket.disconnect(true)
|
||||
socket.emit('ssherror', 'SSH ' + myFunc + theError);
|
||||
oSs.destroy();
|
||||
socket.disconnect(true);
|
||||
} else {
|
||||
theError = (err) ? ': ' + err.message : ''
|
||||
socket.disconnect(true)
|
||||
theError = (err) ? ': ' + err.message : '';
|
||||
socket.disconnect(true);
|
||||
}
|
||||
debugWebSSH2('SSHerror ' + myFunc + theError)
|
||||
debugWebSSH2('SSHerror ' + myFunc + theError);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue