atomicshop 2.16.48__py3-none-any.whl → 2.17.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of atomicshop might be problematic. Click here for more details.
- atomicshop/__init__.py +1 -1
- atomicshop/mitm/connection_thread_worker.py +17 -4
- atomicshop/mitm/engines/create_module_template.py +18 -7
- atomicshop/mitm/initialize_engines.py +13 -8
- atomicshop/wrappers/socketw/certificator.py +5 -2
- atomicshop/wrappers/socketw/creator.py +38 -7
- atomicshop/wrappers/socketw/socket_client.py +15 -9
- {atomicshop-2.16.48.dist-info → atomicshop-2.17.0.dist-info}/METADATA +1 -1
- {atomicshop-2.16.48.dist-info → atomicshop-2.17.0.dist-info}/RECORD +12 -12
- {atomicshop-2.16.48.dist-info → atomicshop-2.17.0.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.16.48.dist-info → atomicshop-2.17.0.dist-info}/WHEEL +0 -0
- {atomicshop-2.16.48.dist-info → atomicshop-2.17.0.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
|
@@ -198,6 +198,14 @@ def thread_worker_main(
|
|
|
198
198
|
responder.logger.info(f"{response_raw_bytes_single[0: 100]}...")
|
|
199
199
|
|
|
200
200
|
def create_client_socket():
|
|
201
|
+
# If there is a custom certificate for the client for this domain, then we'll use it.
|
|
202
|
+
# noinspection PyTypeChecker
|
|
203
|
+
custom_client_pem_certificate_path: str = None
|
|
204
|
+
for subdomain, pem_file_path in mtls_dict.items():
|
|
205
|
+
if subdomain == client_message.server_name:
|
|
206
|
+
custom_client_pem_certificate_path = pem_file_path
|
|
207
|
+
break
|
|
208
|
+
|
|
201
209
|
# If we're on localhost, then use external services list in order to resolve the domain:
|
|
202
210
|
# config['tcp']['forwarding_dns_service_ipv4_list___only_for_localhost']
|
|
203
211
|
if client_message.client_ip in base.THIS_DEVICE_IP_LIST:
|
|
@@ -206,13 +214,18 @@ def thread_worker_main(
|
|
|
206
214
|
tls=is_tls,
|
|
207
215
|
dns_servers_list=(
|
|
208
216
|
config_static.TCPServer.forwarding_dns_service_ipv4_list___only_for_localhost),
|
|
209
|
-
logger=network_logger
|
|
217
|
+
logger=network_logger,
|
|
218
|
+
custom_pem_client_certificate_file_path=custom_client_pem_certificate_path
|
|
210
219
|
)
|
|
211
220
|
# If we're not on localhost, then connect to domain directly.
|
|
212
221
|
else:
|
|
213
222
|
service_client_instance = socket_client.SocketClient(
|
|
214
|
-
service_name=client_message.server_name,
|
|
215
|
-
|
|
223
|
+
service_name=client_message.server_name,
|
|
224
|
+
service_port=client_message.destination_port,
|
|
225
|
+
tls=is_tls,
|
|
226
|
+
logger=network_logger,
|
|
227
|
+
custom_pem_client_certificate_file_path=custom_client_pem_certificate_path
|
|
228
|
+
)
|
|
216
229
|
|
|
217
230
|
return service_client_instance
|
|
218
231
|
|
|
@@ -277,7 +290,7 @@ def thread_worker_main(
|
|
|
277
290
|
|
|
278
291
|
# Loading parser by domain, if there is no parser for current domain - general reference parser is loaded.
|
|
279
292
|
# These should be outside any loop and initialized only once entering the thread.
|
|
280
|
-
parser, responder, recorder = assign_class_by_domain(
|
|
293
|
+
parser, responder, recorder, mtls_dict = assign_class_by_domain(
|
|
281
294
|
engines_usage=config_static.TCPServer.engines_usage,
|
|
282
295
|
engines_list=engines_list,
|
|
283
296
|
message_domain_name=server_name,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import argparse
|
|
2
3
|
from typing import Literal
|
|
3
4
|
|
|
4
5
|
from ... import filesystem
|
|
@@ -19,11 +20,17 @@ SCRIPT_DIRECTORY: str = filesystem.get_file_directory(__file__)
|
|
|
19
20
|
ENGINES_DIRECTORY_PATH: str = filesystem.get_working_directory() + os.sep + ENGINES_DIRECTORY_NAME
|
|
20
21
|
|
|
21
22
|
|
|
23
|
+
def parse_arguments():
|
|
24
|
+
parser = argparse.ArgumentParser(description='Create a new engine module template.')
|
|
25
|
+
parser.add_argument('engine_name', type=str, help='The name of the new engine.')
|
|
26
|
+
return parser.parse_args()
|
|
27
|
+
|
|
28
|
+
|
|
22
29
|
class CreateModuleTemplate:
|
|
23
|
-
def __init__(self
|
|
30
|
+
def __init__(self):
|
|
24
31
|
# === Get input variables. ===
|
|
25
|
-
self.engine_name: str = engine_name
|
|
26
|
-
self.domains: list =
|
|
32
|
+
self.engine_name: str = parse_arguments().engine_name
|
|
33
|
+
self.domains: list = ['example.com']
|
|
27
34
|
|
|
28
35
|
# New engine's directory.
|
|
29
36
|
self.new_engine_directory: str = ENGINES_DIRECTORY_PATH + os.sep + self.engine_name
|
|
@@ -66,10 +73,14 @@ class CreateModuleTemplate:
|
|
|
66
73
|
|
|
67
74
|
# Add "" to each domain.
|
|
68
75
|
domains_with_quotes: list = [f'"{domain}"' for domain in self.domains]
|
|
69
|
-
config_lines_list.append(f'domains = [{", ".join(domains_with_quotes)}]\n')
|
|
70
|
-
config_lines_list.append(f'
|
|
71
|
-
config_lines_list.append(f'
|
|
72
|
-
config_lines_list.append(f'
|
|
76
|
+
config_lines_list.append(f'"domains" = [{", ".join(domains_with_quotes)}]\n')
|
|
77
|
+
# config_lines_list.append(f'\n')
|
|
78
|
+
config_lines_list.append(f'"parser_file" = "{self.parser_file_name}"')
|
|
79
|
+
config_lines_list.append(f'"responder_file" = "{self.responder_file_name}"')
|
|
80
|
+
config_lines_list.append(f'"recorder_file" = "{self.recorder_file_name}"\n')
|
|
81
|
+
# config_lines_list.append(f'\n')
|
|
82
|
+
config_lines_list.append(f'[mtls]')
|
|
83
|
+
config_lines_list.append(f'# "subdomain.domain.com" = "file_name_in_current_dir.pem"')
|
|
73
84
|
|
|
74
85
|
config_file_path = self.new_engine_directory + os.sep + CONFIG_FILE_NAME
|
|
75
86
|
|
|
@@ -2,7 +2,6 @@ import os
|
|
|
2
2
|
import sys
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
|
-
from .. import filesystem
|
|
6
5
|
from ..file_io import tomls
|
|
7
6
|
from ..basics.classes import import_first_class_name_from_file_path
|
|
8
7
|
from .engines.__reference_general import parser___reference_general, responder___reference_general, \
|
|
@@ -26,6 +25,8 @@ class ModuleCategory:
|
|
|
26
25
|
# The instance of the recorder class that will be initiated once in the script start
|
|
27
26
|
self.responder_instance = None
|
|
28
27
|
|
|
28
|
+
self.mtls: dict = dict()
|
|
29
|
+
|
|
29
30
|
def fill_engine_fields_from_general_reference(self, engines_fullpath: str):
|
|
30
31
|
# Reference module variables.
|
|
31
32
|
self.engine_name = '__reference_general'
|
|
@@ -44,6 +45,7 @@ class ModuleCategory:
|
|
|
44
45
|
|
|
45
46
|
# Getting the parameters from engine config file
|
|
46
47
|
self.domain_list = configuration_data['domains']
|
|
48
|
+
self.mtls = configuration_data['mtls']
|
|
47
49
|
|
|
48
50
|
# If there's module configuration file, but no domains in it, there's no point to continue.
|
|
49
51
|
# Since, each engine is based on domains.
|
|
@@ -51,12 +53,12 @@ class ModuleCategory:
|
|
|
51
53
|
raise ValueError(f"Engine Configuration file doesn't contain any domains: {engine_config_file_path}")
|
|
52
54
|
|
|
53
55
|
# Full path to file
|
|
54
|
-
self.parser_file_path =
|
|
55
|
-
|
|
56
|
-
self.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
56
|
+
self.parser_file_path = f'{engine_directory_path}{os.sep}{configuration_data['parser_file']}'
|
|
57
|
+
self.responder_file_path = f'{engine_directory_path}{os.sep}{configuration_data['responder_file']}'
|
|
58
|
+
self.recorder_file_path = f'{engine_directory_path}{os.sep}{configuration_data['recorder_file']}'
|
|
59
|
+
|
|
60
|
+
for subdomain, file_name in self.mtls.items():
|
|
61
|
+
self.mtls[subdomain] = f'{engine_directory_path}{os.sep}{file_name}'
|
|
60
62
|
|
|
61
63
|
def initialize_engine(self, logs_path: str, logger=None, reference_general: bool = False, **kwargs):
|
|
62
64
|
# Initiating logger for each engine by its name
|
|
@@ -105,6 +107,7 @@ def assign_class_by_domain(
|
|
|
105
107
|
function_parser = None
|
|
106
108
|
function_responder = None
|
|
107
109
|
function_recorder = None
|
|
110
|
+
mtls_data: dict = dict()
|
|
108
111
|
|
|
109
112
|
# In case SNI came empty in the request from client, then there's no point in iterating through engine domains.
|
|
110
113
|
if message_domain_name:
|
|
@@ -127,6 +130,8 @@ def assign_class_by_domain(
|
|
|
127
130
|
function_recorder = function_module.recorder_class_object
|
|
128
131
|
# Since the responder is being initiated only once, we're assigning only the instance
|
|
129
132
|
function_responder = function_module.responder_instance
|
|
133
|
+
mtls_data = function_module.mtls
|
|
134
|
+
|
|
130
135
|
|
|
131
136
|
logger.info(f"Assigned Modules for [{message_domain_name}]: "
|
|
132
137
|
f"{function_module.parser_class_object.__name__}, "
|
|
@@ -148,4 +153,4 @@ def assign_class_by_domain(
|
|
|
148
153
|
function_responder = reference_module.responder_instance
|
|
149
154
|
|
|
150
155
|
# Return all the initiated modules
|
|
151
|
-
return function_parser, function_responder, function_recorder
|
|
156
|
+
return function_parser, function_responder, function_recorder, mtls_data
|
|
@@ -154,13 +154,16 @@ class Certificator:
|
|
|
154
154
|
service_name=sni_received_parameters.destination_name,
|
|
155
155
|
service_port=base.get_destination_address_from_socket(sni_received_parameters.ssl_socket)[1],
|
|
156
156
|
tls=self.tls,
|
|
157
|
-
dns_servers_list=self.forwarding_dns_service_ipv4_list___only_for_localhost
|
|
157
|
+
dns_servers_list=self.forwarding_dns_service_ipv4_list___only_for_localhost,
|
|
158
|
+
logger=print_kwargs.get('logger') if print_kwargs else None
|
|
159
|
+
)
|
|
158
160
|
# If we're not on localhost, then connect to domain directly.
|
|
159
161
|
else:
|
|
160
162
|
service_client = socket_client.SocketClient(
|
|
161
163
|
service_name=sni_received_parameters.destination_name,
|
|
162
164
|
service_port=base.get_destination_address_from_socket(sni_received_parameters.ssl_socket)[1],
|
|
163
|
-
tls=self.tls
|
|
165
|
+
tls=self.tls,
|
|
166
|
+
logger=print_kwargs.get('logger') if print_kwargs else None
|
|
164
167
|
)
|
|
165
168
|
|
|
166
169
|
# If certificate from socket exists, then we don't need to get it from the socket and write to file.
|
|
@@ -37,11 +37,26 @@ def create_ssl_context_for_client():
|
|
|
37
37
|
return ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
|
|
38
38
|
|
|
39
39
|
|
|
40
|
-
def
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
def set_client_ssl_context_ca_default_certs(ssl_context):
|
|
41
|
+
"""
|
|
42
|
+
"load_default_certs" method is telling the client to check the local certificate storage on the system for the
|
|
43
|
+
needed certificate of the server. Without this line you will get an error from the server that the client
|
|
44
|
+
is using self-signed certificate. Which is partly true, since you used the SLL wrapper,
|
|
45
|
+
but didn't specify the certificate at all.
|
|
46
|
+
-----------------------------------------
|
|
47
|
+
https://docs.python.org/3/library/ssl.html#ssl.SSLContext.load_default_certs
|
|
48
|
+
Load a set of default “certification authority” (CA) certificates from default locations.
|
|
49
|
+
On Windows it loads CA certs from the CA and ROOT system stores.
|
|
50
|
+
On all systems it calls SSLContext.set_default_verify_paths().
|
|
51
|
+
In the future the method may load CA certificates from other locations, too.
|
|
52
|
+
|
|
53
|
+
The purpose flag specifies what kind of CA certificates are loaded.
|
|
54
|
+
The default settings Purpose.SERVER_AUTH loads certificates, that are flagged and trusted for
|
|
55
|
+
TLS web server authentication (client side sockets). Purpose.CLIENT_AUTH loads CA certificates for
|
|
56
|
+
client certificate verification on the server side.
|
|
57
|
+
-----------------------------------------
|
|
58
|
+
"""
|
|
59
|
+
|
|
45
60
|
# The purpose of the certificate is to authenticate on the server
|
|
46
61
|
# context.load_default_certs(Purpose.SERVER_AUTH)
|
|
47
62
|
# You don't have to specify the purpose to connect, but if you get a purpose error, you know where to find it
|
|
@@ -187,10 +202,26 @@ def set_listen_on_socket(socket_object, **kwargs):
|
|
|
187
202
|
# Socket Creator Presets
|
|
188
203
|
|
|
189
204
|
def wrap_socket_with_ssl_context_client___default_certs___ignore_verification(
|
|
190
|
-
socket_object,
|
|
205
|
+
socket_object,
|
|
206
|
+
server_hostname: str = None,
|
|
207
|
+
custom_pem_client_certificate_file_path: str = None
|
|
208
|
+
):
|
|
209
|
+
"""
|
|
210
|
+
This function is a preset for wrapping the socket with SSL context for the client.
|
|
211
|
+
It sets the CA default certificates, and ignores the server's certificate verification.
|
|
212
|
+
|
|
213
|
+
:param socket_object: socket.socket object
|
|
214
|
+
:param server_hostname: string, hostname of the server. Default is None.
|
|
215
|
+
:param custom_pem_client_certificate_file_path: string, full file path for the client certificate PWM file.
|
|
216
|
+
Default is None.
|
|
217
|
+
"""
|
|
191
218
|
ssl_context: ssl.SSLContext = create_ssl_context_for_client()
|
|
192
|
-
|
|
219
|
+
set_client_ssl_context_ca_default_certs(ssl_context)
|
|
193
220
|
set_client_ssl_context_certificate_verification_ignore(ssl_context)
|
|
221
|
+
|
|
222
|
+
if custom_pem_client_certificate_file_path:
|
|
223
|
+
ssl_context.load_cert_chain(certfile=custom_pem_client_certificate_file_path, keyfile=None)
|
|
224
|
+
|
|
194
225
|
ssl_socket: ssl.SSLSocket = wrap_socket_with_ssl_context_client(
|
|
195
226
|
socket_object, ssl_context, server_hostname=server_hostname)
|
|
196
227
|
|
|
@@ -16,7 +16,7 @@ from .sender import Sender
|
|
|
16
16
|
from . import ssl_base
|
|
17
17
|
from .. import cryptographyw
|
|
18
18
|
from ..loggingw import loggingw
|
|
19
|
-
from ...
|
|
19
|
+
from ... import print_api
|
|
20
20
|
from ...file_io import file_io
|
|
21
21
|
from ...basics import tracebacks
|
|
22
22
|
|
|
@@ -29,7 +29,8 @@ class SocketClient:
|
|
|
29
29
|
tls: bool = False,
|
|
30
30
|
connection_ip=None,
|
|
31
31
|
dns_servers_list=None,
|
|
32
|
-
logger: logging.Logger = None
|
|
32
|
+
logger: logging.Logger = None,
|
|
33
|
+
custom_pem_client_certificate_file_path: str = None
|
|
33
34
|
):
|
|
34
35
|
"""
|
|
35
36
|
If you have a certificate for domain, but not for the IPv4 address, the SSL Socket context can be created for
|
|
@@ -47,6 +48,8 @@ class SocketClient:
|
|
|
47
48
|
:param dns_servers_list: (Optional) List object with dns IPv4 addresses that 'service_name' will be resolved
|
|
48
49
|
with, using 'dnspython' module. 'connection_ip' will be populated with first resolved IP.
|
|
49
50
|
:param logger: (Optional) Logger object. If not provided, the default logger will be used.
|
|
51
|
+
:param custom_pem_client_certificate_file_path: (Optional) If specified, the SSL Socket will be created with
|
|
52
|
+
custom client certificate. The path to the file with the certificate should be provided.
|
|
50
53
|
|
|
51
54
|
If both 'connection_ip' and 'dns_servers_list' specified, ValueException with raise.
|
|
52
55
|
"""
|
|
@@ -55,6 +58,7 @@ class SocketClient:
|
|
|
55
58
|
self.tls: bool = tls
|
|
56
59
|
self.connection_ip = connection_ip
|
|
57
60
|
self.dns_servers_list = dns_servers_list
|
|
61
|
+
self.custom_pem_client_certificate_file_path: str = custom_pem_client_certificate_file_path
|
|
58
62
|
|
|
59
63
|
if logger:
|
|
60
64
|
# Create child logger for the provided logger with the module's name.
|
|
@@ -79,13 +83,15 @@ class SocketClient:
|
|
|
79
83
|
def create_service_socket(self):
|
|
80
84
|
# If TLS is enabled.
|
|
81
85
|
if not self.tls:
|
|
82
|
-
|
|
86
|
+
log_message: str = f"Creating non-SSL socket to [{self.service_name}:{self.service_port}]"
|
|
87
|
+
print_api.print_api(log_message, logger=self.logger, logger_method='info')
|
|
83
88
|
return creator.create_socket_ipv4_tcp()
|
|
84
89
|
else:
|
|
85
|
-
|
|
90
|
+
log_message: str = f"Creating SSL socket to [{self.service_name}:{self.service_port}]"
|
|
91
|
+
print_api.print_api(log_message, logger=self.logger, logger_method='info')
|
|
86
92
|
socket_object = creator.create_socket_ipv4_tcp()
|
|
87
93
|
return creator.wrap_socket_with_ssl_context_client___default_certs___ignore_verification(
|
|
88
|
-
socket_object, self.service_name)
|
|
94
|
+
socket_object, self.service_name, self.custom_pem_client_certificate_file_path)
|
|
89
95
|
|
|
90
96
|
def service_connection(
|
|
91
97
|
self
|
|
@@ -141,7 +147,7 @@ class SocketClient:
|
|
|
141
147
|
error_string = (
|
|
142
148
|
f"Socket Client Connect: {exception_type}: "
|
|
143
149
|
f"Domain {self.service_name} doesn't exist - Couldn't resolve with {self.dns_servers_list}.")
|
|
144
|
-
print_api(error_string, logger=self.logger, logger_method='error')
|
|
150
|
+
print_api.print_api(error_string, logger=self.logger, logger_method='error')
|
|
145
151
|
return None, error_string
|
|
146
152
|
|
|
147
153
|
# If DNS was resolved correctly or DNS servers weren't specified - we can try connecting.
|
|
@@ -165,14 +171,14 @@ class SocketClient:
|
|
|
165
171
|
if exception_type in ['ConnectionRefusedError', 'ConnectionAbortedError', 'ConnectionResetError',
|
|
166
172
|
'TimeoutError'] or 'ssl' in exception_type.lower():
|
|
167
173
|
error_message: str = f"{error_string}: {exception_error}"
|
|
168
|
-
print_api(error_message, logger=self.logger, logger_method='error')
|
|
174
|
+
print_api.print_api(error_message, logger=self.logger, logger_method='error')
|
|
169
175
|
return None, error_message
|
|
170
176
|
elif exception_type == 'socket.gaierror':
|
|
171
177
|
custom_error_message: str = (
|
|
172
178
|
f"Couldn't resolve [{self.service_name}] to IP using default methods. "
|
|
173
179
|
f"Domain doesn't exist or there's no IP assigned to it.")
|
|
174
180
|
error_message: str = f"{error_string}: {custom_error_message}"
|
|
175
|
-
print_api(error_message, logger=self.logger, logger_method='error')
|
|
181
|
+
print_api.print_api(error_message, logger=self.logger, logger_method='error')
|
|
176
182
|
return None, error_message
|
|
177
183
|
else:
|
|
178
184
|
raise e
|
|
@@ -370,7 +376,7 @@ class SocketClient:
|
|
|
370
376
|
server_socket_for_certificate, error_message = self.service_connection()
|
|
371
377
|
# Get the DER byte certificate from the socket.
|
|
372
378
|
certificate_from_socket_der_bytes = ssl_base.get_certificate_from_socket(server_socket_for_certificate)
|
|
373
|
-
print_api('Fetched certificate from socket.', logger=self.logger, **kwargs)
|
|
379
|
+
print_api.print_api('Fetched certificate from socket.', logger=self.logger, **kwargs)
|
|
374
380
|
# Close the socket.
|
|
375
381
|
self.close_socket()
|
|
376
382
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=JaX16ugkhtjjNo6Te9NZk6rsS2IsN9ETiFc6wSyNBes,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
|
|
@@ -126,16 +126,16 @@ atomicshop/file_io/xmls.py,sha256=zh3SuK-dNaFq2NDNhx6ivcf4GYCfGM8M10PcEwDSpxk,21
|
|
|
126
126
|
atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
127
127
|
atomicshop/mitm/config_static.py,sha256=ROAtbibSWSsF3BraUbhu-QO3MPIFqYY5KUKgsQbiSkk,7813
|
|
128
128
|
atomicshop/mitm/config_toml_editor.py,sha256=2p1CMcktWRR_NW-SmyDwylu63ad5e0-w1QPMa8ZLDBw,1635
|
|
129
|
-
atomicshop/mitm/connection_thread_worker.py,sha256=
|
|
129
|
+
atomicshop/mitm/connection_thread_worker.py,sha256=EtEp6aymfQ-btZzeZDmxLJdIortB4Gf5MOaHwEFSShI,21095
|
|
130
130
|
atomicshop/mitm/import_config.py,sha256=0Ij14aISTllTOiWYJpIUMOWobQqGofD6uafui5uWllE,9272
|
|
131
|
-
atomicshop/mitm/initialize_engines.py,sha256=
|
|
131
|
+
atomicshop/mitm/initialize_engines.py,sha256=NWz0yBErSrYBn0xWkJDBcHStBJ-kcsv9VtorcSP9x5M,8258
|
|
132
132
|
atomicshop/mitm/message.py,sha256=URR5JKSuAT8XmGIkyprEjlPW2GW4ef_gfUz_GgcFseE,2184
|
|
133
133
|
atomicshop/mitm/mitm_main.py,sha256=5c-9oxBiLueTbZr4Dyd4EEOorEUix5vSWxX9p5O1fBs,23375
|
|
134
134
|
atomicshop/mitm/recs_files.py,sha256=gzFuTonqcXkMvhpOj1Nwse3E8umFGrKN2H5AleMjJ3w,3051
|
|
135
135
|
atomicshop/mitm/shared_functions.py,sha256=0lzeyINd44sVEfFbahJxQmz6KAMWbYrW5ou3UYfItvw,1777
|
|
136
136
|
atomicshop/mitm/statistic_analyzer.py,sha256=5_sAYGX2Xunzo_pS2W5WijNCwr_BlGJbbOO462y_wN4,27533
|
|
137
137
|
atomicshop/mitm/engines/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
138
|
-
atomicshop/mitm/engines/create_module_template.py,sha256=
|
|
138
|
+
atomicshop/mitm/engines/create_module_template.py,sha256=TAzsA4eLD2wYr7auuL4Nf_71iXqn-BOBXlSkNVrnYD4,5336
|
|
139
139
|
atomicshop/mitm/engines/create_module_template_example.py,sha256=X5xhvbV6-g9jU_bQVhf_crZmaH50LRWz3bS-faQ18ds,489
|
|
140
140
|
atomicshop/mitm/engines/__parent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
141
141
|
atomicshop/mitm/engines/__parent/parser___parent.py,sha256=RK2wviepP0oeq7zuLpgkvqvTJtc0r0a7hDGWdV0dGc4,657
|
|
@@ -303,23 +303,23 @@ atomicshop/wrappers/pywin32w/wmis/win32process.py,sha256=qMzXtJ5hBZ5ydAyqpDbSx0n
|
|
|
303
303
|
atomicshop/wrappers/socketw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
304
304
|
atomicshop/wrappers/socketw/accepter.py,sha256=hZZKVYlF3LOHQJsSIEKXZUf6QXXWm-AtqXZevvaYigE,1732
|
|
305
305
|
atomicshop/wrappers/socketw/base.py,sha256=DV6BWao9kiLAWimhVDKGEi3ISVaWk5iPHXtBHrO3uwc,2264
|
|
306
|
-
atomicshop/wrappers/socketw/certificator.py,sha256=
|
|
307
|
-
atomicshop/wrappers/socketw/creator.py,sha256=
|
|
306
|
+
atomicshop/wrappers/socketw/certificator.py,sha256=mtWPJ_ew3OSwt0-1W4jaoco1VIY4NRCrMv3mDUxb_Cc,12418
|
|
307
|
+
atomicshop/wrappers/socketw/creator.py,sha256=OLcd7FyUk_k8iyoL-xYnCnNmolPSgio6OeQXth7NdLg,11414
|
|
308
308
|
atomicshop/wrappers/socketw/dns_server.py,sha256=RklzINNuoMQn4PGGQEI5hiAldprbVwwvikY6u9X-jTY,49067
|
|
309
309
|
atomicshop/wrappers/socketw/exception_wrapper.py,sha256=B-X5SHLSUIWToihH2MKnOB1F4A81_X0DpLLfnYKYbEc,7067
|
|
310
310
|
atomicshop/wrappers/socketw/get_process.py,sha256=aJC-_qFUv3NgWCSUzDI72E4z8_-VTZE9NVZ0CwUoNlM,5698
|
|
311
311
|
atomicshop/wrappers/socketw/receiver.py,sha256=-QtKK0T_lmoAIypTYaIKOD3pgB1npWGPxcVEN37y_gk,10060
|
|
312
312
|
atomicshop/wrappers/socketw/sender.py,sha256=gwSzF51QD5paeeFav6fpbQpO8KgBO5lNztHYQyN5id0,4959
|
|
313
313
|
atomicshop/wrappers/socketw/sni.py,sha256=Nc8WMZZR21o5GXILQLVWbf7OzNPXAfE8trJY153e9Qk,17591
|
|
314
|
-
atomicshop/wrappers/socketw/socket_client.py,sha256=
|
|
314
|
+
atomicshop/wrappers/socketw/socket_client.py,sha256=YUlwbasxYQqz1xUlPWxwEnSDSCYKGdxWb2CFAogefr8,21131
|
|
315
315
|
atomicshop/wrappers/socketw/socket_server_tester.py,sha256=Qobmh4XV8ZxLUaw-eW4ESKAbeSLecCKn2OWFzMhadk0,6420
|
|
316
316
|
atomicshop/wrappers/socketw/socket_wrapper.py,sha256=WtylpezgIIBuz-A6PfM0hO1sm9Exd4j3qhDXcFc74-E,35567
|
|
317
317
|
atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0LxIwBA4iVvU,2275
|
|
318
318
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=SDYI1cN0oaapvPeLxSXiJrelTy6xbZl-bopR0jAjVGE,3149
|
|
319
319
|
atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
320
320
|
atomicshop/wrappers/winregw/winreg_network.py,sha256=zZQfps-CdODQaTUADbHAwKHr5RUg7BLafnKWBbKaLN4,8728
|
|
321
|
-
atomicshop-2.
|
|
322
|
-
atomicshop-2.
|
|
323
|
-
atomicshop-2.
|
|
324
|
-
atomicshop-2.
|
|
325
|
-
atomicshop-2.
|
|
321
|
+
atomicshop-2.17.0.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
322
|
+
atomicshop-2.17.0.dist-info/METADATA,sha256=MG763mizxXrtHLWqgLymqhAomm0BYskwwRsHU-mvJpY,10499
|
|
323
|
+
atomicshop-2.17.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
324
|
+
atomicshop-2.17.0.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
325
|
+
atomicshop-2.17.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|