atomicshop 2.15.11__py3-none-any.whl → 3.10.5__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.
Files changed (221) hide show
  1. atomicshop/__init__.py +1 -1
  2. atomicshop/{addons/mains → a_mains}/FACT/update_extract.py +3 -2
  3. atomicshop/a_mains/dns_gateway_setting.py +11 -0
  4. atomicshop/a_mains/get_local_tcp_ports.py +85 -0
  5. atomicshop/a_mains/github_wrapper.py +11 -0
  6. atomicshop/a_mains/install_ca_certificate.py +172 -0
  7. atomicshop/a_mains/process_from_port.py +119 -0
  8. atomicshop/a_mains/set_default_dns_gateway.py +90 -0
  9. atomicshop/a_mains/update_config_toml.py +38 -0
  10. atomicshop/basics/ansi_escape_codes.py +3 -1
  11. atomicshop/basics/argparse_template.py +2 -0
  12. atomicshop/basics/booleans.py +27 -30
  13. atomicshop/basics/bytes_arrays.py +43 -0
  14. atomicshop/basics/classes.py +149 -1
  15. atomicshop/basics/enums.py +2 -2
  16. atomicshop/basics/exceptions.py +5 -1
  17. atomicshop/basics/list_of_classes.py +29 -0
  18. atomicshop/basics/multiprocesses.py +374 -50
  19. atomicshop/basics/strings.py +72 -3
  20. atomicshop/basics/threads.py +14 -0
  21. atomicshop/basics/tracebacks.py +13 -3
  22. atomicshop/certificates.py +153 -52
  23. atomicshop/config_init.py +11 -6
  24. atomicshop/console_user_response.py +7 -14
  25. atomicshop/consoles.py +9 -0
  26. atomicshop/datetimes.py +1 -1
  27. atomicshop/diff_check.py +3 -3
  28. atomicshop/dns.py +128 -3
  29. atomicshop/etws/_pywintrace_fix.py +17 -0
  30. atomicshop/etws/trace.py +40 -42
  31. atomicshop/etws/traces/trace_dns.py +56 -44
  32. atomicshop/etws/traces/trace_tcp.py +130 -0
  33. atomicshop/file_io/csvs.py +27 -5
  34. atomicshop/file_io/docxs.py +34 -17
  35. atomicshop/file_io/file_io.py +31 -17
  36. atomicshop/file_io/jsons.py +49 -0
  37. atomicshop/file_io/tomls.py +139 -0
  38. atomicshop/filesystem.py +616 -291
  39. atomicshop/get_process_list.py +3 -3
  40. atomicshop/http_parse.py +149 -93
  41. atomicshop/ip_addresses.py +6 -1
  42. atomicshop/mitm/centered_settings.py +132 -0
  43. atomicshop/mitm/config_static.py +207 -0
  44. atomicshop/mitm/config_toml_editor.py +55 -0
  45. atomicshop/mitm/connection_thread_worker.py +875 -357
  46. atomicshop/mitm/engines/__parent/parser___parent.py +4 -17
  47. atomicshop/mitm/engines/__parent/recorder___parent.py +108 -51
  48. atomicshop/mitm/engines/__parent/requester___parent.py +116 -0
  49. atomicshop/mitm/engines/__parent/responder___parent.py +75 -114
  50. atomicshop/mitm/engines/__reference_general/parser___reference_general.py +10 -7
  51. atomicshop/mitm/engines/__reference_general/recorder___reference_general.py +5 -5
  52. atomicshop/mitm/engines/__reference_general/requester___reference_general.py +47 -0
  53. atomicshop/mitm/engines/__reference_general/responder___reference_general.py +95 -13
  54. atomicshop/mitm/engines/create_module_template.py +58 -14
  55. atomicshop/mitm/import_config.py +359 -139
  56. atomicshop/mitm/initialize_engines.py +160 -80
  57. atomicshop/mitm/message.py +64 -23
  58. atomicshop/mitm/mitm_main.py +892 -0
  59. atomicshop/mitm/recs_files.py +183 -0
  60. atomicshop/mitm/shared_functions.py +4 -10
  61. atomicshop/mitm/ssh_tester.py +82 -0
  62. atomicshop/mitm/statistic_analyzer.py +136 -40
  63. atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py +265 -83
  64. atomicshop/monitor/checks/dns.py +1 -1
  65. atomicshop/networks.py +671 -0
  66. atomicshop/on_exit.py +39 -9
  67. atomicshop/package_mains_processor.py +84 -0
  68. atomicshop/permissions/permissions.py +22 -0
  69. atomicshop/permissions/ubuntu_permissions.py +239 -0
  70. atomicshop/permissions/win_permissions.py +33 -0
  71. atomicshop/print_api.py +24 -42
  72. atomicshop/process.py +24 -6
  73. atomicshop/process_poller/process_pool.py +0 -1
  74. atomicshop/process_poller/simple_process_pool.py +204 -5
  75. atomicshop/python_file_patcher.py +1 -1
  76. atomicshop/python_functions.py +27 -75
  77. atomicshop/speech_recognize.py +8 -0
  78. atomicshop/ssh_remote.py +158 -172
  79. atomicshop/system_resource_monitor.py +61 -47
  80. atomicshop/system_resources.py +8 -8
  81. atomicshop/tempfiles.py +1 -2
  82. atomicshop/urls.py +6 -0
  83. atomicshop/venvs.py +28 -0
  84. atomicshop/versioning.py +27 -0
  85. atomicshop/web.py +98 -27
  86. atomicshop/web_apis/google_custom_search.py +44 -0
  87. atomicshop/web_apis/google_llm.py +188 -0
  88. atomicshop/websocket_parse.py +450 -0
  89. atomicshop/wrappers/certauthw/certauth.py +1 -0
  90. atomicshop/wrappers/cryptographyw.py +29 -8
  91. atomicshop/wrappers/ctyping/etw_winapi/const.py +97 -47
  92. atomicshop/wrappers/ctyping/etw_winapi/etw_functions.py +178 -49
  93. atomicshop/wrappers/ctyping/file_details_winapi.py +67 -0
  94. atomicshop/wrappers/ctyping/msi_windows_installer/cabs.py +2 -1
  95. atomicshop/wrappers/ctyping/msi_windows_installer/extract_msi_main.py +2 -2
  96. atomicshop/wrappers/ctyping/setup_device.py +466 -0
  97. atomicshop/wrappers/ctyping/win_console.py +39 -0
  98. atomicshop/wrappers/dockerw/dockerw.py +113 -2
  99. atomicshop/wrappers/elasticsearchw/config_basic.py +0 -12
  100. atomicshop/wrappers/elasticsearchw/elastic_infra.py +75 -0
  101. atomicshop/wrappers/elasticsearchw/elasticsearchw.py +2 -20
  102. atomicshop/wrappers/factw/get_file_data.py +12 -5
  103. atomicshop/wrappers/factw/install/install_after_restart.py +89 -5
  104. atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py +20 -14
  105. atomicshop/wrappers/githubw.py +537 -54
  106. atomicshop/wrappers/loggingw/consts.py +1 -1
  107. atomicshop/wrappers/loggingw/filters.py +23 -0
  108. atomicshop/wrappers/loggingw/formatters.py +12 -0
  109. atomicshop/wrappers/loggingw/handlers.py +214 -107
  110. atomicshop/wrappers/loggingw/loggers.py +19 -0
  111. atomicshop/wrappers/loggingw/loggingw.py +860 -22
  112. atomicshop/wrappers/loggingw/reading.py +134 -112
  113. atomicshop/wrappers/mongodbw/mongo_infra.py +31 -0
  114. atomicshop/wrappers/mongodbw/mongodbw.py +1324 -36
  115. atomicshop/wrappers/netshw.py +271 -0
  116. atomicshop/wrappers/playwrightw/engine.py +34 -19
  117. atomicshop/wrappers/playwrightw/infra.py +5 -0
  118. atomicshop/wrappers/playwrightw/javascript.py +7 -3
  119. atomicshop/wrappers/playwrightw/keyboard.py +14 -0
  120. atomicshop/wrappers/playwrightw/scenarios.py +172 -5
  121. atomicshop/wrappers/playwrightw/waits.py +9 -7
  122. atomicshop/wrappers/powershell_networking.py +80 -0
  123. atomicshop/wrappers/psutilw/processes.py +37 -1
  124. atomicshop/wrappers/psutilw/psutil_networks.py +85 -0
  125. atomicshop/wrappers/pyopensslw.py +9 -2
  126. atomicshop/wrappers/pywin32w/cert_store.py +116 -0
  127. atomicshop/wrappers/pywin32w/win_event_log/fetch.py +174 -0
  128. atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_create.py +3 -105
  129. atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_terminate.py +3 -57
  130. atomicshop/wrappers/pywin32w/wmis/msft_netipaddress.py +113 -0
  131. atomicshop/wrappers/pywin32w/wmis/win32_networkadapterconfiguration.py +259 -0
  132. atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py +112 -0
  133. atomicshop/wrappers/pywin32w/wmis/wmi_helpers.py +236 -0
  134. atomicshop/wrappers/socketw/accepter.py +21 -7
  135. atomicshop/wrappers/socketw/certificator.py +216 -150
  136. atomicshop/wrappers/socketw/creator.py +190 -50
  137. atomicshop/wrappers/socketw/dns_server.py +491 -182
  138. atomicshop/wrappers/socketw/exception_wrapper.py +45 -52
  139. atomicshop/wrappers/socketw/process_getter.py +86 -0
  140. atomicshop/wrappers/socketw/receiver.py +144 -102
  141. atomicshop/wrappers/socketw/sender.py +65 -35
  142. atomicshop/wrappers/socketw/sni.py +334 -165
  143. atomicshop/wrappers/socketw/socket_base.py +134 -0
  144. atomicshop/wrappers/socketw/socket_client.py +137 -95
  145. atomicshop/wrappers/socketw/socket_server_tester.py +11 -7
  146. atomicshop/wrappers/socketw/socket_wrapper.py +717 -116
  147. atomicshop/wrappers/socketw/ssl_base.py +15 -14
  148. atomicshop/wrappers/socketw/statistics_csv.py +148 -17
  149. atomicshop/wrappers/sysmonw.py +1 -1
  150. atomicshop/wrappers/ubuntu_terminal.py +65 -26
  151. atomicshop/wrappers/win_auditw.py +189 -0
  152. atomicshop/wrappers/winregw/__init__.py +0 -0
  153. atomicshop/wrappers/winregw/winreg_installed_software.py +58 -0
  154. atomicshop/wrappers/winregw/winreg_network.py +232 -0
  155. {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info}/METADATA +31 -51
  156. atomicshop-3.10.5.dist-info/RECORD +306 -0
  157. {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info}/WHEEL +1 -1
  158. atomicshop/_basics_temp.py +0 -101
  159. atomicshop/a_installs/win/fibratus.py +0 -9
  160. atomicshop/a_installs/win/mongodb.py +0 -9
  161. atomicshop/a_installs/win/pycharm.py +0 -9
  162. atomicshop/addons/a_setup_scripts/install_psycopg2_ubuntu.sh +0 -3
  163. atomicshop/addons/a_setup_scripts/install_pywintrace_0.3.cmd +0 -2
  164. atomicshop/addons/mains/__pycache__/install_fibratus_windows.cpython-312.pyc +0 -0
  165. atomicshop/addons/mains/__pycache__/msi_unpacker.cpython-312.pyc +0 -0
  166. atomicshop/addons/mains/install_docker_rootless_ubuntu.py +0 -11
  167. atomicshop/addons/mains/install_docker_ubuntu_main_sudo.py +0 -11
  168. atomicshop/addons/mains/install_elastic_search_and_kibana_ubuntu.py +0 -10
  169. atomicshop/addons/mains/install_wsl_ubuntu_lts_admin.py +0 -9
  170. atomicshop/addons/package_setup/CreateWheel.cmd +0 -7
  171. atomicshop/addons/package_setup/Setup in Edit mode.cmd +0 -6
  172. atomicshop/addons/package_setup/Setup.cmd +0 -7
  173. atomicshop/archiver/_search_in_zip.py +0 -189
  174. atomicshop/archiver/archiver.py +0 -34
  175. atomicshop/archiver/search_in_archive.py +0 -250
  176. atomicshop/archiver/sevenz_app_w.py +0 -86
  177. atomicshop/archiver/sevenzs.py +0 -44
  178. atomicshop/archiver/zips.py +0 -293
  179. atomicshop/file_types.py +0 -24
  180. atomicshop/mitm/config_editor.py +0 -37
  181. atomicshop/mitm/engines/create_module_template_example.py +0 -13
  182. atomicshop/mitm/initialize_mitm_server.py +0 -268
  183. atomicshop/pbtkmultifile_argparse.py +0 -88
  184. atomicshop/permissions.py +0 -151
  185. atomicshop/script_as_string_processor.py +0 -38
  186. atomicshop/ssh_scripts/process_from_ipv4.py +0 -37
  187. atomicshop/ssh_scripts/process_from_port.py +0 -27
  188. atomicshop/wrappers/_process_wrapper_curl.py +0 -27
  189. atomicshop/wrappers/_process_wrapper_tar.py +0 -21
  190. atomicshop/wrappers/dockerw/install_docker.py +0 -209
  191. atomicshop/wrappers/elasticsearchw/infrastructure.py +0 -265
  192. atomicshop/wrappers/elasticsearchw/install_elastic.py +0 -232
  193. atomicshop/wrappers/ffmpegw.py +0 -125
  194. atomicshop/wrappers/fibratusw/install.py +0 -81
  195. atomicshop/wrappers/mongodbw/infrastructure.py +0 -53
  196. atomicshop/wrappers/mongodbw/install_mongodb.py +0 -190
  197. atomicshop/wrappers/msiw.py +0 -149
  198. atomicshop/wrappers/nodejsw/install_nodejs.py +0 -139
  199. atomicshop/wrappers/process_wrapper_pbtk.py +0 -16
  200. atomicshop/wrappers/psutilw/networks.py +0 -45
  201. atomicshop/wrappers/pycharmw.py +0 -81
  202. atomicshop/wrappers/socketw/base.py +0 -59
  203. atomicshop/wrappers/socketw/get_process.py +0 -107
  204. atomicshop/wrappers/wslw.py +0 -191
  205. atomicshop-2.15.11.dist-info/RECORD +0 -302
  206. /atomicshop/{addons/mains → a_mains}/FACT/factw_fact_extractor_docker_image_main_sudo.py +0 -0
  207. /atomicshop/{addons → a_mains/addons}/PlayWrightCodegen.cmd +0 -0
  208. /atomicshop/{addons → a_mains/addons}/ScriptExecution.cmd +0 -0
  209. /atomicshop/{addons → a_mains/addons}/inits/init_to_import_all_modules.py +0 -0
  210. /atomicshop/{addons → a_mains/addons}/process_list/ReadMe.txt +0 -0
  211. /atomicshop/{addons → a_mains/addons}/process_list/compile.cmd +0 -0
  212. /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.dll +0 -0
  213. /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.exp +0 -0
  214. /atomicshop/{addons → a_mains/addons}/process_list/compiled/Win10x64/process_list.lib +0 -0
  215. /atomicshop/{addons → a_mains/addons}/process_list/process_list.cpp +0 -0
  216. /atomicshop/{archiver → permissions}/__init__.py +0 -0
  217. /atomicshop/{wrappers/fibratusw → web_apis}/__init__.py +0 -0
  218. /atomicshop/wrappers/{nodejsw → pywin32w/wmis}/__init__.py +0 -0
  219. /atomicshop/wrappers/pywin32w/{wmi_win32process.py → wmis/win32process.py} +0 -0
  220. {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info/licenses}/LICENSE.txt +0 -0
  221. {atomicshop-2.15.11.dist-info → atomicshop-3.10.5.dist-info}/top_level.txt +0 -0
