atomicshop 2.18.0__py3-none-any.whl → 2.18.2__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 CHANGED
@@ -1,4 +1,4 @@
1
1
  """Atomic Basic functions and classes to make developer life easier"""
2
2
 
3
3
  __author__ = "Den Kras"
4
- __version__ = '2.18.0'
4
+ __version__ = '2.18.2'
@@ -4,7 +4,7 @@ from dataclasses import dataclass
4
4
  from . import import_config
5
5
 
6
6
 
7
- SCRIPT_VERSION: str = '1.7.6'
7
+ SCRIPT_VERSION: str = '1.7.8'
8
8
  """
9
9
  added ca cert check and installation
10
10
  """
@@ -72,6 +72,7 @@ def thread_worker_main(
72
72
  tls_version=tls_version,
73
73
  protocol=client_message.protocol,
74
74
  protocol2=client_message.protocol2,
75
+ protocol3=client_message.protocol3,
75
76
  path=http_path,
76
77
  status_code=http_status_code,
77
78
  command=http_command,
@@ -97,6 +98,8 @@ def thread_worker_main(
97
98
  raw_bytes: bytes,
98
99
  client_message: ClientMessage):
99
100
  nonlocal protocol
101
+ nonlocal protocol3
102
+
100
103
  # Parsing the raw bytes as HTTP.
101
104
  request_http_parsed, is_http_request, request_parsing_error = (
102
105
  HTTPRequestParse(raw_bytes).parse())
@@ -117,9 +120,14 @@ def thread_worker_main(
117
120
  auto_parsed = response_http_parsed
118
121
  network_logger.info(
119
122
  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
120
126
  elif protocol == 'Websocket':
121
127
  client_message.protocol2 = 'Frame'
122
128
  auto_parsed = parse_websocket(raw_bytes)
129
+ if protocol3:
130
+ client_message.protocol3 = protocol3
123
131
  else:
124
132
  auto_parsed = None
125
133
 
@@ -276,6 +284,41 @@ def thread_worker_main(
276
284
 
277
285
  return client_message
278
286
 
287
+ def responder_thread_worker():
288
+ nonlocal exception_or_close_in_receiving_thread
289
+
290
+ client_message: ClientMessage = client_message_first_start()
291
+ try:
292
+ while True:
293
+ client_message = responder_queue.get()
294
+
295
+ # If the message is not a ClientMessage object, then we'll break the loop, since it is the exit signal.
296
+ if not isinstance(client_message, ClientMessage):
297
+ return
298
+
299
+ raw_responses: list[bytes] = create_responder_response(client_message)
300
+
301
+ is_socket_closed: bool = False
302
+ for response_raw_bytes in raw_responses:
303
+ client_message.reinitialize_dynamic_vars()
304
+ client_message.timestamp = datetime.now()
305
+ client_message.response_raw_bytes = response_raw_bytes
306
+ error_on_send: str = sender.Sender(
307
+ ssl_socket=client_socket, class_message=client_message.response_raw_bytes,
308
+ logger=network_logger).send()
309
+
310
+ # If there was problem with sending data, we'll break the main while loop.
311
+ if error_on_send:
312
+ client_message.errors.append(error_on_send)
313
+ record_and_statistics_write(client_message)
314
+ is_socket_closed = True
315
+
316
+ if is_socket_closed:
317
+ exception_or_close_in_receiving_thread = True
318
+ return
319
+ except Exception as exc:
320
+ handle_exceptions_on_sub_connection_thread(client_message, client_exception_queue, exc)
321
+
279
322
  def receive_send_start(
280
323
  receiving_socket,
281
324
  sending_socket = None,
@@ -339,33 +382,14 @@ def thread_worker_main(
339
382
  # the close on the opposite socket.
340
383
  record_and_statistics_write(client_message)
341
384
 
342
- if is_socket_closed:
343
- exception_or_close_in_receiving_thread = True
344
- finish_thread()
345
- return
385
+ # if is_socket_closed:
386
+ # exception_or_close_in_receiving_thread = True
387
+ # finish_thread()
388
+ # return
346
389
 
347
390
  # If we're in response mode, execute responder.
348
391
  if config_static.TCPServer.server_response_mode:
349
- raw_responses: list[bytes] = create_responder_response(client_message)
350
-
351
- is_socket_closed: bool = False
352
- for response_raw_bytes in raw_responses:
353
- client_message.reinitialize_dynamic_vars()
354
- client_message.timestamp = datetime.now()
355
- client_message.response_raw_bytes = response_raw_bytes
356
- error_on_send: str = sender.Sender(
357
- ssl_socket=client_socket, class_message=client_message.response_raw_bytes,
358
- logger=network_logger).send()
359
-
360
- # If there was problem with sending data, we'll break the main while loop.
361
- if error_on_send:
362
- client_message.errors.append(error_on_send)
363
- record_and_statistics_write(client_message)
364
- is_socket_closed = True
365
-
366
- if is_socket_closed:
367
- # exception_or_close_in_receiving_thread = True
368
- return
392
+ responder_queue.put(client_message)
369
393
  else:
370
394
  # if side == 'Client':
371
395
  # raise NotImplementedError
@@ -385,9 +409,10 @@ def thread_worker_main(
385
409
 
386
410
  record_and_statistics_write(client_message)
387
411
 
388
- # If the socket was closed, then we'll break the loop.
412
+ # If the socket was closed on message receive, then we'll break the loop only after send.
389
413
  if is_socket_closed or error_on_send:
390
414
  exception_or_close_in_receiving_thread = True
415
+ responder_queue.put('exit')
391
416
  finish_thread()
392
417
  return
393
418
  except Exception as exc:
@@ -397,20 +422,31 @@ def thread_worker_main(
397
422
  if isinstance(exc, OSError) and exc.errno == 10038:
398
423
  print_api("Both sockets are closed, breaking the loop", logger=network_logger, logger_method='info')
399
424
  else:
400
- exception_or_close_in_receiving_thread = True
401
- # handle_exceptions(exc, client_message, recorded)
402
- exception_message = tracebacks.get_as_string(one_line=True)
403
- error_message = f'Socket Thread [{str(thread_id)}] Exception: {exception_message}'
404
- print_api("Exception in a thread, forwarding to parent thread.", logger_method='info', logger=network_logger)
405
- client_message.errors.append(error_message)
425
+ handle_exceptions_on_sub_connection_thread(client_message, exception_queue, exc)
426
+
427
+ def handle_exceptions_on_sub_connection_thread(
428
+ client_message: ClientMessage,
429
+ exception_queue: queue.Queue,
430
+ exc: Exception
431
+ ):
432
+ nonlocal exception_or_close_in_receiving_thread
406
433
 
407
- # if not recorded:
408
- # record_and_statistics_write(client_message)
434
+ exception_or_close_in_receiving_thread=True
435
+ # handle_exceptions(exc, client_message, recorded)
436
+ exception_message = tracebacks.get_as_string(one_line=True)
437
+
438
+ error_message = f'Socket Thread [{str(thread_id)}] Exception: {exception_message}'
439
+ print_api("Exception in a thread, forwarding to parent thread.", logger_method='info', logger=network_logger)
440
+ client_message.errors.append(error_message)
441
+
442
+ # if not recorded:
443
+ # record_and_statistics_write(client_message)
409
444
 
410
- finish_thread()
411
- exception_queue.put(exc)
445
+ finish_thread()
446
+ responder_queue.put('exit')
447
+ exception_queue.put(exc)
412
448
 
413
- def handle_exceptions(
449
+ def handle_exceptions_on_main_connection_thread(
414
450
  exc: Exception,
415
451
  client_message: ClientMessage
416
452
  ):
@@ -441,7 +477,10 @@ def thread_worker_main(
441
477
 
442
478
  thread_id = threads.current_thread_id()
443
479
 
480
+ # This is the main protocols.
444
481
  protocol: str = str()
482
+ # This is the secondary protocol in the websocket.
483
+ protocol3: str = str()
445
484
  # # This is Client Masked Frame Parser.
446
485
  # websocket_masked_frame_parser = websocket_parse.WebsocketFrameParser()
447
486
  # # This is Server UnMasked Frame Parser.
@@ -465,6 +504,8 @@ def thread_worker_main(
465
504
  client_message_connection: ClientMessage = ClientMessage()
466
505
  # This is needed to indicate if there was an exception or socket was closed in any of the receiving thread.
467
506
  exception_or_close_in_receiving_thread: bool = False
507
+ # Responder queue for ClientMessage objects.
508
+ responder_queue: queue.Queue = queue.Queue()
468
509
 
469
510
  try:
470
511
  client_ip, source_port = client_socket.getpeername()
@@ -473,6 +514,15 @@ def thread_worker_main(
473
514
  network_logger.info(f"Thread Created - Client [{client_ip}:{source_port}] | "
474
515
  f"Destination service: [{server_name}:{destination_port}]")
475
516
 
517
+ # If we're in response mode, we'll start the responder thread.
518
+ if config_static.TCPServer.server_response_mode:
519
+ responder_thread: threading.Thread = threading.Thread(
520
+ target=responder_thread_worker, name=f"Thread-{thread_id}-Responder", daemon=True)
521
+ responder_thread.start()
522
+ else:
523
+ # noinspection PyTypeChecker
524
+ responder_thread = None
525
+
476
526
  service_client = None
477
527
  client_receive_count: int = 0
478
528
  server_receive_count: int = 0
@@ -488,6 +538,11 @@ def thread_worker_main(
488
538
  if not service_client:
489
539
  service_client = create_client_socket(client_message_connection)
490
540
  service_socket_instance, connection_error = service_client.service_connection()
541
+ else:
542
+ client_message_connection.timestamp = datetime.now()
543
+ client_message_connection.action = 'service_connect'
544
+ client_message_connection.info = 'Server Response Mode'
545
+ responder_queue.put(client_message_connection)
491
546
 
492
547
  if connection_error:
493
548
  client_message_connection.timestamp = datetime.now()
@@ -512,6 +567,8 @@ def thread_worker_main(
512
567
 
513
568
  client_thread.join()
514
569
  service_thread.join()
570
+ if config_static.TCPServer.server_response_mode:
571
+ responder_thread.join()
515
572
 
516
573
  # If there was an exception in any of the threads, then we'll raise it here.
517
574
  if not client_exception_queue.empty():
@@ -524,4 +581,4 @@ def thread_worker_main(
524
581
  if not client_message_connection.timestamp:
525
582
  client_message_connection.timestamp = datetime.now()
526
583
 
527
- handle_exceptions(e, client_message_connection)
584
+ handle_exceptions_on_main_connection_thread(e, client_message_connection)
@@ -31,6 +31,7 @@ class ClientMessage:
31
31
  self.errors: list = list()
32
32
  self.protocol: str = str()
33
33
  self.protocol2: str = str()
34
+ self.protocol3: str = str()
34
35
  self.recorded_file_path: str = str()
35
36
  self.action: str = str()
36
37
 
@@ -52,6 +53,7 @@ class ClientMessage:
52
53
  self.errors = list()
53
54
  self.protocol = str()
54
55
  self.protocol2 = str()
56
+ self.protocol3 = str()
55
57
  self.recorded_file_path = str()
56
58
 
57
59
  def __iter__(self):
@@ -6,8 +6,8 @@ from ..loggingw import loggingw
6
6
 
7
7
  LOGGER_NAME: str = 'statistics'
8
8
  STATISTICS_HEADER: str = (
9
- 'request_time_sent,thread_id,tls,protocol,protocol2,host,path,command,status_code,request_size_bytes,response_size_bytes,file_path,'
10
- 'process_cmd,action,error')
9
+ 'request_time_sent,thread_id,tls,protocol,protocol2,protocol3,host,path,command,status_code,request_size_bytes,'
10
+ 'response_size_bytes,file_path,process_cmd,action,error')
11
11
 
12
12
 
13
13
  class StatisticsCSVWriter:
@@ -36,6 +36,7 @@ class StatisticsCSVWriter:
36
36
  tls_version: str,
37
37
  protocol: str,
38
38
  protocol2: str,
39
+ protocol3: str,
39
40
  path: str,
40
41
  status_code: str,
41
42
  command: str,
@@ -61,6 +62,7 @@ class StatisticsCSVWriter:
61
62
  tls_info,
62
63
  protocol,
63
64
  protocol2,
65
+ protocol3,
64
66
  host,
65
67
  path,
66
68
  command,
@@ -100,6 +102,7 @@ class StatisticsCSVWriter:
100
102
  tls_version='',
101
103
  protocol='',
102
104
  protocol2='',
105
+ protocol3='',
103
106
  path='',
104
107
  status_code='',
105
108
  command='',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.18.0
3
+ Version: 2.18.2
4
4
  Summary: Atomic functions and classes to make developer life easier
5
5
  Author: Denis Kras
6
6
  License: MIT License
@@ -1,4 +1,4 @@
1
- atomicshop/__init__.py,sha256=_rMDmeAEfTlnh9BqKgZC0sYcOXLQPbyCSOsQYH_2pl0,123
1
+ atomicshop/__init__.py,sha256=EPl1ua1q9CfR8reaw61h0P-bol2bj9D-p6to1iUifSY,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
@@ -125,12 +125,12 @@ atomicshop/file_io/tomls.py,sha256=ol8EvQPf9sryTmZUf1v55BYSUQ6ml7HVVBHpNKbsIlA,9
125
125
  atomicshop/file_io/xlsxs.py,sha256=v_dyg9GD4LqgWi6wA1QuWRZ8zG4ZwB6Dz52ytdcmmmI,2184
126
126
  atomicshop/file_io/xmls.py,sha256=zh3SuK-dNaFq2NDNhx6ivcf4GYCfGM8M10PcEwDSpxk,2104
127
127
  atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
128
- atomicshop/mitm/config_static.py,sha256=r6M4FJVBr9jGIXmjcOk2KBHvCPelWcbZCQrRh3-G26k,7871
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=78QurvuN4a-_Z9q8Fydny5CkMlfz1jIF_XAaB4BiiIA,24227
130
+ atomicshop/mitm/connection_thread_worker.py,sha256=d7XMZoXbXm9IUywg-IIVApad-NKpSdErLWgHtK8A4F4,26623
131
131
  atomicshop/mitm/import_config.py,sha256=0Ij14aISTllTOiWYJpIUMOWobQqGofD6uafui5uWllE,9272
132
132
  atomicshop/mitm/initialize_engines.py,sha256=NWz0yBErSrYBn0xWkJDBcHStBJ-kcsv9VtorcSP9x5M,8258
133
- atomicshop/mitm/message.py,sha256=lseej719nJeCKt2eGxyJCH8cYYEXBUm_RwkunBhloKE,2918
133
+ atomicshop/mitm/message.py,sha256=mNo4Lphr_Jo6IlNX5mPJzABpogWGkjOhwI4meAivwHw,2987
134
134
  atomicshop/mitm/mitm_main.py,sha256=AxmqUiDHgfzqmIF8v2GZxlEKth6_AMaYcqAxziWMG0U,23430
135
135
  atomicshop/mitm/recs_files.py,sha256=ZAAD0twun-FtmbSniXe3XQhIlawvANNB_HxwbHj7kwI,3151
136
136
  atomicshop/mitm/shared_functions.py,sha256=0lzeyINd44sVEfFbahJxQmz6KAMWbYrW5ou3UYfItvw,1777
@@ -316,11 +316,11 @@ atomicshop/wrappers/socketw/socket_client.py,sha256=oa3GwS4OPgokrJE5_Oc4-5_wlXHx
316
316
  atomicshop/wrappers/socketw/socket_server_tester.py,sha256=Qobmh4XV8ZxLUaw-eW4ESKAbeSLecCKn2OWFzMhadk0,6420
317
317
  atomicshop/wrappers/socketw/socket_wrapper.py,sha256=WtylpezgIIBuz-A6PfM0hO1sm9Exd4j3qhDXcFc74-E,35567
318
318
  atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0LxIwBA4iVvU,2275
319
- atomicshop/wrappers/socketw/statistics_csv.py,sha256=NvN4i7TxTe1kaOYGlIFkSMtrDXuqKlVngc5JIcNkDOg,3305
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.0.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
323
- atomicshop-2.18.0.dist-info/METADATA,sha256=HR1ivCy6rJMstJDq387Vn9-7DrnIHJ-i4CjK1qD_obs,10499
324
- atomicshop-2.18.0.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
325
- atomicshop-2.18.0.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
326
- atomicshop-2.18.0.dist-info/RECORD,,
322
+ atomicshop-2.18.2.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
323
+ atomicshop-2.18.2.dist-info/METADATA,sha256=jeXe5N1uxADb9T7GA5B10ENn-cmKa6WN6RywG1h3WgY,10499
324
+ atomicshop-2.18.2.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
325
+ atomicshop-2.18.2.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
326
+ atomicshop-2.18.2.dist-info/RECORD,,