Use authInfo obj vs weird params. auth factor 1: factor 2 for 2FA, etc.
This commit is contained in:
parent
57938e761e
commit
23779c3abe
|
@ -141,7 +141,7 @@ class NNTPServer extends NNTPServerBase {
|
||||||
|
|
||||||
return new Promise( resolve => {
|
return new Promise( resolve => {
|
||||||
const user = new User();
|
const user = new User();
|
||||||
user.authenticate(username, password, err => {
|
user.authenticateFactor1({ type : User.AuthFactor1Types.Password, username, password }, err => {
|
||||||
if(err) {
|
if(err) {
|
||||||
// :TODO: Log IP address
|
// :TODO: Log IP address
|
||||||
this.log.debug( { username, reason : err.message }, 'Authentication failure');
|
this.log.debug( { username, reason : err.message }, 'Authentication failure');
|
||||||
|
|
|
@ -23,7 +23,6 @@ const fs = require('graceful-fs');
|
||||||
const util = require('util');
|
const util = require('util');
|
||||||
const _ = require('lodash');
|
const _ = require('lodash');
|
||||||
const assert = require('assert');
|
const assert = require('assert');
|
||||||
const crypto = require('crypto');
|
|
||||||
|
|
||||||
const ModuleInfo = exports.moduleInfo = {
|
const ModuleInfo = exports.moduleInfo = {
|
||||||
name : 'SSH',
|
name : 'SSH',
|
||||||
|
@ -108,7 +107,7 @@ function SSHClient(clientConn) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const authWithPasswordOrPubKey = (authType) => {
|
const authWithPasswordOrPubKey = (authType) => {
|
||||||
if('pubKey' !== authType || !self.user.isAuthenticated() || !ctx.signature) {
|
if(User.AuthFactor1Types.PubKey !== authType || !self.user.isAuthenticated() || !ctx.signature) {
|
||||||
// step 1: login/auth using PubKey
|
// step 1: login/auth using PubKey
|
||||||
userLogin(self, ctx.username, ctx.password, { authType, ctx }, (err) => {
|
userLogin(self, ctx.username, ctx.password, { authType, ctx }, (err) => {
|
||||||
if(err) {
|
if(err) {
|
||||||
|
@ -188,11 +187,11 @@ function SSHClient(clientConn) {
|
||||||
|
|
||||||
switch(ctx.method) {
|
switch(ctx.method) {
|
||||||
case 'password' :
|
case 'password' :
|
||||||
return authWithPasswordOrPubKey('password');
|
return authWithPasswordOrPubKey(User.AuthFactor1Types.Password);
|
||||||
//return authWithPassword();
|
//return authWithPassword();
|
||||||
|
|
||||||
case 'publickey' :
|
case 'publickey' :
|
||||||
return authWithPasswordOrPubKey('pubKey');
|
return authWithPasswordOrPubKey(User.AuthFactor1Types.PubKey);
|
||||||
//return authWithPubKey();
|
//return authWithPubKey();
|
||||||
|
|
||||||
case 'keyboard-interactive' :
|
case 'keyboard-interactive' :
|
||||||
|
|
23
core/user.js
23
core/user.js
|
@ -178,17 +178,20 @@ module.exports = class User {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
authenticate(username, password, options, cb) {
|
static get AuthFactor1Types() {
|
||||||
if(!cb && _.isFunction(options)) {
|
return {
|
||||||
cb = options;
|
PubKey : 'pubKey',
|
||||||
options = {};
|
Password : 'password',
|
||||||
}
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
authenticateFactor1(authInfo, cb) {
|
||||||
|
const username = authInfo.username;
|
||||||
const self = this;
|
const self = this;
|
||||||
const tempAuthInfo = {};
|
const tempAuthInfo = {};
|
||||||
|
|
||||||
const validatePassword = (props, callback) => {
|
const validatePassword = (props, callback) => {
|
||||||
User.generatePasswordDerivedKey(password, props[UserProps.PassPbkdf2Salt], (err, dk) => {
|
User.generatePasswordDerivedKey(authInfo.password, props[UserProps.PassPbkdf2Salt], (err, dk) => {
|
||||||
if(err) {
|
if(err) {
|
||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
@ -212,8 +215,8 @@ module.exports = class User {
|
||||||
return callback(Errors.AccessDenied('Invalid public key'));
|
return callback(Errors.AccessDenied('Invalid public key'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(options.ctx.key.algo != pubKeyActual.type ||
|
if(authInfo.pubKey.key.algo != pubKeyActual.type ||
|
||||||
!crypto.timingSafeEqual(options.ctx.key.data, pubKeyActual.getPublicSSH()))
|
!crypto.timingSafeEqual(authInfo.pubKey.key.data, pubKeyActual.getPublicSSH()))
|
||||||
{
|
{
|
||||||
return callback(Errors.AccessDenied('Invalid public key'));
|
return callback(Errors.AccessDenied('Invalid public key'));
|
||||||
}
|
}
|
||||||
|
@ -234,12 +237,12 @@ module.exports = class User {
|
||||||
},
|
},
|
||||||
function getRequiredAuthProperties(callback) {
|
function getRequiredAuthProperties(callback) {
|
||||||
// fetch properties required for authentication
|
// fetch properties required for authentication
|
||||||
User.loadProperties( tempAuthInfo.userId, { names : User.StandardPropertyGroups.auth }, (err, props) => {
|
User.loadProperties(tempAuthInfo.userId, { names : User.StandardPropertyGroups.auth }, (err, props) => {
|
||||||
return callback(err, props);
|
return callback(err, props);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
function validatePassOrPubKey(props, callback) {
|
function validatePassOrPubKey(props, callback) {
|
||||||
if('pubKey' === options.authType) {
|
if(User.AuthFactor1Types.PubKey === authInfo.type) {
|
||||||
return validatePubKey(props, callback);
|
return validatePubKey(props, callback);
|
||||||
}
|
}
|
||||||
return validatePassword(props, callback);
|
return validatePassword(props, callback);
|
||||||
|
|
|
@ -15,6 +15,7 @@ const {
|
||||||
const UserProps = require('./user_property.js');
|
const UserProps = require('./user_property.js');
|
||||||
const SysProps = require('./system_property.js');
|
const SysProps = require('./system_property.js');
|
||||||
const SystemLogKeys = require('./system_log.js');
|
const SystemLogKeys = require('./system_log.js');
|
||||||
|
const User = require('./user.js');
|
||||||
|
|
||||||
// deps
|
// deps
|
||||||
const async = require('async');
|
const async = require('async');
|
||||||
|
@ -39,7 +40,15 @@ function userLogin(client, username, password, options, cb) {
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
client.user.authenticate(username, password, options, err => {
|
const authInfo = {
|
||||||
|
username,
|
||||||
|
password,
|
||||||
|
};
|
||||||
|
|
||||||
|
authInfo.type = options.authType || User.AuthFactor1Types.Password;
|
||||||
|
authInfo.pubKey = options.ctx;
|
||||||
|
|
||||||
|
client.user.authenticateFactor1(authInfo, err => {
|
||||||
if(err) {
|
if(err) {
|
||||||
client.user.sessionFailedLoginAttempts = _.get(client.user, 'sessionFailedLoginAttempts', 0) + 1;
|
client.user.sessionFailedLoginAttempts = _.get(client.user, 'sessionFailedLoginAttempts', 0) + 1;
|
||||||
const disconnect = config.users.failedLogin.disconnect;
|
const disconnect = config.users.failedLogin.disconnect;
|
||||||
|
|
Loading…
Reference in New Issue