@@ -1,145 +1,365 @@
1
- import sys
1
+ import os
2
+ from pathlib import Path
3
+ import socket
2
4
 
3
- from ..wrappers.configparserw import ConfigParserWrapper
4
- from .. import filesystem
5
- from ..permissions import is_admin
6
- from ..basics.booleans import check_3_booleans_when_only_1_can_be_true
5
+ from ..print_api import print_api
6
+ from .. import config_init, filesystem, dns
7
+ from ..permissions import permissions
8
+ from ..wrappers.socketw import socket_base
9
+ from ..basics import booleans
7
10
 
11
+ from . import config_static, initialize_engines
8
12
 
9
- class ImportConfig:
13
+
14
+ def import_config_files(
15
+ config_file_path: str,
16
+ print_kwargs: dict = None
17
+ ):
10
18
  """
11
- ImportConfig class is responsible for importing 'config.ini' file and its variables.
19
+ Import the configuration file 'config.toml' and write all the values to 'config_static' dataclasses module.
20
+
21
+ :param config_file_path:
22
+ :param print_kwargs: dict, additional arguments to pass to the print function.
23
+ :return:
12
24
  """
13
25
 
14
- def __init__(self, file_name: str, directory_path: str):
15
- self.directory_path: str = directory_path
16
- self.admin_rights = None
17
- self.config_parser = ConfigParserWrapper(file_name=file_name, directory_path=self.directory_path)
18
- self.config: dict = dict()
19
-
20
- def open(self) -> None:
21
- """
22
- Open configuration file
23
-
24
- :return:
25
- """
26
-
27
- # Read file to dictionary.
28
- self.config_parser.read_to_dict()
29
-
30
- # === Convert string values to python objects. ===
31
- # Auto convert to booleans.
32
- self.config_parser.auto_convert_values(integers=False)
33
- # Convert keys.
34
- self.config_parser.convert_string_values(['listening_port', 'cache_timeout_minutes'], 'int')
35
- self.config_parser.convert_string_values(
36
- ['forwarding_dns_service_ipv4_list___only_for_localhost'], 'list')
37
- self.config_parser.convert_string_values(['listening_port_list'], 'list_of_int')
38
- self.config_parser.convert_string_values(
39
- ['logs_path', 'recordings_path', 'custom_server_certificate_path', 'custom_private_key_path',
40
- 'sni_server_certificates_cache_directory',
41
- 'sni_server_certificate_from_server_socket_download_directory'],
42
- 'path_relative_to_full')
43
-
44
- # Move final dict to local config.
45
- self.config = self.config_parser.config
46
-
47
- self.check_configurations()
48
- self.manipulations_after_import()
49
-
50
- def check_configurations(self):
51
- # Check if both DNS and TCP servers are disabled. ==============================================================
52
- if not self.config['dns']['enable_dns_server'] and not self.config['tcp']['enable_tcp_server']:
53
- print("What are you trying to do? You had disabled both DNS and TCP servers in config ini file.\n"
54
- "Exiting...")
55
- sys.exit()
56
-
57
- # Check [tcp_server] boolean configurations. ===================================================================
58
- if not self.config['tcp']['engines_usage'] and self.config['tcp']['server_response_mode']:
59
- print(
60
- "You can't set [server_response_mode = True], while setting\n"
61
- "[engines_usage = False].\n"
62
- "No engine modules will be loaded - so nothing to respond to.\n"
63
- "Exiting..."
64
- )
65
-
66
- # Check [dns] boolean configurations. ==========================================================================
67
- check_3_booleans_when_only_1_can_be_true(
68
- (self.config['dns']['route_to_tcp_server_only_engine_domains'], 'route_to_tcp_server_only_engine_domains'),
69
- (self.config['dns']['route_to_tcp_server_all_domains'], 'route_to_tcp_server_all_domains'),
70
- (self.config['dns']['regular_resolving'], 'regular_resolving')
71
- )
72
-
73
- check_3_booleans_when_only_1_can_be_true(
74
- (self.config['certificates']['default_server_certificate_usage'], 'default_server_certificate_usage'),
75
- (self.config['certificates']['sni_create_server_certificate_for_each_domain'],
76
- 'sni_create_server_certificate_for_each_domain'),
77
- (self.config['certificates']['custom_server_certificate_usage'], 'custom_server_certificate_usage'))
78
-
79
- if not self.config['certificates']['default_server_certificate_usage'] and \
80
- self.config['certificates']['sni_default_server_certificate_addons']:
81
- print(
82
- f"No point setting [default_server_certificate_addons = True]\n"
83
- f"If you're not going to use default certificates [default_server_certificate_usage = False]\n"
84
- f"Exiting...")
85
- sys.exit()
86
-
87
- if self.config['certificates']['sni_get_server_certificate_from_server_socket'] and \
88
- not self.config['certificates']['sni_create_server_certificate_for_each_domain']:
89
- print("[sni_get_server_certificate_from_server_socket] was set to 'True', "
90
- "but no [sni_create_server_certificate_for_each_domain] was specified.\n"
91
- "Exiting...")
92
- sys.exit()
93
-
94
- if self.config['certificates']['custom_server_certificate_usage'] and \
95
- not self.config['certificates']['custom_server_certificate_path']:
96
- print("[custom_server_certificate_usage] was set to 'True', but no [custom_server_certificate_path] "
97
- "was specified.\n"
98
- "Exiting...")
99
- sys.exit()
100
-
101
- # Check admin right if on localhost ============================================================================
102
- # If the 'config.dns['target_tcp_server_ipv4']' IP address is localhost, then we need to check if the script
103
- # is executed with admin rights. There are some processes that 'psutil' can't get their command line if not
104
- # executed with administrative privileges.
105
- # Also, check Admin privileges only if 'config.tcp['get_process_name']' was set to 'True' in 'config.ini' of
106
- # the script.
107
- if self.config['dns']['target_tcp_server_ipv4'] == "127.0.0.1" and self.config['ssh']['get_process_name']:
108
- self.admin_rights = is_admin()
109
-
110
- # If we're not running with admin rights, prompt to the user and make him decide what to do.
111
- # If he wants to continue running with 'psutil' exceptions or close the script and rerun with admin rights.
112
- if not self.admin_rights:
113
- print("=============================================================")
114
- error_on_admin: str = \
115
- "[!!!] You're running the script in LOCALHOST mode without Administrative Privileges.\n" \
116
- "[!!!] 'psutil' needs them to read Command Lines of system Processes.\n" \
117
- "[!!!] Press [ENTER] to CONTINUE running with errors " \
118
- "on Process Command Line harvesting or rerun the script with Administrative Rights..."
119
- print(error_on_admin)
120
- # Stopping execution and waiting for user's [ENTER] key.
121
- input()
122
- print("=============================================================")
123
-
124
- def manipulations_after_import(self):
125
- # If 'custom_certificate_usage' was set to 'True'.
126
- if self.config['certificates']['custom_server_certificate_usage']:
127
- # Check file existence.
128
- if not filesystem.is_file_exists(file_path=self.config['certificates']['custom_server_certificate_path']):
129
- raise FileNotFoundError
130
-
131
- # And if 'custom_private_key_path' field was populated in [advanced] section, we'll check its existence.
132
- if self.config['certificates']['custom_private_key_path']:
133
- # Check private key file existence.
134
- if not filesystem.is_file_exists(file_path=self.config['certificates']['custom_private_key_path']):
135
- raise FileNotFoundError
136
-
137
- skip_extensions: list = list()
138
- if self.config['skip_extensions']['tls_web_client_authentication']:
139
- skip_extensions.append('1.3.6.1.5.5.7.3.2')
140
- if self.config['skip_extensions']['crl_distribution_points']:
141
- skip_extensions.append('2.5.29.31')
142
- if self.config['skip_extensions']['authority_information_access']:
143
- skip_extensions.append('1.3.6.1.5.5.7.1.1')
144
-
145
- self.config['skip_extensions'] = skip_extensions
26
+ config_toml: dict = config_init.get_config(
27
+ script_directory=str(Path(config_file_path).parent),
28
+ config_file_name=Path(config_file_path).name,
29
+ print_kwargs=print_kwargs or {}
30
+ )
31
+
32
+
33
+ config_static.MainConfig.is_offline = bool(config_toml['dnstcp']['offline'])
34
+ config_static.MainConfig.network_interface = config_toml['dnstcp']['network_interface']
35
+ config_static.MainConfig.is_localhost = bool(config_toml['dnstcp']['localhost'])
36
+ config_static.MainConfig.set_default_dns_gateway = config_toml['dnstcp']['set_default_dns_gateway']
37
+
38
+ config_static.DNSServer.is_enabled = bool(config_toml['dns']['enable'])
39
+ config_static.DNSServer.listening_ipv4 = config_toml['dns']['listening_ipv4']
40
+ config_static.DNSServer.listening_port = config_toml['dns']['listening_port']
41
+ config_static.DNSServer.forwarding_dns_service_ipv4 = config_toml['dns']['forwarding_dns_service_ipv4']
42
+ config_static.DNSServer.cache_timeout_minutes = config_toml['dns']['cache_timeout_minutes']
43
+ config_static.DNSServer.resolve_by_engine = bool(config_toml['dns']['resolve_by_engine'])
44
+ config_static.DNSServer.resolve_regular_pass_thru = bool(config_toml['dns']['resolve_regular_pass_thru'])
45
+ config_static.DNSServer.resolve_all_domains_to_ipv4 = config_toml['dns']['resolve_all_domains_to_ipv4']
46
+
47
+ config_static.TCPServer.is_enabled = bool(config_toml['tcp']['enable'])
48
+ config_static.TCPServer.no_engines_usage_to_listen_addresses = config_toml['tcp']['no_engines_usage_to_listen_addresses']
49
+
50
+ config_static.LogRec.logs_path = config_toml['logrec']['logs_path']
51
+ config_static.LogRec.enable_request_response_recordings_in_logs = bool(config_toml['logrec']['enable_request_response_recordings_in_logs'])
52
+ config_static.LogRec.store_logs_for_x_days = config_toml['logrec']['store_logs_for_x_days']
53
+
54
+ config_static.Certificates.install_ca_certificate_to_root_store = bool(config_toml['certificates']['install_ca_certificate_to_root_store'])
55
+ config_static.Certificates.uninstall_unused_ca_certificates_with_mitm_ca_name = bool(config_toml['certificates']['uninstall_unused_ca_certificates_with_mitm_ca_name'])
56
+ config_static.Certificates.default_server_certificate_usage = bool(config_toml['certificates']['default_server_certificate_usage'])
57
+ config_static.Certificates.sni_add_new_domains_to_default_server_certificate = bool(config_toml['certificates']['sni_add_new_domains_to_default_server_certificate'])
58
+ config_static.Certificates.custom_server_certificate_usage = bool(config_toml['certificates']['custom_server_certificate_usage'])
59
+ config_static.Certificates.custom_server_certificate_path = config_toml['certificates']['custom_server_certificate_path']
60
+ config_static.Certificates.custom_private_key_path = config_toml['certificates']['custom_private_key_path']
61
+ config_static.Certificates.sni_create_server_certificate_for_each_domain = bool(config_toml['certificates']['sni_create_server_certificate_for_each_domain'])
62
+ config_static.Certificates.sni_server_certificates_cache_directory = config_toml['certificates']['sni_server_certificates_cache_directory']
63
+ config_static.Certificates.sni_get_server_certificate_from_server_socket = bool(config_toml['certificates']['sni_get_server_certificate_from_server_socket'])
64
+ config_static.Certificates.sni_server_certificate_from_server_socket_download_directory = config_toml['certificates']['sni_server_certificate_from_server_socket_download_directory']
65
+
66
+ config_static.SkipExtensions.tls_web_client_authentication = bool(config_toml['skip_extensions']['tls_web_client_authentication'])
67
+ config_static.SkipExtensions.crl_distribution_points = bool(config_toml['skip_extensions']['crl_distribution_points'])
68
+ config_static.SkipExtensions.authority_information_access = bool(config_toml['skip_extensions']['authority_information_access'])
69
+
70
+ config_static.ProcessName.get_process_name = bool(config_toml['process_name']['get_process_name'])
71
+ config_static.ProcessName.ssh_user = config_toml['process_name']['ssh_user']
72
+ config_static.ProcessName.ssh_pass = config_toml['process_name']['ssh_pass']
73
+
74
+
75
+ manipulations_after_import()
76
+
77
+ result = import_engines_configs(print_kwargs=print_kwargs or {})
78
+ if result != 0:
79
+ return result
80
+
81
+ result = check_configurations()
82
+ return result
83
+
84
+
85
+ def import_engines_configs(print_kwargs: dict) -> int:
86
+ """
87
+ Import the engines configuration files and write all the values to 'config_static' dataclasses module.
88
+
89
+ :return: int, status code.
90
+ """
91
+
92
+ # Get full paths of all the 'engine_config.ini' files.
93
+ engine_config_path_list = filesystem.get_paths_from_directory(
94
+ directory_path=config_static.MainConfig.ENGINES_DIRECTORY_PATH,
95
+ get_file=True,
96
+ file_name_check_pattern=config_static.MainConfig.ENGINE_CONFIG_FILE_NAME)
97
+
98
+ # Iterate through all the 'engine_config.ini' file paths.
99
+ domains_engine_list_full: list = list()
100
+ engines_list: list = list()
101
+ for engine_config_path in engine_config_path_list:
102
+ # Initialize engine.
103
+ current_module: initialize_engines.ModuleCategory = initialize_engines.ModuleCategory(config_static.MainConfig.SCRIPT_DIRECTORY)
104
+ rc, error = current_module.fill_engine_fields_from_config(engine_config_path.path, print_kwargs=print_kwargs or {})
105
+ if rc != 0:
106
+ print_api(f"Error reading engine config file: {engine_config_path.path}\n{error}", color='red')
107
+ return rc
108
+ rc, error = current_module.initialize_engine(print_kwargs=print_kwargs or {})
109
+ if rc != 0:
110
+ print_api(f"Error initializing engine from directory: {Path(engine_config_path.path).parent}\n{error}", color='red')
111
+ return rc
112
+
113
+ # Extending the full engine domain list with this list.
114
+ domains_engine_list_full.extend(current_module.domain_list)
115
+ # Append the object to the engines list
116
+ engines_list.append(current_module)
117
+ # === EOF Importing engine modules =============================================================================
118
+ # ==== Initialize Reference Module =============================================================================
119
+ reference_module: initialize_engines.ModuleCategory = initialize_engines.ModuleCategory(config_static.MainConfig.SCRIPT_DIRECTORY)
120
+ reference_module.fill_engine_fields_from_general_reference(config_static.MainConfig.ENGINES_DIRECTORY_PATH)
121
+ result_code, error = reference_module.initialize_engine(reference_general=True)
122
+ if result_code != 0:
123
+ print_api(f"Error initializing reference engine from file: {config_static.MainConfig.ENGINES_DIRECTORY_PATH}\n{error}", color='red')
124
+ return result_code
125
+
126
+ # Assigning all the engines domains to all time domains, that will be responsible for adding new domains.
127
+ domains_all_times_with_ports: list[str] = list(domains_engine_list_full)
128
+
129
+ domains_all_times: list[str] = list()
130
+ for domain_and_port in domains_all_times_with_ports:
131
+ domain: str = domain_and_port.split(':')[0]
132
+ if domain not in domains_engine_list_full:
133
+ domains_all_times.append(domain)
134
+
135
+ config_static.Certificates.domains_all_times = domains_all_times
136
+
137
+ config_static.ENGINES_LIST = engines_list
138
+ config_static.REFERENCE_MODULE = reference_module
139
+
140
+ return 0
141
+
142
+
143
+ def check_configurations() -> int:
144
+ """
145
+ Check the configurations from the 'config.toml' file.
146
+ If there are any errors, print them and return 1.
147
+ :return: int, status code.
148
+ """
149
+
150
+ is_admin = permissions.is_admin()
151
+
152
+ # Check if both DNS and TCP servers are disabled. ==============================================================
153
+ if not config_static.DNSServer.is_enabled and not config_static.TCPServer.is_enabled:
154
+ print_api("Both DNS and TCP servers in config ini file, nothing to run. Exiting...", color='red')
155
+ return 1
156
+
157
+ # Checking if listening interfaces were set.
158
+ if not config_static.TCPServer.no_engines_usage_to_listen_addresses_enable:
159
+ # If no engines were found, check if listening interfaces were set in the main config.
160
+ if not config_static.ENGINES_LIST:
161
+ message = (
162
+ "\n"
163
+ "No engines found. Create with [create_template.py].\n"
164
+ "Exiting...")
165
+ print_api(message, color="red")
166
+ return 1
167
+ else:
168
+ if not config_static.TCPServer.no_engines_listening_address_list:
169
+ message = (
170
+ "\n"
171
+ "No listening interfaces. Set [no_engines_usage_to_listen_addresses] in the main [config.toml].\n"
172
+ "Exiting...")
173
+ print_api(message, color="red")
174
+ return 1
175
+
176
+ if not config_static.ENGINES_LIST and config_static.DNSServer.resolve_by_engine:
177
+ error_message = (
178
+ f"No engines were found in: [{config_static.MainConfig.ENGINES_DIRECTORY_PATH}]\n"
179
+ f"But the DNS routing is set to use them for routing.\n"
180
+ f"Please check your DNS routing configuration in the [config.toml] file or create an engine with [create_template.py].")
181
+ print_api(error_message, color="red")
182
+ return 1
183
+
184
+ for engine in config_static.ENGINES_LIST:
185
+ port_list: list[str] = []
186
+ for domain_port in engine.domain_list:
187
+ # Check if the domains has port.
188
+ if ':' not in domain_port:
189
+ message = (
190
+ f"[*] Domain [{domain_port}] doesn't have a port.\n"
191
+ f"Please check your engine configuration file.")
192
+ print_api(message, color="red")
193
+ return 1
194
+ else:
195
+ # Split the domain and port.
196
+ domain, port = domain_port.split(':')
197
+ port_list.append(port)
198
+ # Check if the port is a number.
199
+ if not port.isdigit():
200
+ message = (
201
+ f"[*] Port [{port}] is not a number.\n"
202
+ f"Please check your engine configuration file.")
203
+ print_api(message, color="red")
204
+ return 1
205
+
206
+ # Check if the ports in on_port_connect are unique.
207
+ if engine.on_port_connect:
208
+ ports_on_connect: list[str] = list(engine.on_port_connect.keys())
209
+ # Check if any of the ports in the on_port_connect are not in the domain list.
210
+ ports_in_domain_list: list[str] = []
211
+ for port in ports_on_connect:
212
+ if port in port_list:
213
+ ports_in_domain_list.append(port)
214
+
215
+ if ports_in_domain_list:
216
+ message = (
217
+ f"[*] Ports in [on_port_connect] config in engine_config.toml: {ports_in_domain_list}\n"
218
+ f"are also in the [domains] field.\n"
219
+ f"This is not supported.")
220
+ print_api(message, color="red")
221
+ return 1
222
+
223
+
224
+ if not config_static.MainConfig.is_localhost and not is_admin:
225
+ # If we're not in localhost mode, this means we need to set virtual IPv4 addresses, which requires admin rights.
226
+ message = "In order to run the server in non-localhost mode, administrative rights are required.\nExiting..."
227
+ print_api(message, color='red')
228
+ return 1
229
+
230
+ # Check admin right if on localhost ============================================================================
231
+ # If any of the DNS IP target addresses is localhost loopback, then we need to check if the script
232
+ # is executed with admin rights. There are some processes that 'psutil' can't get their command line if not
233
+ # executed with administrative privileges.
234
+ # Also, check Admin privileges only if 'config.tcp['get_process_name']' was set to 'True' in 'config.ini' of
235
+ # the script.
236
+ if config_static.ProcessName.get_process_name:
237
+ # If the DNS server was set to resolve by engines, we need to check all relevant engine settings.
238
+ if config_static.DNSServer.resolve_by_engine:
239
+ # Check if the DNS target is localhost loopback.
240
+ if config_static.MainConfig.is_localhost and not is_admin:
241
+ message: str = \
242
+ ("Need to run the script with administrative rights to get the process name while TCP "
243
+ "running on the same computer.\nExiting...")
244
+ print_api(message, color='red')
245
+ return 1
246
+ if config_static.DNSServer.resolve_all_domains_to_ipv4:
247
+ if config_static.DNSServer.target_ipv4 in socket_base.THIS_DEVICE_IP_LIST or \
248
+ config_static.DNSServer.target_ipv4.startswith('127.'):
249
+ if not is_admin:
250
+ message: str = \
251
+ ("Need to run the script with administrative rights to get the process name while TCP "
252
+ "running on the same computer.\nExiting...")
253
+ print_api(message, color='red')
254
+ return 1
255
+
256
+ if (config_static.MainConfig.set_default_dns_gateway or
257
+ config_static.MainConfig.set_default_dns_gateway_to_network_interface_ipv4):
258
+ # Get current settings of the DNS gateway.
259
+ is_dns_dynamic, current_dns_gateway = dns.get_default_dns_gateway()
260
+
261
+ if not is_admin:
262
+ if config_static.MainConfig.set_default_dns_gateway:
263
+ ipv4_address_list = config_static.MainConfig.set_default_dns_gateway
264
+ elif config_static.MainConfig.set_default_dns_gateway_to_network_interface_ipv4 and config_static.MainConfig.is_localhost:
265
+ ipv4_address_list = [config_static.MainConfig.default_localhost_dns_gateway_ipv4]
266
+ elif config_static.MainConfig.set_default_dns_gateway_to_network_interface_ipv4 and not config_static.MainConfig.is_localhost:
267
+ ipv4_address_list = [socket.gethostbyname(socket.gethostname())]
268
+ else:
269
+ raise ValueError("Error: DNS gateway configuration is not set.")
270
+
271
+ # If the setting is dynamic or static, but the needed target address is not in the current DNS gateway.
272
+ if (is_dns_dynamic or
273
+ (not is_dns_dynamic and current_dns_gateway != ipv4_address_list)):
274
+ status_string = 'Dynamic' if is_dns_dynamic else 'Static'
275
+ message: str = (
276
+ "Need to run the script with administrative rights to set the default DNS gateway.\n"
277
+ f"Current DNS gateway: {status_string}, {current_dns_gateway}\n"
278
+ f"Target DNS gateway: Static, {ipv4_address_list}")
279
+ print_api(message, color='red')
280
+ return 1
281
+
282
+ if not config_static.DNSServer.resolve_by_engine and not config_static.DNSServer.resolve_regular_pass_thru and not \
283
+ config_static.DNSServer.resolve_all_domains_to_ipv4_enable:
284
+ message: str = (
285
+ "No DNS server resolving settings were set.\n"
286
+ "Please check your DNS server settings in the [config.toml] file.")
287
+ print_api(message, color='red')
288
+ return 1
289
+
290
+ # This is checked directly in the SocketWrapper.
291
+ # if (config_static.Certificates.install_ca_certificate_to_root_store and not is_admin) or \
292
+ # (config_static.Certificates.uninstall_unused_ca_certificates_with_mitm_ca_name and not is_admin):
293
+ # message: str = \
294
+ # "Need to run the script with administrative rights to install or uninstall CA certificate.\nExiting..."
295
+ # print_api(message, color='red')
296
+ # return 1
297
+
298
+ return 0
299
+
300
+
301
+ def manipulations_after_import():
302
+ for key, value in config_static.DNSServer.resolve_all_domains_to_ipv4.items():
303
+ key = bool(int(key))
304
+ config_static.DNSServer.resolve_all_domains_to_ipv4_enable = key
305
+ config_static.DNSServer.target_ipv4 = value
306
+ break
307
+
308
+ if config_static.MainConfig.set_default_dns_gateway:
309
+ if config_static.MainConfig.set_default_dns_gateway[0] == 'l':
310
+ config_static.MainConfig.set_default_dns_gateway_to_localhost = True
311
+ config_static.MainConfig.set_default_dns_gateway = list()
312
+ elif config_static.MainConfig.set_default_dns_gateway[0] == 'n':
313
+ config_static.MainConfig.set_default_dns_gateway_to_network_interface_ipv4 = True
314
+ config_static.MainConfig.set_default_dns_gateway = list()
315
+
316
+ for key, value in config_static.TCPServer.no_engines_usage_to_listen_addresses.items():
317
+ key = bool(int(key))
318
+ # If the key is False, it means that the user doesn't want to use the no_engines_listening_address_list.
319
+ # So, we'll assign an empty list to it.
320
+ if not key:
321
+ config_static.TCPServer.no_engines_usage_to_listen_addresses_enable = False
322
+ config_static.TCPServer.no_engines_listening_address_list = list()
323
+ # If the key is True, it means that the user wants to use the no_engines_listening_address_list.
324
+ else:
325
+ config_static.TCPServer.no_engines_usage_to_listen_addresses_enable = key
326
+ config_static.TCPServer.no_engines_listening_address_list = value
327
+ break
328
+
329
+ # Convert extensions to skip to a list of extension IDs.
330
+ skip_extensions: list = list()
331
+ if config_static.SkipExtensions.tls_web_client_authentication:
332
+ skip_extensions.append('1.3.6.1.5.5.7.3.2')
333
+ if config_static.SkipExtensions.crl_distribution_points:
334
+ skip_extensions.append('2.5.29.31')
335
+ if config_static.SkipExtensions.authority_information_access:
336
+ skip_extensions.append('1.3.6.1.5.5.7.1.1')
337
+ config_static.SkipExtensions.SKIP_EXTENSION_ID_LIST = skip_extensions
338
+
339
+ # If the paths are relative, convert them to absolute paths.
340
+ config_static.LogRec.logs_path = filesystem.check_absolute_path___add_full(
341
+ config_static.LogRec.logs_path, config_static.MainConfig.SCRIPT_DIRECTORY)
342
+ config_static.Certificates.custom_server_certificate_path = filesystem.check_absolute_path___add_full(
343
+ config_static.Certificates.custom_server_certificate_path, config_static.MainConfig.SCRIPT_DIRECTORY)
344
+
345
+ config_static.LogRec.recordings_path = (
346
+ config_static.LogRec.logs_path + os.sep + config_static.LogRec.recordings_directory_name)
347
+
348
+ # At this point the user that sets the config can set it to null or empty string ''. We will make sure
349
+ # that the path is None if it's empty.
350
+ if config_static.Certificates.custom_private_key_path:
351
+ config_static.Certificates.custom_private_key_path = filesystem.check_absolute_path___add_full(
352
+ config_static.Certificates.custom_private_key_path, config_static.MainConfig.SCRIPT_DIRECTORY)
353
+ else:
354
+ # noinspection PyTypeChecker
355
+ config_static.Certificates.custom_private_key_path = None
356
+
357
+ config_static.Certificates.sni_server_certificates_cache_directory = filesystem.check_absolute_path___add_full(
358
+ config_static.Certificates.sni_server_certificates_cache_directory, config_static.MainConfig.SCRIPT_DIRECTORY)
359
+ config_static.Certificates.sni_server_certificate_from_server_socket_download_directory = \
360
+ filesystem.check_absolute_path___add_full(
361
+ config_static.Certificates.sni_server_certificate_from_server_socket_download_directory,
362
+ config_static.MainConfig.SCRIPT_DIRECTORY)
363
+ config_static.Certificates.sslkeylog_file_path = (f"{config_static.LogRec.logs_path}{os.sep}"
364
+ f"{config_static.Certificates.sslkeylog_file_name}")
365
+