| 
									
										
										
										
											2018-10-31 23:16:55 -06:00
										 |  |  | '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)) { | 
					
						
							| 
									
										
										
										
											2018-10-31 23:47:13 -06:00
										 |  |  |         resolve('yes'); | 
					
						
							| 
									
										
										
										
											2018-10-31 23:16:55 -06:00
										 |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |       if (/\bAuthentications\b/.test(stdout) || /\bAuthentications\b/.test(stderr)) { | 
					
						
							| 
									
										
										
										
											2018-10-31 23:47:13 -06:00
										 |  |  |         resolve('no'); | 
					
						
							| 
									
										
										
										
											2018-10-31 23:16:55 -06:00
										 |  |  |         return; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2018-10-31 23:47:13 -06:00
										 |  |  |       resolve('maybe'); | 
					
						
							| 
									
										
										
										
											2018-10-31 23:16:55 -06:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports.checkSecurity = function () { | 
					
						
							|  |  |  |   var conf = {}; | 
					
						
							| 
									
										
										
										
											2018-10-31 23:47:13 -06:00
										 |  |  |   var noRootPasswordRe = /(?:^|[\r\n]+)\s*PermitRootLogin\s+(prohibit-password|without-password|no)\s*/i; | 
					
						
							|  |  |  |   var noPasswordRe = /(?:^|[\r\n]+)\s*PasswordAuthentication\s+(no)\s*/i; | 
					
						
							| 
									
										
										
										
											2018-11-01 00:56:39 -06:00
										 |  |  |   var sshdConf = '/etc/ssh/sshd_config'; | 
					
						
							|  |  |  |   if (/^win/i.test(process.platform)) { | 
					
						
							|  |  |  |     // TODO use %PROGRAMDATA%\ssh\sshd_config
 | 
					
						
							|  |  |  |     sshdConf = 'C:\\ProgramData\\ssh\\sshd_config'; | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-10-31 23:16:55 -06:00
										 |  |  |   return readFile(sshdConf, null).then(function (sshd) { | 
					
						
							|  |  |  |     sshd = sshd.toString('utf8'); | 
					
						
							| 
									
										
										
										
											2018-10-31 23:47:13 -06:00
										 |  |  |     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'; | 
					
						
							| 
									
										
										
										
											2018-10-31 23:16:55 -06:00
										 |  |  |   }).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) { | 
					
						
							| 
									
										
										
										
											2018-10-31 23:47:13 -06:00
										 |  |  |       conf.requests_password = maybe; | 
					
						
							| 
									
										
										
										
											2018-10-31 23:16:55 -06:00
										 |  |  |     }); | 
					
						
							|  |  |  |   }).then(function () { | 
					
						
							|  |  |  |     return conf; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if (require.main === module) { | 
					
						
							|  |  |  |   module.exports.checkSecurity().then(function (conf) { | 
					
						
							|  |  |  |     console.log(conf); | 
					
						
							|  |  |  |     return conf; | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } |