UNPKG

mecano

Version:

Common functions for system deployment.

378 lines (372 loc) 11.8 kB
// Generated by CoffeeScript 1.11.1 var iptables, jsesc, misc, string; misc = require('./index'); string = require('./string'); jsesc = require('jsesc'); module.exports = iptables = { add_properties: ['--protocol', '--source', '---target', '--jump', '--goto', '--in-interface', '--out-interface', '--fragment', 'tcp|--source-port', 'tcp|--sport', 'tcp|--target-port', 'tcp|--dport', 'tcp|--tcp-flags', 'tcp|--syn', 'tcp|--tcp-option', 'udp|--source-port', 'udp|--sport', 'udp|--target-port', 'udp|--dport'], modify_properties: ['--set-counters', '--log-level', '--log-prefix', '--log-tcp-sequence', '--log-tcp-options', '--log-ip-options', '--log-uid', 'state|--state', 'comment|--comment', 'limit|--limit'], commands_arguments: { '-A': ['chain'], '-D': ['chain'], '-I': ['chain'], '-R': ['chain'], '-N': ['chain'], '-X': ['chain'], '-P': ['chain', 'target'], '-L': true, '-S': true, '-F': true, '-Z': true, '-E': true }, commands_inverted: { '--append': '-A', '--delete': '-D', '--insert': '-I', '--replace': '-R', '--new-chain': '-N', '--delete-chain': '-X', '--policy': '-P', '--list': '-L', '--list-rules': '-S', '--flush': '-F', '--zero': '-Z', '--rename-chain': '-E' }, parameters: ['--protocol', '--source', '--target', '--jump', '--goto', '--in-interface', '--out-interface', '--fragment', '--set-counters', '--log-level', '--log-prefix', '--log-tcp-sequence', '--log-tcp-options', '--log-ip-options', '--log-uid'], parameters_inverted: { '-p': '--protocol', '-s': '--source', '-d': '--target', '-j': '--jump', '-g': '--goto', '-i': '--in-interface', '-o': '--out-interface', '-f': '--fragment', '-c': '--set-counters' }, protocols: { tcp: ['--source-port', '--sport', '--target-port', '--dport', '--tcp-flags', '--syn', '--tcp-option'], udp: ['--source-port', '--sport', '--target-port', '--dport'], udplite: [], icmp: [], esp: [], ah: [], sctp: [], all: [] }, modules: { state: ['--state'], comment: ['--comment'], limit: ['--limit'] }, cmd_args: function(cmd, rule) { var arg, k, match, module, v; for (k in rule) { v = rule[k]; if (['chain', 'rulenum', 'command'].indexOf(k) !== -1) { continue; } if (v == null) { continue; } if (match = /^([\w]+)\|([-\w]+)$/.exec(k)) { module = match[1]; arg = match[2]; cmd += " -m " + module; cmd += " " + arg + " " + v; } else { cmd += " " + k + " " + v; } } return cmd; }, cmd_replace: function(rule) { if (rule.rulenum == null) { rule.rulenum = 1; } return iptables.cmd_args("iptables -R " + rule.chain + " " + rule.rulenum, rule); }, cmd_insert: function(rule) { if (rule.rulenum == null) { rule.rulenum = 1; } return iptables.cmd_args("iptables -I " + rule.chain + " " + rule.rulenum, rule); }, cmd_append: function(rule) { if (rule.rulenum == null) { rule.rulenum = 1; } return iptables.cmd_args("iptables -A " + rule.chain, rule); }, cmd: function(oldrules, newrules) { var add_properties, baserule, cmds, create, i, k, l, len, len1, len2, len3, len4, m, n, new_chains, newrule, o, old_chains, oldrule, p, rulenum, v; cmds = []; new_chains = []; old_chains = oldrules.map(function(oldrule) { return oldrule.chain; }).filter(function(chain, i, chains) { return ['INPUT', 'FORWARD', 'OUTPUT'].indexOf(chain) < 0 && chains.indexOf(chain) >= i; }); for (l = 0, len = newrules.length; l < len; l++) { newrule = newrules[l]; if (['INPUT', 'FORWARD', 'OUTPUT'].indexOf(newrule.chain) < 0 && new_chains.indexOf(newrule.chain) < 0 && old_chains.indexOf(newrule.chain) < 0) { new_chains.push(newrule.chain); cmds.push("iptables -N " + newrule.chain); } } for (m = 0, len1 = newrules.length; m < len1; m++) { newrule = newrules[m]; if (newrule.after && !newrule.rulenum) { rulenum = 0; for (i = n = 0, len2 = oldrules.length; n < len2; i = ++n) { oldrule = oldrules[i]; if (!(oldrule.command === '-A' && oldrule.chain === newrule.chain)) { continue; } rulenum++; if (misc.object.equals(newrule.after, oldrule, Object.keys(newrule.after))) { newrule.rulenum = oldrule.rulenum + 1; } } delete newrule.after; } if (newrule.before && !newrule.rulenum) { rulenum = 0; for (i = o = 0, len3 = oldrules.length; o < len3; i = ++o) { oldrule = oldrules[i]; if (!(oldrule.command === '-A' && oldrule.chain === newrule.chain)) { continue; } rulenum++; if (misc.object.equals(newrule.before, oldrule, Object.keys(newrule.before))) { newrule.rulenum = oldrule.rulenum; break; } } delete newrule.before; } create = true; add_properties = misc.array.intersect(iptables.add_properties, Object.keys(newrule)); for (p = 0, len4 = oldrules.length; p < len4; p++) { oldrule = oldrules[p]; if (oldrule.chain !== newrule.chain) { continue; } if (misc.object.equals(newrule, oldrule, add_properties)) { create = false; if (!misc.object.equals(newrule, oldrule, iptables.modify_properties)) { baserule = misc.merge({}, oldrule); for (k in baserule) { v = baserule[k]; if (iptables.commands_arguments[k]) { baserule[k] = void 0; } baserule.command = void 0; newrule.rulenum = void 0; } cmds.push(iptables.cmd_replace(misc.merge(baserule, newrule))); } } } if (create) { cmds.push(newrule.command === '-A' ? iptables.cmd_append(newrule) : iptables.cmd_insert(newrule)); } } return cmds; }, normalize: function(rules, position) { var k, l, len, len1, len2, len3, m, mk, mv, mvs, n, newrule, newrules, nk, o, oldrules, protocol, ref, ref1, rule, v; if (position == null) { position = true; } oldrules = Array.isArray(rules) ? rules : [rules]; newrules = []; for (l = 0, len = oldrules.length; l < len; l++) { rule = oldrules[l]; rule = misc.merge({}, rule); newrule = {}; for (k in rule) { v = rule[k]; nk = null; if (typeof v === 'number') { v = rule[k] = "" + v; } if (k === 'chain' || k === 'rulenum' || k === 'command') { nk = k; } else if (k.slice(0, 2) === '--' && iptables.parameters.indexOf(k) >= 0) { nk = k; } else if (k[0] !== '-' && iptables.parameters.indexOf("--" + k) >= 0) { nk = "--" + k; } else if (iptables.parameters_inverted[k]) { nk = iptables.parameters_inverted[k]; } if (nk) { newrule[nk] = v; rule[k] = null; } } if (protocol = newrule['--protocol']) { ref = iptables.protocols[protocol]; for (m = 0, len1 = ref.length; m < len1; m++) { k = ref[m]; if (rule[k]) { newrule[protocol + "|" + k] = rule[k]; rule[k] = null; } else if (rule[k.slice(2)]) { newrule[protocol + "|" + k] = rule[k.slice(2)]; rule[k.slice(2)] = null; } } } for (k in rule) { v = rule[k]; if (!v) { continue; } if (k === 'after' || k === 'before') { newrule[k] = iptables.normalize(v, false); continue; } if (k.slice(0, 2) !== '--') { k = "--" + k; } ref1 = iptables.modules; for (mk in ref1) { mvs = ref1[mk]; for (n = 0, len2 = mvs.length; n < len2; n++) { mv = mvs[n]; if (k === mv) { newrule[mk + "|" + k] = v; rule[k] = null; } } } } for (k in newrule) { v = newrule[k]; if (k === 'command') { continue; } if (k === '--log-level' && v === '4') { delete newrule[k]; continue; } if (k === 'comment|--comment') { v = v.replace('-', ''); } if (['--log-prefix', 'comment|--comment'].indexOf(k) !== -1) { v = jsesc(v, { quotes: 'double', wrap: true }); } newrule[k] = v; } newrules.push(newrule); } if (position && newrule.command !== '-A') { for (o = 0, len3 = newrules.length; o < len3; o++) { newrule = newrules[o]; if (!((newrule.after != null) || (newrule.before != null))) { newrule.after = { '-A': 'INPUT', chain: 'INPUT', '--jump': 'ACCEPT' }; } } } if (Array.isArray(rules)) { return newrules; } else { return newrules[0]; } }, /* Parse the result of `iptables -S` */ parse: function(stdout) { var char, command_index, forceflush, i, j, key, l, len, len1, line, m, module, name, newarg, ref, ref1, rule, rules, v, value; rules = []; command_index = {}; ref = string.lines(stdout); for (l = 0, len = ref.length; l < len; l++) { line = ref[l]; if (line.length === 0) { continue; } rule = {}; i = 0; key = ''; value = ''; module = null; while (i <= line.length) { char = line[i]; forceflush = i === line.length; newarg = (i === 0 && char === '-') || line.slice(i - 1, +i + 1 || 9e9) === ' -'; if (newarg || forceflush) { if (value) { value = value.trim(); if (key === '-m') { module = value; } else { if (module) { key = module + "|" + key; } if (iptables.parameters_inverted[key]) { key = iptables.parameters_inverted[key]; } rule[key] = value; } if (iptables.commands_arguments[key]) { if (Array.isArray(iptables.commands_arguments[key])) { rule.command = key; ref1 = value.split(' '); for (j = m = 0, len1 = ref1.length; m < len1; j = ++m) { v = ref1[j]; rule[iptables.commands_arguments[key][j]] = v; } if (command_index[name = rule.chain] == null) { command_index[name] = 0; } if (['-P', '-N'].indexOf(key) === -1) { rule.rulenum = ++command_index[rule.chain]; } } } key = ''; value = ''; if (forceflush) { break; } } key += char; while ((char = line[++i]) !== ' ') { key += char; } if (iptables.parameters_inverted[key]) { module = null; } continue; } if (char === '"') { while ((char = line[++i]) !== '"') { value += char; } i++; continue; } while (char + (char = line[++i]) !== ' -' && i < line.length) { if (char === '-' && key === '--comment') { continue; } value += char; } } rules.push(rule); } return rules; } };