atomicshop 2.9.13__py3-none-any.whl → 2.9.15__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.
- atomicshop/__init__.py +1 -1
- atomicshop/archiver/__init__.py +0 -0
- atomicshop/basics/booleans.py +3 -3
- atomicshop/filesystem.py +2 -2
- atomicshop/mitm/connection_thread_worker.py +3 -4
- atomicshop/mitm/engines/create_module_template.py +0 -1
- atomicshop/mitm/import_config.py +7 -0
- atomicshop/mitm/initialize_engines.py +29 -25
- atomicshop/mitm/initialize_mitm_server.py +69 -26
- atomicshop/process.py +0 -1
- atomicshop/wrappers/elasticsearchw/config_basic.py +17 -3
- atomicshop/wrappers/elasticsearchw/elasticsearchw.py +1 -1
- atomicshop/wrappers/elasticsearchw/infrastructure.py +213 -0
- atomicshop/wrappers/elasticsearchw/install_elastic.py +225 -0
- atomicshop/wrappers/factw/install/install_after_restart.py +1 -1
- atomicshop/wrappers/ffmpegw.py +1 -1
- atomicshop/wrappers/playwrightw/base.py +0 -2
- atomicshop/wrappers/socketw/dns_server.py +26 -10
- atomicshop/wrappers/ubuntu_terminal.py +110 -3
- {atomicshop-2.9.13.dist-info → atomicshop-2.9.15.dist-info}/METADATA +1 -1
- {atomicshop-2.9.13.dist-info → atomicshop-2.9.15.dist-info}/RECORD +24 -21
- {atomicshop-2.9.13.dist-info → atomicshop-2.9.15.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.9.13.dist-info → atomicshop-2.9.15.dist-info}/WHEEL +0 -0
- {atomicshop-2.9.13.dist-info → atomicshop-2.9.15.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
|
File without changes
|
atomicshop/basics/booleans.py
CHANGED
|
@@ -5,9 +5,9 @@ def check_3_booleans_when_only_1_can_be_true(boolean1: tuple, boolean2: tuple, b
|
|
|
5
5
|
(self.config['section']['default_usage'], 'default_usage'),
|
|
6
6
|
(self.config['section']['create_usage'], 'create_usage'),
|
|
7
7
|
(self.config['section']['custom_usage'], 'custom_usage'))
|
|
8
|
-
:param boolean1: tuple,
|
|
9
|
-
:param boolean2: tuple,
|
|
10
|
-
:param boolean3: tuple,
|
|
8
|
+
:param boolean1: tuple, (value, string name of the setting you want to print to the user to be aware of).
|
|
9
|
+
:param boolean2: tuple, (value, string name of the setting you want to print to the user to be aware of).
|
|
10
|
+
:param boolean3: tuple, (value, string name of the setting you want to print to the user to be aware of).
|
|
11
11
|
:return:
|
|
12
12
|
"""
|
|
13
13
|
|
atomicshop/filesystem.py
CHANGED
|
@@ -1071,12 +1071,12 @@ def create_dict_of_path(
|
|
|
1071
1071
|
parent_entry: str = None
|
|
1072
1072
|
):
|
|
1073
1073
|
"""
|
|
1074
|
-
The function receives a path and a
|
|
1074
|
+
The function receives a path and a list, and adds the path to the list.
|
|
1075
1075
|
|
|
1076
1076
|
Check the working example from 'create_dict_of_paths_list' function.
|
|
1077
1077
|
|
|
1078
1078
|
:param path: string, path.
|
|
1079
|
-
:param
|
|
1079
|
+
:param structure_list: list to add the path to.
|
|
1080
1080
|
:param add_data_to_entry: any, data to add to the entry.
|
|
1081
1081
|
:param add_data_key: string, key to add the data to.
|
|
1082
1082
|
:param parent_entry: string, for internal use to pass the current parent entry.
|
|
@@ -112,10 +112,9 @@ def thread_worker_main(
|
|
|
112
112
|
|
|
113
113
|
# Loading parser by domain, if there is no parser for current domain - general reference parser is loaded.
|
|
114
114
|
# These should be outside any loop and initialized only once entering the thread.
|
|
115
|
-
parser, responder, recorder = assign_class_by_domain(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
logger=network_logger)
|
|
115
|
+
parser, responder, recorder = assign_class_by_domain(
|
|
116
|
+
engines_list, client_message.server_name, reference_module=reference_module, config=config,
|
|
117
|
+
logger=network_logger)
|
|
119
118
|
|
|
120
119
|
# Defining client connection boolean variable to enter the loop
|
|
121
120
|
client_connection_boolean: bool = True
|
atomicshop/mitm/import_config.py
CHANGED
|
@@ -63,6 +63,13 @@ class ImportConfig:
|
|
|
63
63
|
"Exiting..."
|
|
64
64
|
)
|
|
65
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
|
+
|
|
66
73
|
check_3_booleans_when_only_1_can_be_true(
|
|
67
74
|
(self.config['certificates']['default_server_certificate_usage'], 'default_server_certificate_usage'),
|
|
68
75
|
(self.config['certificates']['sni_create_server_certificate_for_each_domain'],
|
|
@@ -89,7 +89,8 @@ class ModuleCategory:
|
|
|
89
89
|
|
|
90
90
|
# Assigning external class object by message domain received from client. If the domain is not in the list,
|
|
91
91
|
# the reference general module will be assigned.
|
|
92
|
-
def assign_class_by_domain(
|
|
92
|
+
def assign_class_by_domain(
|
|
93
|
+
engines_list: list, message_domain_name: str, reference_module, config, logger=None):
|
|
93
94
|
# Defining return variables:
|
|
94
95
|
function_parser = None
|
|
95
96
|
function_responder = None
|
|
@@ -97,30 +98,33 @@ def assign_class_by_domain(engines_list: list, message_domain_name: str, referen
|
|
|
97
98
|
|
|
98
99
|
# In case SNI came empty in the request from client, then there's no point in iterating through engine domains.
|
|
99
100
|
if message_domain_name:
|
|
100
|
-
#
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
#
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
#
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
101
|
+
# If the engines_usage is set to True in the config file, then we'll iterate through the list of engines
|
|
102
|
+
# to find the domain in the list of domains of the engine.
|
|
103
|
+
if config['tcp']['engines_usage']:
|
|
104
|
+
# Checking if current domain is in engines' domain list to activate domain specific engine
|
|
105
|
+
for function_module in engines_list:
|
|
106
|
+
# The list: matches_list = ["domain1.com", "domain2.com", "domain3.com"]
|
|
107
|
+
# The string: a_string = "www.domain1.com"
|
|
108
|
+
# Checking that the message subdomain + domain contains current module's domain name
|
|
109
|
+
# Template Should be like this: if any(x in a_string for x in matches_list):
|
|
110
|
+
|
|
111
|
+
# On the other hand if you want to find if partial string is
|
|
112
|
+
# in the list of strings: if any(a_string in x for x in matches_list):
|
|
113
|
+
# In this case list is the same and string: a_string = domain
|
|
114
|
+
if any(x in message_domain_name for x in function_module.domain_list):
|
|
115
|
+
# Assigning modules by current engine of the domain
|
|
116
|
+
function_parser = function_module.parser_class_object
|
|
117
|
+
function_recorder = function_module.recorder_class_object
|
|
118
|
+
# Since the responder is being initiated only once, we're assigning only the instance
|
|
119
|
+
function_responder = function_module.responder_instance
|
|
120
|
+
|
|
121
|
+
logger.info(f"Assigned Modules for [{message_domain_name}]: "
|
|
122
|
+
f"{function_module.parser_class_object.__name__}, "
|
|
123
|
+
f"{function_module.responder_class_object.__name__}, "
|
|
124
|
+
f"{function_module.recorder_class_object.__name__}")
|
|
125
|
+
|
|
126
|
+
# If the domain was found in the current list of class domains, we can stop the loop
|
|
127
|
+
break
|
|
124
128
|
|
|
125
129
|
# If none of the domains were found in the engine domains list, then we'll assign reference module.
|
|
126
130
|
# It's enough to check only parser, since responder and recorder also will be empty.
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import threading
|
|
3
3
|
|
|
4
|
+
# Importing atomicshop package to get the version of the package.
|
|
4
5
|
import atomicshop
|
|
5
|
-
|
|
6
|
+
|
|
6
7
|
from .import_config import ImportConfig
|
|
7
8
|
from .initialize_engines import ModuleCategory
|
|
8
9
|
from .connection_thread_worker import thread_worker_main
|
|
@@ -12,6 +13,7 @@ from ..wrappers.socketw.socket_wrapper import SocketWrapper
|
|
|
12
13
|
from ..wrappers.socketw.dns_server import DnsServer
|
|
13
14
|
from ..basics import dicts_nested
|
|
14
15
|
from ..wrappers.loggingw import loggingw
|
|
16
|
+
from ..print_api import print_api
|
|
15
17
|
|
|
16
18
|
|
|
17
19
|
def initialize_mitm_server(config_static):
|
|
@@ -129,20 +131,57 @@ def initialize_mitm_server(config_static):
|
|
|
129
131
|
logger=system_logger, stdout=False, reference_general=True)
|
|
130
132
|
# === EOF Initialize Reference Module ==========================================================================
|
|
131
133
|
# === Engine logging ===========================================================================================
|
|
132
|
-
#
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
134
|
+
# Printing the parsers using "start=1" for index to start counting from "1" and not "0"
|
|
135
|
+
print_api(f"[*] Found Engines:", logger=system_logger)
|
|
136
|
+
for index, engine in enumerate(engines_list, start=1):
|
|
137
|
+
message = f"[*] {index}: {engine.engine_name} | {engine.domain_list}"
|
|
138
|
+
print_api(message, logger=system_logger)
|
|
139
|
+
|
|
140
|
+
message = (f"[*] Modules: {engine.parser_class_object.__name__}, "
|
|
141
|
+
f"{engine.responder_class_object.__name__}, "
|
|
142
|
+
f"{engine.recorder_class_object.__name__}")
|
|
143
|
+
print_api(message, logger=system_logger)
|
|
144
|
+
|
|
145
|
+
if config['dns']['enable_dns_server']:
|
|
146
|
+
print_api("DNS Server is enabled.", logger=system_logger)
|
|
147
|
+
|
|
148
|
+
# If engines were found and dns is set to route by the engine domains.
|
|
149
|
+
if engines_list and config['dns']['route_to_tcp_server_only_engine_domains']:
|
|
150
|
+
print_api("Engine domains will be routed by the DNS server to Built-in TCP Server.", logger=system_logger)
|
|
151
|
+
# If engines were found, but the dns isn't set to route to engines.
|
|
152
|
+
elif engines_list and not config['dns']['route_to_tcp_server_only_engine_domains']:
|
|
153
|
+
message = f"[*] Engine domains found, but the DNS routing is set not to use them for routing."
|
|
154
|
+
print_api(message, color="yellow", logger=system_logger)
|
|
155
|
+
elif not engines_list and config['dns']['route_to_tcp_server_only_engine_domains']:
|
|
156
|
+
raise ValueError("No engines were found, but the DNS routing is set to use them for routing.\n"
|
|
157
|
+
"Please check your DNS configuration in the 'config.ini' file.")
|
|
158
|
+
|
|
159
|
+
if config['dns']['route_to_tcp_server_all_domains']:
|
|
160
|
+
print_api("All domains will be routed by the DNS server to Built-in TCP Server.", logger=system_logger)
|
|
161
|
+
|
|
162
|
+
if config['dns']['regular_resolving']:
|
|
163
|
+
print_api(
|
|
164
|
+
"Regular DNS resolving is enabled. Built-in TCP server will not be routed to",
|
|
165
|
+
logger=system_logger, color="yellow")
|
|
142
166
|
else:
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
167
|
+
print_api("DNS Server is disabled.", logger=system_logger, color="yellow")
|
|
168
|
+
|
|
169
|
+
if config['tcp']['enable_tcp_server']:
|
|
170
|
+
print_api("TCP Server is enabled.", logger=system_logger)
|
|
171
|
+
|
|
172
|
+
if engines_list and not config['tcp']['engines_usage']:
|
|
173
|
+
message = \
|
|
174
|
+
f"Engines found, but the TCP server is set not to use them for processing. General responses only."
|
|
175
|
+
print_api(message, color="yellow", logger=system_logger)
|
|
176
|
+
elif engines_list and config['tcp']['engines_usage']:
|
|
177
|
+
message = f"Engines found, and the TCP server is set to use them for processing."
|
|
178
|
+
print_api(message, logger=system_logger)
|
|
179
|
+
elif not engines_list and config['tcp']['engines_usage']:
|
|
180
|
+
raise ValueError("No engines were found, but the TCP server is set to use them for processing.\n"
|
|
181
|
+
"Please check your TCP configuration in the 'config.ini' file.")
|
|
182
|
+
else:
|
|
183
|
+
print_api("TCP Server is disabled.", logger=system_logger, color="yellow")
|
|
184
|
+
|
|
146
185
|
# === EOF Engine Logging =======================================================================================
|
|
147
186
|
|
|
148
187
|
# Assigning all the engines domains to all time domains, that will be responsible for adding new domains.
|
|
@@ -178,20 +217,24 @@ def initialize_mitm_server(config_static):
|
|
|
178
217
|
dns_server.request_domain_queue = domain_queue
|
|
179
218
|
# Initiate the thread.
|
|
180
219
|
threading.Thread(target=dns_server.start).start()
|
|
220
|
+
|
|
181
221
|
# === EOF Initialize DNS module ================================================================================
|
|
222
|
+
# === Initialize TCP Server ====================================================================================
|
|
223
|
+
if config['tcp']['enable_tcp_server']:
|
|
224
|
+
socket_wrapper = SocketWrapper(
|
|
225
|
+
config=dicts_nested.merge(config, config_static.CONFIG_EXTENDED), logger=listener_logger,
|
|
226
|
+
statistics_logger=statistics_logger)
|
|
182
227
|
|
|
183
|
-
|
|
184
|
-
config=dicts_nested.merge(config, config_static.CONFIG_EXTENDED), logger=listener_logger,
|
|
185
|
-
statistics_logger=statistics_logger)
|
|
228
|
+
socket_wrapper.create_tcp_listening_socket_list()
|
|
186
229
|
|
|
187
|
-
|
|
230
|
+
socket_wrapper.requested_domain_from_dns_server = domain_queue
|
|
188
231
|
|
|
189
|
-
|
|
232
|
+
# General exception handler will catch all the exceptions that occurred in the threads and write it to the log.
|
|
233
|
+
try:
|
|
234
|
+
socket_wrapper.loop_for_incoming_sockets(function_reference=thread_worker_main, reference_args=(
|
|
235
|
+
network_logger, statistics_logger, engines_list, reference_module, config,))
|
|
236
|
+
except Exception:
|
|
237
|
+
message = f"Unhandled Exception occurred in 'loop_for_incoming_sockets' function"
|
|
238
|
+
print_api(message, error_type=True, color="red", logger=network_logger, traceback_string=True, oneline=True)
|
|
190
239
|
|
|
191
|
-
#
|
|
192
|
-
try:
|
|
193
|
-
socket_wrapper.loop_for_incoming_sockets(function_reference=thread_worker_main, reference_args=(
|
|
194
|
-
network_logger, statistics_logger, engines_list, reference_module, config,))
|
|
195
|
-
except Exception:
|
|
196
|
-
message = f"Unhandled Exception occurred in 'loop_for_incoming_sockets' function"
|
|
197
|
-
print_api(message, error_type=True, color="red", logger=network_logger, traceback_string=True, oneline=True)
|
|
240
|
+
# === EOF Initialize TCP Server ================================================================================
|
atomicshop/process.py
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
DEFAULT_ELASTIC_PORT: str = '9200'
|
|
2
|
+
DEFAULT_ELASTIC_HOST: str = 'localhost'
|
|
3
|
+
DEFAULT_ELASTIC_URL: str = f"http://{DEFAULT_ELASTIC_HOST}:{DEFAULT_ELASTIC_PORT}"
|
|
4
|
+
|
|
5
|
+
DEFAULT_KIBANA_PORT: str = '5601'
|
|
6
|
+
DEFAULT_KIBANA_HOST: str = 'localhost'
|
|
7
|
+
DEFAULT_KIBANA_URL: str = f"http://{DEFAULT_KIBANA_HOST}:{DEFAULT_KIBANA_PORT}"
|
|
8
|
+
|
|
9
|
+
ELASTIC_CONFIG_FILE: str = "/etc/elasticsearch/elasticsearch.yml"
|
|
10
|
+
ELASTIC_JVM_OPTIONS_FILE: str = "/etc/elasticsearch/jvm.options"
|
|
11
|
+
XPACK_SECURITY_SETTING_NAME: str = "xpack.security.enabled"
|
|
12
|
+
|
|
13
|
+
UBUNTU_DEPENDENCY_PACKAGES: list[str] = ['apt-transport-https', 'openjdk-11-jdk', 'wget']
|
|
14
|
+
UBUNTU_ELASTIC_PACKAGE_NAME: str = 'elasticsearch'
|
|
15
|
+
UBUNTU_ELASTIC_SERVICE_NAME: str = 'elasticsearch'
|
|
16
|
+
UBUNTU_KIBANA_PACKAGE_NAME: str = 'kibana'
|
|
17
|
+
UBUNTU_KIBANA_SERVICE_NAME: str = 'kibana'
|
|
@@ -25,7 +25,7 @@ def get_elastic_wrapper(url: str = None, overwrite: bool = False):
|
|
|
25
25
|
|
|
26
26
|
# If no url is provided, use the default url.
|
|
27
27
|
if url is None:
|
|
28
|
-
url = config_basic.
|
|
28
|
+
url = config_basic.DEFAULT_ELASTIC_URL
|
|
29
29
|
|
|
30
30
|
# Get the global variable.
|
|
31
31
|
global ELASTIC_WRAPPER
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import time
|
|
3
|
+
import requests
|
|
4
|
+
|
|
5
|
+
from ...print_api import print_api
|
|
6
|
+
from ... import filesystem
|
|
7
|
+
from .. import ubuntu_terminal
|
|
8
|
+
from . import config_basic
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def is_elastic_service_running():
|
|
12
|
+
return ubuntu_terminal.is_service_running(config_basic.UBUNTU_ELASTIC_SERVICE_NAME, return_false_on_error=False)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def enable_elastic_service():
|
|
16
|
+
ubuntu_terminal.enable_service(config_basic.UBUNTU_ELASTIC_SERVICE_NAME)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def start_elastic_service():
|
|
20
|
+
ubuntu_terminal.start_service(config_basic.UBUNTU_ELASTIC_SERVICE_NAME)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def is_kibana_service_running():
|
|
24
|
+
return ubuntu_terminal.is_service_running(config_basic.UBUNTU_KIBANA_SERVICE_NAME, return_false_on_error=False)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def enable_kibana_service():
|
|
28
|
+
ubuntu_terminal.enable_service(config_basic.UBUNTU_KIBANA_SERVICE_NAME)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def start_kibana_service():
|
|
32
|
+
ubuntu_terminal.start_service(config_basic.UBUNTU_KIBANA_SERVICE_NAME)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def start_elastic_and_check_service_availability(wait_time_seconds: float = 30, exit_on_error: bool = True):
|
|
36
|
+
"""
|
|
37
|
+
Function starts the Elasticsearch service and checks its availability.
|
|
38
|
+
:param wait_time_seconds: float, the time to wait after starting the service before checking
|
|
39
|
+
the service availability.
|
|
40
|
+
:param exit_on_error: bool, if True, the function will exit the program if the service is not available.
|
|
41
|
+
:return:
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
# Start, enable and check the Elasticsearch service.
|
|
45
|
+
ubuntu_terminal.start_enable_service_check_availability(
|
|
46
|
+
service_name=config_basic.UBUNTU_ELASTIC_SERVICE_NAME,
|
|
47
|
+
wait_time_seconds=wait_time_seconds,
|
|
48
|
+
exit_on_error=exit_on_error
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
# Check if Elasticsearch is running.
|
|
52
|
+
if not is_server_available():
|
|
53
|
+
if exit_on_error:
|
|
54
|
+
sys.exit(1)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def start_kibana_and_check_service_availability(wait_time_seconds: float = 30, exit_on_error: bool = True):
|
|
58
|
+
"""
|
|
59
|
+
Function starts the Kibana service and checks its availability.
|
|
60
|
+
:param wait_time_seconds: float, the time to wait after starting the service before checking
|
|
61
|
+
the service availability.
|
|
62
|
+
:param exit_on_error: bool, if True, the function will exit the program if the service is not available.
|
|
63
|
+
:return:
|
|
64
|
+
"""
|
|
65
|
+
|
|
66
|
+
# Start, enable and check the Elasticsearch service.
|
|
67
|
+
ubuntu_terminal.start_enable_service_check_availability(
|
|
68
|
+
service_name=config_basic.UBUNTU_KIBANA_SERVICE_NAME,
|
|
69
|
+
wait_time_seconds=wait_time_seconds,
|
|
70
|
+
exit_on_error=exit_on_error
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def is_elastic_config_file_exists(
|
|
75
|
+
config_file_path: str = None,
|
|
76
|
+
exit_on_error: bool = False,
|
|
77
|
+
output_message: bool = False
|
|
78
|
+
) -> bool:
|
|
79
|
+
"""
|
|
80
|
+
The function checks if the Elasticsearch configuration file exists.
|
|
81
|
+
|
|
82
|
+
:param config_file_path: str, the path to the configuration file.
|
|
83
|
+
:param exit_on_error: bool, if True, the function will exit the program if the file does not exist.
|
|
84
|
+
:param output_message: bool, if True, the function will print a message if the file does not exist.
|
|
85
|
+
:return:
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
if not config_file_path:
|
|
89
|
+
config_file_path = config_basic.ELASTIC_CONFIG_FILE
|
|
90
|
+
|
|
91
|
+
if not filesystem.check_file_existence(config_file_path):
|
|
92
|
+
if output_message:
|
|
93
|
+
message = f"Configuration file does not exist at {config_file_path}."
|
|
94
|
+
print_api(message, color='red', error_type=True)
|
|
95
|
+
if exit_on_error:
|
|
96
|
+
sys.exit(1)
|
|
97
|
+
return False
|
|
98
|
+
else:
|
|
99
|
+
return True
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def check_xpack_security_setting(config_file_path: str = None):
|
|
103
|
+
"""
|
|
104
|
+
The function checks if the 'xpack.security.enabled' setting is set to 'false' in the Elasticsearch
|
|
105
|
+
configuration file.
|
|
106
|
+
|
|
107
|
+
:param config_file_path:
|
|
108
|
+
:return:
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
if not config_file_path:
|
|
112
|
+
config_file_path = config_basic.ELASTIC_CONFIG_FILE
|
|
113
|
+
|
|
114
|
+
with open(config_file_path, 'r') as file:
|
|
115
|
+
# Read the file contents
|
|
116
|
+
contents = file.read()
|
|
117
|
+
# Check if the specific setting exists
|
|
118
|
+
if f"{config_basic.XPACK_SECURITY_SETTING_NAME}: false" in contents:
|
|
119
|
+
return False
|
|
120
|
+
elif f"{config_basic.XPACK_SECURITY_SETTING_NAME}: true" in contents:
|
|
121
|
+
return True
|
|
122
|
+
# If the setting doesn't exist, return None.
|
|
123
|
+
else:
|
|
124
|
+
return None
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def modify_xpack_security_setting(
|
|
128
|
+
config_file_path: str = None,
|
|
129
|
+
setting: bool = False,
|
|
130
|
+
output_message: bool = True
|
|
131
|
+
):
|
|
132
|
+
"""
|
|
133
|
+
The function modifies the 'xpack.security.enabled' setting in the Elasticsearch configuration file.
|
|
134
|
+
:param config_file_path: str, the path to the configuration file.
|
|
135
|
+
:param setting: bool, the setting to change to. Will be added, if doesn't exist.
|
|
136
|
+
:param output_message: bool, if True, the function will print a message.
|
|
137
|
+
:return:
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
if not config_file_path:
|
|
141
|
+
config_file_path = config_basic.ELASTIC_CONFIG_FILE
|
|
142
|
+
|
|
143
|
+
# The setting to set in the configuration file.
|
|
144
|
+
xpack_setting_to_set: str = f'{config_basic.XPACK_SECURITY_SETTING_NAME}: {str(setting).lower()}'
|
|
145
|
+
|
|
146
|
+
# Check if the setting exists in the configuration file and get its value.
|
|
147
|
+
current_xpack_security_setting = check_xpack_security_setting(config_file_path)
|
|
148
|
+
|
|
149
|
+
# If the setting doesn't exist, add it to the configuration file.
|
|
150
|
+
if current_xpack_security_setting is None:
|
|
151
|
+
with open(config_file_path, 'a') as file:
|
|
152
|
+
file.write(f'{xpack_setting_to_set}\n')
|
|
153
|
+
if output_message:
|
|
154
|
+
print_api(f"Added [{xpack_setting_to_set}] to the configuration.")
|
|
155
|
+
# If the setting exists and is different from the desired setting, change it.
|
|
156
|
+
elif current_xpack_security_setting != setting:
|
|
157
|
+
with open(config_file_path, 'r') as file:
|
|
158
|
+
lines = file.readlines()
|
|
159
|
+
with open(config_file_path, 'w') as file:
|
|
160
|
+
for line in lines:
|
|
161
|
+
if f"{config_basic.XPACK_SECURITY_SETTING_NAME}:" in line:
|
|
162
|
+
file.write(f'{xpack_setting_to_set}\n')
|
|
163
|
+
else:
|
|
164
|
+
file.write(line)
|
|
165
|
+
if output_message:
|
|
166
|
+
print_api(f"Changed [{config_basic.XPACK_SECURITY_SETTING_NAME}] to [{setting}].")
|
|
167
|
+
# If the setting is already set to the desired value, print a message.
|
|
168
|
+
elif current_xpack_security_setting == setting:
|
|
169
|
+
if output_message:
|
|
170
|
+
print_api(f"The setting is already set to [{setting}].")
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
def is_server_available(
|
|
174
|
+
max_attempts: int = 5,
|
|
175
|
+
wait_between_attempts_seconds: float = 10,
|
|
176
|
+
elastic_url: str = None,
|
|
177
|
+
print_kwargs: dict = None
|
|
178
|
+
):
|
|
179
|
+
"""
|
|
180
|
+
The function checks if Elasticsearch server is up and running by sending GET request to the Elasticsearch server.
|
|
181
|
+
:param max_attempts: int, the maximum number of attempts to check if Elasticsearch is running.
|
|
182
|
+
:param wait_between_attempts_seconds: float, the time to wait between attempts.
|
|
183
|
+
:param elastic_url: str, the URL of the Elasticsearch server. If None, the default URL will be used.
|
|
184
|
+
:param print_kwargs: dict, the keyword arguments for the print_api function.
|
|
185
|
+
:return:
|
|
186
|
+
"""
|
|
187
|
+
|
|
188
|
+
if not elastic_url:
|
|
189
|
+
elastic_url = config_basic.DEFAULT_ELASTIC_URL
|
|
190
|
+
|
|
191
|
+
if not print_kwargs:
|
|
192
|
+
print_kwargs = dict()
|
|
193
|
+
|
|
194
|
+
for attempt in range(1, max_attempts + 1):
|
|
195
|
+
print_api(f"Checking if Elasticsearch is running (Attempt {attempt}/{max_attempts})...", **print_kwargs)
|
|
196
|
+
|
|
197
|
+
try:
|
|
198
|
+
response = requests.get(elastic_url)
|
|
199
|
+
status_code = response.status_code
|
|
200
|
+
|
|
201
|
+
if status_code == 200:
|
|
202
|
+
print_api("Elasticsearch is up and running.", color='green', **print_kwargs)
|
|
203
|
+
return True
|
|
204
|
+
else:
|
|
205
|
+
print_api(f"Elasticsearch is not running. Status code: {status_code}", color='yellow', **print_kwargs)
|
|
206
|
+
except requests.exceptions.RequestException as e:
|
|
207
|
+
print_api(f"Failed to connect to Elasticsearch: {e}", color='yellow', **print_kwargs)
|
|
208
|
+
|
|
209
|
+
print_api("Waiting for Elasticsearch to start...", **print_kwargs)
|
|
210
|
+
time.sleep(wait_between_attempts_seconds)
|
|
211
|
+
|
|
212
|
+
print_api("Elasticsearch did not start within the expected time.", color='red', **print_kwargs)
|
|
213
|
+
return False
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
|
|
3
|
+
from ...print_api import print_api
|
|
4
|
+
from ... import process
|
|
5
|
+
from .. import ubuntu_terminal
|
|
6
|
+
from . import config_basic, infrastructure
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def install_elastic_kibana_ubuntu(install_elastic: bool = True, install_kibana: bool = True):
|
|
10
|
+
"""
|
|
11
|
+
The function will install docker on ubuntu.
|
|
12
|
+
|
|
13
|
+
:param install_elastic: bool, if True, install Elasticsearch.
|
|
14
|
+
:param install_kibana: bool, if True, install Kibana.
|
|
15
|
+
|
|
16
|
+
Usage in main.py (run with sudo):
|
|
17
|
+
from atomicshop.wrappers.elasticw import install_elastic
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def main():
|
|
21
|
+
install_elastic.install_elastic_ubuntu()
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
if __name__ == '__main__':
|
|
25
|
+
main()
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
# This is pure bash script.
|
|
29
|
+
"""
|
|
30
|
+
#!/bin/bash
|
|
31
|
+
|
|
32
|
+
# Color text in red.
|
|
33
|
+
echo_red() {
|
|
34
|
+
local color="\e[31m" # Red color
|
|
35
|
+
local reset="\e[0m" # Reset formatting
|
|
36
|
+
echo -e "${color}$1${reset}"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
# Function to check if a service is running
|
|
40
|
+
check_service_running() {
|
|
41
|
+
local service_name=$1
|
|
42
|
+
local status=$(systemctl is-active "$service_name")
|
|
43
|
+
|
|
44
|
+
if [ "$status" == "active" ]; then
|
|
45
|
+
echo "$service_name service is active and running."
|
|
46
|
+
return 0
|
|
47
|
+
else
|
|
48
|
+
echo_red "$service_name service is not running or has failed. Status: $service_status, Failed: $service_failed"
|
|
49
|
+
return 1
|
|
50
|
+
fi
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# Update and upgrade system packages
|
|
54
|
+
sudo apt-get update && sudo apt-get upgrade -y
|
|
55
|
+
|
|
56
|
+
# Install necessary dependencies
|
|
57
|
+
sudo apt-get install apt-transport-https openjdk-11-jdk wget -y
|
|
58
|
+
|
|
59
|
+
# Download and install the GPG signing key
|
|
60
|
+
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | gpg --dearmor | sudo tee /usr/share/keyrings/elasticsearch-keyring.gpg > /dev/null
|
|
61
|
+
|
|
62
|
+
# Add the Elastic repository to the system
|
|
63
|
+
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
|
|
64
|
+
|
|
65
|
+
# Update package index
|
|
66
|
+
sudo apt-get update
|
|
67
|
+
|
|
68
|
+
# Install Elasticsearch
|
|
69
|
+
sudo apt-get install elasticsearch -y
|
|
70
|
+
|
|
71
|
+
# Path to the Elasticsearch configuration file
|
|
72
|
+
CONFIG_FILE="/etc/elasticsearch/elasticsearch.yml"
|
|
73
|
+
|
|
74
|
+
# Check if the configuration file exists
|
|
75
|
+
if [ ! -f "$CONFIG_FILE" ]; then
|
|
76
|
+
echo "Configuration file does not exist at $CONFIG_FILE."
|
|
77
|
+
exit 1
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# Function to check the setting in the configuration file
|
|
81
|
+
check_setting() {
|
|
82
|
+
if grep -q "^xpack.security.enabled: false" "$CONFIG_FILE"; then
|
|
83
|
+
echo "The setting is confirmed to be 'xpack.security.enabled: false'."
|
|
84
|
+
else
|
|
85
|
+
echo "Failed to set 'xpack.security.enabled: false'."
|
|
86
|
+
exit 1
|
|
87
|
+
fi
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
# Check if 'xpack.security.enabled' is set to 'false'
|
|
91
|
+
if grep -q "^xpack.security.enabled: false" "$CONFIG_FILE"; then
|
|
92
|
+
echo "The setting is already set to false."
|
|
93
|
+
elif grep -q "^xpack.security.enabled: true" "$CONFIG_FILE"; then
|
|
94
|
+
# If the setting is true, change it to false
|
|
95
|
+
sudo sed -i 's/^xpack.security.enabled: true/xpack.security.enabled: false/' "$CONFIG_FILE"
|
|
96
|
+
echo "Changed xpack.security.enabled to false."
|
|
97
|
+
check_setting
|
|
98
|
+
else
|
|
99
|
+
# If the setting doesn't exist, add it
|
|
100
|
+
echo "xpack.security.enabled: false" | sudo tee -a "$CONFIG_FILE" > /dev/null
|
|
101
|
+
echo "Added xpack.security.enabled: false to the configuration."
|
|
102
|
+
check_setting
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
# Start and enable Elasticsearch service
|
|
106
|
+
sudo systemctl start elasticsearch
|
|
107
|
+
sudo systemctl enable elasticsearch
|
|
108
|
+
|
|
109
|
+
echo "Waiting 30 seconds for program to start before availability check..."
|
|
110
|
+
sleep 30
|
|
111
|
+
|
|
112
|
+
# Check if Elasticsearch service is running
|
|
113
|
+
if ! check_service_running "elasticsearch"; then
|
|
114
|
+
echo "Elasticsearch service failed to start. Exiting."
|
|
115
|
+
exit 1
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
# Function to check if Elasticsearch is up and running
|
|
119
|
+
check_elasticsearch() {
|
|
120
|
+
max_attempts=5
|
|
121
|
+
wait_seconds=10
|
|
122
|
+
|
|
123
|
+
for ((i=1; i<=max_attempts; i++)); do
|
|
124
|
+
echo "Checking if Elasticsearch is running (Attempt $i/$max_attempts)..."
|
|
125
|
+
|
|
126
|
+
# Using curl to get the HTTP status code
|
|
127
|
+
status=$(curl --write-out %{http_code} --silent --output /dev/null http://localhost:9200)
|
|
128
|
+
|
|
129
|
+
if [ "$status" -eq 200 ]; then
|
|
130
|
+
echo "Elasticsearch is up and running."
|
|
131
|
+
return 0
|
|
132
|
+
else
|
|
133
|
+
echo "Elasticsearch is not running. Status code: $status"
|
|
134
|
+
fi
|
|
135
|
+
|
|
136
|
+
echo "Waiting for Elasticsearch to start..."
|
|
137
|
+
sleep $wait_seconds
|
|
138
|
+
done
|
|
139
|
+
|
|
140
|
+
echo "Elasticsearch did not start within the expected time."
|
|
141
|
+
return 1
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
# Check if Elasticsearch is running
|
|
145
|
+
if ! check_elasticsearch; then
|
|
146
|
+
echo "Elasticsearch failed to start. Exiting."
|
|
147
|
+
exit 1
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
# Install Kibana
|
|
151
|
+
sudo apt-get install kibana -y
|
|
152
|
+
|
|
153
|
+
# Start and enable Kibana service
|
|
154
|
+
sudo systemctl start kibana
|
|
155
|
+
sudo systemctl enable kibana
|
|
156
|
+
|
|
157
|
+
echo "Waiting 30 seconds for program to start before availability check..."
|
|
158
|
+
sleep 30
|
|
159
|
+
|
|
160
|
+
# Check if Kibana service is running
|
|
161
|
+
if ! check_service_running "kibana"; then
|
|
162
|
+
echo "Kibana service failed to start. Exiting."
|
|
163
|
+
exit 1
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
# Print status
|
|
167
|
+
echo "Elasticsearch and Kibana installation completed."
|
|
168
|
+
echo "Elasticsearch is running on http://localhost:9200"
|
|
169
|
+
echo "Kibana is running on http://localhost:5601"
|
|
170
|
+
"""
|
|
171
|
+
|
|
172
|
+
if not install_elastic and not install_kibana:
|
|
173
|
+
raise ValueError("At least one of the services (Elasticsearch or Kibana) must be installed.")
|
|
174
|
+
|
|
175
|
+
# Update and upgrade system packages.
|
|
176
|
+
ubuntu_terminal.upgrade_system_packages()
|
|
177
|
+
ubuntu_terminal.update_system_packages()
|
|
178
|
+
|
|
179
|
+
# Install necessary dependencies.
|
|
180
|
+
ubuntu_terminal.install_packages(config_basic.UBUNTU_DEPENDENCY_PACKAGES)
|
|
181
|
+
|
|
182
|
+
# Install the GPG key and add elastic repository.
|
|
183
|
+
script = f"""
|
|
184
|
+
# Download and install the GPG signing key
|
|
185
|
+
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | gpg --dearmor | sudo tee /usr/share/keyrings/elasticsearch-keyring.gpg > /dev/null
|
|
186
|
+
|
|
187
|
+
# Add the Elastic repository to the system
|
|
188
|
+
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
|
|
189
|
+
"""
|
|
190
|
+
process.execute_script(script, shell=True)
|
|
191
|
+
|
|
192
|
+
# Update system with elastic search packages.
|
|
193
|
+
ubuntu_terminal.update_system_packages()
|
|
194
|
+
|
|
195
|
+
if install_elastic:
|
|
196
|
+
# Install Elasticsearch.
|
|
197
|
+
ubuntu_terminal.install_packages([config_basic.UBUNTU_ELASTIC_PACKAGE_NAME])
|
|
198
|
+
|
|
199
|
+
# Check if the configuration file exists.
|
|
200
|
+
infrastructure.is_elastic_config_file_exists(exit_on_error=True, output_message=True)
|
|
201
|
+
|
|
202
|
+
# Check if the specific setting exists or not and set it to false.
|
|
203
|
+
infrastructure.modify_xpack_security_setting(setting=False, output_message=True)
|
|
204
|
+
|
|
205
|
+
# Check if the setting was really set to false.
|
|
206
|
+
if infrastructure.check_xpack_security_setting() is False:
|
|
207
|
+
print_api(f"The setting is confirmed to be [{config_basic.XPACK_SECURITY_SETTING_NAME}: false].")
|
|
208
|
+
else:
|
|
209
|
+
print_api(f"Failed to set [{config_basic.XPACK_SECURITY_SETTING_NAME}: false].")
|
|
210
|
+
sys.exit(1)
|
|
211
|
+
|
|
212
|
+
infrastructure.start_elastic_and_check_service_availability()
|
|
213
|
+
|
|
214
|
+
if install_kibana:
|
|
215
|
+
# Install Kibana.
|
|
216
|
+
ubuntu_terminal.install_packages([config_basic.UBUNTU_KIBANA_PACKAGE_NAME])
|
|
217
|
+
|
|
218
|
+
# Start and enable Kibana service.
|
|
219
|
+
infrastructure.start_kibana_and_check_service_availability()
|
|
220
|
+
|
|
221
|
+
print_api("Installation completed.", color='green')
|
|
222
|
+
if install_elastic:
|
|
223
|
+
print_api(f"Default Elasticsearch on {config_basic.DEFAULT_ELASTIC_URL}")
|
|
224
|
+
if install_kibana:
|
|
225
|
+
print_api(f"Default Kibana on {config_basic.DEFAULT_KIBANA_URL}")
|
atomicshop/wrappers/ffmpegw.py
CHANGED
|
@@ -91,9 +91,19 @@ class DnsServer:
|
|
|
91
91
|
|
|
92
92
|
# Check if 'route_to_tcp_server_only_engine_domains' was set to 'True' and output message accordingly.
|
|
93
93
|
if self.config['dns']['route_to_tcp_server_only_engine_domains']:
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
message = "Routing only engine domains to Built-in TCP Server."
|
|
95
|
+
print_api(message, logger=self.logger)
|
|
96
|
+
|
|
97
|
+
message = f"Current engine domains: {self.domain_list}"
|
|
98
|
+
print_api(message, logger=self.logger, color='green')
|
|
99
|
+
|
|
100
|
+
if self.config['dns']['route_to_tcp_server_all_domains']:
|
|
101
|
+
message = "Routing all domains to Built-in TCP Server."
|
|
102
|
+
print_api(message, logger=self.logger, color='green')
|
|
103
|
+
|
|
104
|
+
if self.config['dns']['regular_resolving']:
|
|
105
|
+
message = f"Routing all domains to Live DNS Service: {self.config['dns']['forwarding_dns_service_ipv4']}"
|
|
106
|
+
print_api(message, logger=self.logger, color='green')
|
|
97
107
|
|
|
98
108
|
# The list that will hold all the threads that can be joined later
|
|
99
109
|
threads_list: list = list()
|
|
@@ -201,22 +211,28 @@ class DnsServer:
|
|
|
201
211
|
else:
|
|
202
212
|
# Check if the incoming Record is "A" record.
|
|
203
213
|
if qtype_string == "A":
|
|
204
|
-
#
|
|
214
|
+
# Check if 'route_to_tcp_server_only_engine_domains' is set to 'True' in 'config.ini'.
|
|
205
215
|
# If so, we need to check if the incoming domain contain any of the 'engine_domains'.
|
|
206
216
|
if self.config['dns']['route_to_tcp_server_only_engine_domains']:
|
|
207
217
|
# If current query domain (+ subdomains) CONTAIN any of the domains from modules config
|
|
208
218
|
# files and current request contains "A" (IPv4) record.
|
|
209
219
|
if any(x in question_domain for x in self.domain_list):
|
|
210
|
-
# If incoming domain contains any of the 'engine_domains' then domain will
|
|
211
|
-
# to our TCP Server.
|
|
220
|
+
# If incoming domain contains any of the 'engine_domains' then domain will
|
|
221
|
+
# be forwarded to our TCP Server.
|
|
212
222
|
forward_to_tcp_server = True
|
|
213
223
|
else:
|
|
214
224
|
forward_to_tcp_server = False
|
|
215
|
-
|
|
216
|
-
#
|
|
217
|
-
#
|
|
218
|
-
|
|
225
|
+
|
|
226
|
+
# If 'route_to_tcp_server_all_domains' was set to 'False' in 'config.ini' file then
|
|
227
|
+
# we'll forward all 'A' records domains to the Built-in TCP Server.
|
|
228
|
+
if self.config['dns']['route_to_tcp_server_all_domains']:
|
|
219
229
|
forward_to_tcp_server = True
|
|
230
|
+
|
|
231
|
+
# If 'regular_resolving' was set to 'True' in 'config.ini' file then
|
|
232
|
+
# we'll forward all 'A' records domains to the Live DNS Service.
|
|
233
|
+
if self.config['dns']['regular_resolving']:
|
|
234
|
+
forward_to_tcp_server = False
|
|
235
|
+
|
|
220
236
|
# If incoming record is not an "A" record, then it will not be forwarded to our TCP Server.
|
|
221
237
|
else:
|
|
222
238
|
forward_to_tcp_server = False
|
|
@@ -1,14 +1,22 @@
|
|
|
1
|
+
import sys
|
|
1
2
|
import subprocess
|
|
2
3
|
import shutil
|
|
4
|
+
import time
|
|
3
5
|
|
|
6
|
+
from ..print_api import print_api
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
|
|
9
|
+
def install_packages(package_list: list[str]):
|
|
6
10
|
"""
|
|
7
11
|
Function installs a package using apt-get.
|
|
8
|
-
:param
|
|
12
|
+
:param package_list: list of strings, package names to install.
|
|
9
13
|
:return:
|
|
10
14
|
"""
|
|
11
|
-
|
|
15
|
+
|
|
16
|
+
# Construct the command with the package list
|
|
17
|
+
command = ["sudo", "apt-get", "install", "-y"] + package_list
|
|
18
|
+
|
|
19
|
+
subprocess.check_call(command)
|
|
12
20
|
|
|
13
21
|
|
|
14
22
|
def is_package_installed(package: str) -> bool:
|
|
@@ -22,3 +30,102 @@ def is_package_installed(package: str) -> bool:
|
|
|
22
30
|
return False
|
|
23
31
|
else:
|
|
24
32
|
return True
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def update_system_packages():
|
|
36
|
+
"""
|
|
37
|
+
Function updates the system packages.
|
|
38
|
+
:return:
|
|
39
|
+
"""
|
|
40
|
+
subprocess.check_call(['sudo', 'apt-get', 'update'])
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def upgrade_system_packages():
|
|
44
|
+
"""
|
|
45
|
+
Function upgrades the system packages.
|
|
46
|
+
:return:
|
|
47
|
+
"""
|
|
48
|
+
subprocess.check_call(['sudo', 'apt-get', 'upgrade', '-y'])
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def is_service_running(service_name: str, return_false_on_error: bool = False) -> bool:
|
|
52
|
+
try:
|
|
53
|
+
# Use subprocess to run 'systemctl is-active' and capture its output
|
|
54
|
+
status = subprocess.check_output(['systemctl', 'is-active', service_name], text=True).strip()
|
|
55
|
+
except subprocess.CalledProcessError as e:
|
|
56
|
+
if return_false_on_error:
|
|
57
|
+
# Handle error if systemctl command fails
|
|
58
|
+
return False
|
|
59
|
+
else:
|
|
60
|
+
# Raise the exception if return_false_on_error is False
|
|
61
|
+
raise e
|
|
62
|
+
|
|
63
|
+
if status == "active":
|
|
64
|
+
return True
|
|
65
|
+
else:
|
|
66
|
+
return False
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def enable_service(service_name: str):
|
|
70
|
+
"""
|
|
71
|
+
Function enables a service.
|
|
72
|
+
:param service_name: str, the service name.
|
|
73
|
+
:return:
|
|
74
|
+
"""
|
|
75
|
+
subprocess.check_call(['sudo', 'systemctl', 'enable', service_name])
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def start_service(service_name: str):
|
|
79
|
+
"""
|
|
80
|
+
Function starts a service.
|
|
81
|
+
:param service_name: str, the service name.
|
|
82
|
+
:return:
|
|
83
|
+
"""
|
|
84
|
+
subprocess.check_call(['sudo', 'systemctl', 'start', service_name])
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def start_enable_service_check_availability(
|
|
88
|
+
service_name: str,
|
|
89
|
+
wait_time_seconds: float = 30,
|
|
90
|
+
exit_on_error: bool = True,
|
|
91
|
+
start_service_bool: bool = True,
|
|
92
|
+
enable_service_bool: bool = True,
|
|
93
|
+
check_service_running: bool = True,
|
|
94
|
+
print_kwargs: dict = None
|
|
95
|
+
):
|
|
96
|
+
"""
|
|
97
|
+
Function starts and enables a service and checks its availability.
|
|
98
|
+
|
|
99
|
+
:param service_name: str, the service name.
|
|
100
|
+
:param wait_time_seconds: float, the time to wait after starting the service before checking the service
|
|
101
|
+
availability.
|
|
102
|
+
:param exit_on_error: bool, if True, the function will exit the program if the service is not available.
|
|
103
|
+
:param start_service_bool: bool, if True, the service will be started.
|
|
104
|
+
:param enable_service_bool: bool, if True, the service will be enabled.
|
|
105
|
+
:param check_service_running: bool, if True, the function will check if the service is running.
|
|
106
|
+
:param print_kwargs: dict, the print arguments.
|
|
107
|
+
:return:
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
if not start_service_bool and not enable_service_bool:
|
|
111
|
+
raise ValueError("Either 'start_service_bool' or 'enable_service_bool' must be True.")
|
|
112
|
+
|
|
113
|
+
# Start and enable the service.
|
|
114
|
+
if start_service_bool:
|
|
115
|
+
start_service(service_name)
|
|
116
|
+
if enable_service_bool:
|
|
117
|
+
enable_service(service_name)
|
|
118
|
+
|
|
119
|
+
if check_service_running:
|
|
120
|
+
print_api(
|
|
121
|
+
f"Waiting {str(wait_time_seconds)} seconds for the program to start before availability check...",
|
|
122
|
+
**(print_kwargs or {}))
|
|
123
|
+
time.sleep(wait_time_seconds)
|
|
124
|
+
|
|
125
|
+
if not is_service_running(service_name):
|
|
126
|
+
print_api(
|
|
127
|
+
f"[{service_name}] service failed to start.", color='red', error_type=True, **(print_kwargs or {}))
|
|
128
|
+
if exit_on_error:
|
|
129
|
+
sys.exit(1)
|
|
130
|
+
else:
|
|
131
|
+
print_api(f"[{service_name}] service is running.", color='green', **(print_kwargs or {}))
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=YjtN4-RYTZwCTFS1O3pUEqPdO7RNYB0bgcXRvqPDH1Y,123
|
|
2
2
|
atomicshop/_basics_temp.py,sha256=6cu2dd6r2dLrd1BRNcVDKTHlsHs_26Gpw8QS6v32lQ0,3699
|
|
3
3
|
atomicshop/_create_pdf_demo.py,sha256=Yi-PGZuMg0RKvQmLqVeLIZYadqEZwUm-4A9JxBl_vYA,3713
|
|
4
4
|
atomicshop/_patch_import.py,sha256=ENp55sKVJ0e6-4lBvZnpz9PQCt3Otbur7F6aXDlyje4,6334
|
|
@@ -14,7 +14,7 @@ atomicshop/dns.py,sha256=bNZOo5jVPzq7OT2qCPukXoK3zb1oOsyaelUwQEyK1SA,2500
|
|
|
14
14
|
atomicshop/domains.py,sha256=Rxu6JhhMqFZRcoFs69IoEd1PtYca0lMCG6F1AomP7z4,3197
|
|
15
15
|
atomicshop/emails.py,sha256=I0KyODQpIMEsNRi9YWSOL8EUPBiWyon3HRdIuSj3AEU,1410
|
|
16
16
|
atomicshop/file_types.py,sha256=-0jzQMRlmU1AP9DARjk-HJm1tVE22E6ngP2mRblyEjY,763
|
|
17
|
-
atomicshop/filesystem.py,sha256=
|
|
17
|
+
atomicshop/filesystem.py,sha256=kMsAMp6ij1j1Qdd-T1H8A-5PYD6zH4cTLMwBnQoHgJ8,42791
|
|
18
18
|
atomicshop/functions.py,sha256=pK8hoCE9z61PtWCxQJsda7YAphrLH1wxU5x-1QJP-sY,499
|
|
19
19
|
atomicshop/hashing.py,sha256=Le8qGFyt3_wX-zGTeQShz7L2HL_b6nVv9PnawjglyHo,3474
|
|
20
20
|
atomicshop/http_parse.py,sha256=nrf2rZcprLqtW8HVrV7TCZ1iTBcWRRy-mXIlAOzcaJs,9703
|
|
@@ -24,7 +24,7 @@ atomicshop/keyboard_press.py,sha256=1W5kRtOB75fulVx-uF2yarBhW0_IzdI1k73AnvXstk0,
|
|
|
24
24
|
atomicshop/pbtkmultifile_argparse.py,sha256=aEk8nhvoQVu-xyfZosK3ma17CwIgOjzO1erXXdjwtS4,4574
|
|
25
25
|
atomicshop/permissions.py,sha256=GYWxm9niuJWY0pWCnASF34_HiTuvhTamn8BCgcFyVAk,2540
|
|
26
26
|
atomicshop/print_api.py,sha256=DhbCQd0MWZZ5GYEk4oTu1opRFC-b31g1VWZgTGewG2Y,11568
|
|
27
|
-
atomicshop/process.py,sha256=
|
|
27
|
+
atomicshop/process.py,sha256=SXaqG8pzNkHvppPhuhixEIXSaqbeDlTUFLaS5bYSp54,14176
|
|
28
28
|
atomicshop/process_name_cmd.py,sha256=TNAK6kQZm5JKWzEW6QLqVHEG98ZLNDQiSS4YwDk8V8c,3830
|
|
29
29
|
atomicshop/process_poller.py,sha256=WfmwCLALfTYOq8ri0vkPeqq8ruEyA_43DaN--CU2_XY,10854
|
|
30
30
|
atomicshop/python_file_patcher.py,sha256=kd3rBWvTcosLEk-7TycNdfKW9fZbe161iVwmH4niUo0,5515
|
|
@@ -64,6 +64,7 @@ atomicshop/addons/process_list/process_list.cpp,sha256=e7olpLfLVg9vQnjEr5L2Y8aWG
|
|
|
64
64
|
atomicshop/addons/process_list/compiled/Win10x64/process_list.dll,sha256=SkAZvYAfSbzQTTq-5aL6_dYR2rA4DHbgyenFfgLFzW0,266752
|
|
65
65
|
atomicshop/addons/process_list/compiled/Win10x64/process_list.exp,sha256=VTph513eqa6f6HmqAj_6mBS1Rf9G56bgYqZNuDePYcs,708
|
|
66
66
|
atomicshop/addons/process_list/compiled/Win10x64/process_list.lib,sha256=n9c2MVPs3GBNoOQjMesAwzNpv5aFZsW8c-ADS7GYRhA,1886
|
|
67
|
+
atomicshop/archiver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
67
68
|
atomicshop/archiver/_search_in_zip.py,sha256=dd8qFSvIhcKmtnPj_uYNJFPmMwZp4tZys0kKgTw_ACw,8385
|
|
68
69
|
atomicshop/archiver/archiver.py,sha256=BomnK7zT-nQXA1z0i2R2aTv8eu88wPx7tf2HtOdbmEc,1280
|
|
69
70
|
atomicshop/archiver/search_in_archive.py,sha256=mEngDfULXBd3Oio8a2SUtynfJASVLsH74XIYJOWVkH0,10467
|
|
@@ -72,7 +73,7 @@ atomicshop/archiver/zip.py,sha256=k742K1bEDtc_4N44j_Waebi-uOkxxavqltvV6q-BLW4,14
|
|
|
72
73
|
atomicshop/basics/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
73
74
|
atomicshop/basics/ansi_escape_codes.py,sha256=WtIkm-BjSZS5J5irDUdAMBNvdX-qXFZcTX98jcBMpJE,3140
|
|
74
75
|
atomicshop/basics/argparse_template.py,sha256=horwgSf3MX1ZgRnYxtmmQuz9OU_vKrKggF65gmjlmfg,5836
|
|
75
|
-
atomicshop/basics/booleans.py,sha256=
|
|
76
|
+
atomicshop/basics/booleans.py,sha256=va3LYIaSOhjdifW4ZEesnIQxBICNHyQjUAkYelzchhE,2047
|
|
76
77
|
atomicshop/basics/bytes_arrays.py,sha256=WvSRDhIGt1ywF95t-yNgpxLm1nlZUbM1Dz6QckcyE8Y,5915
|
|
77
78
|
atomicshop/basics/classes.py,sha256=EijW_g4EhdNBnKPMG3nT3HjFspTchtM7to6zm9Ad_Mk,9771
|
|
78
79
|
atomicshop/basics/dicts.py,sha256=N696f-vamrCcLpLOvtRpHrEmLfyOqkCyW8JDZnwYLpg,11295
|
|
@@ -105,15 +106,15 @@ atomicshop/file_io/tomls.py,sha256=oa0Wm8yMkPRXKN9jgBuTnKbioSOee4mABW5IMUFCYyU,3
|
|
|
105
106
|
atomicshop/file_io/xlsxs.py,sha256=v_dyg9GD4LqgWi6wA1QuWRZ8zG4ZwB6Dz52ytdcmmmI,2184
|
|
106
107
|
atomicshop/file_io/xmls.py,sha256=zh3SuK-dNaFq2NDNhx6ivcf4GYCfGM8M10PcEwDSpxk,2104
|
|
107
108
|
atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
108
|
-
atomicshop/mitm/connection_thread_worker.py,sha256=
|
|
109
|
-
atomicshop/mitm/import_config.py,sha256=
|
|
110
|
-
atomicshop/mitm/initialize_engines.py,sha256=
|
|
111
|
-
atomicshop/mitm/initialize_mitm_server.py,sha256=
|
|
109
|
+
atomicshop/mitm/connection_thread_worker.py,sha256=PQ8bwOgrPudYP5oPnSi_DWaKXOi038M8TMImlLkxuPI,20486
|
|
110
|
+
atomicshop/mitm/import_config.py,sha256=_V-IVJ7a1L6E-VOR4CDfZj-S1odbsIlBe13ij0NlpqY,7974
|
|
111
|
+
atomicshop/mitm/initialize_engines.py,sha256=UGdT5DKYNri3MNOxESP7oeSxYiUDrVilJ4jic_nwdew,8055
|
|
112
|
+
atomicshop/mitm/initialize_mitm_server.py,sha256=aXNZlRu1_RGjC7lagvs2Q8rjQiygxYucy-U4C_SBnsk,13871
|
|
112
113
|
atomicshop/mitm/message.py,sha256=u2U2f2SOHdBNU-6r1Ik2W14ai2EOwxUV4wVfGZA098k,1732
|
|
113
114
|
atomicshop/mitm/shared_functions.py,sha256=NeHABBlY-tmQRooWGVl2jZQx1wSTKJtEqG7mMvF2Jqo,4268
|
|
114
115
|
atomicshop/mitm/statistic_analyzer.py,sha256=1g5l6X-NbnHvh_TREJRumTDWgE4ixUNJ8pKGneKcf4Y,23524
|
|
115
116
|
atomicshop/mitm/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
116
|
-
atomicshop/mitm/engines/create_module_template.py,sha256=
|
|
117
|
+
atomicshop/mitm/engines/create_module_template.py,sha256=tRjVSm1sD6FzML71Qbuwvita0qsusdFGm8NZLsZ-XMs,4853
|
|
117
118
|
atomicshop/mitm/engines/create_module_template_example.py,sha256=X5xhvbV6-g9jU_bQVhf_crZmaH50LRWz3bS-faQ18ds,489
|
|
118
119
|
atomicshop/mitm/engines/__parent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
119
120
|
atomicshop/mitm/engines/__parent/parser___parent.py,sha256=sBvPlFMOCTdS-qgW9uTKvvJCFT5nNW9n3UyhaFcjAfg,1365
|
|
@@ -141,12 +142,12 @@ atomicshop/wrappers/_process_wrapper_tar.py,sha256=WUMZFKNrlG4nJP9tWZ51W7BR1j_pI
|
|
|
141
142
|
atomicshop/wrappers/astw.py,sha256=VkYfkfyc_PJLIOxByT6L7B8uUmKY6-I8XGZl4t_z828,4239
|
|
142
143
|
atomicshop/wrappers/configparserw.py,sha256=JwDTPjZoSrv44YKwIRcjyUnpN-FjgXVfMqMK_tJuSgU,22800
|
|
143
144
|
atomicshop/wrappers/cryptographyw.py,sha256=H5NaHHDkr97QYhUrHFO9vY218u8k3N3Zgh6bQRnicUE,13140
|
|
144
|
-
atomicshop/wrappers/ffmpegw.py,sha256=
|
|
145
|
+
atomicshop/wrappers/ffmpegw.py,sha256=wcq0ZnAe0yajBOuTKZCCaKI7CDBjkq7FAgdW5IsKcVE,6031
|
|
145
146
|
atomicshop/wrappers/githubw.py,sha256=AjD0VUlV2Kcddns2OaGmyX-FOAvdps-8SPSWS05E0QA,4809
|
|
146
147
|
atomicshop/wrappers/numpyw.py,sha256=sBV4gSKyr23kXTalqAb1oqttzE_2XxBooCui66jbAqc,1025
|
|
147
148
|
atomicshop/wrappers/process_wrapper_pbtk.py,sha256=ycPmBRnv627RWks6N8OhxJQe8Gu3h3Vwj-4HswPOw0k,599
|
|
148
149
|
atomicshop/wrappers/pyopensslw.py,sha256=OBWxA6EJ2vU_Qlf4M8m6ilcG3hyYB4yB0EsXUf7NhEU,6804
|
|
149
|
-
atomicshop/wrappers/ubuntu_terminal.py,sha256=
|
|
150
|
+
atomicshop/wrappers/ubuntu_terminal.py,sha256=1CcTXASzxdFFFJTf3G1OtHcs8abbn_jgkPsY0OzEs1w,4132
|
|
150
151
|
atomicshop/wrappers/wslw.py,sha256=AKphiHLSddL7ErevUowr3f9Y1AgGz_R3KZ3NssW07h8,6959
|
|
151
152
|
atomicshop/wrappers/certauthw/certauth.py,sha256=hKedW0DOWlEigSNm8wu4SqHkCQsGJ1tJfH7s4nr3Bk0,12223
|
|
152
153
|
atomicshop/wrappers/certauthw/certauthw.py,sha256=4WvhjANI7Kzqrr_nKmtA8Kf7B6rute_5wfP65gwQrjw,8082
|
|
@@ -155,8 +156,10 @@ atomicshop/wrappers/dockerw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
|
|
|
155
156
|
atomicshop/wrappers/dockerw/dockerw.py,sha256=w8zSJr5C7cbvbuG09ORCpAe0BOcibqqL_Z2EKEBHYK4,6266
|
|
156
157
|
atomicshop/wrappers/dockerw/install_docker.py,sha256=dpSOmD690oLukoLCo0u6Pzh5fRyCWBuSQEtG8VwC3jk,2765
|
|
157
158
|
atomicshop/wrappers/elasticsearchw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
158
|
-
atomicshop/wrappers/elasticsearchw/config_basic.py,sha256=
|
|
159
|
-
atomicshop/wrappers/elasticsearchw/elasticsearchw.py,sha256=
|
|
159
|
+
atomicshop/wrappers/elasticsearchw/config_basic.py,sha256=XJMKKfDrUq9ZKxYnQ-xFJxSA51z31Nn4eB8_n_hryVk,800
|
|
160
|
+
atomicshop/wrappers/elasticsearchw/elasticsearchw.py,sha256=7TqFdEFznO8NlligJhEKk1vm641ALpCYdaRl1uoXdzM,9768
|
|
161
|
+
atomicshop/wrappers/elasticsearchw/infrastructure.py,sha256=J1hKIEQA8ImRUmkM25fbmwHbZPC9VnT9NK1_kOfXitA,8311
|
|
162
|
+
atomicshop/wrappers/elasticsearchw/install_elastic.py,sha256=Lez_Tt21Jlprz7EaRZlppzbpTkYerWkkHd9cfIwcyy8,8308
|
|
160
163
|
atomicshop/wrappers/elasticsearchw/queries/__init__.py,sha256=KBjT-bAt75CJsx1Apko9mpuFU4pfZV8DcGWQvpX65RU,78
|
|
161
164
|
atomicshop/wrappers/elasticsearchw/queries/aggregation.py,sha256=N9a5yMMnb10sMa_x1qJBFQpgyJ49UWo8_vxuqmUtZ1A,1742
|
|
162
165
|
atomicshop/wrappers/elasticsearchw/queries/info.py,sha256=P_VhhBo8MvRI4Shi-bh4RsYtlYNRKRBzScXPC64Up_Q,2900
|
|
@@ -173,7 +176,7 @@ atomicshop/wrappers/factw/fact_extractor/__init__.py,sha256=47DEQpj8HBSa-_TImW-5
|
|
|
173
176
|
atomicshop/wrappers/factw/fact_extractor/docker_image.py,sha256=jJAoJNQ4aoATjn3x_va031Obb4oBtcqCY40hydghm0s,2504
|
|
174
177
|
atomicshop/wrappers/factw/fact_extractor/get_extractor.py,sha256=2mfOAftHIlCcGt1s7MWdq7DsDCuI6wX3MtvcEZ4SK-0,756
|
|
175
178
|
atomicshop/wrappers/factw/install/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
176
|
-
atomicshop/wrappers/factw/install/install_after_restart.py,sha256=
|
|
179
|
+
atomicshop/wrappers/factw/install/install_after_restart.py,sha256=roM1W2hkDynpEKda55xd7AsZxodsFj8i4wmFGt_HHzA,1558
|
|
177
180
|
atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py,sha256=OWlT1h9XJChuKOT3GPa69nnrqxgM4TD9Cy-GR7E23LY,2377
|
|
178
181
|
atomicshop/wrappers/factw/postgresql/__init__.py,sha256=xMBn2d3Exo23IPP2F_9-SXmOlhFbwWDgS9KwozSTjA0,162
|
|
179
182
|
atomicshop/wrappers/factw/postgresql/analysis.py,sha256=2Rxzy2jyq3zEKIo53z8VkjuslKE_i5mq2ZpmJAvyd6U,716
|
|
@@ -197,7 +200,7 @@ atomicshop/wrappers/loggingw/loggingw.py,sha256=v9WAseZXB50LluT9rIUcRvvevg2nLVKP
|
|
|
197
200
|
atomicshop/wrappers/loggingw/reading.py,sha256=xs7L6Jo-vedrhCVP7m-cJo0VhWmoSoK86avR4Tm0kG4,3675
|
|
198
201
|
atomicshop/wrappers/playwrightw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
199
202
|
atomicshop/wrappers/playwrightw/_tryouts.py,sha256=l1BLkFsiIMNlgv7nfZd1XGEvXQkIQkIcg48__9OaC00,4920
|
|
200
|
-
atomicshop/wrappers/playwrightw/base.py,sha256=
|
|
203
|
+
atomicshop/wrappers/playwrightw/base.py,sha256=WeRpx8otdXuKSr-BjY-uCJTze21kbPpfitoOjKQz5-g,9818
|
|
201
204
|
atomicshop/wrappers/playwrightw/combos.py,sha256=215y7wugyyBrFK9_0WutnMXsF1jqJ2PLm9eHEa2PMz0,7145
|
|
202
205
|
atomicshop/wrappers/playwrightw/engine.py,sha256=Ik9hysgJAtjbzr6ED-9gRBaxnt3cNt5hu1u4ut_M3To,14861
|
|
203
206
|
atomicshop/wrappers/playwrightw/javascript.py,sha256=CL3tVE9C4SVvy76FEgGCl77B-xziCG6JZR5Ed8IfcSo,1112
|
|
@@ -216,7 +219,7 @@ atomicshop/wrappers/socketw/accepter.py,sha256=HQC1EyZmyUtVEfFbaBkHCE-VZp6RWyd9m
|
|
|
216
219
|
atomicshop/wrappers/socketw/base.py,sha256=1vvg8EhRGvnxdrRAm1VJSLCXkm2SZDHRjdpTuhkH3Mg,1844
|
|
217
220
|
atomicshop/wrappers/socketw/certificator.py,sha256=SxCKFyBlwzs4uohugfBokOYQpZJyH8KY46m87Q23n6w,9017
|
|
218
221
|
atomicshop/wrappers/socketw/creator.py,sha256=C-l57G854HAtWJonVbgfQge290-Dg0Ov4aurJAWIKls,11199
|
|
219
|
-
atomicshop/wrappers/socketw/dns_server.py,sha256=
|
|
222
|
+
atomicshop/wrappers/socketw/dns_server.py,sha256=laMR_opplvytVTvVcztNoDChZGMCDR31fDQejrCNaEI,42032
|
|
220
223
|
atomicshop/wrappers/socketw/exception_wrapper.py,sha256=_YDnzyEcUnV6VISU3bk-UPdnsMvHjKJBHwxLMTsxQu8,8495
|
|
221
224
|
atomicshop/wrappers/socketw/get_process.py,sha256=APw_oOXsuR5KljYesd4J8MuzR-kaw2ez3MN3oD_h9Qc,5226
|
|
222
225
|
atomicshop/wrappers/socketw/receiver.py,sha256=m8hXKOa8dqEQGUdcbYjshH8-j0CsMGRkge2ifYKhaAw,9050
|
|
@@ -227,8 +230,8 @@ atomicshop/wrappers/socketw/socket_server_tester.py,sha256=AhpurHJmP2kgzHaUbq5ey
|
|
|
227
230
|
atomicshop/wrappers/socketw/socket_wrapper.py,sha256=aXBwlEIJhFT0-c4i8iNlFx2It9VpCEpsv--5Oqcpxao,11624
|
|
228
231
|
atomicshop/wrappers/socketw/ssl_base.py,sha256=k4V3gwkbq10MvOH4btU4onLX2GNOsSfUAdcHmL1rpVE,2274
|
|
229
232
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=t3dtDEfN47CfYVi0CW6Kc2QHTEeZVyYhc57IYYh5nmA,826
|
|
230
|
-
atomicshop-2.9.
|
|
231
|
-
atomicshop-2.9.
|
|
232
|
-
atomicshop-2.9.
|
|
233
|
-
atomicshop-2.9.
|
|
234
|
-
atomicshop-2.9.
|
|
233
|
+
atomicshop-2.9.15.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
234
|
+
atomicshop-2.9.15.dist-info/METADATA,sha256=Pvhwhgb3o01SAy7xGphWOTiNIaCfMSxpVvgdSzOX9XE,10423
|
|
235
|
+
atomicshop-2.9.15.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
236
|
+
atomicshop-2.9.15.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
237
|
+
atomicshop-2.9.15.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|