domotz-remote-pawn
Version:
Domotz Agent
148 lines (131 loc) • 4.64 kB
JavaScript
/** This file is part of Domotz Agent.
* Copyright (C) 2016 Domotz Ltd
*
* Domotz Agent is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Domotz Agent is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Domotz Agent. If not, see <http://www.gnu.org/licenses/>.
*
* Created by Tommaso Latini <tommaso@domotz.com> on 06/09/16.
*
*/
const MODULE = 'SSH_COMMAND_EXECUTOR';
const USER = 'domotz';
const PASSWORD = null;
const HOST = 'localhost';
const TTL = 3600000; // 1 hour
const SSH_BINARY = 'ssh';
const SSHPASS_BINARY = 'domotz_sshpass';
const USER_KNOWN_HOST_FILE = '/dev/null';
const HOST_KEY_CHECKING = 'no';
// To add options check ssh manual. We assume to use standard openssh client.
const OPTIONS_MAP = {
bind_address: '-b',
cipher_spec: '-c',
escape_char: '-e',
config_file: '-F',
dynamic_port_forwarding: '-D',
identity_file: '-i',
pkcs11: '-I',
login_name: '-l',
local_port_forwarding: '-L',
mac_spec: '-m',
disable_remote_command: '-N',
host_key_checking: '-oStrictHostKeyChecking=',
user_known_host_file: '-oUserKnownHostsFile=',
server_alive_interval: '-oServerAliveInterval=',
server_alive_count_max: '-oServerAliveCountMax=',
kex_algorithm: '-oKexAlgorithms=',
ctl_cmd: '-O',
port: '-p',
remote_port_forwarding: '-R',
ctl_path: '-S',
disable_pseudo_tty_alloc: '-T'
};
module.exports.factory = function (procUtils) {
/**
* SSH is an external tool. It must be linked with system libraries!
*/
function getCleanEnv() {
var cleanedEnv = Object.create(process.env);
cleanedEnv.LD_LIBRARY_PATH = "";
return cleanedEnv;
}
function getOpt(options, names, dflt) {
for (var i = 0; i < names.length; i++) {
var name = names[i];
var o = options[name];
if (typeof o !== 'undefined') {
delete options[name];
return o;
}
}
return dflt;
}
function setDefault(options, name, dflt) {
if (typeof options[name] === 'undefined') {
options[name] = dflt;
}
}
/**
* @param command: Command to run in ssh <OPTIONAL>
* @param options:
* --> log_prefix: prefix for log [default SSH_COMMAND_EXECUTOR]
* --> user: user login for remote shell [default domotz]
* --> password: password to forward to ssh using domotz_sshpass
* --> host: target device [default localhost]
* --> ttl: lifetime of channel [default 1 hour]
* --> ... see OPTIONS_MAP
* }
*/
function exec(command, options) {
var ssh, args = [];
var logId = getOpt(options, ['log_prefix'], MODULE);
var user = getOpt(options, ['user', 'username'], USER);
var password = getOpt(options, ['password', 'pwd'], PASSWORD);
var host = getOpt(options, ['host', 'hostname'], HOST);
if (password) {
console.verbose(logId + ' - Use sshpass to forward login password');
ssh = SSHPASS_BINARY;
args.push('-p');
args.push(password);
args.push(SSH_BINARY);
} else {
ssh = SSH_BINARY;
}
setDefault(options, 'user_known_host_file', USER_KNOWN_HOST_FILE);
setDefault(options, 'host_key_checking', HOST_KEY_CHECKING);
Object.keys(options).forEach(function (opt) {
if (OPTIONS_MAP.hasOwnProperty(opt)) {
var arg1 = OPTIONS_MAP[opt],
arg2 = options[opt];
if (arg1.indexOf('-o') === 0) {
args.push(arg1 + arg2);
} else if (typeof arg2 !== 'boolean') {
args.push(arg1);
args.push(arg2);
} else {
args.push(arg1);
}
delete options[opt];
}
});
args.push(user + '@' + host);
if (command) {
args.push(command);
}
options.env = getCleanEnv();
return procUtils.spawn(ssh, args, options);
}
return {
exec: exec
};
};