Skip to content

Commit

Permalink
Add more info to login activities alerts
Browse files Browse the repository at this point in the history
  • Loading branch information
cardigliano committed Feb 14, 2025
1 parent af5e4c1 commit aebd8b4
Show file tree
Hide file tree
Showing 9 changed files with 34 additions and 16 deletions.
2 changes: 1 addition & 1 deletion include/AlertsQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ class AlertsQueue {
void pushBroadcastDomainTooLargeAlert(const u_int8_t *src_mac,
const u_int8_t *dst_mac, u_int32_t spa,
u_int32_t tpa, u_int16_t vlan_id);
void pushLoginTrace(const char *user, bool authorized);
void pushLoginTrace(const char *user, const char *method, bool authorized);
void pushNfqFlushedAlert(int queue_len, int queue_len_pct, int queue_dropped);
void pushCloudDisconnectionAlert(const char *descr);
void pushCloudReconnectionAlert(const char *descr);
Expand Down
2 changes: 1 addition & 1 deletion include/HTTPserver.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class HTTPserver {

bool valid_user_pwd(char *user, char *pass);
static bool authorized_localhost_user_login(const struct mg_connection *conn);
static void traceLogin(const char *user, bool authorized);
static void traceLogin(const char *user, const char *method, bool authorized);

bool authorize_noconn(char *username, char *session_id, u_int session_id_size,
u_int session_duration);
Expand Down
1 change: 1 addition & 0 deletions scripts/locales/en.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8645,6 +8645,7 @@ local lang = {
["live_extraction_with_filter"] = "User '%{user}' downloaded traffic from interface %{ifname} from %{from} to %{to} matching filter '%{filter}'.",
["login_not_authorized"] = "Login denied for user '%{user}'.",
["login_successful"] = "User '%{user}' logged in.",
["login_successful_method"] = "User '%{user}' logged in with '%{method}' authentication.",
["password_changed"] = "Password for user '%{pwd_user}' changed by '%{user}' with ip '%{ip}'.",
["recording_disabled"] = "User '%{user}' disabled Traffic Recording on interface %{ifname}.",
["recording_enabled"] = "User '%{user}' enabled Traffic Recording on interface %{ifname}.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,15 @@ alert_login_failed.meta = {

-- @brief Prepare an alert table used to generate the alert
-- @return A table with the alert built
function alert_login_failed:init()
function alert_login_failed:init(params)
-- Call the parent constructor
self.super:init()

self.alert_type_params = {}
self.alert_type_params = {
params = {
method = params.method
}
}
end

-- #######################################################
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ function alert_user_activity:init(scope, name, params, remote_addr, status)
self.alert_type_params = {
scope = scope,
name = name,
params = params,
params = {
method = params.method
},
remote_addr = remote_addr,
status = status,
}
Expand All @@ -55,12 +57,16 @@ end
function alert_user_activity.format(ifid, alert, alert_type_params)
local decoded = alert_type_params
local user = alert.user or alert.entity_val

if decoded.scope ~= nil then

if decoded.scope == 'login' and decoded.status ~= nil then
if decoded.status == 'authorized' then
return i18n('user_activity.login_successful', {user=user})
if decoded.params and decoded.params['method'] then
return i18n('user_activity.login_successful_method', {user=user, method=decoded.params['method']})
else
return i18n('user_activity.login_successful', {user=user})
end
else
return i18n('user_activity.login_not_authorized', {user=user})
end
Expand Down
4 changes: 2 additions & 2 deletions scripts/lua/modules/notifications/recipients.lua
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ local function processStoreAlertFromQueue(alert)
type_info:set_subtype(string.format("%s_%s_%s", alert.ip, alert.old_mac, alert.new_mac))
elseif (alert.alert_id == "login_failed") then
entity_info = alert_entity_builders.userEntity(alert.user)
type_info = alert_consts.alert_types.alert_login_failed.new()
type_info = alert_consts.alert_types.alert_login_failed.new(alert)
type_info:set_score_warning()
elseif (alert.alert_id == "broadcast_domain_too_large") then
entity_info = alert_entity_builders.macEntity(alert.src_mac)
Expand All @@ -121,7 +121,7 @@ local function processStoreAlertFromQueue(alert)
alert.tpa))
elseif ((alert.alert_id == "user_activity") and (alert.scope == "login")) then
entity_info = alert_entity_builders.userEntity(alert.user)
type_info = alert_consts.alert_types.alert_user_activity.new("login", nil, nil, nil, "authorized")
type_info = alert_consts.alert_types.alert_user_activity.new("login", nil, alert, nil, "authorized")
type_info:set_score_notice()
type_info:set_subtype("login//")
elseif (alert.alert_id == "nfq_flushed") then
Expand Down
4 changes: 3 additions & 1 deletion src/AlertsQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ void AlertsQueue::pushBroadcastDomainTooLargeAlert(const u_int8_t *src_mac,

/* **************************************************** */

void AlertsQueue::pushLoginTrace(const char *user, bool authorized) {
void AlertsQueue::pushLoginTrace(const char *user, const char *method, bool authorized) {
ndpi_serializer *tlv;

if (ntop->getPrefs()->are_alerts_disabled()) return;
Expand All @@ -182,6 +182,8 @@ void AlertsQueue::pushLoginTrace(const char *user, bool authorized) {

ndpi_serialize_string_string(tlv, "scope", "login");
ndpi_serialize_string_string(tlv, "user", user);
if (method)
ndpi_serialize_string_string(tlv, "method", method);

pushAlertJson(tlv, authorized ? "user_activity" : "login_failed", NULL, alert_category_system);
}
Expand Down
6 changes: 3 additions & 3 deletions src/HTTPserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,11 +196,11 @@ bool HTTPserver::authorized_localhost_user_login(

/* ****************************************** */

void HTTPserver::traceLogin(const char *user, bool authorized) {
void HTTPserver::traceLogin(const char *user, const char *method, bool authorized) {
if (ntop->getSystemInterface()
/* Can be NULL during startup so check is necessary */
&& ntop->getSystemInterface()->getAlertsQueue())
ntop->getSystemInterface()->getAlertsQueue()->pushLoginTrace(user, authorized);
ntop->getSystemInterface()->getAlertsQueue()->pushLoginTrace(user, method, authorized);
}

/* ****************************************** */
Expand Down Expand Up @@ -242,7 +242,7 @@ static void create_session(const char *user, const char *group, bool localuser,
ntop->getTrace()->traceEvent(TRACE_INFO, "[HTTP] Set session sessions.%s",
session_id);

HTTPserver::traceLogin(user, true);
HTTPserver::traceLogin(user, localuser ? "local" : "remote", true);
}

/* ****************************************** */
Expand Down
11 changes: 8 additions & 3 deletions src/Ntop.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1988,7 +1988,8 @@ bool Ntop::checkGuiUserPassword(struct mg_connection *conn, const char *user,
if (ntop->isCaptivePortalUser(user)) {
ntop->getTrace()->traceEvent(
TRACE_WARNING, "User %s is not a gui user. Login is denied.", user);
return false;
rv = false;
goto failure;
}

remote_ip = client_addr.print(ipbuf, sizeof(ipbuf));
Expand All @@ -2013,9 +2014,13 @@ bool Ntop::checkGuiUserPassword(struct mg_connection *conn, const char *user,
TRACE_INFO, "IP %s is now blacklisted from login for %d seconds",
remote_ip, FAILED_LOGIN_ATTEMPTS_INTERVAL);

HTTPserver::traceLogin(user, false);
} else
} else {
ntop->getRedis()->del(key);
}

failure:
if (!rv)
HTTPserver::traceLogin(user, NULL, false);

return (rv);
}
Expand Down

0 comments on commit aebd8b4

Please sign in to comment.