diff --git a/core/oputil/oputil_help.js b/core/oputil/oputil_help.js index 7104d827e..14bf9de12 100644 --- a/core/oputil/oputil_help.js +++ b/core/oputil/oputil_help.js @@ -20,6 +20,7 @@ Commands: config Configuration management fb File base management mb Message base management + ssh SSH key management `, User: `usage: oputil.js user [] @@ -219,6 +220,11 @@ qwk-export arguments: TIMESTAMP. --no-qwke Disable QWKE extensions. --no-synchronet Disable Synchronet style extensions. +`, + SSH: `usage: oputil.js ssh + +Actions: + create Create new SSH Keys `, }); diff --git a/core/oputil/oputil_main.js b/core/oputil/oputil_main.js index 9dcbc5104..9b79ad3dc 100644 --- a/core/oputil/oputil_main.js +++ b/core/oputil/oputil_main.js @@ -10,6 +10,7 @@ const handleFileBaseCommand = require('./oputil_file_base.js').handleFileBaseCom const handleMessageBaseCommand = require('./oputil_message_base.js').handleMessageBaseCommand; const handleConfigCommand = require('./oputil_config.js').handleConfigCommand; +const handleSSHKeyCommand = require('./oputil_ssh_key.js').handleSSHKeyCommand; const getHelpFor = require('./oputil_help.js').getHelpFor; module.exports = function () { @@ -32,6 +33,8 @@ module.exports = function () { return handleFileBaseCommand(); case 'mb': return handleMessageBaseCommand(); + case 'ssh': + return handleSSHKeyCommand(); default: return printUsageAndSetExitCode(getHelpFor('General'), ExitCodes.BAD_COMMAND); } diff --git a/core/oputil/oputil_ssh_key.js b/core/oputil/oputil_ssh_key.js new file mode 100644 index 000000000..00ba83677 --- /dev/null +++ b/core/oputil/oputil_ssh_key.js @@ -0,0 +1,137 @@ +/* jslint node: true */ +/* eslint-disable no-console */ +'use strict'; + +// ENiGMA½ +const initConfigAndDatabases = require('./oputil_common.js').initConfigAndDatabases; + +const { + printUsageAndSetExitCode, + argv, + ExitCodes, + getAnswers, +} = require('./oputil_common.js'); +const getHelpFor = require('./oputil_help.js').getHelpFor; + +// deps +const async = require('async'); +const fs = require('fs-extra'); +const exec = require('child_process').exec; +const inq = require('inquirer'); +const _ = require('lodash'); + + +exports.handleSSHKeyCommand = handleSSHKeyCommand; + +const ConfigIncludeKeys = [ + 'loginServers.ssh', + 'loginServers.ssh.privateKeyPem', +]; + +const MINIMUM_PASSWORD_LENGTH = 8; +const QUESTIONS = { + Create: [ + { + name: 'createNew', + message: 'Generate New SSH Keys?', + type: 'confirm', + default: false, + }, + { + name: 'password', + message: 'SSL Password:', + default: "", + when: answers => answers.createNew, + }, + ], +}; + +function execute(ui, command) { + exec( + command, + function (error, stdout, stderr) { + ui.log.write(error); + + if (error) { + const reason = error ? error.message : 'OpenSSL Error'; + logDebug( + { + reason: reason, + cmd: util.cmd, + args: args + }, + `openssl command failed` + ); + } + else { + ui.log.write("SSH Keys Generated") + } + } + ); +} + +function createNew(cb) { + const ui = new inq.ui.BottomBar(); + + async.waterfall( + [ + function init(callback) { + return initConfigAndDatabases(callback); + }, + function create(configuration, callback) { + getAnswers(QUESTIONS.Create, answers => { + if (!answers.createNew) { + return callback('exit'); + } + + // Get Answer Value + const sslPassword = answers.password.trim(); + if (!sslPassword || sslPassword == "") { + ui.log.write('Password must be set.'); + + return callback('exit'); + } + if (sslPassword.length < MINIMUM_PASSWORD_LENGTH) { + ui.log.write(`Password must be at least ${MINIMUM_PASSWORD_LENGTH} characters.`); + + return callback('exit'); + } + + // Check if Keyfiles Exist + const sshKeyPath = "config/security/"; + const sshKeyFilename = "ssh_private_key.pem"; + const targetKeyFile = sshKeyPath + sshKeyFilename; + + ui.log.write(`Creating SSH Key: ${targetKeyFile}`); + + // Create Dir + ui.log.write(`Creating Directory: ${sshKeyPath}`); + fs.ensureDirSync(sshKeyPath); + + // Create SSH Keys + const command = `openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -pkeyopt rsa_keygen_pubexp:65537 | openssl rsa -out ./${targetKeyFile} -aes128 -traditional -passout pass:`; + execute(ui, `${command}${sslPassword}`); + }); + }, + ], + err => { + return cb(err, configPath, config); + } + ); +} + +function handleSSHKeyCommand() { + if (true === argv.help) { + return printUsageAndSetExitCode(getHelpFor('SSH'), ExitCodes.ERROR); + } + + const action = argv._[1]; + + switch (action) { + case 'create': + return createNew(); + + default: + return printUsageAndSetExitCode(getHelpFor('SSH'), ExitCodes.ERROR); + } +}