/** * @copyright Copyright(c) 2011 Ajax.org B.V. * @author Fabian Jakobs * @author Mike de Boer * @license http://github.com/ajaxorg/node-sftp/blob/master/LICENSE MIT License */ var child_process = require("child_process"); var fs = require("fs"); var uuid = require("node-uuid"); exports.buildArgs = function(prvkeyFile, host) { var args = [ "-o", "PasswordAuthentication=no", "-o", "IdentityFile=" + prvkeyFile, "-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "-F", "/dev/null", // use empty config file to not depend on local settings // force pseudo terminal to make sure that the remote process is killed // when the local ssh process is killed "-t", "-t", "-o", "BatchMode=yes", "-o", "ConnectTimeout=10" // default timeout is 2 minutes, which is quite long ]; if (host) { host = host.split(":"); args.push("-p", host[1] || 22); args.push(host[0]); } return args; }; exports.spawnWithKeyFile = function(prvkeyFile, host, command, args) { var sshArgs = exports.buildArgs(prvkeyFile, host); var args = sshArgs.concat(command ? [command] : []).concat(args || []); console.log("executing: ssh " + args.join(" ")); return child_process.spawn("ssh", args); }; exports.writeKeyFile = function(prvkey, callback) { var filename = Util.DEFAULT_TMPDIR + "/" + uuid(); fs.writeFile(filename, prvkey, function(err) { if (err) return callback(err); fs.chmod(filename, "0600", function(err) { callback(err, filename); }); }); }; exports.writeKeyFiles = function(prvkey, pubkey, callback) { var filename = Util.DEFAULT_TMPDIR + "/" + uuid(); fs.writeFile(filename, prvkey, function(err) { if (err) return callback(err); fs.chmod(filename, "0600", function(err) { fs.writeFile(filename + ".pub", pubkey, function(err) { if (err) return callback(err); fs.chmod(filename + ".pub", "0600", function(err) { callback(err, filename); }); }); }); }); }; exports.spawn = function(prvkey, host, command, args, callback) { exports.writeKeyFile(prvkey, function(err, filename) { var child = exports.spawnWithKeyFile(filename, host, command, args); child.on("exit", function(code) { fs.unlink(filename, function() {}); }); callback(null, child); }); }; exports.exec = function(prvkey, host, command, args, callback) { exports.spawn(prvkey, host, command, args, function(err, child) { if (err) return callback(err); var out = err = ""; child.stdout.on("data", function (data) { out += data; }); child.stderr.on("data", function (data) { err += data; }); child.on("exit", function(code) { callback(code, out, err); }); }); }; exports.generateKeyPair = function(email, callback) { var tmp = process.env.TMP || process.env.TMPDIR || process.env.TMP_DIR || "/tmp"; var filename = tmp + "/" + uuid(); var phrase = ""; var command = "ssh-keygen -t rsa " + "-f \"" + filename + "\" " + "-P \"" + phrase + "\" " + "-C \"" + email + "\" "; child_process.exec(command, function (err, stdout, stderr) { if (err) return callback(err); fs.readFile(filename + ".pub", function (err, pubkey) { if (err) return callback(err); fs.readFile(filename, function (err, prvkey) { if (err) return callback(err); fs.unlink(filename + ".pub", function() { fs.unlink(filename, function() { callback(null, pubkey.toString(), prvkey.toString()); }); }); }); }); }); }; exports.validateSSHKey = function(prvkey, host, callback) { exports.exec(prvkey, host, "", [], function(err, stdout, stderr) { //console.log("out >> " + stdout) //console.log("err >> " + stderr) //console.log(err) callback(null, !stderr.match(/Permission denied \(.*publickey/)); }); };