atomicshop 2.20.8__py3-none-any.whl → 2.21.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of atomicshop might be problematic. Click here for more details.
- atomicshop/__init__.py +1 -1
- atomicshop/mitm/config_static.py +27 -20
- atomicshop/mitm/connection_thread_worker.py +25 -20
- atomicshop/mitm/engines/create_module_template.py +11 -5
- atomicshop/mitm/engines/create_module_template_main_example.py +13 -0
- atomicshop/mitm/import_config.py +174 -22
- atomicshop/mitm/initialize_engines.py +49 -68
- atomicshop/mitm/mitm_main.py +118 -152
- atomicshop/wrappers/socketw/dns_server.py +92 -68
- atomicshop/wrappers/socketw/socket_client.py +1 -1
- atomicshop/wrappers/socketw/socket_wrapper.py +136 -46
- {atomicshop-2.20.8.dist-info → atomicshop-2.21.0.dist-info}/METADATA +1 -1
- {atomicshop-2.20.8.dist-info → atomicshop-2.21.0.dist-info}/RECORD +16 -16
- atomicshop/mitm/engines/create_module_template_example.py +0 -13
- {atomicshop-2.20.8.dist-info → atomicshop-2.21.0.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.20.8.dist-info → atomicshop-2.21.0.dist-info}/WHEEL +0 -0
- {atomicshop-2.20.8.dist-info → atomicshop-2.21.0.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
atomicshop/mitm/config_static.py
CHANGED
|
@@ -6,16 +6,15 @@ from . import import_config
|
|
|
6
6
|
|
|
7
7
|
# CONFIG = None
|
|
8
8
|
LIST_OF_BOOLEANS: list = [
|
|
9
|
+
('dnstcp', 'offline'),
|
|
9
10
|
('dns', 'enable'),
|
|
10
|
-
('dns', '
|
|
11
|
-
('dns', '
|
|
12
|
-
('dns', '
|
|
13
|
-
('dns', 'resolve_regular'),
|
|
11
|
+
('dns', 'resolve_by_engine'),
|
|
12
|
+
('dns', 'resolve_regular_pass_thru'),
|
|
13
|
+
('dns', 'resolve_all_domains_to_ipv4'),
|
|
14
14
|
('dns', 'set_default_dns_gateway_to_localhost'),
|
|
15
15
|
('dns', 'set_default_dns_gateway_to_default_interface_ipv4'),
|
|
16
16
|
('tcp', 'enable'),
|
|
17
|
-
('tcp', '
|
|
18
|
-
('tcp', 'server_response_mode'),
|
|
17
|
+
('tcp', 'no_engines_usage_to_listen_addresses'),
|
|
19
18
|
('logrec', 'enable_request_response_recordings_in_logs'),
|
|
20
19
|
('certificates', 'install_ca_certificate_to_root_store'),
|
|
21
20
|
('certificates', 'uninstall_unused_ca_certificates_with_mitm_ca_name'),
|
|
@@ -32,6 +31,7 @@ LIST_OF_BOOLEANS: list = [
|
|
|
32
31
|
|
|
33
32
|
|
|
34
33
|
TOML_TO_STATIC_CATEGORIES: dict = {
|
|
34
|
+
'dnstcp': 'MainConfig',
|
|
35
35
|
'dns': 'DNSServer',
|
|
36
36
|
'tcp': 'TCPServer',
|
|
37
37
|
'logrec': 'LogRec',
|
|
@@ -40,6 +40,10 @@ TOML_TO_STATIC_CATEGORIES: dict = {
|
|
|
40
40
|
'process_name': 'ProcessName'
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
# noinspection PyTypeChecker
|
|
44
|
+
ENGINES_LIST: list = None # list[initialize_engines.ModuleCategory]
|
|
45
|
+
REFERENCE_MODULE = None # initialize_engines.ModuleCategory
|
|
46
|
+
|
|
43
47
|
|
|
44
48
|
class MainConfig:
|
|
45
49
|
LOGGER_NAME: str = 'network'
|
|
@@ -61,6 +65,7 @@ class MainConfig:
|
|
|
61
65
|
# Default server certificate file name and path.
|
|
62
66
|
default_server_certificate_filename = f'{default_server_certificate_name}.pem'
|
|
63
67
|
default_server_certificate_filepath: str = None
|
|
68
|
+
offline: bool = False
|
|
64
69
|
|
|
65
70
|
@classmethod
|
|
66
71
|
def update(cls):
|
|
@@ -77,32 +82,34 @@ class DNSServer:
|
|
|
77
82
|
enable: bool
|
|
78
83
|
offline_mode: bool
|
|
79
84
|
|
|
80
|
-
|
|
81
|
-
listening_port: int
|
|
85
|
+
listening_address: str
|
|
82
86
|
forwarding_dns_service_ipv4: str
|
|
83
87
|
cache_timeout_minutes: int
|
|
84
88
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
resolve_by_engine: bool
|
|
90
|
+
resolve_regular_pass_thru: bool
|
|
91
|
+
resolve_all_domains_to_ipv4_enable: bool
|
|
92
|
+
target_ipv4: str
|
|
89
93
|
|
|
90
94
|
set_default_dns_gateway: str
|
|
91
95
|
set_default_dns_gateway_to_localhost: bool
|
|
92
96
|
set_default_dns_gateway_to_default_interface_ipv4: bool
|
|
93
97
|
|
|
98
|
+
# Convertable variables.
|
|
99
|
+
resolve_all_domains_to_ipv4: dict
|
|
100
|
+
|
|
101
|
+
# Static variables.
|
|
102
|
+
forwarding_dns_service_port: int = 53
|
|
103
|
+
|
|
94
104
|
|
|
95
105
|
@dataclass
|
|
96
106
|
class TCPServer:
|
|
97
107
|
enable: bool
|
|
108
|
+
no_engines_usage_to_listen_addresses_enable: bool
|
|
109
|
+
no_engines_listening_address_list: list[str]
|
|
98
110
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
listening_address_list: list[str]
|
|
103
|
-
|
|
104
|
-
forwarding_dns_service_ipv4_list___only_for_localhost: list[str]
|
|
105
|
-
|
|
111
|
+
# Convertable variables.
|
|
112
|
+
no_engines_usage_to_listen_addresses: dict
|
|
106
113
|
|
|
107
114
|
@dataclass
|
|
108
115
|
class LogRec:
|
|
@@ -161,7 +168,7 @@ def load_config(config_toml_file_path: str):
|
|
|
161
168
|
MainConfig.update()
|
|
162
169
|
|
|
163
170
|
# Load the configuration file.
|
|
164
|
-
result = import_config.
|
|
171
|
+
result = import_config.import_config_files(config_toml_file_path)
|
|
165
172
|
return result
|
|
166
173
|
|
|
167
174
|
|
|
@@ -205,7 +205,7 @@ def thread_worker_main(
|
|
|
205
205
|
# If there is a custom certificate for the client for this domain, then we'll use it.
|
|
206
206
|
# noinspection PyTypeChecker
|
|
207
207
|
custom_client_pem_certificate_path: str = None
|
|
208
|
-
for subdomain, pem_file_path in
|
|
208
|
+
for subdomain, pem_file_path in found_domain_module.mtls.items():
|
|
209
209
|
if subdomain == client_message.server_name:
|
|
210
210
|
custom_client_pem_certificate_path = pem_file_path
|
|
211
211
|
break
|
|
@@ -217,8 +217,7 @@ def thread_worker_main(
|
|
|
217
217
|
service_name=client_message.server_name,
|
|
218
218
|
service_port=client_message.destination_port,
|
|
219
219
|
tls=is_tls,
|
|
220
|
-
dns_servers_list=
|
|
221
|
-
config_static.TCPServer.forwarding_dns_service_ipv4_list___only_for_localhost),
|
|
220
|
+
dns_servers_list=[config_static.DNSServer.forwarding_dns_service_ipv4],
|
|
222
221
|
logger=network_logger,
|
|
223
222
|
custom_pem_client_certificate_file_path=custom_client_pem_certificate_path,
|
|
224
223
|
enable_sslkeylogfile_env_to_client_ssl_context=(
|
|
@@ -415,8 +414,8 @@ def thread_worker_main(
|
|
|
415
414
|
finish_thread()
|
|
416
415
|
return
|
|
417
416
|
|
|
418
|
-
# If we're in
|
|
419
|
-
if config_static.
|
|
417
|
+
# If we're in offline mode, execute responder.
|
|
418
|
+
if config_static.MainConfig.offline:
|
|
420
419
|
responder_queue.put(copy.deepcopy(client_message))
|
|
421
420
|
else:
|
|
422
421
|
# if side == 'Client':
|
|
@@ -517,16 +516,22 @@ def thread_worker_main(
|
|
|
517
516
|
|
|
518
517
|
# Loading parser by domain, if there is no parser for current domain - general reference parser is loaded.
|
|
519
518
|
# These should be outside any loop and initialized only once entering the thread.
|
|
520
|
-
|
|
521
|
-
engines_usage=config_static.TCPServer.engines_usage,
|
|
519
|
+
found_domain_module = assign_class_by_domain(
|
|
522
520
|
engines_list=engines_list,
|
|
523
521
|
message_domain_name=server_name,
|
|
524
|
-
reference_module=reference_module
|
|
525
|
-
logger=network_logger
|
|
522
|
+
reference_module=reference_module
|
|
526
523
|
)
|
|
527
|
-
|
|
524
|
+
parser = found_domain_module.parser_class_object
|
|
525
|
+
responder = found_domain_module.responder_class_object
|
|
526
|
+
recorder_no_init = found_domain_module.recorder_class_object
|
|
528
527
|
recorder = recorder_no_init(record_path=config_static.LogRec.recordings_path)
|
|
529
528
|
|
|
529
|
+
network_logger.info(f"Assigned Modules for [{server_name}]: "
|
|
530
|
+
f"{parser.__name__}, "
|
|
531
|
+
f"{responder.__name__}, "
|
|
532
|
+
f"{recorder_no_init.__name__}")
|
|
533
|
+
|
|
534
|
+
|
|
530
535
|
# Initializing the client message object with current thread's data.
|
|
531
536
|
# This is needed only to skip error alerts after 'try'.
|
|
532
537
|
client_message_connection: ClientMessage = ClientMessage()
|
|
@@ -543,18 +548,18 @@ def thread_worker_main(
|
|
|
543
548
|
client_name = socket.gethostbyaddr(client_ip)[0]
|
|
544
549
|
destination_port = client_socket.getsockname()[1]
|
|
545
550
|
|
|
546
|
-
if config_static.
|
|
547
|
-
# If in
|
|
551
|
+
if config_static.MainConfig.offline:
|
|
552
|
+
# If in offline mode, then we'll get the TCP server's input address.
|
|
548
553
|
server_ip = client_socket.getsockname()[0]
|
|
549
554
|
else:
|
|
550
|
-
# If not in
|
|
555
|
+
# If not in offline mode, we will get the ip from the socket that will connect later to the service.
|
|
551
556
|
server_ip = ""
|
|
552
557
|
|
|
553
558
|
network_logger.info(f"Thread Created - Client [{client_ip}:{source_port}] | "
|
|
554
559
|
f"Destination service: [{server_name}:{destination_port}]")
|
|
555
560
|
|
|
556
|
-
# If we're in
|
|
557
|
-
if config_static.
|
|
561
|
+
# If we're in offline mode, we'll start the responder thread.
|
|
562
|
+
if config_static.MainConfig.offline:
|
|
558
563
|
responder_thread: threading.Thread = threading.Thread(
|
|
559
564
|
target=responder_thread_worker, name=f"Thread-{thread_id}-Responder", daemon=True)
|
|
560
565
|
responder_thread.start()
|
|
@@ -567,11 +572,11 @@ def thread_worker_main(
|
|
|
567
572
|
server_receive_count: int = 0
|
|
568
573
|
client_message_connection = client_message_first_start()
|
|
569
574
|
|
|
570
|
-
# If we're not in
|
|
575
|
+
# If we're not in offline mode, then we'll create the client socket to the service.
|
|
571
576
|
# noinspection PyTypeChecker
|
|
572
577
|
connection_error: str = None
|
|
573
578
|
service_socket_instance = None
|
|
574
|
-
if not config_static.
|
|
579
|
+
if not config_static.MainConfig.offline:
|
|
575
580
|
# If "service_client" object is not defined, we'll define it.
|
|
576
581
|
# If it's defined, then there's still active "ssl_socket" with connection to the service domain.
|
|
577
582
|
if not service_client:
|
|
@@ -599,7 +604,7 @@ def thread_worker_main(
|
|
|
599
604
|
client_thread.daemon = True
|
|
600
605
|
client_thread.start()
|
|
601
606
|
|
|
602
|
-
if not config_static.
|
|
607
|
+
if not config_static.MainConfig.offline:
|
|
603
608
|
service_exception_queue: queue.Queue = queue.Queue()
|
|
604
609
|
service_thread = threading.Thread(
|
|
605
610
|
target=receive_send_start, args=(service_socket_instance, client_socket, service_exception_queue),
|
|
@@ -608,7 +613,7 @@ def thread_worker_main(
|
|
|
608
613
|
service_thread.start()
|
|
609
614
|
|
|
610
615
|
client_thread.join()
|
|
611
|
-
if config_static.
|
|
616
|
+
if config_static.MainConfig.offline:
|
|
612
617
|
responder_thread.join()
|
|
613
618
|
else:
|
|
614
619
|
service_thread.join()
|
|
@@ -616,7 +621,7 @@ def thread_worker_main(
|
|
|
616
621
|
# If there was an exception in any of the threads, then we'll raise it here.
|
|
617
622
|
if not client_exception_queue.empty():
|
|
618
623
|
raise client_exception_queue.get()
|
|
619
|
-
if not config_static.
|
|
624
|
+
if not config_static.MainConfig.offline:
|
|
620
625
|
if not service_exception_queue.empty():
|
|
621
626
|
raise service_exception_queue.get()
|
|
622
627
|
|
|
@@ -73,12 +73,18 @@ class CreateModuleTemplate:
|
|
|
73
73
|
|
|
74
74
|
# Add "" to each domain.
|
|
75
75
|
domains_with_quotes: list = [f'"{domain}"' for domain in self.domains]
|
|
76
|
-
|
|
76
|
+
|
|
77
|
+
config_lines_list.append('[engine]')
|
|
78
|
+
config_lines_list.append(f'domains = [{", ".join(domains_with_quotes)}]')
|
|
79
|
+
config_lines_list.append('dns_target = "127.0.0.1"')
|
|
80
|
+
config_lines_list.append('tcp_listening_address_list = ["0.0.0.0:443"]\n')
|
|
81
|
+
# config_lines_list.append(f'\n')
|
|
82
|
+
config_lines_list.append('[mtls]')
|
|
83
|
+
config_lines_list.append('# "subdomain.domain.com" = "file_name_in_current_dir.pem"\n')
|
|
77
84
|
# config_lines_list.append(f'\n')
|
|
78
|
-
config_lines_list.append(
|
|
79
|
-
config_lines_list.append(
|
|
80
|
-
config_lines_list.append(
|
|
81
|
-
config_lines_list.append(f'# "domain" = "example.com"\n')
|
|
85
|
+
config_lines_list.append('[no_sni]')
|
|
86
|
+
config_lines_list.append('get_from_dns = 1 # Blocking, the accept function will wait until the domain is received from DNS.')
|
|
87
|
+
config_lines_list.append('serve_domain_on_address = {0 = [{"example.com" = "127.0.0.2:443"}]}')
|
|
82
88
|
|
|
83
89
|
config_file_path = self.new_engine_directory + os.sep + CONFIG_FILE_NAME
|
|
84
90
|
|
atomicshop/mitm/import_config.py
CHANGED
|
@@ -8,7 +8,7 @@ from ..permissions import permissions
|
|
|
8
8
|
from ..wrappers.socketw import base
|
|
9
9
|
from ..basics import booleans
|
|
10
10
|
|
|
11
|
-
from . import config_static
|
|
11
|
+
from . import config_static, initialize_engines
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
def assign_bool(dict_instance: dict, section: str, key: str):
|
|
@@ -19,16 +19,27 @@ def assign_bool(dict_instance: dict, section: str, key: str):
|
|
|
19
19
|
dict_instance[section][key] = True
|
|
20
20
|
elif dict_instance[section][key] == 0:
|
|
21
21
|
dict_instance[section][key] = False
|
|
22
|
+
elif isinstance(dict_instance[section][key], dict):
|
|
23
|
+
for subkey, subvalue in dict_instance[section][key].items():
|
|
24
|
+
if subkey == '1':
|
|
25
|
+
dict_instance[section][key] = {True: subvalue}
|
|
26
|
+
elif subkey == '0':
|
|
27
|
+
dict_instance[section][key] = {False: subvalue}
|
|
28
|
+
else:
|
|
29
|
+
print_api(f"Error: {section}.{key}.{subkey} must be 0 or 1.", color='red')
|
|
30
|
+
return 1
|
|
31
|
+
break
|
|
22
32
|
else:
|
|
23
33
|
print_api(f"Error: {section}.{key} must be 0 or 1.", color='red')
|
|
24
34
|
return 1
|
|
25
35
|
|
|
26
36
|
|
|
27
|
-
def
|
|
37
|
+
def import_config_files(
|
|
28
38
|
config_file_path: str
|
|
29
39
|
):
|
|
30
40
|
"""
|
|
31
41
|
Import the configuration file 'config.toml' and write all the values to 'config_static' dataclasses module.
|
|
42
|
+
|
|
32
43
|
:param config_file_path:
|
|
33
44
|
:return:
|
|
34
45
|
"""
|
|
@@ -50,10 +61,55 @@ def import_config_file(
|
|
|
50
61
|
|
|
51
62
|
manipulations_after_import()
|
|
52
63
|
|
|
64
|
+
result = import_engines_configs()
|
|
65
|
+
if result != 0:
|
|
66
|
+
return result
|
|
67
|
+
|
|
53
68
|
result = check_configurations()
|
|
54
69
|
return result
|
|
55
70
|
|
|
56
71
|
|
|
72
|
+
def import_engines_configs() -> int:
|
|
73
|
+
"""
|
|
74
|
+
Import the engines configuration files and write all the values to 'config_static' dataclasses module.
|
|
75
|
+
|
|
76
|
+
:return: int, status code.
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
# Get full paths of all the 'engine_config.ini' files.
|
|
80
|
+
engine_config_path_list = filesystem.get_paths_from_directory(
|
|
81
|
+
directory_path=config_static.MainConfig.ENGINES_DIRECTORY_PATH,
|
|
82
|
+
get_file=True,
|
|
83
|
+
file_name_check_pattern=config_static.MainConfig.ENGINE_CONFIG_FILE_NAME)
|
|
84
|
+
|
|
85
|
+
# Iterate through all the 'engine_config.ini' file paths.
|
|
86
|
+
domains_engine_list_full: list = list()
|
|
87
|
+
engines_list: list = list()
|
|
88
|
+
for engine_config_path in engine_config_path_list:
|
|
89
|
+
# Initialize engine.
|
|
90
|
+
current_module: initialize_engines.ModuleCategory = initialize_engines.ModuleCategory(config_static.MainConfig.SCRIPT_DIRECTORY)
|
|
91
|
+
current_module.fill_engine_fields_from_config(engine_config_path.path)
|
|
92
|
+
current_module.initialize_engine()
|
|
93
|
+
|
|
94
|
+
# Extending the full engine domain list with this list.
|
|
95
|
+
domains_engine_list_full.extend(current_module.domain_list)
|
|
96
|
+
# Append the object to the engines list
|
|
97
|
+
engines_list.append(current_module)
|
|
98
|
+
# === EOF Importing engine modules =============================================================================
|
|
99
|
+
# ==== Initialize Reference Module =============================================================================
|
|
100
|
+
reference_module: initialize_engines.ModuleCategory = initialize_engines.ModuleCategory(config_static.MainConfig.SCRIPT_DIRECTORY)
|
|
101
|
+
reference_module.fill_engine_fields_from_general_reference(config_static.MainConfig.ENGINES_DIRECTORY_PATH)
|
|
102
|
+
reference_module.initialize_engine(reference_general=True)
|
|
103
|
+
|
|
104
|
+
# Assigning all the engines domains to all time domains, that will be responsible for adding new domains.
|
|
105
|
+
config_static.Certificates.domains_all_times = list(domains_engine_list_full)
|
|
106
|
+
|
|
107
|
+
config_static.ENGINES_LIST = engines_list
|
|
108
|
+
config_static.REFERENCE_MODULE = reference_module
|
|
109
|
+
|
|
110
|
+
return 0
|
|
111
|
+
|
|
112
|
+
|
|
57
113
|
def check_configurations() -> int:
|
|
58
114
|
"""
|
|
59
115
|
Check the configurations from the 'config.toml' file.
|
|
@@ -68,31 +124,103 @@ def check_configurations() -> int:
|
|
|
68
124
|
print_api("Both DNS and TCP servers in config ini file, nothing to run. Exiting...", color='red')
|
|
69
125
|
return 1
|
|
70
126
|
|
|
71
|
-
#
|
|
72
|
-
if not config_static.TCPServer.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
127
|
+
# Checking if listening interfaces were set.
|
|
128
|
+
if not config_static.TCPServer.no_engines_usage_to_listen_addresses_enable:
|
|
129
|
+
# If no engines were found, check if listening interfaces were set in the main config.
|
|
130
|
+
if not config_static.ENGINES_LIST:
|
|
131
|
+
message = (
|
|
132
|
+
"\n"
|
|
133
|
+
"No engines found. Create with [create_template.py].\n"
|
|
134
|
+
"Exiting...")
|
|
135
|
+
print_api(message, color="red")
|
|
136
|
+
return 1
|
|
137
|
+
else:
|
|
138
|
+
if not config_static.TCPServer.no_engines_listening_address_list:
|
|
139
|
+
message = (
|
|
140
|
+
"\n"
|
|
141
|
+
"No listening interfaces. Set [no_engines_usage_to_listen_addresses] in the main [config.toml].\n"
|
|
142
|
+
"Exiting...")
|
|
143
|
+
print_api(message, color="red")
|
|
144
|
+
return 1
|
|
145
|
+
|
|
146
|
+
if not config_static.ENGINES_LIST and config_static.DNSServer.resolve_by_engine:
|
|
147
|
+
error_message = (
|
|
148
|
+
f"No engines were found in: [{config_static.MainConfig.ENGINES_DIRECTORY_PATH}]\n"
|
|
149
|
+
f"But the DNS routing is set to use them for routing.\n"
|
|
150
|
+
f"Please check your DNS routing configuration in the [config.toml] file or create an engine with [create_template.py].")
|
|
151
|
+
print_api(error_message, color="red")
|
|
78
152
|
return 1
|
|
79
153
|
|
|
154
|
+
for engine in config_static.ENGINES_LIST:
|
|
155
|
+
if engine.no_sni.get_from_dns and engine.no_sni.serve_domain_on_address_enable:
|
|
156
|
+
message = (
|
|
157
|
+
f"Both [get_from_dns] and [serve_domain_on_address] are enabled in [no_sni] section of the engine.\n"
|
|
158
|
+
f"Only one Can be True.")
|
|
159
|
+
print_api(message, color="red")
|
|
160
|
+
return 1
|
|
161
|
+
if not engine.no_sni.get_from_dns and not engine.no_sni.serve_domain_on_address_enable:
|
|
162
|
+
message = (
|
|
163
|
+
f"Both [get_from_dns] and [serve_domain_on_address] are disabled in [no_sni] section of the engine.\n"
|
|
164
|
+
f"Only one Can be True.")
|
|
165
|
+
print_api(message, color="red")
|
|
166
|
+
return 1
|
|
167
|
+
|
|
168
|
+
if engine.no_sni.serve_domain_on_address_enable:
|
|
169
|
+
# Check if the domains in no_sni are the same as in the engine. They should not be.
|
|
170
|
+
# Same goes for the address.
|
|
171
|
+
for domain, address_ip_port in engine.no_sni.serve_domain_on_address_dict.items():
|
|
172
|
+
if domain in engine.domain_list:
|
|
173
|
+
message = (
|
|
174
|
+
f"[*] No SNI setting: The domain [{domain}] is in the engine domains list [{engine.domain_list}].\n"
|
|
175
|
+
f"The point of the no_sni section is to serve specific domains on separate addresses.\n")
|
|
176
|
+
print_api(message, color="red")
|
|
177
|
+
return 1
|
|
178
|
+
|
|
179
|
+
if address_ip_port in engine.tcp_listening_address_list:
|
|
180
|
+
message = (
|
|
181
|
+
f"[*] No SNI setting: The address [{address_ip_port}] is in the engine listening interfaces list [{engine.tcp_listening_address_list}].\n"
|
|
182
|
+
f"The point of the no_sni section is to serve specific domains on separate addresses.\n")
|
|
183
|
+
print_api(message, color="red")
|
|
184
|
+
return 1
|
|
185
|
+
|
|
80
186
|
# Check admin right if on localhost ============================================================================
|
|
81
|
-
# If the
|
|
187
|
+
# If any of the DNS IP target addresses is localhost loopback, then we need to check if the script
|
|
82
188
|
# is executed with admin rights. There are some processes that 'psutil' can't get their command line if not
|
|
83
189
|
# executed with administrative privileges.
|
|
84
190
|
# Also, check Admin privileges only if 'config.tcp['get_process_name']' was set to 'True' in 'config.ini' of
|
|
85
191
|
# the script.
|
|
86
|
-
if
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
192
|
+
if config_static.ProcessName.get_process_name:
|
|
193
|
+
# If the DNS server was set to resolve by engines, we need to check all relevant engine settings.
|
|
194
|
+
if config_static.DNSServer.resolve_by_engine:
|
|
195
|
+
for engine in config_static.ENGINES_LIST:
|
|
196
|
+
# Check if the DNS target is localhost loopback.
|
|
197
|
+
if engine.dns_target in base.THIS_DEVICE_IP_LIST or engine.dns_target.startswith('127.'):
|
|
198
|
+
if not is_admin:
|
|
199
|
+
message: str = \
|
|
200
|
+
("Need to run the script with administrative rights to get the process name while TCP "
|
|
201
|
+
"running on the same computer.\nExiting...")
|
|
202
|
+
print_api(message, color='red')
|
|
203
|
+
return 1
|
|
204
|
+
if engine.no_sni.serve_domain_on_address_enable:
|
|
205
|
+
no_sni_target_address_list: list = engine.no_sni.serve_domain_on_address_dict.values()
|
|
206
|
+
for no_sni_target_address in no_sni_target_address_list:
|
|
207
|
+
if no_sni_target_address in base.THIS_DEVICE_IP_LIST or \
|
|
208
|
+
no_sni_target_address.startswith('127.'):
|
|
209
|
+
if not is_admin:
|
|
210
|
+
message: str = \
|
|
211
|
+
("Need to run the script with administrative rights to get the process name while TCP "
|
|
212
|
+
"running on the same computer.\nExiting...")
|
|
213
|
+
print_api(message, color='red')
|
|
214
|
+
return 1
|
|
215
|
+
if config_static.DNSServer.resolve_all_domains_to_ipv4:
|
|
216
|
+
if config_static.DNSServer.target_ipv4 in base.THIS_DEVICE_IP_LIST or \
|
|
217
|
+
config_static.DNSServer.target_ipv4.startswith('127.'):
|
|
218
|
+
if not is_admin:
|
|
219
|
+
message: str = \
|
|
220
|
+
("Need to run the script with administrative rights to get the process name while TCP "
|
|
221
|
+
"running on the same computer.\nExiting...")
|
|
222
|
+
print_api(message, color='red')
|
|
223
|
+
return 1
|
|
96
224
|
|
|
97
225
|
try:
|
|
98
226
|
booleans.is_only_1_true_in_list(
|
|
@@ -136,6 +264,14 @@ def check_configurations() -> int:
|
|
|
136
264
|
print_api(message, color='red')
|
|
137
265
|
return 1
|
|
138
266
|
|
|
267
|
+
if not config_static.DNSServer.resolve_by_engine and not config_static.DNSServer.resolve_regular_pass_thru and not \
|
|
268
|
+
config_static.DNSServer.resolve_all_domains_to_ipv4_enable:
|
|
269
|
+
message: str = (
|
|
270
|
+
"No DNS server resolving settings were set.\n"
|
|
271
|
+
"Please check your DNS server settings in the [config.toml] file.")
|
|
272
|
+
print_api(message, color='red')
|
|
273
|
+
return 1
|
|
274
|
+
|
|
139
275
|
# This is checked directly in the SocketWrapper.
|
|
140
276
|
# if (config_static.Certificates.install_ca_certificate_to_root_store and not is_admin) or \
|
|
141
277
|
# (config_static.Certificates.uninstall_unused_ca_certificates_with_mitm_ca_name and not is_admin):
|
|
@@ -144,11 +280,27 @@ def check_configurations() -> int:
|
|
|
144
280
|
# print_api(message, color='red')
|
|
145
281
|
# return 1
|
|
146
282
|
|
|
147
|
-
|
|
148
283
|
return 0
|
|
149
284
|
|
|
150
285
|
|
|
151
286
|
def manipulations_after_import():
|
|
287
|
+
for key, value in config_static.DNSServer.resolve_all_domains_to_ipv4.items():
|
|
288
|
+
config_static.DNSServer.resolve_all_domains_to_ipv4_enable = key
|
|
289
|
+
config_static.DNSServer.target_ipv4 = value
|
|
290
|
+
break
|
|
291
|
+
|
|
292
|
+
for key, value in config_static.TCPServer.no_engines_usage_to_listen_addresses.items():
|
|
293
|
+
# If the key is False, it means that the user doesn't want to use the no_engines_listening_address_list.
|
|
294
|
+
# So, we'll assign an empty list to it.
|
|
295
|
+
if not key:
|
|
296
|
+
config_static.TCPServer.no_engines_usage_to_listen_addresses_enable = False
|
|
297
|
+
config_static.TCPServer.no_engines_listening_address_list = list()
|
|
298
|
+
# If the key is True, it means that the user wants to use the no_engines_listening_address_list.
|
|
299
|
+
else:
|
|
300
|
+
config_static.TCPServer.no_engines_usage_to_listen_addresses_enable = key
|
|
301
|
+
config_static.TCPServer.no_engines_listening_address_list = value
|
|
302
|
+
break
|
|
303
|
+
|
|
152
304
|
# Convert extensions to skip to a list of extension IDs.
|
|
153
305
|
skip_extensions: list = list()
|
|
154
306
|
if config_static.SkipExtensions.tls_web_client_authentication:
|
|
@@ -166,7 +318,7 @@ def manipulations_after_import():
|
|
|
166
318
|
config_static.Certificates.custom_server_certificate_path, config_static.MainConfig.SCRIPT_DIRECTORY)
|
|
167
319
|
|
|
168
320
|
config_static.LogRec.recordings_path = (
|
|
169
|
-
|
|
321
|
+
config_static.LogRec.logs_path + os.sep + config_static.LogRec.recordings_directory_name)
|
|
170
322
|
|
|
171
323
|
# At this point the user that sets the config can set it to null or empty string ''. We will make sure
|
|
172
324
|
# that the path is None if it's empty.
|