Viewing File: /usr/local/cpanel/whostmgr/docroot/templates/hulkd/services/HulkdDataSource.js
/*
# cpanel - whostmgr/docroot/templates/hulkd/services/HulkdDataSource.js
# Copyright 2022 cPanel, L.L.C.
# All rights reserved.
# copyright@cpanel.net http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
*/
/* eslint-disable camelcase */
define(
[
"angular",
"jquery",
"lodash",
"cjt/util/locale",
"cjt/util/query",
"cjt/util/parse",
"cjt/io/api",
"cjt/io/whm-v1-request",
"cjt/io/whm-v1", // IMPORTANT: Load the driver so it's ready
],
function(angular, $, _, LOCALE, QUERY, PARSE, API, APIREQUEST, APIDRIVER) {
"use strict";
// Retrieve the current application
var app = angular.module("App");
var hulkDataSource = app.factory("HulkdDataSource", ["$q", "PAGE", "COUNTRY_CONSTANTS", function($q, PAGE, COUNTRY_CONSTANTS) {
var hulkData = {};
hulkData.whitelist = [];
hulkData.blacklist = [];
hulkData.whitelist_comments = {};
hulkData.blacklist_comments = {};
hulkData.whitelist_is_cached = false;
hulkData.blacklist_is_cached = false;
hulkData.config_settings = {};
hulkData.enabled = PAGE.hulkd_status.is_enabled;
hulkData.hulkd_status = function() {
var deferred = $q.defer();
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "cphulk_status");
API.promise(apiCall.getRunArguments())
.done(function(response) {
response = response.parsedResponse;
hulkData.enabled = PARSE.parsePerlBoolean(response.data.is_enabled);
deferred.resolve(hulkData.enabled);
});
return deferred.promise;
};
hulkData.get_countries_with_known_ip_ranges = function() {
var deferred = $q.defer();
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "get_countries_with_known_ip_ranges");
API.promise(apiCall.getRunArguments())
.done(function(response) {
response = response.parsedResponse;
deferred.resolve(response.data);
});
return deferred.promise;
};
hulkData.clear_caches = function() {
hulkData.whitelist = [];
hulkData.blacklist = [];
hulkData.whitelist_comments = {};
hulkData.blacklist_comments = {};
hulkData.whitelist_is_cached = false;
hulkData.blacklist_is_cached = false;
};
hulkData.enable_hulkd = function() {
var deferred = $q.defer();
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "enable_cphulk");
API.promise(apiCall.getRunArguments())
.done(function(response) {
response = response.parsedResponse;
if (response.status) {
deferred.resolve(response);
hulkData.enabled = true;
} else {
deferred.reject(response.error);
}
});
return deferred.promise;
};
hulkData.disable_hulkd = function() {
var deferred = $q.defer();
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "disable_cphulk");
API.promise(apiCall.getRunArguments())
.done(function(response) {
response = response.parsedResponse;
if (response.status) {
deferred.resolve(response.status);
hulkData.enabled = false;
// clear the caches to force a reload if
// hulkd is re-enabled later
hulkData.clear_caches();
} else {
deferred.reject(response.error);
}
});
return deferred.promise;
};
hulkData.convert_config_settings = function(config) {
var settings = {};
settings.block_brute_force_with_firewall = PARSE.parsePerlBoolean(config.cphulk_config.block_brute_force_with_firewall);
settings.block_excessive_brute_force_with_firewall = PARSE.parsePerlBoolean(config.cphulk_config.block_excessive_brute_force_with_firewall);
settings.brute_force_period_mins = config.cphulk_config.brute_force_period_mins;
settings.command_to_run_on_brute_force = config.cphulk_config.command_to_run_on_brute_force;
settings.command_to_run_on_excessive_brute_force = config.cphulk_config.command_to_run_on_excessive_brute_force;
settings.is_enabled = PARSE.parsePerlBoolean(config.cphulk_config.is_enabled);
settings.ip_brute_force_period_mins = config.cphulk_config.ip_brute_force_period_mins;
settings.lookback_period_min = config.cphulk_config.lookback_period_min;
settings.max_failures = config.cphulk_config.max_failures;
settings.max_failures_byip = config.cphulk_config.max_failures_byip;
settings.mark_as_brute = config.cphulk_config.mark_as_brute;
settings.notify_on_root_login = PARSE.parsePerlBoolean(config.cphulk_config.notify_on_root_login);
settings.notify_on_root_login_for_known_netblock = PARSE.parsePerlBoolean(config.cphulk_config.notify_on_root_login_for_known_netblock);
settings.notify_on_brute = PARSE.parsePerlBoolean(config.cphulk_config.notify_on_brute);
settings.can_temp_ban_firewall = PARSE.parsePerlBoolean(config.cphulk_config.can_temp_ban_firewall);
settings.iptable_error = config.cphulk_config.iptable_error;
settings.username_based_protection = PARSE.parsePerlBoolean(config.cphulk_config.username_based_protection);
settings.ip_based_protection = PARSE.parsePerlBoolean(config.cphulk_config.ip_based_protection);
settings.username_based_protection_local_origin = PARSE.parsePerlBoolean(config.cphulk_config.username_based_protection_local_origin);
settings.username_based_protection_for_root = PARSE.parsePerlBoolean(config.cphulk_config.username_based_protection_for_root);
settings.country_whitelist = config.cphulk_config.country_whitelist ? config.cphulk_config.country_whitelist.split(",") : [];
settings.country_blacklist = config.cphulk_config.country_blacklist ? config.cphulk_config.country_blacklist.split(",") : [];
hulkData.config_settings = settings;
return settings;
};
hulkData.save_config_settings = function(config) {
var deferred = $q.defer();
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "save_cphulk_config");
for (var i = 0, keys = _.keys(config), len = keys.length; i < len; i++) {
// we do not want to send this option
if (keys[i] === "is_enabled") {
continue;
}
var value = config[keys[i]];
if (_.isArray(value)) {
value = value.join(",");
} else if (_.isBoolean(value)) {
if (value) {
value = 1;
} else {
value = 0;
}
}
apiCall.addArgument(keys[i], value);
}
API.promise(apiCall.getRunArguments())
.done(function(response) {
response = response.parsedResponse;
if (response.status) {
// clean up the restart_ssh boolean
response.data.restart_ssh = PARSE.parsePerlBoolean(response.data.restart_ssh);
deferred.resolve(response.data);
} else {
deferred.reject(response.error);
}
});
return deferred.promise;
};
hulkData.load_config_settings = function() {
var deferred = $q.defer();
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "load_cphulk_config");
API.promise(apiCall.getRunArguments())
.done(function(response) {
response = response.parsedResponse;
if (response.status) {
var results = response.data,
settings = hulkData.convert_config_settings(results);
deferred.resolve(settings);
} else {
deferred.reject(response.error);
}
});
return deferred.promise;
};
hulkData.set_cphulk_config_keys = function(updatedKeys) {
var batchCalls = [];
angular.forEach(updatedKeys, function(value, key) {
batchCalls.push({
func: "set_cphulk_config_key",
data: {
key: key,
value: value,
},
});
});
return _batch_apiv1(batchCalls).then(function(results) {
// Use the last updated config, giving the most recent cphulk configuration
var response = results.pop();
response = response.parsedResponse;
var settings = hulkData.convert_config_settings(response.data);
return hulkData._parse_xlisted_countries(settings);
});
};
function _batch_apiv1(calls_infos) {
var deferred = $q.defer();
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "batch");
calls_infos.forEach(function(call, i) {
apiCall.addArgument(
("command-" + i),
call.func + "?" + QUERY.make_query_string(call.data)
);
});
API.promise(apiCall.getRunArguments())
.done(function(response) {
response = response.parsedResponse;
if (response.status) {
var results = response.data;
deferred.resolve(results);
} else {
deferred.reject(response.error);
}
});
return deferred.promise;
}
hulkData.load_xlisted_countries = function() {
return hulkData.load_config_settings().then(function(settings) {
return hulkData._parse_xlisted_countries(settings);
});
};
hulkData._parse_xlisted_countries = function(settings) {
var countries = {};
settings.country_blacklist.forEach(function(item) {
countries[item] = COUNTRY_CONSTANTS.BLACKLISTED;
});
settings.country_whitelist.forEach(function(item) {
countries[item] = COUNTRY_CONSTANTS.WHITELISTED;
});
return countries;
};
hulkData.add_to_list = function(list, records) {
var deferred = $q.defer();
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "batch_create_cphulk_records", null, null, { json: true });
apiCall.addArgument("list_name", list);
apiCall.addArgument("records", records);
API.promise(apiCall.getRunArguments())
.done(function(response) {
// create items from the response
response = response.parsedResponse;
if (response.status) {
// on API call success, add to list
var return_data = {
added: [],
rejected: response.data.ips_failed,
updated: [],
};
var original_ips_added = response.data.original_ips_added || [];
var ip_list = hulkData[ list + "list" ];
var comment_list = hulkData[ list + "list_comments"];
for (var i = 0, len = original_ips_added.length; i < len; i++) {
var ip = original_ips_added[i];
var ip_formatted = response.data.ips_added[i];
// Update the ip cache and parse the return data
var index = _.indexOf(hulkData.whitelist, ip_formatted);
if (index === -1) {
ip_list.push(ip_formatted);
return_data.added.push(ip_formatted);
} else {
return_data.updated.push(ip_formatted);
}
// Update the comment cache.
var record = _.find(records, function(record) {
return record.ip === ip;
});
if (record && record.comment) {
comment_list[ip_formatted] = record.comment;
}
// Extra info for the whitelist return.
if (list === "white") {
return_data.requester_ip = response.data.requester_ip;
return_data.requester_ip_is_whitelisted = response.data.requester_ip_is_whitelisted;
}
}
deferred.resolve(return_data);
} else {
// pass the error along
var error_details = {
main_message: response.error,
secondary_messages: [],
};
// Build the reason individual ips were rejected.
Object.keys(response.data.ips_failed).forEach(function(ip) {
var rejectReason = response.data.ips_failed[ip];
error_details.secondary_messages.push(rejectReason);
});
deferred.reject(error_details);
}
});
// pass the promise back to the controller
return deferred.promise;
};
hulkData.add_to_whitelist = function(records) {
return hulkData.add_to_list("white", records);
};
hulkData.add_to_blacklist = function(records) {
return hulkData.add_to_list("black", records);
};
hulkData.remove_from_list = function(ips_to_delete, list) {
var deferred = $q.defer();
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "delete_cphulk_record");
apiCall.addArgument("list_name", list);
for (var i = 0; i < ips_to_delete.length; i++) {
apiCall.addArgument("ip-" + i, ips_to_delete[i]);
}
API.promise(apiCall.getRunArguments())
.done(function(response) {
// create items from the response
response = response.parsedResponse;
if (response.status) {
var i = 0;
if (list === "white") {
// remove the IPs
hulkData.whitelist = _.difference(hulkData.whitelist, response.data.ips_removed);
// remove the comment
for (i = 0; i < response.data.ips_removed.length; i++) {
delete hulkData.whitelist_comments[response.data.ips_removed[i]];
}
} else {
// remove the IPs
hulkData.blacklist = _.difference(hulkData.blacklist, response.data.ips_removed);
// remove the comment
for (i = 0; i < response.data.ips_removed.length; i++) {
delete hulkData.blacklist_comments[response.data.ips_removed[i]];
}
}
deferred.resolve({ removed: response.data.ips_removed, not_removed: response.data.ips_failed, requester_ip: response.data.requester_ip, requester_ip_is_whitelisted: response.data.requester_ip_is_whitelisted });
} else {
// pass the error along
deferred.reject(response.error);
}
});
// pass the promise back to the controller
return deferred.promise;
};
hulkData.remove_from_whitelist = function(ips_to_delete) {
return hulkData.remove_from_list(ips_to_delete, "white");
};
hulkData.remove_from_blacklist = function(ip_to_delete) {
return hulkData.remove_from_list(ip_to_delete, "black");
};
hulkData.remove_all_from_whitelist = function() {
return hulkData.remove_from_whitelist(hulkData.whitelist);
};
hulkData.remove_all_from_blacklist = function() {
return hulkData.remove_from_blacklist(hulkData.blacklist);
};
hulkData.load_list = function(list) {
var deferred = $q.defer();
var apiCall = new APIREQUEST.Class();
apiCall.initialize("", "read_cphulk_records");
apiCall.addArgument("list_name", list);
API.promise(apiCall.getRunArguments())
.done(function(response) {
// create items from the response
response = response.parsedResponse;
if (response.status) {
// on API call success, populate data structure
var return_data = {};
if (list === "white") {
// check to see if the ip address is not whitelisted
if (!response.data.requester_ip_is_whitelisted) {
return_data.whitelist_warning = response.data.warning_ip;
}
if (response.data.restart_ssh) {
return_data.restart_ssh = true;
}
if (response.data.warning_ssh) {
return_data.warning_ssh = response.data.warning_ssh;
}
hulkData.whitelist = Object.keys(response.data.ips_in_list).slice();
for (var i = 0; i < hulkData.whitelist.length; i++) {
if (response.data.ips_in_list[hulkData.whitelist[i]]) {
hulkData.whitelist_comments[hulkData.whitelist[i]] = response.data.ips_in_list[hulkData.whitelist[i]];
}
}
hulkData.whitelist_is_cached = true;
return_data.list = hulkData.whitelist;
return_data.comments = hulkData.whitelist_comments;
return_data.requester_ip = response.data.requester_ip;
return_data.requester_ip_is_whitelisted = response.data.requester_ip_is_whitelisted;
deferred.resolve(return_data);
} else if (list === "black") {
hulkData.blacklist = Object.keys(response.data.ips_in_list).slice();
for (var j = 0; j < hulkData.blacklist.length; j++) {
if (response.data.ips_in_list[hulkData.blacklist[j]]) {
hulkData.blacklist_comments[hulkData.blacklist[j]] = response.data.ips_in_list[hulkData.blacklist[j]];
}
}
hulkData.blacklist_is_cached = true;
return_data.list = hulkData.blacklist;
return_data.comments = hulkData.blacklist_comments;
return_data.requester_ip = response.data.requester_ip;
deferred.resolve(return_data);
}
} else {
// pass the error along
deferred.reject(response.error);
}
});
// pass the promise back to the controller
return deferred.promise;
};
function init() {
// check for page data in the template if this is a first load
if (app.firstLoad && app.firstLoad.configs && PAGE.config_values) {
app.firstLoad.configs = false;
hulkData.config_settings = hulkData.convert_config_settings(PAGE.config_values);
}
}
init();
return hulkData;
}]);
return hulkDataSource;
}
);
Back to Directory
File Manager