atomicshop 3.3.29__py3-none-any.whl → 3.4.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 +289 -142
- atomicshop/mitm/engines/__parent/requester___parent.py +1 -1
- atomicshop/wrappers/githubw.py +170 -59
- atomicshop/wrappers/socketw/dns_server.py +5 -5
- atomicshop/wrappers/socketw/sender.py +3 -2
- {atomicshop-3.3.29.dist-info → atomicshop-3.4.0.dist-info}/METADATA +1 -1
- {atomicshop-3.3.29.dist-info → atomicshop-3.4.0.dist-info}/RECORD +11 -11
- {atomicshop-3.3.29.dist-info → atomicshop-3.4.0.dist-info}/WHEEL +0 -0
- {atomicshop-3.3.29.dist-info → atomicshop-3.4.0.dist-info}/licenses/LICENSE.txt +0 -0
- {atomicshop-3.3.29.dist-info → atomicshop-3.4.0.dist-info}/top_level.txt +0 -0
atomicshop/__init__.py
CHANGED
|
@@ -2,6 +2,8 @@ from datetime import datetime
|
|
|
2
2
|
import threading
|
|
3
3
|
import queue
|
|
4
4
|
import socket
|
|
5
|
+
import ssl
|
|
6
|
+
from typing import Literal
|
|
5
7
|
|
|
6
8
|
from ..wrappers.socketw import receiver, sender, socket_client, base
|
|
7
9
|
from .. import websocket_parse, ip_addresses
|
|
@@ -187,13 +189,19 @@ def thread_worker_main(
|
|
|
187
189
|
def create_requester_request(
|
|
188
190
|
client_message: ClientMessage,
|
|
189
191
|
sending_socket: socket.socket
|
|
190
|
-
) ->
|
|
192
|
+
) -> tuple[bytes, bool]:
|
|
193
|
+
request_received_raw: bytes = client_message.request_raw_bytes
|
|
191
194
|
request_custom_raw: bytes = requester.create_request(client_message, sending_socket=sending_socket)
|
|
192
195
|
|
|
193
|
-
|
|
194
|
-
|
|
196
|
+
if request_custom_raw is None or request_received_raw == request_custom_raw:
|
|
197
|
+
is_requester_worked: bool = False
|
|
198
|
+
else:
|
|
199
|
+
is_requester_worked: bool = True
|
|
200
|
+
|
|
201
|
+
# Output first 100 characters of the request.
|
|
202
|
+
requester.logger.info(f"{request_custom_raw[0: 100]}...")
|
|
195
203
|
|
|
196
|
-
return
|
|
204
|
+
return request_custom_raw, is_requester_worked
|
|
197
205
|
|
|
198
206
|
def create_responder_response(client_message: ClientMessage) -> list[bytes]:
|
|
199
207
|
if client_message.action == 'service_connect':
|
|
@@ -335,6 +343,260 @@ def thread_worker_main(
|
|
|
335
343
|
|
|
336
344
|
return client_message
|
|
337
345
|
|
|
346
|
+
def receive_send_service_connect(
|
|
347
|
+
client_connection_message: ClientMessage,
|
|
348
|
+
sending_socket: ssl.SSLSocket | socket.socket
|
|
349
|
+
) -> Literal['continue', 'return'] | None:
|
|
350
|
+
|
|
351
|
+
nonlocal exception_or_close_in_receiving_thread
|
|
352
|
+
|
|
353
|
+
client_message = client_connection_message
|
|
354
|
+
|
|
355
|
+
bytes_to_send_list: list[bytes] = create_responder_response(client_message)
|
|
356
|
+
print_api(f"Got responses from connect responder, count: [{len(bytes_to_send_list)}]",
|
|
357
|
+
logger=network_logger, logger_method='info')
|
|
358
|
+
|
|
359
|
+
# If the client message is the connection message, then we'll skip to the next iteration.
|
|
360
|
+
if not bytes_to_send_list:
|
|
361
|
+
return 'continue'
|
|
362
|
+
|
|
363
|
+
# is_socket_closed: bool = False
|
|
364
|
+
error_on_send: str = str()
|
|
365
|
+
for bytes_to_send_single in bytes_to_send_list:
|
|
366
|
+
client_message.reinitialize_dynamic_vars()
|
|
367
|
+
client_message.timestamp = datetime.now()
|
|
368
|
+
client_message.response_raw_bytes = bytes_to_send_single
|
|
369
|
+
client_message.action = 'service_responder'
|
|
370
|
+
record_and_statistics_write(client_message)
|
|
371
|
+
|
|
372
|
+
# Send the bytes back to the client socket.
|
|
373
|
+
error_on_send: str = sender.Sender(
|
|
374
|
+
ssl_socket=sending_socket, class_message=bytes_to_send_single,
|
|
375
|
+
logger=network_logger).send()
|
|
376
|
+
|
|
377
|
+
if error_on_send:
|
|
378
|
+
client_message.reinitialize_dynamic_vars()
|
|
379
|
+
client_message.errors.append(error_on_send)
|
|
380
|
+
client_message.timestamp = datetime.now()
|
|
381
|
+
client_message.action = 'client_send'
|
|
382
|
+
record_and_statistics_write(client_message)
|
|
383
|
+
|
|
384
|
+
if error_on_send:
|
|
385
|
+
exception_or_close_in_receiving_thread = True
|
|
386
|
+
finish_thread()
|
|
387
|
+
return 'return'
|
|
388
|
+
|
|
389
|
+
return None
|
|
390
|
+
|
|
391
|
+
def receive_send_client_offline(
|
|
392
|
+
client_message: ClientMessage,
|
|
393
|
+
receiving_socket: ssl.SSLSocket | socket.socket,
|
|
394
|
+
sending_socket: ssl.SSLSocket | socket.socket
|
|
395
|
+
) -> Literal['return'] | None:
|
|
396
|
+
nonlocal exception_or_close_in_receiving_thread
|
|
397
|
+
nonlocal client_receive_count
|
|
398
|
+
|
|
399
|
+
client_receive_count += 1
|
|
400
|
+
|
|
401
|
+
network_logger.info(f"Initializing Receiver for Client cycle: {str(client_receive_count)}")
|
|
402
|
+
client_message.timestamp = datetime.now()
|
|
403
|
+
|
|
404
|
+
received_raw_data, is_socket_closed, error_message = receiver.Receiver(
|
|
405
|
+
ssl_socket=receiving_socket, logger=network_logger).receive()
|
|
406
|
+
|
|
407
|
+
process_client_raw_data(received_raw_data, error_message, client_message)
|
|
408
|
+
client_message.action = 'client_receive'
|
|
409
|
+
|
|
410
|
+
record_and_statistics_write(client_message)
|
|
411
|
+
|
|
412
|
+
# If there was an exception in the service thread, then receiving empty bytes doesn't mean that
|
|
413
|
+
# the socket was closed by the other side, it means that the service thread closed the socket.
|
|
414
|
+
if (received_raw_data == b'' or error_message) and exception_or_close_in_receiving_thread:
|
|
415
|
+
print_api("Both sockets are closed, breaking the loop", logger=network_logger,
|
|
416
|
+
logger_method='info')
|
|
417
|
+
return 'return'
|
|
418
|
+
|
|
419
|
+
# If the socket was closed on receive, and we're in offline mode, then we'll finish the thread right away.
|
|
420
|
+
# Since nothing more can be done, like responding to service or using requester.
|
|
421
|
+
if is_socket_closed:
|
|
422
|
+
exception_or_close_in_receiving_thread = True
|
|
423
|
+
finish_thread()
|
|
424
|
+
return 'return'
|
|
425
|
+
|
|
426
|
+
# Send to requester.
|
|
427
|
+
# THERE IS ALWAYS WILL BE ONLY ONE REQUEST FROM REQUESTER, SINCE THIS IS WHAT WE GOT FROM THE CLIENT.
|
|
428
|
+
request_custom_raw, is_requester_worked = create_requester_request(client_message, sending_socket=sending_socket)
|
|
429
|
+
# We will not process the raw data if requester didn't change anything.
|
|
430
|
+
if is_requester_worked:
|
|
431
|
+
client_message.reinitialize_dynamic_vars()
|
|
432
|
+
client_message.timestamp = datetime.now()
|
|
433
|
+
client_message.request_raw_bytes = request_custom_raw
|
|
434
|
+
client_message.action = 'client_requester'
|
|
435
|
+
process_client_raw_data(request_custom_raw, error_message, client_message)
|
|
436
|
+
record_and_statistics_write(client_message)
|
|
437
|
+
|
|
438
|
+
print_api("Offline Mode, sending to responder directly.", logger=network_logger,
|
|
439
|
+
logger_method='info')
|
|
440
|
+
bytes_to_send_list: list[bytes] = create_responder_response(client_message)
|
|
441
|
+
|
|
442
|
+
error_on_send: str = str()
|
|
443
|
+
for bytes_to_send_single in bytes_to_send_list:
|
|
444
|
+
client_message.reinitialize_dynamic_vars()
|
|
445
|
+
client_message.timestamp = datetime.now()
|
|
446
|
+
client_message.response_raw_bytes = bytes_to_send_single
|
|
447
|
+
client_message.action = 'client_responder_offline'
|
|
448
|
+
process_server_raw_data(bytes_to_send_single, '', client_message)
|
|
449
|
+
record_and_statistics_write(client_message)
|
|
450
|
+
|
|
451
|
+
error_on_send: str = sender.Sender(
|
|
452
|
+
ssl_socket=receiving_socket, class_message=bytes_to_send_single,
|
|
453
|
+
logger=network_logger).send()
|
|
454
|
+
|
|
455
|
+
if error_on_send:
|
|
456
|
+
client_message.reinitialize_dynamic_vars()
|
|
457
|
+
client_message.errors.append(error_on_send)
|
|
458
|
+
client_message.timestamp = datetime.now()
|
|
459
|
+
client_message.action = 'service_send'
|
|
460
|
+
|
|
461
|
+
record_and_statistics_write(client_message)
|
|
462
|
+
|
|
463
|
+
# If the socket was closed on message receive, then we'll break the loop only after send.
|
|
464
|
+
if is_socket_closed or error_on_send:
|
|
465
|
+
exception_or_close_in_receiving_thread = True
|
|
466
|
+
finish_thread()
|
|
467
|
+
return 'return'
|
|
468
|
+
|
|
469
|
+
return None
|
|
470
|
+
|
|
471
|
+
def receive_send_client(
|
|
472
|
+
client_message: ClientMessage,
|
|
473
|
+
receiving_socket: ssl.SSLSocket | socket.socket,
|
|
474
|
+
sending_socket: ssl.SSLSocket | socket.socket
|
|
475
|
+
) -> Literal['return'] | None:
|
|
476
|
+
|
|
477
|
+
nonlocal exception_or_close_in_receiving_thread
|
|
478
|
+
nonlocal client_receive_count
|
|
479
|
+
|
|
480
|
+
client_receive_count += 1
|
|
481
|
+
|
|
482
|
+
network_logger.info(f"Initializing Receiver for Client cycle: {str(client_receive_count)}")
|
|
483
|
+
|
|
484
|
+
# Getting message from the client over the socket using specific class.
|
|
485
|
+
client_message.timestamp = datetime.now()
|
|
486
|
+
received_raw_data, is_socket_closed, error_message = receiver.Receiver(
|
|
487
|
+
ssl_socket=receiving_socket, logger=network_logger).receive()
|
|
488
|
+
|
|
489
|
+
process_client_raw_data(received_raw_data, error_message, client_message)
|
|
490
|
+
client_message.action = 'client_receive'
|
|
491
|
+
|
|
492
|
+
record_and_statistics_write(client_message)
|
|
493
|
+
|
|
494
|
+
# If there was an exception in the service thread, then receiving empty bytes doesn't mean that
|
|
495
|
+
# the socket was closed by the other side, it means that the service thread closed the socket.
|
|
496
|
+
if (received_raw_data == b'' or error_message) and exception_or_close_in_receiving_thread:
|
|
497
|
+
print_api("Both sockets are closed, breaking the loop", logger=network_logger,
|
|
498
|
+
logger_method='info')
|
|
499
|
+
return 'return'
|
|
500
|
+
|
|
501
|
+
# Send to requester.
|
|
502
|
+
# THERE IS ALWAYS WILL BE ONLY ONE REQUEST FROM REQUESTER, SINCE THIS IS WHAT WE GOT FROM THE CLIENT.
|
|
503
|
+
request_custom_raw, is_requester_worked = create_requester_request(client_message, sending_socket=sending_socket)
|
|
504
|
+
# We will not process the raw data if requester didn't change anything.
|
|
505
|
+
if is_requester_worked:
|
|
506
|
+
client_message.reinitialize_dynamic_vars()
|
|
507
|
+
client_message.timestamp = datetime.now()
|
|
508
|
+
client_message.request_raw_bytes = request_custom_raw
|
|
509
|
+
client_message.action = 'client_requester'
|
|
510
|
+
process_client_raw_data(request_custom_raw, error_message, client_message)
|
|
511
|
+
record_and_statistics_write(client_message)
|
|
512
|
+
|
|
513
|
+
error_on_send: str = sender.Sender(
|
|
514
|
+
ssl_socket=sending_socket, class_message=client_message.request_raw_bytes,
|
|
515
|
+
logger=network_logger).send()
|
|
516
|
+
|
|
517
|
+
if error_on_send:
|
|
518
|
+
client_message.reinitialize_dynamic_vars()
|
|
519
|
+
client_message.errors.append(error_on_send)
|
|
520
|
+
client_message.timestamp = datetime.now()
|
|
521
|
+
client_message.action = 'service_send'
|
|
522
|
+
record_and_statistics_write(client_message)
|
|
523
|
+
|
|
524
|
+
# If the socket was closed on message receive, then we'll break the loop only after send.
|
|
525
|
+
if is_socket_closed or error_on_send:
|
|
526
|
+
exception_or_close_in_receiving_thread = True
|
|
527
|
+
finish_thread()
|
|
528
|
+
return 'return'
|
|
529
|
+
|
|
530
|
+
return None
|
|
531
|
+
|
|
532
|
+
def receive_send_service(
|
|
533
|
+
client_message: ClientMessage,
|
|
534
|
+
receiving_socket: ssl.SSLSocket | socket.socket,
|
|
535
|
+
sending_socket: ssl.SSLSocket | socket.socket
|
|
536
|
+
) -> Literal['return'] | None:
|
|
537
|
+
|
|
538
|
+
nonlocal exception_or_close_in_receiving_thread
|
|
539
|
+
nonlocal server_receive_count
|
|
540
|
+
|
|
541
|
+
server_receive_count += 1
|
|
542
|
+
|
|
543
|
+
network_logger.info(f"Initializing Receiver for Service cycle: {str(server_receive_count)}")
|
|
544
|
+
|
|
545
|
+
# Getting message from the client over the socket using specific class.
|
|
546
|
+
client_message.timestamp = datetime.now()
|
|
547
|
+
received_raw_data, is_socket_closed, error_message = receiver.Receiver(
|
|
548
|
+
ssl_socket=receiving_socket, logger=network_logger).receive()
|
|
549
|
+
|
|
550
|
+
process_server_raw_data(received_raw_data, error_message, client_message)
|
|
551
|
+
client_message.action = 'service_receive'
|
|
552
|
+
record_and_statistics_write(client_message)
|
|
553
|
+
|
|
554
|
+
# If there was an exception in the service thread, then receiving empty bytes doesn't mean that
|
|
555
|
+
# the socket was closed by the other side, it means that the service thread closed the socket.
|
|
556
|
+
if (received_raw_data == b'' or error_message) and exception_or_close_in_receiving_thread:
|
|
557
|
+
print_api("Both sockets are closed, breaking the loop", logger=network_logger,
|
|
558
|
+
logger_method='info')
|
|
559
|
+
return 'return'
|
|
560
|
+
|
|
561
|
+
# Now send it to requester/responder.
|
|
562
|
+
bytes_to_send_list: list[bytes] = create_responder_response(client_message)
|
|
563
|
+
print_api(f"Got responses from responder, count: [{len(bytes_to_send_list)}]",
|
|
564
|
+
logger=network_logger, logger_method='info')
|
|
565
|
+
|
|
566
|
+
# is_socket_closed: bool = False
|
|
567
|
+
error_on_send: str = str()
|
|
568
|
+
for bytes_to_send_single in bytes_to_send_list:
|
|
569
|
+
client_message.reinitialize_dynamic_vars()
|
|
570
|
+
client_message.timestamp = datetime.now()
|
|
571
|
+
client_message.response_raw_bytes = bytes_to_send_single
|
|
572
|
+
|
|
573
|
+
# This records the requester or responder output, only if it is not the same as the original
|
|
574
|
+
# message.
|
|
575
|
+
if bytes_to_send_single != received_raw_data:
|
|
576
|
+
client_message.action = 'service_responder'
|
|
577
|
+
record_and_statistics_write(client_message)
|
|
578
|
+
|
|
579
|
+
error_on_send: str = sender.Sender(
|
|
580
|
+
ssl_socket=sending_socket, class_message=bytes_to_send_single,
|
|
581
|
+
logger=network_logger).send()
|
|
582
|
+
|
|
583
|
+
if error_on_send:
|
|
584
|
+
client_message.reinitialize_dynamic_vars()
|
|
585
|
+
client_message.errors.append(error_on_send)
|
|
586
|
+
client_message.timestamp = datetime.now()
|
|
587
|
+
client_message.action = 'client_send'
|
|
588
|
+
|
|
589
|
+
record_and_statistics_write(client_message)
|
|
590
|
+
|
|
591
|
+
# If the socket was closed on message receive, then we'll break the loop only after send.
|
|
592
|
+
if is_socket_closed or error_on_send:
|
|
593
|
+
exception_or_close_in_receiving_thread = True
|
|
594
|
+
finish_thread()
|
|
595
|
+
return 'return'
|
|
596
|
+
|
|
597
|
+
return None
|
|
598
|
+
|
|
599
|
+
|
|
338
600
|
def receive_send_start(
|
|
339
601
|
receiving_socket,
|
|
340
602
|
sending_socket = None,
|
|
@@ -360,146 +622,25 @@ def thread_worker_main(
|
|
|
360
622
|
raise ValueError(f"Unknown side of the socket: {receiving_socket}")
|
|
361
623
|
|
|
362
624
|
while True:
|
|
363
|
-
|
|
364
|
-
# pass the socket connect to responder.
|
|
365
|
-
if side == 'Service' and client_connection_message:
|
|
366
|
-
client_message = client_connection_message
|
|
367
|
-
|
|
368
|
-
bytes_to_send_list: list[bytes] = create_responder_response(client_message)
|
|
369
|
-
print_api(f"Got responses from connect responder, count: [{len(bytes_to_send_list)}]", logger=network_logger,
|
|
370
|
-
logger_method='info')
|
|
625
|
+
client_message.reinitialize_dynamic_vars()
|
|
371
626
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
if side == 'Client':
|
|
377
|
-
client_receive_count += 1
|
|
378
|
-
current_count = client_receive_count
|
|
379
|
-
else:
|
|
380
|
-
server_receive_count += 1
|
|
381
|
-
current_count = server_receive_count
|
|
382
|
-
|
|
383
|
-
# Getting current time of message received, either from client or service.
|
|
384
|
-
client_message.timestamp = datetime.now()
|
|
385
|
-
|
|
386
|
-
# # No need to receive on service socket if we're in offline mode, because there is no service to connect to.
|
|
387
|
-
# if config_static.MainConfig.offline and side == 'Service':
|
|
388
|
-
# print_api("Offline Mode, skipping receiving on service socket.", logger=network_logger,
|
|
389
|
-
# logger_method='info')
|
|
390
|
-
# else:
|
|
391
|
-
|
|
392
|
-
network_logger.info(
|
|
393
|
-
f"Initializing Receiver for {side} cycle: {str(current_count)}")
|
|
394
|
-
|
|
395
|
-
# Getting message from the client over the socket using specific class.
|
|
396
|
-
received_raw_data, is_socket_closed, error_message = receiver.Receiver(
|
|
397
|
-
ssl_socket=receiving_socket, logger=network_logger).receive()
|
|
398
|
-
|
|
399
|
-
# In case of client socket, we'll process the raw data specifically for the client.
|
|
400
|
-
if side == 'Client':
|
|
401
|
-
process_client_raw_data(received_raw_data, error_message, client_message)
|
|
402
|
-
client_message.action = 'client_receive'
|
|
403
|
-
# In case of service socket, we'll process the raw data specifically for the service.
|
|
404
|
-
else:
|
|
405
|
-
process_server_raw_data(received_raw_data, error_message, client_message)
|
|
406
|
-
client_message.action = 'service_receive'
|
|
407
|
-
|
|
408
|
-
# If there was an exception in the service thread, then receiving empty bytes doesn't mean that
|
|
409
|
-
# the socket was closed by the other side, it means that the service thread closed the socket.
|
|
410
|
-
if (received_raw_data == b'' or error_message) and exception_or_close_in_receiving_thread:
|
|
411
|
-
print_api("Both sockets are closed, breaking the loop", logger=network_logger,
|
|
412
|
-
logger_method='info')
|
|
413
|
-
return
|
|
414
|
-
|
|
415
|
-
# We will record only if there was no closing signal, because if there was, it means that we initiated
|
|
416
|
-
# the close on the opposite socket.
|
|
417
|
-
record_and_statistics_write(client_message)
|
|
418
|
-
|
|
419
|
-
# if is_socket_closed:
|
|
420
|
-
# exception_or_close_in_receiving_thread = True
|
|
421
|
-
# finish_thread()
|
|
422
|
-
# return
|
|
423
|
-
|
|
424
|
-
# Now send it to requester/responder.
|
|
425
|
-
if side == 'Client':
|
|
426
|
-
# Send to requester.
|
|
427
|
-
bytes_to_send_list: list[bytes] = create_requester_request(
|
|
428
|
-
client_message, sending_socket=sending_socket)
|
|
429
|
-
|
|
430
|
-
# If we're in offline mode, then we'll put the request to the responder right away.
|
|
431
|
-
if config_static.MainConfig.offline:
|
|
432
|
-
print_api("Offline Mode, sending to responder directly.", logger=network_logger,
|
|
433
|
-
logger_method='info')
|
|
434
|
-
process_client_raw_data(bytes_to_send_list[0], error_message, client_message)
|
|
435
|
-
bytes_to_send_list = create_responder_response(client_message)
|
|
436
|
-
elif side == 'Service':
|
|
437
|
-
bytes_to_send_list: list[bytes] = create_responder_response(client_message)
|
|
438
|
-
print_api(f"Got responses from responder, count: [{len(bytes_to_send_list)}]",
|
|
439
|
-
logger=network_logger,
|
|
440
|
-
logger_method='info')
|
|
441
|
-
else:
|
|
442
|
-
raise ValueError(f"Unknown side [{side}] of the socket: {receiving_socket}")
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
# If nothing was passed from the responder, and the client message is the connection message, then we'll skip to the next iteration.
|
|
446
|
-
if not bytes_to_send_list and client_connection_message:
|
|
627
|
+
if side == 'Service' and client_connection_message:
|
|
628
|
+
result: Literal['continue', 'return'] | None = (
|
|
629
|
+
receive_send_service_connect(client_connection_message, sending_socket))
|
|
447
630
|
client_connection_message = None
|
|
448
|
-
continue
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
client_message
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
else:
|
|
459
|
-
client_message.response_raw_bytes = bytes_to_send_single
|
|
460
|
-
|
|
461
|
-
# This records the requester or responder output, only if it is not the same as the original
|
|
462
|
-
# message.
|
|
463
|
-
if bytes_to_send_single != received_raw_data:
|
|
464
|
-
if side == 'Client':
|
|
465
|
-
client_message.action = 'client_requester'
|
|
466
|
-
|
|
467
|
-
if config_static.MainConfig.offline:
|
|
468
|
-
client_message.action = 'client_responder_offline'
|
|
469
|
-
elif side == 'Service':
|
|
470
|
-
client_message.action = 'service_responder'
|
|
471
|
-
record_and_statistics_write(client_message)
|
|
472
|
-
|
|
473
|
-
# If we're in offline mode, it means we're in the client thread, and we'll send the
|
|
474
|
-
# bytes back to the client socket.
|
|
475
|
-
if config_static.MainConfig.offline:
|
|
476
|
-
error_on_send: str = sender.Sender(
|
|
477
|
-
ssl_socket=receiving_socket, class_message=bytes_to_send_single,
|
|
478
|
-
logger=network_logger).send()
|
|
479
|
-
else:
|
|
480
|
-
error_on_send: str = sender.Sender(
|
|
481
|
-
ssl_socket=sending_socket, class_message=bytes_to_send_single,
|
|
482
|
-
logger=network_logger).send()
|
|
483
|
-
|
|
484
|
-
if error_on_send:
|
|
485
|
-
client_message.reinitialize_dynamic_vars()
|
|
486
|
-
client_message.errors.append(error_on_send)
|
|
487
|
-
client_message.timestamp = datetime.now()
|
|
488
|
-
if side == 'Client':
|
|
489
|
-
client_message.action = 'service_send'
|
|
490
|
-
else:
|
|
491
|
-
client_message.action = 'client_send'
|
|
492
|
-
|
|
493
|
-
record_and_statistics_write(client_message)
|
|
494
|
-
|
|
495
|
-
# If the socket was closed on message receive, then we'll break the loop only after send.
|
|
496
|
-
if is_socket_closed or error_on_send:
|
|
497
|
-
exception_or_close_in_receiving_thread = True
|
|
498
|
-
finish_thread()
|
|
499
|
-
return
|
|
631
|
+
if result == 'continue':
|
|
632
|
+
continue
|
|
633
|
+
elif side == 'Client' and config_static.MainConfig.offline:
|
|
634
|
+
result: Literal['return'] | None = receive_send_client_offline(client_message, receiving_socket, sending_socket)
|
|
635
|
+
elif side == 'Client':
|
|
636
|
+
result: Literal['return'] | None = receive_send_client(client_message, receiving_socket, sending_socket)
|
|
637
|
+
elif side == 'Service':
|
|
638
|
+
result: Literal['return'] | None = receive_send_service(client_message, receiving_socket, sending_socket)
|
|
639
|
+
else:
|
|
640
|
+
raise ValueError(f"Unknown side [{side}] of the socket: {receiving_socket}")
|
|
500
641
|
|
|
501
|
-
|
|
502
|
-
|
|
642
|
+
if result == 'return':
|
|
643
|
+
return
|
|
503
644
|
except Exception as exc:
|
|
504
645
|
# If the sockets were already closed, then there is nothing to do here besides log.
|
|
505
646
|
# if (isinstance(exc, OSError) and exc.errno == 10038 and
|
|
@@ -602,7 +743,13 @@ def thread_worker_main(
|
|
|
602
743
|
try:
|
|
603
744
|
engine_name: str = recorder.engine_name
|
|
604
745
|
client_ip, source_port = client_socket.getpeername()
|
|
605
|
-
|
|
746
|
+
|
|
747
|
+
try:
|
|
748
|
+
client_name: str = socket.gethostbyaddr(client_ip)[0]
|
|
749
|
+
# This can happen if the host changed IP address, but it wasn't propagated over DHCP.
|
|
750
|
+
except socket.herror:
|
|
751
|
+
client_name = ""
|
|
752
|
+
|
|
606
753
|
client_name = client_name.lower()
|
|
607
754
|
destination_port: int = client_socket.getsockname()[1]
|
|
608
755
|
destination_port_str: str = str(destination_port)
|
|
@@ -112,5 +112,5 @@ class RequesterParent:
|
|
|
112
112
|
def create_request(self, class_client_message: ClientMessage, **kwargs) -> bytes:
|
|
113
113
|
""" This function should be overridden in the child class. """
|
|
114
114
|
|
|
115
|
-
request_bytes: bytes =
|
|
115
|
+
request_bytes: bytes = None
|
|
116
116
|
return request_bytes
|
atomicshop/wrappers/githubw.py
CHANGED
|
@@ -163,11 +163,103 @@ class GitHubWrapper:
|
|
|
163
163
|
|
|
164
164
|
self.build_links_from_user_and_repo()
|
|
165
165
|
|
|
166
|
-
def check_github_domain(
|
|
166
|
+
def check_github_domain(
|
|
167
|
+
self,
|
|
168
|
+
domain: str
|
|
169
|
+
):
|
|
167
170
|
if self.domain not in domain:
|
|
168
171
|
print_api(
|
|
169
172
|
f'This is not [{self.domain}] domain.', color="red", error_type=True)
|
|
170
173
|
|
|
174
|
+
def download_file(
|
|
175
|
+
self,
|
|
176
|
+
file_name: str,
|
|
177
|
+
target_dir: str
|
|
178
|
+
) -> str:
|
|
179
|
+
"""
|
|
180
|
+
Download a single repo file to a local directory.
|
|
181
|
+
|
|
182
|
+
:param file_name: string, Full repo-relative path to the file. Example:
|
|
183
|
+
"eng.traineddata"
|
|
184
|
+
"script\\English.script"
|
|
185
|
+
:param target_dir: string, Local directory to save into.
|
|
186
|
+
|
|
187
|
+
:return: The local path to the downloaded file.
|
|
188
|
+
"""
|
|
189
|
+
|
|
190
|
+
# Normalize to GitHub path format
|
|
191
|
+
file_path = file_name.replace("\\", "/").strip("/")
|
|
192
|
+
|
|
193
|
+
headers = self._get_headers()
|
|
194
|
+
url = f"{self.contents_url}/{file_path}"
|
|
195
|
+
params = {"ref": self.branch}
|
|
196
|
+
|
|
197
|
+
resp = requests.get(url, headers=headers, params=params)
|
|
198
|
+
resp.raise_for_status()
|
|
199
|
+
item = resp.json()
|
|
200
|
+
|
|
201
|
+
# Expect a single file object
|
|
202
|
+
if isinstance(item, list) or item.get("type") != "file":
|
|
203
|
+
raise ValueError(f"'{file_name}' is not a file in branch '{self.branch}'.")
|
|
204
|
+
|
|
205
|
+
download_url = item.get("download_url")
|
|
206
|
+
if not download_url:
|
|
207
|
+
raise ValueError(f"Unable to obtain download URL for '{file_name}'.")
|
|
208
|
+
|
|
209
|
+
os.makedirs(target_dir, exist_ok=True)
|
|
210
|
+
local_name = item.get("name") or os.path.basename(file_path)
|
|
211
|
+
|
|
212
|
+
from .. import web # ensure available in your module structure
|
|
213
|
+
web.download(
|
|
214
|
+
file_url=download_url,
|
|
215
|
+
target_directory=target_dir,
|
|
216
|
+
file_name=local_name,
|
|
217
|
+
headers=headers,
|
|
218
|
+
)
|
|
219
|
+
return os.path.join(target_dir, local_name)
|
|
220
|
+
|
|
221
|
+
def download_directory(
|
|
222
|
+
self,
|
|
223
|
+
folder_name: str,
|
|
224
|
+
target_dir: str
|
|
225
|
+
) -> None:
|
|
226
|
+
"""
|
|
227
|
+
Recursively download a repo directory to a local directory.
|
|
228
|
+
|
|
229
|
+
:param folder_name: string, Repo-relative directory path to download (e.g., "tests/langs").
|
|
230
|
+
:param target_dir: string, Local directory to save the folder tree into.
|
|
231
|
+
"""
|
|
232
|
+
headers = self._get_headers()
|
|
233
|
+
root_path = folder_name.replace("\\", "/").strip("/")
|
|
234
|
+
|
|
235
|
+
def _walk_dir(rel_path: str, local_dir: str) -> None:
|
|
236
|
+
contents_url = f"{self.contents_url}/{rel_path}" if rel_path else self.contents_url
|
|
237
|
+
params = {"ref": self.branch}
|
|
238
|
+
|
|
239
|
+
response = requests.get(contents_url, headers=headers, params=params)
|
|
240
|
+
response.raise_for_status()
|
|
241
|
+
items = response.json()
|
|
242
|
+
|
|
243
|
+
# If a file path was passed accidentally, delegate to download_file
|
|
244
|
+
if isinstance(items, dict) and items.get("type") == "file":
|
|
245
|
+
self.download_file(rel_path, local_dir)
|
|
246
|
+
return
|
|
247
|
+
|
|
248
|
+
if not isinstance(items, list):
|
|
249
|
+
raise ValueError(f"Unexpected response shape when listing '{rel_path or '/'}'.")
|
|
250
|
+
|
|
251
|
+
os.makedirs(local_dir, exist_ok=True)
|
|
252
|
+
|
|
253
|
+
for item in items:
|
|
254
|
+
name = item["name"]
|
|
255
|
+
if item["type"] == "file":
|
|
256
|
+
self.download_file(f"{rel_path}/{name}" if rel_path else name, local_dir)
|
|
257
|
+
elif item["type"] == "dir":
|
|
258
|
+
_walk_dir(f"{rel_path}/{name}" if rel_path else name, os.path.join(local_dir, name))
|
|
259
|
+
# ignore symlinks/submodules if present
|
|
260
|
+
|
|
261
|
+
_walk_dir(root_path, target_dir)
|
|
262
|
+
|
|
171
263
|
def download_and_extract_branch(
|
|
172
264
|
self,
|
|
173
265
|
target_directory: str,
|
|
@@ -195,48 +287,6 @@ class GitHubWrapper:
|
|
|
195
287
|
:return:
|
|
196
288
|
"""
|
|
197
289
|
|
|
198
|
-
def download_file(file_url: str, target_dir: str, file_name: str, current_headers: dict) -> None:
|
|
199
|
-
os.makedirs(target_dir, exist_ok=True)
|
|
200
|
-
|
|
201
|
-
web.download(
|
|
202
|
-
file_url=file_url,
|
|
203
|
-
target_directory=target_dir,
|
|
204
|
-
file_name=file_name,
|
|
205
|
-
headers=current_headers
|
|
206
|
-
)
|
|
207
|
-
|
|
208
|
-
def download_directory(folder_path: str, target_dir: str, current_headers: dict) -> None:
|
|
209
|
-
# Construct the API URL for the current folder.
|
|
210
|
-
contents_url = f"{self.contents_url}/{folder_path}"
|
|
211
|
-
params = {'ref': self.branch}
|
|
212
|
-
|
|
213
|
-
response = requests.get(contents_url, headers=current_headers, params=params)
|
|
214
|
-
response.raise_for_status()
|
|
215
|
-
|
|
216
|
-
# Get the list of items (files and subdirectories) in the folder.
|
|
217
|
-
items = response.json()
|
|
218
|
-
|
|
219
|
-
# Ensure the local target directory exists.
|
|
220
|
-
os.makedirs(target_dir, exist_ok=True)
|
|
221
|
-
|
|
222
|
-
# Process each item.
|
|
223
|
-
for item in items:
|
|
224
|
-
local_item_path = os.path.join(target_dir, item['name'])
|
|
225
|
-
if item['type'] == 'file':
|
|
226
|
-
download_file(
|
|
227
|
-
file_url=item['download_url'],
|
|
228
|
-
target_dir=target_dir,
|
|
229
|
-
file_name=item['name'],
|
|
230
|
-
current_headers=current_headers
|
|
231
|
-
)
|
|
232
|
-
elif item['type'] == 'dir':
|
|
233
|
-
# Recursively download subdirectories.
|
|
234
|
-
download_directory(
|
|
235
|
-
folder_path=f"{folder_path}/{item['name']}",
|
|
236
|
-
target_dir=local_item_path,
|
|
237
|
-
current_headers=current_headers
|
|
238
|
-
)
|
|
239
|
-
|
|
240
290
|
headers: dict = self._get_headers()
|
|
241
291
|
|
|
242
292
|
if not download_each_file:
|
|
@@ -275,7 +325,7 @@ class GitHubWrapper:
|
|
|
275
325
|
else:
|
|
276
326
|
current_target_directory = os.path.join(target_directory, self.path)
|
|
277
327
|
|
|
278
|
-
download_directory(self.path, current_target_directory
|
|
328
|
+
self.download_directory(self.path, current_target_directory)
|
|
279
329
|
|
|
280
330
|
def get_releases_json(
|
|
281
331
|
self,
|
|
@@ -530,8 +580,77 @@ class GitHubWrapper:
|
|
|
530
580
|
commit_message = latest_commit.get("commit", {}).get("message", "")
|
|
531
581
|
return commit_message
|
|
532
582
|
|
|
583
|
+
def list_files(
|
|
584
|
+
self,
|
|
585
|
+
pattern: str = "*",
|
|
586
|
+
recursive: bool = True,
|
|
587
|
+
path: str | None = None,
|
|
588
|
+
) -> list[str]:
|
|
589
|
+
"""
|
|
590
|
+
List files in the repository (or in a specific subfolder).
|
|
533
591
|
|
|
534
|
-
|
|
592
|
+
:param pattern: Glob-style pattern (e.g., "*.ex*", "*test*.py"). Matching is done
|
|
593
|
+
against the file's base name (not the full path).
|
|
594
|
+
:param recursive: If True, include files in all subfolders (returns full repo-relative
|
|
595
|
+
paths). If False, list only the immediate files in the chosen folder.
|
|
596
|
+
:param path: Optional subfolder to list from (e.g., "tests/langs"). If omitted,
|
|
597
|
+
uses self.path if set, otherwise the repo root.
|
|
598
|
+
|
|
599
|
+
:return: A list of repo-relative file paths that match the pattern.
|
|
600
|
+
"""
|
|
601
|
+
headers = self._get_headers()
|
|
602
|
+
base_path = (path or self.path or "").strip("/")
|
|
603
|
+
|
|
604
|
+
if recursive:
|
|
605
|
+
# Use the Git Trees API to fetch all files in one call, then filter.
|
|
606
|
+
tree_url = f"{self.api_url}/git/trees/{self.branch}"
|
|
607
|
+
params = {"recursive": "1"}
|
|
608
|
+
resp = requests.get(tree_url, headers=headers, params=params)
|
|
609
|
+
resp.raise_for_status()
|
|
610
|
+
data = resp.json()
|
|
611
|
+
|
|
612
|
+
files = []
|
|
613
|
+
for entry in data.get("tree", []):
|
|
614
|
+
if entry.get("type") != "blob":
|
|
615
|
+
continue # only files
|
|
616
|
+
entry_path = entry.get("path", "")
|
|
617
|
+
# If a base_path was provided, keep only files under it
|
|
618
|
+
if base_path and not entry_path.startswith(base_path + "/") and entry_path != base_path:
|
|
619
|
+
continue
|
|
620
|
+
# Match pattern against the *file name* (basename)
|
|
621
|
+
if fnmatch.fnmatch(os.path.basename(entry_path), pattern):
|
|
622
|
+
files.append(entry_path)
|
|
623
|
+
return files
|
|
624
|
+
|
|
625
|
+
else:
|
|
626
|
+
# Non-recursive: use the Contents API to list a single directory.
|
|
627
|
+
# If base_path is empty, list the repo root.
|
|
628
|
+
if base_path:
|
|
629
|
+
contents_url = f"{self.contents_url}/{base_path}"
|
|
630
|
+
else:
|
|
631
|
+
contents_url = self.contents_url
|
|
632
|
+
|
|
633
|
+
params = {"ref": self.branch}
|
|
634
|
+
resp = requests.get(contents_url, headers=headers, params=params)
|
|
635
|
+
resp.raise_for_status()
|
|
636
|
+
items = resp.json()
|
|
637
|
+
|
|
638
|
+
# The Contents API returns a dict when the path points to a single file;
|
|
639
|
+
# normalize to a list to simplify handling.
|
|
640
|
+
if isinstance(items, dict):
|
|
641
|
+
items = [items]
|
|
642
|
+
|
|
643
|
+
files = []
|
|
644
|
+
for item in items:
|
|
645
|
+
if item.get("type") == "file":
|
|
646
|
+
name = item.get("name", "")
|
|
647
|
+
if fnmatch.fnmatch(name, pattern):
|
|
648
|
+
# item["path"] is the full repo-relative path we want to return
|
|
649
|
+
files.append(item.get("path", name))
|
|
650
|
+
return files
|
|
651
|
+
|
|
652
|
+
|
|
653
|
+
def _make_parser():
|
|
535
654
|
import argparse
|
|
536
655
|
|
|
537
656
|
parser = argparse.ArgumentParser(description='GitHub Wrapper')
|
|
@@ -562,7 +681,7 @@ def parse_github_args():
|
|
|
562
681
|
'-db', '--download_branch', action='store_true', default=False,
|
|
563
682
|
help='Sets if the branch will be downloaded. In conjunction with path, only the path will be downloaded.')
|
|
564
683
|
|
|
565
|
-
return parser
|
|
684
|
+
return parser
|
|
566
685
|
|
|
567
686
|
|
|
568
687
|
def github_wrapper_main(
|
|
@@ -571,8 +690,8 @@ def github_wrapper_main(
|
|
|
571
690
|
path: str = None,
|
|
572
691
|
target_directory: str = None,
|
|
573
692
|
pat: str = None,
|
|
574
|
-
get_latest_commit_json: bool = False,
|
|
575
693
|
get_latest_commit_message: bool = False,
|
|
694
|
+
get_latest_commit_json: bool = False,
|
|
576
695
|
download_branch: bool = False
|
|
577
696
|
):
|
|
578
697
|
"""
|
|
@@ -610,15 +729,7 @@ def github_wrapper_main(
|
|
|
610
729
|
|
|
611
730
|
|
|
612
731
|
def github_wrapper_main_with_args():
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
branch=args.branch,
|
|
618
|
-
path=args.path,
|
|
619
|
-
target_directory=args.target_directory,
|
|
620
|
-
pat=args.pat,
|
|
621
|
-
get_latest_commit_json=args.get_latest_commit_json,
|
|
622
|
-
get_latest_commit_message=args.get_latest_commit_message,
|
|
623
|
-
download_branch=args.download_branch
|
|
624
|
-
)
|
|
732
|
+
main_parser = _make_parser()
|
|
733
|
+
args = main_parser.parse_args()
|
|
734
|
+
|
|
735
|
+
return github_wrapper_main(**vars(args))
|
|
@@ -478,7 +478,7 @@ class DnsServer:
|
|
|
478
478
|
dns_cached_request = False
|
|
479
479
|
# Check if the received data request from client is already in the cache
|
|
480
480
|
if client_data in self.dns_questions_to_answers_cache:
|
|
481
|
-
# message = "!!!
|
|
481
|
+
# message = "!!! Request / Response is already in the dictionary..."
|
|
482
482
|
# self.logger.info(message)
|
|
483
483
|
|
|
484
484
|
# Get the response from the cached answers list
|
|
@@ -561,7 +561,7 @@ class DnsServer:
|
|
|
561
561
|
f'{self.offline_route_ipv6}')
|
|
562
562
|
)
|
|
563
563
|
|
|
564
|
-
message = f"!!!
|
|
564
|
+
message = f"!!! Request / Response is in offline mode returning " \
|
|
565
565
|
f"{self.offline_route_ipv6}."
|
|
566
566
|
self.logger.info(message)
|
|
567
567
|
|
|
@@ -577,7 +577,7 @@ class DnsServer:
|
|
|
577
577
|
elif qtype_string == "SRV" or qtype_string == "SOA" or qtype_string == "HTTPS":
|
|
578
578
|
dns_built_response.add_answer(*RR.fromZone(self.offline_srv_answer))
|
|
579
579
|
|
|
580
|
-
message = f"!!!
|
|
580
|
+
message = f"!!! Request / Response is in offline mode returning: " \
|
|
581
581
|
f"{self.offline_srv_answer}."
|
|
582
582
|
self.logger.info(message)
|
|
583
583
|
elif qtype_string == "ANY":
|
|
@@ -586,7 +586,7 @@ class DnsServer:
|
|
|
586
586
|
self.offline_route_domain)
|
|
587
587
|
)
|
|
588
588
|
|
|
589
|
-
message = f"!!!
|
|
589
|
+
message = f"!!! Request / Response is in offline mode returning " \
|
|
590
590
|
f"{self.offline_route_domain}."
|
|
591
591
|
self.logger.info(message)
|
|
592
592
|
else:
|
|
@@ -596,7 +596,7 @@ class DnsServer:
|
|
|
596
596
|
" " + self.offline_route_ipv4)
|
|
597
597
|
)
|
|
598
598
|
|
|
599
|
-
message = f"!!!
|
|
599
|
+
message = f"!!! Request / Response is in offline mode returning " \
|
|
600
600
|
f"{self.offline_route_ipv4}."
|
|
601
601
|
self.logger.info(message)
|
|
602
602
|
# Values error means in most cases that you create wrong response
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import socket
|
|
1
2
|
import ssl
|
|
2
3
|
import logging
|
|
3
4
|
from pathlib import Path
|
|
@@ -12,12 +13,12 @@ from . import base
|
|
|
12
13
|
class Sender:
|
|
13
14
|
def __init__(
|
|
14
15
|
self,
|
|
15
|
-
ssl_socket: ssl.SSLSocket,
|
|
16
|
+
ssl_socket: ssl.SSLSocket | socket.socket,
|
|
16
17
|
class_message: bytes,
|
|
17
18
|
logger: logging.Logger = None
|
|
18
19
|
):
|
|
19
20
|
self.class_message: bytes = class_message
|
|
20
|
-
self.ssl_socket: ssl.SSLSocket = ssl_socket
|
|
21
|
+
self.ssl_socket: ssl.SSLSocket | socket.socket = ssl_socket
|
|
21
22
|
|
|
22
23
|
if logger:
|
|
23
24
|
# Create child logger for the provided logger with the module's name.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=ixOmnAbr1hvPV-ANWmylWbdUrobDsVq3iPHZfp7dYM4,122
|
|
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,7 +126,7 @@ 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=KzO8DjZjRHfkQMYSIGTkW4jLNPzMR8visTqs1H6ZQ-U,8926
|
|
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=NPHizpPJOaYjP05EEGxEOOKHhgbe4CSzUuk7WTPgZd4,38858
|
|
130
130
|
atomicshop/mitm/import_config.py,sha256=7aLfKqflc3ZnzKc2_Y4T0eenzQpKG94M0r-PaVwF99M,18881
|
|
131
131
|
atomicshop/mitm/initialize_engines.py,sha256=qzz5jzh_lKC03bI1w5ebngVXo1K-RV3poAyW-nObyqo,11042
|
|
132
132
|
atomicshop/mitm/message.py,sha256=CDhhm4BTuZE7oNZCjvIZ4BuPOW4MuIzQLOg91hJaxDI,3065
|
|
@@ -140,7 +140,7 @@ atomicshop/mitm/engines/create_module_template_main_example.py,sha256=LeQ44Rp2Gi
|
|
|
140
140
|
atomicshop/mitm/engines/__parent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
141
141
|
atomicshop/mitm/engines/__parent/parser___parent.py,sha256=HHaCXhScl3OlPjz6eUxsDpJaZyk6BNuDMc9xCkeo2Ws,661
|
|
142
142
|
atomicshop/mitm/engines/__parent/recorder___parent.py,sha256=D99cbpMneY9STSAPETa6eIxyfs_Q9etRYxm2dosA-DI,6203
|
|
143
|
-
atomicshop/mitm/engines/__parent/requester___parent.py,sha256
|
|
143
|
+
atomicshop/mitm/engines/__parent/requester___parent.py,sha256=-S817ERzs1pdY2rXiQBnG4eB4sm2jsy2wycpvuiDlpI,5092
|
|
144
144
|
atomicshop/mitm/engines/__parent/responder___parent.py,sha256=mtiS_6ej9nxT9UhAQR4ftMqnqL-j_kO3u8KEaoEaI9k,9495
|
|
145
145
|
atomicshop/mitm/engines/__reference_general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
146
146
|
atomicshop/mitm/engines/__reference_general/parser___reference_general.py,sha256=57MEPZMAjTO6xBDZ-yt6lgGJyqRrP0Do5Gk_cgCiPns,2998
|
|
@@ -187,7 +187,7 @@ atomicshop/wrappers/astw.py,sha256=VkYfkfyc_PJLIOxByT6L7B8uUmKY6-I8XGZl4t_z828,4
|
|
|
187
187
|
atomicshop/wrappers/configparserw.py,sha256=JwDTPjZoSrv44YKwIRcjyUnpN-FjgXVfMqMK_tJuSgU,22800
|
|
188
188
|
atomicshop/wrappers/cryptographyw.py,sha256=QEUpDn8vUvMg3ADz6-4oC2kbDNC_woDlw7C0zU7qFVM,14233
|
|
189
189
|
atomicshop/wrappers/ffmpegw.py,sha256=wcq0ZnAe0yajBOuTKZCCaKI7CDBjkq7FAgdW5IsKcVE,6031
|
|
190
|
-
atomicshop/wrappers/githubw.py,sha256=
|
|
190
|
+
atomicshop/wrappers/githubw.py,sha256=95RAbxomp4GA9-7B1pk6q3aYOmrCO0vkHyhSPgr3n3Q,31924
|
|
191
191
|
atomicshop/wrappers/netshw.py,sha256=8WE_576XiiHykwFuE-VkCx5CydMpFlztX4frlEteCtI,6350
|
|
192
192
|
atomicshop/wrappers/numpyw.py,sha256=sBV4gSKyr23kXTalqAb1oqttzE_2XxBooCui66jbAqc,1025
|
|
193
193
|
atomicshop/wrappers/olefilew.py,sha256=biD5m58rogifCYmYhJBrAFb9O_Bn_spLek_9HofLeYE,2051
|
|
@@ -300,11 +300,11 @@ atomicshop/wrappers/socketw/accepter.py,sha256=4I9ORugRDvwaqSzm_gWSjZnRwQGY8hDTl
|
|
|
300
300
|
atomicshop/wrappers/socketw/base.py,sha256=EcosGkD8VzgBY3GeIHDSG29ThQfXwg3-GQPmBTAqTdw,3048
|
|
301
301
|
atomicshop/wrappers/socketw/certificator.py,sha256=mtWPJ_ew3OSwt0-1W4jaoco1VIY4NRCrMv3mDUxb_Cc,12418
|
|
302
302
|
atomicshop/wrappers/socketw/creator.py,sha256=hHq8frKQtqZ1-Xfdm2kAsxqtsLFxXKDNwgGKdVKV6yg,16192
|
|
303
|
-
atomicshop/wrappers/socketw/dns_server.py,sha256=
|
|
303
|
+
atomicshop/wrappers/socketw/dns_server.py,sha256=UHq1a3NVdOrclEOOQIe-wNtIgbF8DFeNXsobvtoM1U8,55961
|
|
304
304
|
atomicshop/wrappers/socketw/exception_wrapper.py,sha256=_p98OdOaKYSMqJ23pHLXBUA7NkbVmpgqcSJAdWr6wwc,7560
|
|
305
305
|
atomicshop/wrappers/socketw/get_process.py,sha256=aJC-_qFUv3NgWCSUzDI72E4z8_-VTZE9NVZ0CwUoNlM,5698
|
|
306
306
|
atomicshop/wrappers/socketw/receiver.py,sha256=9B3MvcDqr4C3x2fsnjG5SQognd1wRqsBgikxZa0wXG8,8243
|
|
307
|
-
atomicshop/wrappers/socketw/sender.py,sha256=
|
|
307
|
+
atomicshop/wrappers/socketw/sender.py,sha256=5ecHUlz4Sxt4oWevBFfy33jQLRXmmVLOF34njfvSbxY,4801
|
|
308
308
|
atomicshop/wrappers/socketw/sni.py,sha256=uj6KKYKmSrzXcKBhVLaHQhYn1wNfIUpdnmcvn21V9iE,18176
|
|
309
309
|
atomicshop/wrappers/socketw/socket_client.py,sha256=WWIiCxUX9irN9aWzJ6-1xrXNB_iv_diq3ha1yrWsNGU,22671
|
|
310
310
|
atomicshop/wrappers/socketw/socket_server_tester.py,sha256=Qobmh4XV8ZxLUaw-eW4ESKAbeSLecCKn2OWFzMhadk0,6420
|
|
@@ -314,8 +314,8 @@ atomicshop/wrappers/socketw/statistics_csv.py,sha256=_gA8bMX6Sw_UCXKi2y9wNAwlqif
|
|
|
314
314
|
atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
315
315
|
atomicshop/wrappers/winregw/winreg_installed_software.py,sha256=Qzmyktvob1qp6Tjk2DjLfAqr_yXV0sgWzdMW_9kwNjY,2345
|
|
316
316
|
atomicshop/wrappers/winregw/winreg_network.py,sha256=ih0BVNwByLvf9F_Lac4EdmDYYJA3PzMvmG0PieDZrsE,9905
|
|
317
|
-
atomicshop-3.
|
|
318
|
-
atomicshop-3.
|
|
319
|
-
atomicshop-3.
|
|
320
|
-
atomicshop-3.
|
|
321
|
-
atomicshop-3.
|
|
317
|
+
atomicshop-3.4.0.dist-info/licenses/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
318
|
+
atomicshop-3.4.0.dist-info/METADATA,sha256=7L3q8e0dAu6OukGb_M71h6kx-aLtHEr7E710wUkSUpI,9317
|
|
319
|
+
atomicshop-3.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
320
|
+
atomicshop-3.4.0.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
321
|
+
atomicshop-3.4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|