1 | 'use strict';
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | var debug = require('debug')('plugin:accesscontrol');
|
7 | var util = require("util");
|
8 | const dns = require('dns');
|
9 |
|
10 | module.exports.init = function (config /*, logger, stats */) {
|
11 |
|
12 | var allow;
|
13 | var deny;
|
14 |
|
15 | |
16 |
|
17 |
|
18 |
|
19 | function checkAccessControlInfo(sourceIP) {
|
20 | if (config === null) debug('WARNING: insufficient information to run accesscontrol');
|
21 | else if (config.allow === null && config.deny === null) debug('WARNING: insufficient information to run accesscontrol');
|
22 | else if (config.allow !== null) {
|
23 | debug ('allow list: ' + util.inspect(config.allow, 2, true));
|
24 | if (scanIP(config.allow, sourceIP)) {
|
25 | allow = true;
|
26 | }
|
27 | }
|
28 | else if (config.deny !== null) {
|
29 | debug ('deny list: ' + util.inspect(config.deny, 2, true));
|
30 | if (scanIP(config.deny, sourceIP)) {
|
31 | debug ('deny incoming message');
|
32 | deny = true;
|
33 | }
|
34 | }
|
35 | }
|
36 |
|
37 | |
38 |
|
39 |
|
40 | function checkIsIPV4(entry) {
|
41 | var blocks = entry.split(".");
|
42 | if(blocks.length === 4) {
|
43 | return blocks.every(function(block) {
|
44 | return (block === '*' || (parseInt(block,10) >=0 && parseInt(block,10) <= 255));
|
45 | });
|
46 | }
|
47 | return false;
|
48 | }
|
49 |
|
50 | |
51 |
|
52 |
|
53 |
|
54 | |
55 |
|
56 |
|
57 |
|
58 |
|
59 |
|
60 |
|
61 |
|
62 |
|
63 | function scanIP(list, sourceIP) {
|
64 |
|
65 | var sourceOctets = sourceIP.split('.');
|
66 |
|
67 | for (var i=0; i < list.length; i++) {
|
68 |
|
69 | if (list[i].indexOf('*') === -1 && list[i] === sourceIP) {
|
70 | return true;
|
71 | } else if (list[i].indexOf('*') !== -1) {
|
72 | var listOctets = list[i].split('.');
|
73 | if (octetCompare(listOctets, sourceOctets)) return true;
|
74 | }
|
75 | }
|
76 |
|
77 | return false;
|
78 | }
|
79 |
|
80 | |
81 |
|
82 |
|
83 |
|
84 | function octetCompare (listOctets, sourceOctets) {
|
85 | var compare = false;
|
86 | for (var i=0; i < listOctets.length; i++) {
|
87 |
|
88 | if (listOctets[i] !== '*' && parseInt(listOctets[i]) === parseInt(sourceOctets[i])) {
|
89 | compare = true;
|
90 | } else if (listOctets[i] !== '*' && parseInt(listOctets[i]) !== parseInt(sourceOctets[i])) {
|
91 | return false;
|
92 | }
|
93 | }
|
94 | return compare;
|
95 | }
|
96 |
|
97 | |
98 |
|
99 |
|
100 | function sendError(res) {
|
101 | var errorInfo = {
|
102 | "code": "403",
|
103 | "message": "Forbidden"
|
104 | };
|
105 | res.writeHead(403, { 'Content-Type': 'application/json' });
|
106 | res.write(JSON.stringify(errorInfo));
|
107 | res.end();
|
108 | }
|
109 |
|
110 | return {
|
111 |
|
112 | onrequest: function(req, res, next) {
|
113 | debug('plugin onrequest');
|
114 | var host = req.headers.host;
|
115 | debug ("source ip " + host);
|
116 | var sourceIP = host.split(":");
|
117 |
|
118 | if (checkIsIPV4(sourceIP[0])) {
|
119 | checkAccessControlInfo(sourceIP[0]);
|
120 | if (allow === false || deny === true)
|
121 | sendError(res);
|
122 | } else {
|
123 | dns.lookup(sourceIP[0], (err, address, family) => {
|
124 | debug('address: %j family: IPv%s', address, family);
|
125 | if (err) {
|
126 | debug(err);
|
127 | sendError(res);
|
128 | }
|
129 | checkAccessControlInfo(address);
|
130 | if (allow === false || deny === true)
|
131 | sendError(res);
|
132 | });
|
133 | }
|
134 | next();
|
135 | }
|
136 | };
|
137 | } |
\ | No newline at end of file |