Skip to content

Commit

Permalink
Refactor for State
Browse files Browse the repository at this point in the history
Added src/state
Allows management of state.
immutable and mutable work, but not with get and set.
Extends properties to the current state object.

Updated code otherwise to include references.
  • Loading branch information
Dustyn Blackmore committed May 16, 2018
1 parent 84de2dd commit 9c9c877
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 70 deletions.
69 changes: 34 additions & 35 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,80 +122,79 @@ function handleActions (action, packet) {

function handlePacket (packet) {
let verdict = {
policy: packet.state.enums.netfilterVerdict.NF_DROP,
policy: packet.enums.netfilterVerdict.NF_DROP,
mark: 0
};

// Check we even handle this protocol
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()]) {
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()]) {
// Check if the global (blanket) rule applies
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.policy && rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.policy === 'allow') {
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()].global.policy && rules[packet.direction][packet.nfpacketDecoded.protocol.toString()].global.policy === 'allow') {
// Trigger the callback, if it exists..
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.action) {
handleActions(rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.action, packet);
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.action === 'log') {
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()].global.action) {
handleActions(rules[packet.direction][packet.nfpacketDecoded.protocol.toString()].global.action, packet);
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()].global.action === 'log') {
verdict.mark = 9999;
}
}
// Check if the global setting has any specific ports
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.ports) {
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()].global.ports) {
// Check, if there are ports, if the port is allowed.
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.ports[packet.state.nfpacketDecoded.payload.dport]) {
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()].global.ports[packet.nfpacketDecoded.payload.dport]) {
// Check if the policy is allow
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.ports[packet.state.nfpacketDecoded.payload.dport].policy && rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.ports[packet.state.nfpacketDecoded.payload.dport].policy === 'allow') {
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()].global.ports[packet.nfpacketDecoded.payload.dport].policy && rules[packet.direction][packet.nfpacketDecoded.protocol.toString()].global.ports[packet.nfpacketDecoded.payload.dport].policy === 'allow') {
// Set to accept packet.
verdict.policy = packet.state.enums.netfilterVerdict.NF_ACCEPT;
verdict.policy = packet.enums.netfilterVerdict.NF_ACCEPT;
}
// Finally - if the port is allowed, check if there's a callback to trigger.
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.ports[packet.state.nfpacketDecoded.payload.dport].action) {
handleActions(rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.ports[packet.state.nfpacketDecoded.payload.dport].action, packet);
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()].global.ports[packet.state.nfpacketDecoded.payload.dport].action === 'log') {
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()].global.ports[packet.nfpacketDecoded.payload.dport].action) {
handleActions(rules[packet.direction][packet.nfpacketDecoded.protocol.toString()].global.ports[packet.nfpacketDecoded.payload.dport].action, packet);
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()].global.ports[packet.nfpacketDecoded.payload.dport].action === 'log') {
verdict.mark = 9999;
}
}
// Do not further traverse ruleset, or this function ; wasted cycles.
packet.state.nfpacket.setVerdict(verdict.policy, verdict.mark);
packet.nfpacket.setVerdict(verdict.policy, verdict.mark);
}
// The global default is enabled, yet there is no ports key..
// (Likely) means this is a port-less protocol, or a blanket 'allow' rule is in place.
} else {
verdict.policy = packet.state.enums.netfilterVerdict.NF_ACCEPT;
packet.state.nfpacket.setVerdict(verdict.policy, verdict.mark);
verdict.policy = packet.enums.netfilterVerdict.NF_ACCEPT;
packet.nfpacket.setVerdict(verdict.policy, verdict.mark);
}
// Else, as if globally accepted we don't need to traverse other zones.
}
// Check if the protocol is zone allowed.
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].policy && rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].policy === 'allow') {
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].policy && rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].policy === 'allow') {
// Trigger the protocol zone callback, if it exists.
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].action) {
handleActions(rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].action, packet);
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].action === 'log') {
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].action) {
handleActions(rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].action, packet);
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].action === 'log') {
verdict.mark = 9999;
}
}
// Check if the protocol's zone setting has any specific ports
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].ports) {
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports) {
// Check, if there are ports, if the port is allowed.
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].ports[packet.state.nfpacketDecoded.payload.dport] && rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].ports[packet.state.nfpacketDecoded.payload.dport].policy && rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].ports[packet.state.nfpacketDecoded.payload.dport].policy === 'allow') {
verdict.policy = packet.state.enums.netfilterVerdict.NF_ACCEPT;
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.dport] && rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.dport].policy && rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.dport].policy === 'allow') {
verdict.policy = packet.enums.netfilterVerdict.NF_ACCEPT;
// Finally - if the port is allowed, check if there's a callback to trigger.
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].ports[packet.state.nfpacketDecoded.payload.dport].action) {
handleActions(rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].ports[packet.state.nfpacketDecoded.payload.dport].action, packet);
if (rules[packet.getDirection()][packet.state.nfpacketDecoded.protocol.toString()][packet.getInterface().zone].ports[packet.state.nfpacketDecoded.payload.dport].action === 'log') {
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.dport].action) {
handleActions(rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.dport].action, packet);
if (rules[packet.direction][packet.nfpacketDecoded.protocol.toString()][packet.interface.zone].ports[packet.nfpacketDecoded.payload.dport].action === 'log') {
verdict.mark = 9999;
}
}
}
// The global default is enabled, yet there are no ports.. which likely
// Means this is a port-less protocol.
} else {
verdict.policy = packet.state.enums.netfilterVerdict.NF_ACCEPT;
verdict.policy = packet.enums.netfilterVerdict.NF_ACCEPT;
}
}
}

