Mini Shell
from defence360agent import utils
from defence360agent.contracts.messages import (
Accumulatable,
Message,
MessageList,
Received,
Reportable,
ShortenReprListMixin,
)
from im360.contracts.message_pb2 import WebShieldData
from defence360agent.utils.validate import IP
HIGHEST_PRIORITY = 0
class StrategyChange(Message):
"""The message is generated when an IDS change is detected."""
DEFAULT_METHOD = "STRATEGY_CHANGE"
PRIORITY = HIGHEST_PRIORITY
class SensorIncident(Message):
"""Single incident, e.g. user auth failed once"""
DEFAULT_METHOD = "INCIDENT"
class SensorIncidentList(MessageList, Reportable):
"""Aggregated incident list"""
DEFAULT_METHOD = "INCIDENT_LIST"
class UnreportableLocalIncidentList(MessageList):
"""Aggregate local incident list that are not reported to server"""
DEFAULT_METHOD = "LOCALINCIDENT_LIST"
class LocalIncidentList(MessageList, Reportable):
"""Aggregate local incident list - where no ip provided"""
DEFAULT_METHOD = "INCIDENT_LIST"
class SensorAlert(Message, Reportable):
"""Alert incident, e.g. user auth failures reached threshold"""
DEFAULT_METHOD = "ALERT"
PRIORITY = 1
@classmethod
def from_incident(cls, message):
"""When generate ALERT from INCIDENT change method"""
new_message = message.copy()
new_message["method"] = cls.DEFAULT_METHOD
return cls(**new_message)
class ClientUnblock(Message, Reportable):
DEFAULT_METHOD = "UNBLOCK"
PRIORITY = HIGHEST_PRIORITY
class CaptchaEventList(ShortenReprListMixin, Message, Reportable):
DEFAULT_METHOD = "CAPTCHA_LIST"
class CaptchaEvent(Accumulatable):
DEFAULT_METHOD = "CAPTCHA"
FAILED = "FAILED"
PASSED = "PASSED"
REQUESTED = "REQUESTED"
LIST_CLASS = CaptchaEventList
@classmethod
def from_parcel(cls, parcel):
if parcel.websh.captcha == WebShieldData.NA:
return None
return cls(
timestamp=parcel.timestamp,
attackers_ip=parcel.ip,
event=WebShieldData.Captcha.Name(parcel.websh.captcha),
user_id=parcel.websh.user_id,
plugin_id="captcha",
)
class CaptchaDosAlert(Message):
DEFAULT_METHOD = "CAPTCHA_DOS_ALERT"
PRIORITY = 1
class SynclistResponse(Message, Received):
DEFAULT_METHOD = "SYNCLIST"
PRIORITY = 2
@utils.sync.timefun(
action="SynclistResponse{str->IP.adopt_to_ipvX_network}"
)
def __init__(self, *args, **kwargs):
"""
Do str -> Union[IPv4Network, IPv6Network]
conversion only once per SynclistResponse message processing
:raise ValueError: if str keys to IPv4Network,
IPv6Network conversion fails
"""
super().__init__(*args, **kwargs)
for field in ["blocklist", "unblocklist"]:
self[field] = {
IP.adopt_to_ipvX_network(ip_str): dict_
for ip_str, dict_ in self[field].items()
}
@staticmethod
def filter_blocklist(ips: dict, *, action_type: str):
"""Given [un]blocklist *ips* with their properties return ips
matching given *action_type*.
ip without an action type set matches any action type.
"""
return (
ip
for ip, p in (ips.items() if ips else [])
if not p # no properties
or "action_type" not in p # no action_type
or p["action_type"] == action_type # with given action_type
)
class SynclistRequest(Message, Reportable):
DEFAULT_METHOD = "SYNCLIST"
class BlockUnblockList(Message):
"""Used internally for block/unblock ip from lists
{
"blocklist": {(IPNetwork, "listname"): {"expiration": int}},
"unblocklist": [(IPNetwork,"listname")] ,
}
If ip is present in both lists: first unblock then block it
(upsert semantics if applicable).
"""
DEFAULT_METHOD = "BLOCK_UNBLOCK"
PRIORITY = HIGHEST_PRIORITY
class ProactiveQueueList(MessageList, Reportable):
DEFAULT_METHOD = "PROACTIVE_QUEUE_LIST"
class RuleDisabled(Message, Reportable):
"""
Rule disabled by customer
"""
DEFAULT_METHOD = "RULE_DISABLED"
class RuleEnabled(Message, Reportable):
"""
Rule enabled back
"""
DEFAULT_METHOD = "RULE_ENABLED"
class ConfigSet(Message, Received):
"""Updates to the agent's config."""
RECEIVED_ACTIONS = ["CONFIG_SET"]
class UpdateCustomLists(Message):
"""
Send message for class RealProtector for updating custom ip white and
black list
"""
DEFAULT_METHOD = "UPDATE_CUSTOM_LISTS"
class IPListsUpdate(Message):
"""
Send message for iplists plugin for updating IPs purposed lists
"""
DEFAULT_METHOD = "IP_LISTS_UPDATE"
class GroupIPSync(Message, Reportable):
DEFAULT_METHOD = "GROUP_SYNC"
class GroupIPSyncPush(Message, Received):
DEFAULT_METHOD = "GROUP_SYNC"
class EnduserPasswordReset(Message, Received):
DEFAULT_METHOD = "ENDUSER_PASSWORD_RESET"
class WhitelistCacheUpdate(Message):
"""Receiveing this message indicates that resident part should clear whitelist cache"""
DEFAULT_METHOD = "WHITELIST_CACHE_UPDATE"
class IpsetUpdate(Message):
"""Receiveing this message indicates that resident part should check ipsets consistency"""
DEFAULT_METHOD = "IPSET_UPDATE"
class BlockedPortUpdate(Message):
"""Receiveing this message indicates that resident part should update blockedport"""
DEFAULT_METHOD = "BLOCKED_PORT_UPDATE"
class BlockedPortIPUpdate(Message):
"""Receiveing this message indicates that resident part should update blockedportip"""
DEFAULT_METHOD = "BLOCKED_PORT_IP_UPDATE"