diff --git a/app.js b/app.js index d00e6a4..c8109ae 100644 --- a/app.js +++ b/app.js @@ -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(); \ No newline at end of file diff --git a/src/getSSLSettings.js b/src/getSSLSettings.js new file mode 100644 index 0000000..55199a3 --- /dev/null +++ b/src/getSSLSettings.js @@ -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()); + diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..c958cdf --- /dev/null +++ b/src/index.js @@ -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 }) \ No newline at end of file diff --git a/public/index.html b/src/public/index.html similarity index 100% rename from public/index.html rename to src/public/index.html diff --git a/public/wetty/hterm_all.js b/src/public/wetty/hterm_all.js similarity index 100% rename from public/wetty/hterm_all.js rename to src/public/wetty/hterm_all.js diff --git a/public/wetty/index.html b/src/public/wetty/index.html similarity index 100% rename from public/wetty/index.html rename to src/public/wetty/index.html diff --git a/public/wetty/wetty.js b/src/public/wetty/wetty.js similarity index 100% rename from public/wetty/wetty.js rename to src/public/wetty/wetty.js diff --git a/src/startServer.js b/src/startServer.js new file mode 100644 index 0000000..c75445e --- /dev/null +++ b/src/startServer.js @@ -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;