console.log(verdict.policy);
packet.state.nfpacket.setVerdict(verdict.policy, verdict.mark);
packet.nfpacket.setVerdict(verdict.policy, verdict.mark);
}

function updateOutput () {
Expand All @@ -207,9 +206,9 @@ function bindQueueHandlers () {
interfaces.forEach(interface => {
interface.queueIn = nfq.createQueueHandler(parseInt(interface.number), buffer, (nfpacket) => {
let thisPacket = netFilterPacket(nfpacket);
thisPacket.setDirection('incoming');
thisPacket.setInterface(interface);

thisPacket.direction = 'incoming';
thisPacket.interface = interface;
thisPacket.encoding.decode();

handlePacket(thisPacket);
Expand All @@ -227,9 +226,9 @@ function bindQueueHandlers () {

interface.queueOut = nfq.createQueueHandler(parseInt('100' + interface.number), buffer, (nfpacket) => {
let thisPacket = netFilterPacket(nfpacket);
thisPacket.setDirection('outgoing');
thisPacket.setInterface(interface);

thisPacket.direction = 'outgoing';
thisPacket.interface = interface;
thisPacket.encoding.decode();

handlePacket(thisPacket);
Expand Down
6 changes: 3 additions & 3 deletions src/nfpacket/encoding.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const encoding = (dependencies) => (state) => ({
decode: () => {
let IPv4 = dependencies || null;

state.nfpacketDecoded = IPv4
let nfpacketDecoded = IPv4
? new IPv4().decode(state.nfpacket.payload, 0)
: false;
: false
state.nfpacketDecoded = nfpacketDecoded;
}
})

Expand Down
41 changes: 9 additions & 32 deletions src/nfpacket/index.js
Original file line number Diff line number Diff line change
@@ -1,45 +1,22 @@
const actions = require('./actions');
const encoding = require('./encoding');
const enums = require('./enums.js');

const setDirection = (state) => (direction) => {
if (direction === 'incoming' || direction === 'outgoing') {
state.direction = direction;
} else {
state.direction = undefined;
}
}

const getDirection = (state) => () => {
return state.direction;
}

const setInterface = (state) => (interface) => {
state.interface = interface;
}

const getInterface = (state) => () => {
return state.interface;
}
const statable = require('./../state');

module.exports = (dependencies) => (nfpacket) => {
let state = {
nfpacket: nfpacket,
enums: enums,
let state = statable('mutable')({
direction: undefined,
interface: undefined
}
enums: enums,
interface: undefined,
nfpacket: nfpacket,
});

if (Object.keys(dependencies).includes('nfq') && Object.keys(dependencies).includes('pcapIPv4')) {
return Object.assign(
{},
state,
{
actions: actions(dependencies)(state),
encoding: encoding(dependencies.pcapIPv4)(state),
getDirection: getDirection(state),
getInterface: getInterface(state),
setDirection: setDirection(state),
setInterface: setInterface(state),
state
encoding: encoding(dependencies.pcapIPv4)(state)
}
);
}
Expand Down
5 changes: 5 additions & 0 deletions src/state/immutable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = (state) => ({
get: (property) => {
return state.property || undefined;
}
});
28 changes: 28 additions & 0 deletions src/state/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const immutable = require('./immutable');
const mutable = require('./mutable');

module.exports = (type) => (initialState) => {
let state = {};

if (typeof initialState !== 'undefined') {
state = initialState;
}

if (typeof type === 'string' && (type === 'mutable' || type === 'immutable')) {
if (type === 'immutable') {
return Object.freeze(Object.assign(
state,
immutable(state),
));
}

if (type === 'mutable') {
return Object.assign(
state,
mutable(state),
)
}
}

return state;
}
22 changes: 22 additions & 0 deletions src/state/mutable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const checkSetObject = (setObject) => {
return typeof Object.keys(setObject)[0] !== undefined;
}

module.exports = (state) => ({
get: (property) => {
return state[property] || undefined;
},
set: (setObject) => {
if (checkSetObject(setObject)) {
let currentState = Object.assign({}, state);

let targetProperty = Object.keys(setObject)[0];
let targetValue = setObject[targetProperty];

console.log('Attempting to set %s, with %s.', targetProperty, targetValue);
let newState = Object.assign({ [targetProperty]: targetValue }, currentState);

state = newState;
}
}
});

0 comments on commit 9c9c877

Please sign in to comment.