MAJOR: Updates for Authenticated Web UI and CLI #30
							
								
								
									
										72
									
								
								lib/ssh.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								lib/ssh.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,72 @@ | |||||||
|  | '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(true); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |       if (/\bAuthentications\b/.test(stdout) || /\bAuthentications\b/.test(stderr)) { | ||||||
|  |         resolve(false); | ||||||
|  |         return; | ||||||
|  |       } | ||||||
|  |       resolve(); | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | module.exports.checkSecurity = function () { | ||||||
|  |   var conf = {}; | ||||||
|  |   var sshdConf = '/etc/ssh/sshd_config'; | ||||||
|  |   var noRootPasswordRe = /(^|[\r\n]+)\s*PermitRootLogin\s+(prohibit-password|without-password|no)\s*/i; | ||||||
|  |   var noPasswordRe = /(^|[\r\n]+)\s*PasswordAuthentication\s+no\s*/i; | ||||||
|  |   return readFile(sshdConf, null).then(function (sshd) { | ||||||
|  |     sshd = sshd.toString('utf8'); | ||||||
|  |     conf.disallowPasswordRoot = noRootPasswordRe.test(sshd); | ||||||
|  |     conf.disallowPassword = noPasswordRe.test(sshd); | ||||||
|  |   }).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.allowsPassword = maybe; | ||||||
|  |       return sshAllowsPassword('root').then(function (maybe) { | ||||||
|  |         conf.allowsRootPassword = maybe; | ||||||
|  |       }); | ||||||
|  |     }); | ||||||
|  |   }).then(function () { | ||||||
|  |     return conf; | ||||||
|  |   }); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | if (require.main === module) { | ||||||
|  |   module.exports.checkSecurity().then(function (conf) { | ||||||
|  |     console.log(conf); | ||||||
|  |     return conf; | ||||||
|  |   }); | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user