8 changed files with 187 additions and 134 deletions
@ -1,134 +1,2 @@ |
|||
var express = require('express'); |
|||
var http = require('http'); |
|||
var https = require('https'); |
|||
var path = require('path'); |
|||
var server = require('socket.io'); |
|||
var pty = require('pty.js'); |
|||
var fs = require('fs'); |
|||
|
|||
var opts = require('optimist') |
|||
.options({ |
|||
sslkey: { |
|||
demand: false, |
|||
description: 'path to SSL key' |
|||
}, |
|||
sslcert: { |
|||
demand: false, |
|||
description: 'path to SSL certificate' |
|||
}, |
|||
sshhost: { |
|||
demand: false, |
|||
description: 'ssh server host' |
|||
}, |
|||
sshport: { |
|||
demand: false, |
|||
description: 'ssh server port' |
|||
}, |
|||
sshuser: { |
|||
demand: false, |
|||
description: 'ssh user' |
|||
}, |
|||
sshauth: { |
|||
demand: false, |
|||
description: 'defaults to "password", you can use "publickey,password" instead' |
|||
}, |
|||
port: { |
|||
demand: true, |
|||
alias: 'p', |
|||
description: 'wetty listen port' |
|||
}, |
|||
}).boolean('allow_discovery').argv; |
|||
|
|||
var runhttps = false; |
|||
var sshport = 22; |
|||
var sshhost = 'localhost'; |
|||
var sshauth = 'password'; |
|||
var globalsshuser = ''; |
|||
|
|||
if (opts.sshport) { |
|||
sshport = opts.sshport; |
|||
} |
|||
|
|||
if (opts.sshhost) { |
|||
sshhost = opts.sshhost; |
|||
} |
|||
|
|||
if (opts.sshauth) { |
|||
sshauth = opts.sshauth |
|||
} |
|||
|
|||
if (opts.sshuser) { |
|||
globalsshuser = opts.sshuser; |
|||
} |
|||
|
|||
if (opts.sslkey && opts.sslcert) { |
|||
runhttps = true; |
|||
opts['ssl'] = {}; |
|||
opts.ssl['key'] = fs.readFileSync(path.resolve(opts.sslkey)); |
|||
opts.ssl['cert'] = fs.readFileSync(path.resolve(opts.sslcert)); |
|||
} |
|||
|
|||
process.on('uncaughtException', function(e) { |
|||
console.error('Error: ' + e); |
|||
}); |
|||
|
|||
var httpserv; |
|||
|
|||
var app = express(); |
|||
app.get('/wetty/ssh/:user', function(req, res) { |
|||
res.sendfile(__dirname + '/public/wetty/index.html'); |
|||
}); |
|||
app.use('/', express.static(path.join(__dirname, 'public'))); |
|||
|
|||
if (runhttps) { |
|||
httpserv = https.createServer(opts.ssl, app).listen(opts.port, function() { |
|||
console.log('https on port ' + opts.port); |
|||
}); |
|||
} else { |
|||
httpserv = http.createServer(app).listen(opts.port, function() { |
|||
console.log('http on port ' + opts.port); |
|||
}); |
|||
} |
|||
|
|||
var io = server(httpserv,{path: '/wetty/socket.io'}); |
|||
io.on('connection', function(socket){ |
|||
var sshuser = ''; |
|||
var request = socket.request; |
|||
console.log((new Date()) + ' Connection accepted.'); |
|||
if (match = request.headers.referer.match('/wetty/ssh/.+$')) { |
|||
sshuser = match[0].replace('/wetty/ssh/', '') + '@'; |
|||
} else if (globalsshuser) { |
|||
sshuser = globalsshuser + '@'; |
|||
} |
|||
|
|||
var term; |
|||
if (process.getuid() == 0) { |
|||
term = pty.spawn('/bin/login', [], { |
|||
name: 'xterm-256color', |
|||
cols: 80, |
|||
rows: 30 |
|||
}); |
|||
} else { |
|||
term = pty.spawn('ssh', [sshuser + sshhost, '-p', sshport, '-o', 'PreferredAuthentications=' + sshauth], { |
|||
name: 'xterm-256color', |
|||
cols: 80, |
|||
rows: 30 |
|||
}); |
|||
} |
|||
console.log((new Date()) + " PID=" + term.pid + " STARTED on behalf of user=" + sshuser) |
|||
term.on('data', function(data) { |
|||
socket.emit('output', data); |
|||
}); |
|||
term.on('exit', function(code) { |
|||
console.log((new Date()) + " PID=" + term.pid + " ENDED") |
|||
}); |
|||
socket.on('resize', function(data) { |
|||
term.resize(data.col, data.row); |
|||
}); |
|||
socket.on('input', function(data) { |
|||
term.write(data); |
|||
}); |
|||
socket.on('disconnect', function() { |
|||
term.end(); |
|||
}); |
|||
}) |
|||
const runWettyCommandLine = require('./src/index').runApp; |
|||
runWettyCommandLine(); |
@ -0,0 +1,65 @@ |
|||
const optimist = require('optimist'); |
|||
const path = require('path'); |
|||
|
|||
const getOptions = () => { |
|||
return ( |
|||
optimist |
|||
.options({ |
|||
sslkey: { |
|||
demand: false, |
|||
description: 'path to SSL key' |
|||
}, |
|||
sslcert: { |
|||
demand: false, |
|||
description: 'path to SSL certificate' |
|||
}, |
|||
sshhost: { |
|||
demand: false, |
|||
description: 'ssh server host' |
|||
}, |
|||
sshport: { |
|||
demand: false, |
|||
description: 'ssh server port' |
|||
}, |
|||
sshuser: { |
|||
demand: false, |
|||
description: 'ssh user' |
|||
}, |
|||
sshauth: { |
|||
demand: false, |
|||
description: 'defaults to "password", you can use "publickey,password" instead' |
|||
}, |
|||
port: { |
|||
demand: true, |
|||
alias: 'p', |
|||
description: 'wetty listen port' |
|||
}, |
|||
}).boolean('allow_discovery').argv |
|||
); |
|||
}; |
|||
|
|||
const getSSLObject = opts => { |
|||
if (opts.sslkey && opts.sslcert){ |
|||
return ({ |
|||
key: fs.readFileSync(path.resolve(opts.sslkey)), |
|||
cert: fs.readFileSync(path.resolve(opts.sslcert)), |
|||
}); |
|||
} |
|||
return undefined; |
|||
}; |
|||
|
|||
const getArgs = opts => { |
|||
const args = { |
|||
runhttps: (opts.sslkey && opts.sslcert) ? true: false, |
|||
sshport: opts.sshport ? opts.sshport: 22, |
|||
sshhost: opts.sshhost ? opts.sshhost: 'localhost', |
|||
sshauth: opts.sshauth ? opts.sshauth : 'password', |
|||
globalsshuser: opts.sshuser? opts.sshuser: '', |
|||
ssl: getSSLObject(opts), |
|||
port: opts.port, |
|||
}; |
|||
return args; |
|||
}; |
|||
|
|||
module.exports = () => getArgs(getOptions()); |
|||
|
@ -0,0 +1,35 @@ |
|||
var getSSLSettings = require('./getSSLSettings.js'); |
|||
var startServer = require('./startServer'); |
|||
|
|||
process.on('uncaughtException', function(e) { |
|||
console.error('Error: ' + e); |
|||
}); |
|||
|
|||
|
|||
const runApp = () => { |
|||
const SSLSettings = getSSLSettings(); |
|||
startServer(SSLSettings, { |
|||
onConnectionAccepted: () => { |
|||
console.log((new Date()) + ' Connection accepted.'); |
|||
}, |
|||
onServerListen: isHttp => { |
|||
console.log('https on port ' + SSLSettings.port); |
|||
}, |
|||
onTerminalExit: () => { |
|||
console.log((new Date()) + " PID=" + term.pid + " ENDED"); |
|||
}, |
|||
onTerminalStart: () => { |
|||
console.log((new Date()) + " PID=" + term.pid + " STARTED on behalf of user=" + sshuser) |
|||
}, |
|||
}); |
|||
}; |
|||
|
|||
|
|||
module.exports = { |
|||
runApp, |
|||
startServer, |
|||
}; |
|||
|
|||
|
|||
|
|||
//wetty.startSSLServer({ port: 3000 })
|
@ -0,0 +1,85 @@ |
|||
var express = require('express'); |
|||
var http = require('http'); |
|||
var https = require('https'); |
|||
var path = require('path'); |
|||
var server = require('socket.io'); |
|||
var pty = require('pty.js'); |
|||
|
|||
const createRoutes = () => { |
|||
var app = express(); |
|||
app.get('/wetty/ssh/:user', function(req, res) { |
|||
res.sendfile(__dirname + '/public/wetty/index.html'); |
|||
}); |
|||
app.use('/', express.static(path.join(__dirname, 'public'))); |
|||
return app; |
|||
}; |
|||
|
|||
const getUsername = (theArgs, request) => { |
|||
var sshuser = ''; |
|||
const match = request.headers.referer.match('/wetty/ssh/.+$'); |
|||
if (match) { |
|||
sshuser = match[0].replace('/wetty/ssh/', '') + '@'; |
|||
} else if (theArgs.globalsshuser) { |
|||
sshuser = theArgs.globalsshuser + '@'; |
|||
} |
|||
return sshuser; |
|||
|
|||
}; |
|||
|
|||
const startTerminal = (theArgs, sshuser, onTerminalStart) => { |
|||
var term; |
|||
if (process.getuid() == 0) { |
|||
term = pty.spawn('/bin/login', [], { |
|||
name: 'xterm-256color', |
|||
cols: 80, |
|||
rows: 30 |
|||
}); |
|||
} else { |
|||
term = pty.spawn('ssh', [sshuser + theArgs.sshhost, '-p', theArgs.sshport, '-o', 'PreferredAuthentications=' + theArgs.sshauth], { |
|||
name: 'xterm-256color', |
|||
cols: 80, |
|||
rows: 30 |
|||
}); |
|||
} |
|||
return term; |
|||
}; |
|||
|
|||
const startServer = (theArgs, { onConnectionAccepted, onServerListen, onTerminalStart, onTerminalExit }) => { |
|||
|
|||
const app = createRoutes(); |
|||
|
|||
var httpserv; |
|||
if (theArgs.runhttps) { |
|||
httpserv = https.createServer(theArgs.ssl, app).listen(theArgs.port, () => { onServerListen(true); }); |
|||
} else { |
|||
httpserv = http.createServer(app).listen(theArgs.port, () => { onServerListen(false); }); |
|||
} |
|||
|
|||
var io = server(httpserv,{path: '/wetty/socket.io'}); |
|||
io.on('connection', function(socket){ |
|||
onConnectionAccepted(); |
|||
|
|||
const sshuser = getUsername(theArgs, socket.request); |
|||
|
|||
const term = startTerminal(theArgs, sshuser, onTerminalStart ); |
|||
onTerminalStart(); |
|||
term.on('data', function(data) { |
|||
socket.emit('output', data); |
|||
}); |
|||
term.on('exit', function(code) { |
|||
onTerminalExit(); |
|||
}); |
|||
socket.on('resize', function(data) { |
|||
term.resize(data.col, data.row); |
|||
}); |
|||
socket.on('input', function(data) { |
|||
term.write(data); |
|||
}); |
|||
socket.on('disconnect', function() { |
|||
term.end(); |
|||
}); |
|||
}) |
|||
|
|||
}; |
|||
|
|||
module.exports = startServer; |
Loading…
Reference in new issue