2020-08-31 18:22:33 -07:00
'use strict' ;
exports = module . exports = {
getBlocklist ,
setBlocklist
} ;
const assert = require ( 'assert' ) ,
BoxError = require ( './boxerror.js' ) ,
2020-09-14 10:29:48 -07:00
ipaddr = require ( 'ipaddr.js' ) ,
2020-08-31 18:22:33 -07:00
path = require ( 'path' ) ,
paths = require ( './paths.js' ) ,
safe = require ( 'safetydance' ) ,
2020-09-02 23:04:42 -07:00
settings = require ( './settings.js' ) ,
2020-08-31 18:22:33 -07:00
shell = require ( './shell.js' ) ,
validator = require ( 'validator' ) ;
const SET _BLOCKLIST _CMD = path . join ( _ _dirname , 'scripts/setblocklist.sh' ) ;
function getBlocklist ( callback ) {
assert . strictEqual ( typeof callback , 'function' ) ;
2021-05-04 15:21:38 -07:00
settings . getFirewallBlocklist ( function ( error , blocklist ) {
if ( error ) return callback ( error ) ;
callback ( null , blocklist ) ;
} ) ;
2020-08-31 18:22:33 -07:00
}
2020-09-14 10:29:48 -07:00
function setBlocklist ( blocklist , auditSource , callback ) {
assert . strictEqual ( typeof blocklist , 'string' ) ;
assert . strictEqual ( typeof auditSource , 'object' ) ;
2020-08-31 18:22:33 -07:00
assert . strictEqual ( typeof callback , 'function' ) ;
2020-09-14 10:29:48 -07:00
const parsedIp = ipaddr . process ( auditSource . ip ) ;
2020-08-31 18:22:33 -07:00
2020-09-14 10:29:48 -07:00
for ( const line of blocklist . split ( '\n' ) ) {
if ( ! line || line . startsWith ( '#' ) ) continue ;
const rangeOrIP = line . trim ( ) ;
if ( ! validator . isIP ( rangeOrIP ) && ! validator . isIPRange ( rangeOrIP ) ) return callback ( new BoxError ( BoxError . BAD _FIELD , ` ${ rangeOrIP } is not a valid IP or range ` ) ) ;
2020-09-02 23:04:42 -07:00
2020-09-14 10:29:48 -07:00
if ( rangeOrIP . indexOf ( '/' ) === - 1 ) {
if ( auditSource . ip === rangeOrIP ) return callback ( new BoxError ( BoxError . BAD _FIELD , ` ${ rangeOrIP } includes client IP. Cannot block yourself ` ) ) ;
} else {
2021-04-07 17:31:04 +02:00
const parsedRange = ipaddr . parseCIDR ( rangeOrIP ) ; // returns [addr, range]
if ( parsedRange [ 0 ] . kind ( ) === parsedIp . kind ( ) && parsedIp . match ( parsedRange ) ) return callback ( new BoxError ( BoxError . BAD _FIELD , ` ${ rangeOrIP } includes client IP. Cannot block yourself ` ) ) ;
2020-09-14 10:29:48 -07:00
}
}
2020-08-31 18:22:33 -07:00
2020-09-14 10:29:48 -07:00
if ( settings . isDemo ( ) ) return callback ( new BoxError ( BoxError . CONFLICT , 'Not allowed in demo mode' ) ) ;
2020-08-31 18:22:33 -07:00
2021-05-04 15:21:38 -07:00
settings . setFirewallBlocklist ( blocklist , function ( error ) {
if ( error ) return callback ( error ) ;
// this is done only because it's easier for the shell script and the firewall service to get the value
if ( ! safe . fs . writeFileSync ( paths . FIREWALL _BLOCKLIST _FILE , blocklist + '\n' , 'utf8' ) ) return callback ( new BoxError ( BoxError . FS _ERROR , safe . error . message ) ) ;
2020-08-31 18:22:33 -07:00
2021-05-04 15:21:38 -07:00
shell . sudo ( 'setBlocklist' , [ SET _BLOCKLIST _CMD ] , { } , function ( error ) {
if ( error ) return callback ( new BoxError ( BoxError . IPTABLES _ERROR , ` Error setting blocklist: ${ error . message } ` ) ) ;
2020-08-31 18:22:33 -07:00
2021-05-04 15:21:38 -07:00
callback ( null ) ;
} ) ;
2020-08-31 18:22:33 -07:00
} ) ;
}