77 lines
2.4 KiB
JavaScript
77 lines
2.4 KiB
JavaScript
'use strict';
|
|
|
|
/*global Promise*/
|
|
var PromiseA = Promise;
|
|
var crypto = require('crypto');
|
|
var util = require('util');
|
|
var readFile = util.promisify(require('fs').readFile);
|
|
var exec = require('child_process').exec;
|
|
|
|
function sshAllowsPassword(user) {
|
|
// SSH on Windows is a thing now (beta 2015, standard 2018)
|
|
// https://stackoverflow.com/questions/313111/is-there-a-dev-null-on-windows
|
|
var nullfile = '/dev/null';
|
|
if (/^win/i.test(process.platform)) {
|
|
nullfile = 'NUL';
|
|
}
|
|
var args = [
|
|
'ssh', '-v', '-n'
|
|
, '-o', 'Batchmode=yes'
|
|
, '-o', 'StrictHostKeyChecking=no'
|
|
, '-o', 'UserKnownHostsFile=' + nullfile
|
|
, user + '@localhost'
|
|
, '| true'
|
|
];
|
|
return new PromiseA(function (resolve) {
|
|
// not using promisify because all 3 arguments convey information
|
|
exec(args.join(' '), function (err, stdout, stderr) {
|
|
stdout = (stdout||'').toString('utf8');
|
|
stderr = (stderr||'').toString('utf8');
|
|
if (/\bpassword\b/.test(stdout) || /\bpassword\b/.test(stderr)) {
|
|
resolve('yes');
|
|
return;
|
|
}
|
|
if (/\bAuthentications\b/.test(stdout) || /\bAuthentications\b/.test(stderr)) {
|
|
resolve('no');
|
|
return;
|
|
}
|
|
resolve('maybe');
|
|
});
|
|
});
|
|
}
|
|
|
|
module.exports.checkSecurity = function () {
|
|
var conf = {};
|
|
var noRootPasswordRe = /(?:^|[\r\n]+)\s*PermitRootLogin\s+(prohibit-password|without-password|no)\s*/i;
|
|
var noPasswordRe = /(?:^|[\r\n]+)\s*PasswordAuthentication\s+(no)\s*/i;
|
|
var sshdConf = '/etc/ssh/sshd_config';
|
|
if (/^win/i.test(process.platform)) {
|
|
// TODO use %PROGRAMDATA%\ssh\sshd_config
|
|
sshdConf = 'C:\\ProgramData\\ssh\\sshd_config';
|
|
}
|
|
return readFile(sshdConf, null).then(function (sshd) {
|
|
sshd = sshd.toString('utf8');
|
|
var match;
|
|
match = sshd.match(noRootPasswordRe);
|
|
conf.permit_root_login = match ? match[1] : 'yes';
|
|
match = sshd.match(noPasswordRe);
|
|
conf.password_authentication = match ? match[1] : 'yes';
|
|
}).catch(function () {
|
|
// ignore error as that might not be the correct sshd_config location
|
|
}).then(function () {
|
|
var doesntExist = crypto.randomBytes(16).toString('hex');
|
|
return sshAllowsPassword(doesntExist).then(function (maybe) {
|
|
conf.requests_password = maybe;
|
|
});
|
|
}).then(function () {
|
|
return conf;
|
|
});
|
|
};
|
|
|
|
if (require.main === module) {
|
|
module.exports.checkSecurity().then(function (conf) {
|
|
console.log(conf);
|
|
return conf;
|
|
});
|
|
}
|