atomicshop 2.18.2__py3-none-any.whl → 2.18.3__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 +7 -6
- atomicshop/mitm/mitm_main.py +4 -1
- atomicshop/python_functions.py +53 -16
- atomicshop/websocket_parse.py +4 -4
- {atomicshop-2.18.2.dist-info → atomicshop-2.18.3.dist-info}/METADATA +1 -1
- {atomicshop-2.18.2.dist-info → atomicshop-2.18.3.dist-info}/RECORD +10 -10
- {atomicshop-2.18.2.dist-info → atomicshop-2.18.3.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.18.2.dist-info → atomicshop-2.18.3.dist-info}/WHEEL +0 -0
- {atomicshop-2.18.2.dist-info → atomicshop-2.18.3.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
|
@@ -98,7 +98,6 @@ def thread_worker_main(
|
|
|
98
98
|
raw_bytes: bytes,
|
|
99
99
|
client_message: ClientMessage):
|
|
100
100
|
nonlocal protocol
|
|
101
|
-
nonlocal protocol3
|
|
102
101
|
|
|
103
102
|
# Parsing the raw bytes as HTTP.
|
|
104
103
|
request_http_parsed, is_http_request, request_parsing_error = (
|
|
@@ -120,9 +119,6 @@ def thread_worker_main(
|
|
|
120
119
|
auto_parsed = response_http_parsed
|
|
121
120
|
network_logger.info(
|
|
122
121
|
f"HTTP Response Parsed: Status: {response_http_parsed.code}")
|
|
123
|
-
protocol3 = auto_parsed.headers.get('Sec-WebSocket-Protocol', None)
|
|
124
|
-
if protocol3:
|
|
125
|
-
client_message.protocol3 = protocol3
|
|
126
122
|
elif protocol == 'Websocket':
|
|
127
123
|
client_message.protocol2 = 'Frame'
|
|
128
124
|
auto_parsed = parse_websocket(raw_bytes)
|
|
@@ -137,12 +133,16 @@ def thread_worker_main(
|
|
|
137
133
|
auto_parsed,
|
|
138
134
|
client_message: ClientMessage):
|
|
139
135
|
nonlocal protocol
|
|
136
|
+
nonlocal protocol3
|
|
140
137
|
|
|
141
138
|
if protocol == 'HTTP':
|
|
142
139
|
if auto_parsed and hasattr(auto_parsed, 'headers') and 'Upgrade' in auto_parsed.headers:
|
|
143
140
|
if auto_parsed.headers['Upgrade'] == 'websocket':
|
|
144
141
|
protocol = 'Websocket'
|
|
145
142
|
client_message.protocol2 = 'Handshake'
|
|
143
|
+
protocol3 = auto_parsed.headers.get('Sec-WebSocket-Protocol', None)
|
|
144
|
+
if protocol3:
|
|
145
|
+
client_message.protocol3 = protocol3
|
|
146
146
|
|
|
147
147
|
network_logger.info(f'Protocol upgraded to Websocket')
|
|
148
148
|
|
|
@@ -171,7 +171,7 @@ def thread_worker_main(
|
|
|
171
171
|
|
|
172
172
|
# If it's the first cycle and the protocol is Websocket, then we'll create the HTTP Handshake
|
|
173
173
|
# response automatically.
|
|
174
|
-
if protocol == 'Websocket' and client_receive_count ==
|
|
174
|
+
if protocol == 'Websocket' and client_receive_count == 1:
|
|
175
175
|
responses: list = list()
|
|
176
176
|
responses.append(
|
|
177
177
|
websocket_parse.create_byte_http_response(client_message.request_raw_bytes))
|
|
@@ -240,11 +240,12 @@ def thread_worker_main(
|
|
|
240
240
|
return
|
|
241
241
|
|
|
242
242
|
client_message.response_auto_parsed = parse_http(client_message.request_raw_bytes, client_message)
|
|
243
|
+
# This is needed for each cycle that is not HTTP, but its protocol maybe set by HTTP, like websocket.
|
|
243
244
|
if protocol != '':
|
|
244
245
|
client_message.protocol = protocol
|
|
245
246
|
|
|
246
247
|
# Parse websocket frames only if it is not the first protocol upgrade request.
|
|
247
|
-
if protocol == 'Websocket' and client_receive_count !=
|
|
248
|
+
if protocol == 'Websocket' and client_receive_count != 1:
|
|
248
249
|
client_message.request_auto_parsed = parse_websocket(client_message.request_raw_bytes)
|
|
249
250
|
|
|
250
251
|
# Custom parser, should parse HTTP body or the whole message if not HTTP.
|
atomicshop/mitm/mitm_main.py
CHANGED
|
@@ -3,6 +3,8 @@ import multiprocessing
|
|
|
3
3
|
import time
|
|
4
4
|
import datetime
|
|
5
5
|
|
|
6
|
+
from distro import minor_version
|
|
7
|
+
|
|
6
8
|
import atomicshop # Importing atomicshop package to get the version of the package.
|
|
7
9
|
|
|
8
10
|
from .. import filesystem, queues, dns, on_exit, print_api
|
|
@@ -65,7 +67,8 @@ def mitm_server(config_file_path: str):
|
|
|
65
67
|
# Main function should return integer with error code, 0 is successful.
|
|
66
68
|
# Since listening server is infinite, this will not be reached.
|
|
67
69
|
# After modules import - we check for python version.
|
|
68
|
-
check_python_version_compliance(
|
|
70
|
+
if not check_python_version_compliance(minor_version='3.12'):
|
|
71
|
+
return 1
|
|
69
72
|
|
|
70
73
|
# Import the configuration file.
|
|
71
74
|
result = config_static.load_config(config_file_path)
|
atomicshop/python_functions.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import sys
|
|
2
|
+
from typing import Union
|
|
2
3
|
|
|
3
4
|
from .print_api import print_api
|
|
4
5
|
|
|
@@ -43,23 +44,46 @@ def check_if_version_object_is_tuple_or_string(version_object: any,
|
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
# noinspection PyUnusedLocal
|
|
46
|
-
def check_python_version_compliance(
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
def check_python_version_compliance(
|
|
48
|
+
minimum_version: Union[str, tuple] = None,
|
|
49
|
+
maximum_version: Union[str, tuple] = None,
|
|
50
|
+
minor_version: Union[str, tuple] = None,
|
|
51
|
+
**kwargs
|
|
52
|
+
) -> bool:
|
|
49
53
|
"""
|
|
50
54
|
Python version check. Should be executed before importing external libraries, since they depend on Python version.
|
|
51
55
|
|
|
52
56
|
:param minimum_version: Can be string ('3.10') or tuple of integers ((3, 10)).
|
|
53
57
|
:param maximum_version: Can be string ('3.10') or tuple of integers ((3, 10)).
|
|
54
58
|
If maximum version is not specified, it will be considered as all versions above the minimum are compliant.
|
|
59
|
+
:param minor_version: Can be string ('3.10') or tuple of integers ((3, 10)).
|
|
60
|
+
If minor version is specified, it will be considered as all the versions with the same major, minor version
|
|
61
|
+
are compliant. Example: if minor_version is '3.10', then all the versions with '3.10.x' are compliant.
|
|
55
62
|
:return:
|
|
56
63
|
"""
|
|
57
64
|
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
if not minimum_version and not maximum_version and not minor_version:
|
|
66
|
+
raise ValueError("At least one of the version parameters should be passed.")
|
|
67
|
+
|
|
68
|
+
if minor_version and (minimum_version or maximum_version):
|
|
69
|
+
raise ValueError("Minor version should be passed alone.")
|
|
70
|
+
|
|
71
|
+
# Check objects for string or tuple and get the tuple.
|
|
72
|
+
if minimum_version:
|
|
73
|
+
minimum_version_scheme: tuple = check_if_version_object_is_tuple_or_string(minimum_version, **kwargs)
|
|
74
|
+
else:
|
|
75
|
+
minimum_version_scheme = tuple()
|
|
60
76
|
# If 'maximum_version' object was passed, check it for string or tuple and get the tuple.
|
|
61
77
|
if maximum_version:
|
|
62
78
|
maximum_version_scheme: tuple = check_if_version_object_is_tuple_or_string(maximum_version, **kwargs)
|
|
79
|
+
else:
|
|
80
|
+
maximum_version_scheme = tuple()
|
|
81
|
+
|
|
82
|
+
# If 'minor_version' object was passed, check it for string or tuple and get the tuple.
|
|
83
|
+
if minor_version:
|
|
84
|
+
minor_version_scheme: tuple = check_if_version_object_is_tuple_or_string(minor_version, **kwargs)
|
|
85
|
+
else:
|
|
86
|
+
minor_version_scheme = tuple()
|
|
63
87
|
|
|
64
88
|
# Get current python version.
|
|
65
89
|
python_version_full: str = get_current_python_version_string()
|
|
@@ -67,24 +91,37 @@ def check_python_version_compliance(minimum_version: any,
|
|
|
67
91
|
message = f"[*] Current Python Version: {python_version_full}"
|
|
68
92
|
print_api(message, logger_method='info', **kwargs)
|
|
69
93
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
94
|
+
if minor_version_scheme:
|
|
95
|
+
# Check if current python version is later or equals to the minimum required version.
|
|
96
|
+
if sys.version_info[:2] != minor_version_scheme:
|
|
97
|
+
message = f"[!!!] YOU NEED TO INSTALL ANY PYTHON " \
|
|
98
|
+
f"[{'.'.join(str(i) for i in minor_version_scheme)}] version, " \
|
|
99
|
+
f"to work properly."
|
|
100
|
+
print_api(message, error_type=True, logger_method='critical', **kwargs)
|
|
101
|
+
|
|
102
|
+
return False
|
|
103
|
+
elif minimum_version_scheme and maximum_version_scheme:
|
|
73
104
|
if not sys.version_info >= minimum_version_scheme or not sys.version_info < maximum_version_scheme:
|
|
74
105
|
message = f"[!!!] YOU NEED TO INSTALL AT LEAST PYTHON " \
|
|
75
|
-
f"{'.'.join(str(i) for i in minimum_version_scheme)}, " \
|
|
76
|
-
f"AND EARLIER THAN {'.'.join(str(i) for i in maximum_version_scheme)}, " \
|
|
77
|
-
f"to work properly.
|
|
106
|
+
f"[{'.'.join(str(i) for i in minimum_version_scheme)}], " \
|
|
107
|
+
f"AND EARLIER THAN [{'.'.join(str(i) for i in maximum_version_scheme)}], " \
|
|
108
|
+
f"to work properly."
|
|
78
109
|
print_api(message, error_type=True, logger_method='critical', **kwargs)
|
|
79
110
|
|
|
80
111
|
return False
|
|
81
|
-
|
|
82
|
-
else:
|
|
83
|
-
# Check if current python version is later or equals to the minimum required version.
|
|
112
|
+
elif minimum_version_scheme and not maximum_version_scheme:
|
|
84
113
|
if not sys.version_info >= minimum_version_scheme:
|
|
85
114
|
message = f"[!!!] YOU NEED TO INSTALL AT LEAST PYTHON " \
|
|
86
|
-
f"{'.'.join(str(i) for i in minimum_version_scheme)}, " \
|
|
87
|
-
f"to work properly.
|
|
115
|
+
f"[{'.'.join(str(i) for i in minimum_version_scheme)}], " \
|
|
116
|
+
f"to work properly."
|
|
117
|
+
print_api(message, error_type=True, logger_method='critical', **kwargs)
|
|
118
|
+
|
|
119
|
+
return False
|
|
120
|
+
elif not minimum_version_scheme and maximum_version_scheme:
|
|
121
|
+
if not sys.version_info < maximum_version_scheme:
|
|
122
|
+
message = f"[!!!] YOU NEED TO INSTALL EARLIER THAN PYTHON " \
|
|
123
|
+
f"[{'.'.join(str(i) for i in maximum_version_scheme)}], " \
|
|
124
|
+
f"to work properly."
|
|
88
125
|
print_api(message, error_type=True, logger_method='critical', **kwargs)
|
|
89
126
|
|
|
90
127
|
return False
|
atomicshop/websocket_parse.py
CHANGED
|
@@ -133,11 +133,11 @@ class WebsocketFrameParser:
|
|
|
133
133
|
elif current_frame.opcode == Opcode.BINARY:
|
|
134
134
|
return current_frame.data, 'BINARY'
|
|
135
135
|
elif current_frame.opcode == Opcode.CLOSE:
|
|
136
|
-
return
|
|
136
|
+
return current_frame.data, 'CLOSE'
|
|
137
137
|
elif current_frame.opcode == Opcode.PING:
|
|
138
|
-
return
|
|
138
|
+
return current_frame.data, 'PING'
|
|
139
139
|
elif current_frame.opcode == Opcode.PONG:
|
|
140
|
-
return
|
|
140
|
+
return current_frame.data, 'PONG'
|
|
141
141
|
else:
|
|
142
142
|
raise WebsocketParseWrongOpcode("Received unknown frame with opcode:", current_frame.opcode)
|
|
143
143
|
|
|
@@ -239,7 +239,7 @@ def create_websocket_frame(
|
|
|
239
239
|
return frame_bytes
|
|
240
240
|
|
|
241
241
|
|
|
242
|
-
def is_frame_masked(frame_bytes):
|
|
242
|
+
def is_frame_masked(frame_bytes: bytes):
|
|
243
243
|
"""
|
|
244
244
|
Determine whether a WebSocket frame is masked.
|
|
245
245
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=aciLHL-9AkNeS_Ahx9NP3lvs533n84eEd96p1hCCdRU,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
|
|
@@ -28,7 +28,7 @@ atomicshop/pbtkmultifile_argparse.py,sha256=aEk8nhvoQVu-xyfZosK3ma17CwIgOjzO1erX
|
|
|
28
28
|
atomicshop/print_api.py,sha256=q9dAQCASk3pHp_PtYIpr6iZmRcW_lvrV_gPPNwTMRsw,11152
|
|
29
29
|
atomicshop/process.py,sha256=PeLvyixXaCfftdUF3oMbohI1L4MdLtvQVDx2V1Tz_Rk,16662
|
|
30
30
|
atomicshop/python_file_patcher.py,sha256=-uhbUX-um5k-If_XXuOfCr8wMzZ3QE6h9N8xGWw6W_o,5486
|
|
31
|
-
atomicshop/python_functions.py,sha256=
|
|
31
|
+
atomicshop/python_functions.py,sha256=BPZ3sv5DgQs6Xrl3nIMdPABRpgrau3XSrsnDIz-LEwY,6175
|
|
32
32
|
atomicshop/question_answer_engine.py,sha256=7nM6kGDSFjQNi87b87-kP9lYM0vTjBHn1rEQGNAfdGA,825
|
|
33
33
|
atomicshop/queues.py,sha256=Al0fdC3ZJmdKfv-PyBeIck9lnfLr82BYchvzr189gsI,640
|
|
34
34
|
atomicshop/scheduling.py,sha256=MvF20M6uU0Kh_CQn2ERxMTLvvF-ToBrdMhXNrKxYFj8,4682
|
|
@@ -46,7 +46,7 @@ atomicshop/uuids.py,sha256=JSQdm3ZTJiwPQ1gYe6kU0TKS_7suwVrHc8JZDGYlydM,2214
|
|
|
46
46
|
atomicshop/venvs.py,sha256=D9lwOoObkYoRx-weuoAmbvN-RdSHhVm4DE9TVl-utAs,903
|
|
47
47
|
atomicshop/virtualization.py,sha256=LPP4vjE0Vr10R6DA4lqhfX_WaNdDGRAZUW0Am6VeGco,494
|
|
48
48
|
atomicshop/web.py,sha256=GLdTXgMxg1_0UQaXC4bOvARVyuFg7SPIeJdsCHV8rNE,11662
|
|
49
|
-
atomicshop/websocket_parse.py,sha256=
|
|
49
|
+
atomicshop/websocket_parse.py,sha256=aLHWyKqaYqEn_MRBWm2L6rIl6QPmqbVrjEXE_rBzwCw,16711
|
|
50
50
|
atomicshop/a_installs/ubuntu/docker_rootless.py,sha256=9IPNtGZYjfy1_n6ZRt7gWz9KZgR6XCgevjqq02xk-o0,281
|
|
51
51
|
atomicshop/a_installs/ubuntu/docker_sudo.py,sha256=JzayxeyKDtiuT4Icp2L2LyFRbx4wvpyN_bHLfZ-yX5E,281
|
|
52
52
|
atomicshop/a_installs/ubuntu/elastic_search_and_kibana.py,sha256=yRB-l1zBxdiN6av-FwNkhcBlaeu4zrDPjQ0uPGgpK2I,244
|
|
@@ -127,11 +127,11 @@ atomicshop/file_io/xmls.py,sha256=zh3SuK-dNaFq2NDNhx6ivcf4GYCfGM8M10PcEwDSpxk,21
|
|
|
127
127
|
atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
128
128
|
atomicshop/mitm/config_static.py,sha256=HIzxyMEj7DZksYvJsN5VuKpB-_HSVvuR6U59ztS9gi0,7871
|
|
129
129
|
atomicshop/mitm/config_toml_editor.py,sha256=2p1CMcktWRR_NW-SmyDwylu63ad5e0-w1QPMa8ZLDBw,1635
|
|
130
|
-
atomicshop/mitm/connection_thread_worker.py,sha256=
|
|
130
|
+
atomicshop/mitm/connection_thread_worker.py,sha256=Of-QmuIbUO8Qd1N_BXdGQk2TnPpZd2z-Pxrj0wyq9S8,26758
|
|
131
131
|
atomicshop/mitm/import_config.py,sha256=0Ij14aISTllTOiWYJpIUMOWobQqGofD6uafui5uWllE,9272
|
|
132
132
|
atomicshop/mitm/initialize_engines.py,sha256=NWz0yBErSrYBn0xWkJDBcHStBJ-kcsv9VtorcSP9x5M,8258
|
|
133
133
|
atomicshop/mitm/message.py,sha256=mNo4Lphr_Jo6IlNX5mPJzABpogWGkjOhwI4meAivwHw,2987
|
|
134
|
-
atomicshop/mitm/mitm_main.py,sha256=
|
|
134
|
+
atomicshop/mitm/mitm_main.py,sha256=3F227Vh-F2ZGxOPE7eP4bgIZ72e3BzdUAHhWIMBbhFo,23490
|
|
135
135
|
atomicshop/mitm/recs_files.py,sha256=ZAAD0twun-FtmbSniXe3XQhIlawvANNB_HxwbHj7kwI,3151
|
|
136
136
|
atomicshop/mitm/shared_functions.py,sha256=0lzeyINd44sVEfFbahJxQmz6KAMWbYrW5ou3UYfItvw,1777
|
|
137
137
|
atomicshop/mitm/statistic_analyzer.py,sha256=5_sAYGX2Xunzo_pS2W5WijNCwr_BlGJbbOO462y_wN4,27533
|
|
@@ -319,8 +319,8 @@ atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0L
|
|
|
319
319
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=fgMzDXI0cybwUEqAxprRmY3lqbh30KAV-jOpoFKT-m8,3395
|
|
320
320
|
atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
321
321
|
atomicshop/wrappers/winregw/winreg_network.py,sha256=zZQfps-CdODQaTUADbHAwKHr5RUg7BLafnKWBbKaLN4,8728
|
|
322
|
-
atomicshop-2.18.
|
|
323
|
-
atomicshop-2.18.
|
|
324
|
-
atomicshop-2.18.
|
|
325
|
-
atomicshop-2.18.
|
|
326
|
-
atomicshop-2.18.
|
|
322
|
+
atomicshop-2.18.3.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
323
|
+
atomicshop-2.18.3.dist-info/METADATA,sha256=9sxUGrK_-bQdIzS6k4nNclLdMORnzGbWBI4vqP7c378,10499
|
|
324
|
+
atomicshop-2.18.3.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
325
|
+
atomicshop-2.18.3.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
326
|
+
atomicshop-2.18.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|