netsh-rule
Version:
Utility to generate a batch file to manage inbound and outbound Windows firewall connections for a single exe file or all exe files in folder
141 lines (139 loc) • 6.03 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const minimist_1 = __importDefault(require("minimist"));
const chalk_1 = __importDefault(require("chalk"));
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const unique_names_1 = require("./unique-names");
const generate_1 = require("./generate");
function help(info) {
const msg = `
netsh-rules will generate a batch file to manage inbound and outbound Windows
firewall connections for a single exe file or all exe files in folder.
Usage:
netsh-rules <absolute path to filename | absolute path to folder> [options]
Options:
--name - The rule name (name will be generated from the last folder if not specified)
--program - Absolute path to <filename | folder>
--enable - Enable rule: yes | no (default: yes)
--dir - The rule is inbound or outbound: in | out | both (default: both i.e. in and out)
--action - The action for rule: allow | block (default: block)
--profile - Apply rule for: public | private | domain (default: public, private, domain)
--format - Output format can be batch file, powershell, or javascript: bat | ps1 | js (default: bat)
`;
console.log(chalk_1.default.gray(msg));
if (info) {
console.log(chalk_1.default.red(info));
}
console.log('');
}
function checkArgs() {
// 1. get and verify arguments
let args = minimist_1.default(process.argv.slice(2), {
string: ['name', 'action', 'enable', 'dir', 'profile', 'program', 'format'],
default: {
name: '',
enable: 'yes',
action: 'block',
dir: 'both',
profile: 'public,private,domain',
// generated defaults:
files: [],
format: 'bat',
nameRoot: '',
}
});
if (args._.length > 1) {
help('Only one filename or folder can be specified');
process.exit(1);
}
!args.program && (args.program = args._[0]);
checkArg(args.enable, 'enable', ['yes', 'no']);
checkArg(args.action, 'action', ['allow', 'block']);
checkArg(args.dir, 'dir', ['in', 'out', 'both']);
checkArg(args.profile, 'profile', ['public', 'private', 'domain']);
checkArg(args.format, 'format', ['bat', 'ps1', 'js']);
// 2. prepare source files
if (!args.program) {
help('Nothing to process');
process.exit(1);
}
args.program = args.program.replace(/"$/, ''); // remove quota if path is "c:\abc\" on Win10 the last \" becomes "
args.program = path_1.default.normalize(args.program);
const st = unique_names_1.exist(args.program);
if (!st) {
console.log('st', JSON.stringify(st, null, 4));
help(`Source not found: ${args.program}`);
process.exit(2);
}
if (st.isDirectory()) {
// prepare root
args.program = args.program.replace(new RegExp(`${path_1.default.sep}${path_1.default.sep}$`), ''); // remove last slash from folder name
args.root = args.program;
args.nameRoot = args.name || args.program.split(path_1.default.sep).pop().replace(/ /g, '');
// collect files
let files = [];
collectExeFiles(args.program, files, true);
args.files = filterDuplicated(files);
}
else {
// prepare root
args.root = path_1.default.dirname(args.program);
args.nameRoot = args.name || args.root.split(path_1.default.sep).pop().replace(/ /g, '');
// collect files
args.files.push(args.program);
}
//args.files = args.files.map(toWindows); // netsh accepts only back slashes
args.files = args.files.map(path_1.default.normalize); // netsh accepts only back slashes
args.files.sort((a, b) => a.length - b.length); // shortest first
console.log(chalk_1.default.yellow('Found exe files:'));
console.log(chalk_1.default.yellow(`${args.files.map((_) => ` ${_}\n`).join('')}`));
// 3. prepate dest output filename
args.dest = `${unique_names_1.uniqueFileName('netsh-rules')}.${args.format}`;
//console.log(chalk.red(JSON.stringify(args, null, 4)));
return args;
function collectExeFiles(folder, rv, recursive) {
rv.push(...fs_1.default.readdirSync(folder).map((_) => {
let fname = path_1.default.join(folder, _);
let _st = fs_1.default.statSync(fname);
if (_st.isDirectory()) {
recursive && collectExeFiles(fname, rv, recursive);
}
else {
return _st.isFile() && path_1.default.extname(_).toLowerCase() === '.exe' ? fname : '';
}
}).filter(Boolean));
}
function filterDuplicated(names) {
return [...new Map(names.map(_ => [_.toLowerCase(), _])).values()]; // leave unique and preserve names case.
}
function checkArg(value, name, allowed) {
let s = (value || '').trim();
if (!s) {
help(`Required argument '${name}' is missing. Allowed values are '${allowed.join(' | ')}'`);
process.exit(3);
}
let arr = s.toLowerCase().split(',').map(_ => _.trim().toLowerCase());
arr.forEach((src) => {
if (!allowed.includes(src)) {
help(`Invalid argument '${name} = ${value}'. Allowed values are '${allowed.join(' | ')}'`);
process.exit(3);
}
});
}
} //checkArgs()
function main() {
let args = checkArgs();
let content = generate_1.genearateFile(args);
if (content) {
fs_1.default.writeFileSync(args.dest, content);
}
else {
console.log(chalk_1.default.yellow('Generated nothing'));
}
} //main()
main();
//# sourceMappingURL=index.js.map