����JFIF���������
__ __ __ __ _____ _ _ _____ _ _ _ | \/ | \ \ / / | __ \ (_) | | / ____| | | | | | \ / |_ __\ V / | |__) | __ ___ ____ _| |_ ___ | (___ | |__ ___| | | | |\/| | '__|> < | ___/ '__| \ \ / / _` | __/ _ \ \___ \| '_ \ / _ \ | | | | | | |_ / . \ | | | | | |\ V / (_| | || __/ ____) | | | | __/ | | |_| |_|_(_)_/ \_\ |_| |_| |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1 if you need WebShell for Seo everyday contact me on Telegram Telegram Address : @jackleetFor_More_Tools:
import asyncio
import json
import logging
import os
import time
from collections import namedtuple
from datetime import date, datetime, timedelta
from functools import wraps
from ipaddress import IPv4Network, IPv6Network, ip_network
from pathlib import Path
import jsonschema
from defence360agent.rpc_tools.validate import (
SchemaValidator as SchemaValidatorBase,
)
from defence360agent.rpc_tools.validate import validate
from im360.contracts.config import Webshield
from im360.internals.core import IPSetPort, libipset
from defence360agent.utils.validate import IP
logger = logging.getLogger(__name__)
TODAY = "today"
YESTERDAY = "yesterday"
PortProtoBase = namedtuple("PortProtoBase", ["port", "proto"])
PeriodBase = namedtuple("PeriodBase", ["since", "to"])
class PortProto(PortProtoBase):
def __new__(cls, port, proto):
if proto not in IPSetPort.PROTOS:
raise ValueError("Protocol {} is not supported".format(proto))
if not (IPSetPort.MIN_PORT < port < IPSetPort.MAX_PORT):
raise ValueError("Port {} is incorrect".format(port))
return super().__new__(cls, port, proto)
@classmethod
def fromstring(cls, pp_string):
try:
port, proto = pp_string.split(":")
port = int(port)
return cls(port, proto)
except ValueError as e:
raise ValueError(
"Incorrect port_proto ({}): {}".format(str(e), pp_string)
)
class Period(PeriodBase):
def __new__(cls, since, to):
try:
datetime.fromtimestamp(since), datetime.fromtimestamp(to)
except ValueError as e:
raise ValueError("Incorrect value for period: {}".format(str(e)))
return super().__new__(cls, since, to)
@classmethod
def fromstring(cls, period_string):
now = datetime.now()
seconds_since_midnight = (
now - now.replace(hour=0, minute=0, second=0, microsecond=0)
).total_seconds()
if period_string == TODAY:
since, to = time.time() - seconds_since_midnight, time.time()
elif period_string == YESTERDAY:
from_date = (
time.time()
- seconds_since_midnight
- timedelta(days=1).total_seconds()
)
to_date = time.time() - seconds_since_midnight
since, to = from_date, to_date
else:
period_names = "weeks", "days", "hours", "minutes", "seconds"
try:
val, sfx = int(period_string[:-1]), period_string[-1:]
except (ValueError, IndexError) as e:
raise ValueError(
"Invalid string from period: {} ({})".format(
period_string, str(e)
)
)
if not sfx.endswith(tuple(p_name[0] for p_name in period_names)):
# argparse will handle this exception
raise ValueError("Invalid suffix: {}".format(sfx))
sfx_expanded = next(xp for xp in period_names if sfx == xp[0])
real_args = {sfx_expanded: val}
since, to = (
(datetime.now() - timedelta(**real_args)).timestamp(),
time.time(),
)
return cls(since, to)
class SchemaValidator(SchemaValidatorBase):
MAX_IPSET_TIMEOUT = libipset.IPSET_TIMEOUT_MAX # ipset's maximum ttl
def _normalize_coerce_port_proto(self, value):
if isinstance(value, PortProto):
return value
elif isinstance(value, str):
return PortProto.fromstring(value)
raise ValueError("String or PortProto must be provided")
def _normalize_coerce_ip(self, value):
if isinstance(value, (IPv4Network, IPv6Network)):
return value
elif isinstance(value, str):
return ip_network(value)
def _normalize_coerce_ip_discard_host_bits(self, value):
if isinstance(value, (IPv4Network, IPv6Network)):
return value
elif isinstance(value, str):
return ip_network(value, strict=False)
def _normalize_coerce_period(self, value):
if isinstance(value, Period):
return value
elif isinstance(value, str):
return Period.fromstring(value)
raise ValueError("String or Period must be provided")
def _normalize_coerce_tolower(self, value):
# please, don't try to casefold() instead of lower()
# see https://tools.ietf.org/html/rfc4343
return value.lower()
def _validate_type_port_proto(self, value):
if isinstance(value, PortProto):
return True
return False
def _validate_type_period(self, value):
if isinstance(value, Period):
return True
return False
def _validate_type_ip(self, value):
return isinstance(value, (IPv4Network, IPv6Network))
def _validator_enforce64min_subnet_mask_for_ipv6(self, field, value):
if IP.is_valid_ipv6_network(value):
# 64 - min subnet mask for ipv6 addr
if IPv6Network(value).prefixlen > 64:
self._error(
field, "Supported only ipv6 /64 networks: {}".format(value)
)
def _validator_max_days(self, field, value):
max_days = timedelta.max.days
max_past = date.today() - date(1970, 1, 1)
if value > max_days or timedelta(days=value) > max_past:
self._error(
field,
"Number of days ({}) exceeds maximum value of {}. "
"Please, specify lesser amount of days".format(
value, max_past.days
),
)
def _validator_expiration(self, field, value):
if not value:
return
expiration_time = value
now = time.time()
if expiration_time <= now:
self._error(
field,
"Expiration contains expired timestamp {}!".format(
time.strftime("%x %X %Z", time.gmtime(expiration_time))
),
)
max_expiration_time = now + self.MAX_IPSET_TIMEOUT
if expiration_time > max_expiration_time:
self._error(
field,
(
"Expiration time {} is too far into the future."
" It is more than {} seconds from now"
).format(expiration_time, self.MAX_IPSET_TIMEOUT),
)
def _validator_webshield_is_enabled(self, field, value):
if not Webshield.ENABLE:
self._error(
field,
"This command is not supported when webshield is disabled",
)
def validate_middleware(validator):
base = Path(os.path.dirname(__file__)) / "../.."
core_schemas = base / "defence360agent/simple_rpc/schema_responses/another"
imav_schemas = base / "imav/simple_rpc/schema_responses/another"
im360_schemas = base / "im360/simple_rpc/schema_responses/another"
def get_file_from_schema_responses_dirs(filename):
core_schema_path = core_schemas.with_name(filename)
if core_schema_path.exists():
return core_schema_path
imav_schema_path = imav_schemas.with_name(filename)
if imav_schema_path.exists():
return imav_schema_path
return im360_schemas.with_name(filename)
def get_response_schema(return_type):
schema_path = get_file_from_schema_responses_dirs(
return_type + ".json"
)
try:
with schema_path.open("r") as f:
return json.load(f)
except FileNotFoundError:
logger.warning("Schema file not found: %s", schema_path)
return None
async def validate_response(hashable, result):
return_type = validator.schema.get(hashable).get("return_type", None)
if return_type is None:
return
schema = get_response_schema(return_type)
if schema is None:
return
# validation should be performed after
# result gets such format (ui accepts it)
# in some cases result never gets such format
# like test_addmany_invalid_request
target = {"result": "success", "messages": [], "data": result}
try:
jsonschema.validate(target, schema)
except jsonschema.ValidationError as error:
logger.critical(
'Validating %r using schema %r failed with error "%s".',
target,
schema,
error,
exc_info=error,
)
def wrapped(f):
@wraps(f)
async def wrapper(request, *args, **kwargs):
hashable = tuple(request["command"])
request["params"] = validate(
validator, hashable, request["params"]
)
result = await f(request, *args, **kwargs)
# no cpu overhead during rpc request
# since validation is asynchronous
# (only next request may be delayed a little)
# run_until_complete waits until this task will be finished (why?)
# so test will be failed
asyncio.ensure_future(validate_response(hashable, result))
return result
return wrapper
return wrapped
| Name | Type | Size | Permission | Actions |
|---|---|---|---|---|
| __pycache__ | Folder | 0755 |
|
|
| schema | Folder | 0755 |
|
|
| schema_responses | Folder | 0755 |
|
|
| __init__.py | File | 0 B | 0644 |
|
| configuration_management.py | File | 3.12 KB | 0644 |
|
| conflicts.py | File | 3.21 KB | 0644 |
|
| control_panel.py | File | 484 B | 0644 |
|
| countries.py | File | 5.72 KB | 0644 |
|
| csf_imports.py | File | 2.63 KB | 0644 |
|
| custom_lists.py | File | 642 B | 0644 |
|
| disabled_rules.py | File | 7.47 KB | 0644 |
|
| feature.py | File | 1.9 KB | 0644 |
|
| health.py | File | 343 B | 0644 |
|
| hosting_panel.py | File | 2.73 KB | 0644 |
|
| incidents.py | File | 1.83 KB | 0644 |
|
| kcarectl.py | File | 824 B | 0644 |
|
| lists.py | File | 30.66 KB | 0644 |
|
| malware.py | File | 385 B | 0644 |
|
| middleware.py | File | 1.32 KB | 0644 |
|
| proactive.py | File | 7.91 KB | 0644 |
|
| remote_proxy.py | File | 2.97 KB | 0644 |
|
| resident_socket.py | File | 1.59 KB | 0644 |
|
| schema.py | File | 1.05 KB | 0644 |
|
| smart_advice.py | File | 1.25 KB | 0644 |
|
| smtp_blocking.py | File | 1.72 KB | 0644 |
|
| unavailable_on_freemium.py | File | 354 B | 0644 |
|
| uninstall_cleanup.py | File | 2.42 KB | 0644 |
|
| validate.py | File | 9.19 KB | 0644 |
|
| whitelist_rbl.py | File | 409 B | 0644 |
|
| whitelisted_crawlers.py | File | 1.02 KB | 0644 |
|
| whitelisted_domains.py | File | 821 B | 0644 |
|