123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268 |
- #!/usr/bin/env node
- var net = require('net'),
- fs = require('fs'),
- http = require('http'),
- websocket = require('websocket'),
- ssh2 = require('ssh2'),
- crypto = require('crypto');
- config = require('../config');
- libs = require('./libs');
- world = require('./world');
- try {
- var banner = fs.readFileSync(__dirname + "/../banner.txt", "utf-8");
- config.welcomeBanner = banner;
- world.mud_load();
- } catch (error) {
- libs.Output.toServerError("MUD cannot be loaded.", error);
- process.exit(1);
- }
- var telnetserver = net.createServer(function(socket) {
- var login = new libs.TelnetLogin(socket);
- login.attach();
- socket.on('data', function(data) {
- try {
- login.receive(data);
- } catch (error) {
- libs.Output.toServerError("Error in telnet socket when receiving data", error);
- libs.Output.worldToMobiles("You sense a {error}tear{/error} in the fabric of reality.");
- }
- });
- socket.on('end', function() {
- login.disconnect();
- });
- socket.on('error', function(error) {
- if(error.code == "EPIPE") {
- libs.Output.toServerError("Telnet socket "+socket.nickname+" was written to after being closed.", error);
- } else if (error.code == "ECONNRESET") {
- libs.Output.toServerError("Telnet socket connection reset.", error);
- } else {
- libs.Output.toServerError("Unknown telnet socket error", error);
- }
- });
- socket.setTimeout(config.telnettimeout);
- socket.on('timeout', function() {
- socket.write('\nConnection timed out.\n');
- socket.end();
- });
- });
- telnetserver.on('error', function(error) {
- if(error.code == "EADDRINUSE") {
- libs.Output.toServerError("There is already a server running!", error);
- process.exit(1);
- } else {
- libs.Output.toServerError("Unknown telnet server error", error);
- }
- });
- var webserver = http.createServer(function(request, response) {
- if(!config.enableWebserver) {
- return;
- }
- var configData = fs.readFileSync(__dirname + "/../config.json", "utf-8");
- var webconfig = JSON.parse(configData);
- var controller = new libs.WebserverController();
- controller.handleRequest(webconfig, request, response);
- });
- webserver.on('error', function(error) {
- libs.Output.toServerError("Unknown webserver error", error);
- });
- // create the server
- var websocketserver = new websocket.server({
- httpServer: webserver
- });
- // WebSocket server
- websocketserver.on('request', function(request) {
- var connection = request.accept(null, request.origin);
- var login = new libs.WebsocketLogin(connection);
- login.attach();
- connection.on('message', function(message) {
- if (message.type === 'utf8') {
- try {
- login.receive(message.utf8Data);
- } catch (error) {
- libs.Output.toServerError("Error in websocket socket when receiving data", error);
- libs.Output.worldToMobiles("You sense a {error}tear{/error} in the fabric of reality.");
- }
- } else {
- libs.Output.toServer(message);
- }
- });
- connection.on('close', function(connection) {
- login.disconnect();
- });
- });
- var buffersEqual = function(buffer1, buffer2) {
- return 0 == Buffer.compare(buffer1, buffer2);
- }
- var sshserver = new ssh2.Server({
- hostKeys: [fs.readFileSync(config.sshKeyPath)]
- }, function(client) {
- var userData = null;
- var login = new libs.SSHLogin();
- client.on('authentication', function(ctx) {
- switch(ctx.method) {
- case "password":
- userData = world.mud_getUserData(ctx.username);
- if(userData == null) {
- ctx.reject(["password"]);
- return;
- }
- if(world.mud_isValidLogin(userData, ctx.password)) {
- ctx.accept();
- } else {
- ctx.reject();
- return;
- }
- break;
- case "publickey":
- var pubKeys = [];
- var validCheck = false;
- userData = world.mud_getUserData(ctx.username);
- if(userData == null) {
- ctx.reject(["publickey", "password"]);
- return;
- }
- for(var index in userData.pubKeys) {
- var pubKey = ssh2.utils.parseKey(userData.pubKeys[index]);
- if(ctx.key.algo === pubKey.type && buffersEqual(ctx.key.data, pubKey.getPublicSSH())) {
- if(ctx.signature) {
- if(pubKey.verify(ctx.blob, ctx.signature)) {
- ctx.accept()
- validCheck = true
- }
- } else {
- ctx.accept();
- validCheck = true;
- }
- }
- }
- if(!validCheck) {
- ctx.reject(["password"]);
- }
- break;
- case "none":
- ctx.reject(["publickey","password"]);
- break;
- default:
- ctx.reject();
- break;
- }
- });
- client.on('ready', function() {
- client.on('session', function(accept, reject) {
- var session = accept();
- session.on("pty", function(accept, reject, info) {
- //todo: some kinda screen resolution config
- console.log(info);
- });
- session.on("shell", function(accept, reject) {
- var channel = accept();
- login.attachChannel(channel);
- try {
- login.attach(userData);
- } catch (error) {
- libs.Output.toServerError("Error when attaching user in SSH", error);
- libs.Output.worldToMobiles("You sense a {error}ripple{/error} in the fabric of reality.");
- }
- channel.on("data", function(data){
- try {
- login.receive(data);
- } catch (error) {
- libs.Output.toServerError("Error in ssh socket when receiving data", error);
- libs.Output.worldToMobiles("You sense a {error}tear{/error} in the fabric of reality.");
- }
- });
- channel.on("close", function(data){
- console.log("closing channel");
- try {
- session.close();
- } catch (error) {
- console.log("error closing session");
- }
- });
- });
- session.on("close", function() {
- console.log("closing session");
- try {
- client.end();
- } catch (error) {
- console.log("error ending client");
- }
- });
- });
- });
- client.on('end', function() {
- console.log("client ending");
- login.disconnect();
- });
- });
- telnetserver.listen(config.telnetport, config.telnetlisten, function() {
- libs.Output.toServer("Telnet server listening on " + config.telnetlisten + ":" + config.telnetport);
- });
- webserver.listen(config.websocketport, config.websocketlisten, function() {
- libs.Output.toServer("Websocket server listening on " + config.websocketlisten + ":" + config.websocketport);
- });
- sshserver.listen(config.sshport, config.sshlisten, function() {
- libs.Output.toServer("SSH server listening on " + config.sshlisten + ":" + config.sshport);
- });
- process.stdin.resume();
- process.stdin.setEncoding('utf8');
- process.stdin.on('data', function (data) {
- var input = data.trim().split(" ");
- switch(input.shift()) {
- case "say":
- libs.Output.worldToMobiles(input.join(" "));
- break;
- case "exit":
- case "quit":
- case "stop":
- libs.Output.worldToMobiles("The server is shutting down!");
- for(var playerIndex in session.players) {
- var player = session.players[playerIndex];
- player.quit();
- }
- process.exit(0);
- break;
- case "restart":
- for(var playerIndex in session.players) {
- var player = session.players[playerIndex];
- player.quit();
- }
- world.mud_load();
- break;
- }
-
- });
|