* New user reserved names now direct to applicaiton process for SSH
This commit is contained in:
parent
93cff52c1f
commit
e9836e18db
|
@ -180,9 +180,6 @@ function startListening() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// servers require 'firstMenu'
|
|
||||||
assert(module.runtime.config.firstMenu, 'Server missing \'firstMenu\' member!');
|
|
||||||
|
|
||||||
var moduleInst = new module.getModule();
|
var moduleInst = new module.getModule();
|
||||||
var server = moduleInst.createServer();
|
var server = moduleInst.createServer();
|
||||||
|
|
||||||
|
@ -202,13 +199,13 @@ function startListening() {
|
||||||
|
|
||||||
clientConns.addNewClient(client, clientSock);
|
clientConns.addNewClient(client, clientSock);
|
||||||
|
|
||||||
client.on('ready', function onClientReady() {
|
client.on('ready', function clientReady(readyOptions) {
|
||||||
|
|
||||||
client.startIdleMonitor();
|
client.startIdleMonitor();
|
||||||
|
|
||||||
// Go to module -- use default error handler
|
// Go to module -- use default error handler
|
||||||
prepareClient(client, function onPrepared() {
|
prepareClient(client, function clientPrepared() {
|
||||||
require('./connect.js').connectEntry(client, module.runtime.config.firstMenu);
|
require('./connect.js').connectEntry(client, readyOptions.firstMenu);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,8 @@ function getDefaultConfig() {
|
||||||
general : {
|
general : {
|
||||||
boardName : 'Another Fine ENiGMA½ BBS',
|
boardName : 'Another Fine ENiGMA½ BBS',
|
||||||
|
|
||||||
|
closedSystem : false, // is the system closed to new users?
|
||||||
|
|
||||||
loginAttempts : 3,
|
loginAttempts : 3,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -127,11 +129,12 @@ function getDefaultConfig() {
|
||||||
firstMenu : 'telnetConnected',
|
firstMenu : 'telnetConnected',
|
||||||
},
|
},
|
||||||
ssh : {
|
ssh : {
|
||||||
port : 8889,
|
port : 8889,
|
||||||
enabled : true,
|
enabled : true,
|
||||||
rsaPrivateKey : paths.join(__dirname, './../misc/default_key.rsa'),
|
rsaPrivateKey : paths.join(__dirname, './../misc/default_key.rsa'),
|
||||||
dsaPrivateKey : paths.join(__dirname, './../misc/default_key.dsa'),
|
dsaPrivateKey : paths.join(__dirname, './../misc/default_key.dsa'),
|
||||||
firstMenu : 'sshConnected',
|
firstMenu : 'sshConnected',
|
||||||
|
firstMenuNewUser : 'sshConnectedNewUser',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// ENiGMA½
|
// ENiGMA½
|
||||||
var conf = require('../config.js');
|
var Config = require('../config.js').config;
|
||||||
var baseClient = require('../client.js');
|
var baseClient = require('../client.js');
|
||||||
var Log = require('../logger.js').log;
|
var Log = require('../logger.js').log;
|
||||||
var ServerModule = require('../server_module.js').ServerModule;
|
var ServerModule = require('../server_module.js').ServerModule;
|
||||||
|
@ -45,16 +45,25 @@ function SSHClient(clientConn) {
|
||||||
var loginAttempts = 0;
|
var loginAttempts = 0;
|
||||||
|
|
||||||
clientConn.on('authentication', function authAttempt(ctx) {
|
clientConn.on('authentication', function authAttempt(ctx) {
|
||||||
self.log.trace( { method : ctx.method, username : ctx.username }, 'SSH authentication attempt');
|
|
||||||
|
|
||||||
var username = ctx.username || '';
|
var username = ctx.username || '';
|
||||||
var password = ctx.password || '';
|
var password = ctx.password || '';
|
||||||
|
self.isNewUser = (Config.users.newUserNames || []).indexOf(username) > -1;
|
||||||
|
|
||||||
|
self.log.trace( { method : ctx.method, username : username, newUser : self.isNewUser }, 'SSH authentication attempt');
|
||||||
|
|
||||||
function termConnection() {
|
function termConnection() {
|
||||||
ctx.reject();
|
ctx.reject();
|
||||||
clientConn.end();
|
clientConn.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// If the system is open and |isNewUser| is true, the login
|
||||||
|
// sequence is hijacked in order to start the applicaiton process.
|
||||||
|
//
|
||||||
|
if(false === Config.general.closedSystem && self.isNewUser) {
|
||||||
|
return ctx.accept();
|
||||||
|
}
|
||||||
|
|
||||||
if(username.length > 0 && password.length > 0) {
|
if(username.length > 0 && password.length > 0) {
|
||||||
loginAttempts += 1;
|
loginAttempts += 1;
|
||||||
|
|
||||||
|
@ -76,8 +85,6 @@ function SSHClient(clientConn) {
|
||||||
return ctx.reject(SSHClient.ValidAuthMethods);
|
return ctx.reject(SSHClient.ValidAuthMethods);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(ctx.method)
|
|
||||||
|
|
||||||
if(0 === username.length) {
|
if(0 === username.length) {
|
||||||
// :TODO: can we display something here?
|
// :TODO: can we display something here?
|
||||||
return ctx.reject();
|
return ctx.reject();
|
||||||
|
@ -94,7 +101,7 @@ function SSHClient(clientConn) {
|
||||||
// :TODO: can we display something here?
|
// :TODO: can we display something here?
|
||||||
termConnection();
|
termConnection();
|
||||||
} else {
|
} else {
|
||||||
if(loginAttempts >= conf.config.general.loginAttempts) {
|
if(loginAttempts >= Config.general.loginAttempts) {
|
||||||
termConnection();
|
termConnection();
|
||||||
} else {
|
} else {
|
||||||
var artOpts = {
|
var artOpts = {
|
||||||
|
@ -106,7 +113,7 @@ function SSHClient(clientConn) {
|
||||||
if(err) {
|
if(err) {
|
||||||
interactivePrompt.prompt = 'Access denied\n' + ctx.username + '\'s password: ';
|
interactivePrompt.prompt = 'Access denied\n' + ctx.username + '\'s password: ';
|
||||||
} else {
|
} else {
|
||||||
var newUserNameList = '"' + (conf.config.users.newUserNames || []).join(', ') + '"';
|
var newUserNameList = '"' + (Config.users.newUserNames || []).join(', ') + '"';
|
||||||
interactivePrompt.prompt =
|
interactivePrompt.prompt =
|
||||||
'Access denied\n' +
|
'Access denied\n' +
|
||||||
artInfo.data.format( { newUserNames : newUserNameList } ) +
|
artInfo.data.format( { newUserNames : newUserNameList } ) +
|
||||||
|
@ -194,7 +201,8 @@ function SSHClient(clientConn) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// we're ready!
|
// we're ready!
|
||||||
self.emit('ready');
|
var firstMenu = self.isNewUser ? Config.servers.ssh.firstMenuNewUser : Config.servers.ssh.firstMenu;
|
||||||
|
self.emit('ready', { firstMenu : firstMenu } );
|
||||||
});
|
});
|
||||||
|
|
||||||
session.on('window-change', function windowChange(accept, reject, info) {
|
session.on('window-change', function windowChange(accept, reject, info) {
|
||||||
|
@ -231,11 +239,11 @@ SSHServerModule.prototype.createServer = function() {
|
||||||
SSHServerModule.super_.prototype.createServer.call(this);
|
SSHServerModule.super_.prototype.createServer.call(this);
|
||||||
|
|
||||||
var serverConf = {
|
var serverConf = {
|
||||||
privateKey : fs.readFileSync(conf.config.servers.ssh.rsaPrivateKey),
|
privateKey : fs.readFileSync(Config.servers.ssh.rsaPrivateKey),
|
||||||
ident : 'enigma-bbs-' + enigVersion + '-srv',
|
ident : 'enigma-bbs-' + enigVersion + '-srv',
|
||||||
// Note that sending 'banner' breaks at least EtherTerm!
|
// Note that sending 'banner' breaks at least EtherTerm!
|
||||||
debug : function debugSsh(dbgLine) {
|
debug : function debugSsh(dbgLine) {
|
||||||
if(true === conf.config.servers.ssh.debugConnections) {
|
if(true === Config.servers.ssh.debugConnections) {
|
||||||
Log.trace('SSH: ' + dbgLine);
|
Log.trace('SSH: ' + dbgLine);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
var baseClient = require('../client.js');
|
var baseClient = require('../client.js');
|
||||||
var Log = require('../logger.js').log;
|
var Log = require('../logger.js').log;
|
||||||
var ServerModule = require('../server_module.js').ServerModule;
|
var ServerModule = require('../server_module.js').ServerModule;
|
||||||
|
var Config = require('../config.js').config;
|
||||||
|
|
||||||
var net = require('net');
|
var net = require('net');
|
||||||
var buffers = require('buffers');
|
var buffers = require('buffers');
|
||||||
|
@ -583,7 +584,7 @@ TelnetClient.prototype.handleSbCommand = function(evt) {
|
||||||
|
|
||||||
if(!self.didReady) {
|
if(!self.didReady) {
|
||||||
self.didReady = true;
|
self.didReady = true;
|
||||||
self.emit('ready');
|
self.emit('ready', { firstMenu : Config.servers.telnet.firstMenu } );
|
||||||
}
|
}
|
||||||
} else if('new environment' === evt.option) {
|
} else if('new environment' === evt.option) {
|
||||||
//
|
//
|
||||||
|
|
101
mods/menu.hjson
101
mods/menu.hjson
|
@ -70,6 +70,17 @@
|
||||||
options: { nextTimeout: 1500 }
|
options: { nextTimeout: 1500 }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Another SSH specialization: If the user logs in with a new user
|
||||||
|
// name (e.g. "new", "apply", ...) they will be directed to the
|
||||||
|
// application process.
|
||||||
|
//
|
||||||
|
sshConnectedNewUser: {
|
||||||
|
art: CONNECT
|
||||||
|
next: newUserApplicationSsh
|
||||||
|
options: { nextTimeout: 1500 }
|
||||||
|
}
|
||||||
|
|
||||||
matrix: {
|
matrix: {
|
||||||
art: matrix
|
art: matrix
|
||||||
options: {
|
options: {
|
||||||
|
@ -248,7 +259,7 @@
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
value: { "submission" : 1 }
|
value: { "submission" : 1 }
|
||||||
action: @menu:matrix
|
action: @systemMethod:fallbackMenu
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -256,7 +267,93 @@
|
||||||
actionKeys: [
|
actionKeys: [
|
||||||
{
|
{
|
||||||
keys: [ "escape" ]
|
keys: [ "escape" ]
|
||||||
action: @menu:matrix
|
action: @systemMethod:fallbackMenu
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SSH specialization of NUA
|
||||||
|
newUserApplicationSsh: {
|
||||||
|
art: NUA
|
||||||
|
fallback: logoff
|
||||||
|
next: newUserFeedbackToSysOpPreamble
|
||||||
|
form: {
|
||||||
|
0: {
|
||||||
|
mci: {
|
||||||
|
ET1: {
|
||||||
|
focus: true
|
||||||
|
argName: username
|
||||||
|
maxLength: @config:users.usernameMax
|
||||||
|
}
|
||||||
|
ET2: {
|
||||||
|
argName: realName
|
||||||
|
maxLength: 32
|
||||||
|
}
|
||||||
|
MET3: {
|
||||||
|
argName: birthdate
|
||||||
|
maskPattern: "####/##/##"
|
||||||
|
}
|
||||||
|
ME4: {
|
||||||
|
argName: sex
|
||||||
|
maskPattern: A
|
||||||
|
textStyle: upper
|
||||||
|
}
|
||||||
|
ET5: {
|
||||||
|
argName: location
|
||||||
|
maxLength: 32
|
||||||
|
}
|
||||||
|
ET6: {
|
||||||
|
argName: affils
|
||||||
|
maxLength: 32
|
||||||
|
}
|
||||||
|
ET7: {
|
||||||
|
argName: email
|
||||||
|
maxLength: 255
|
||||||
|
}
|
||||||
|
ET8: {
|
||||||
|
argName: web
|
||||||
|
maxLength: 255
|
||||||
|
}
|
||||||
|
ET9: {
|
||||||
|
argName: password
|
||||||
|
password: true
|
||||||
|
maxLength: @config:users.passwordMax
|
||||||
|
}
|
||||||
|
ET10: {
|
||||||
|
argName: passwordConfirm
|
||||||
|
password: true
|
||||||
|
maxLength: @config:users.passwordMax
|
||||||
|
}
|
||||||
|
TM12: {
|
||||||
|
argName: submission
|
||||||
|
items: [ "apply", "cancel" ]
|
||||||
|
submit: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
submit: {
|
||||||
|
*: [
|
||||||
|
{
|
||||||
|
value: { "submission" : 0 }
|
||||||
|
action: @method:apply/submitApplication
|
||||||
|
extraArgs: {
|
||||||
|
inactive: userNeedsActivated
|
||||||
|
error: newUserCreateError
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
value: { "submission" : 1 }
|
||||||
|
action: @systemMethod:fallbackMenu
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
actionKeys: [
|
||||||
|
{
|
||||||
|
keys: [ "escape" ]
|
||||||
|
action: @systemMethod:fallbackMenu
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue