atomicshop 2.15.12__py3-none-any.whl → 2.16.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.

Files changed (42) hide show
  1. atomicshop/__init__.py +1 -1
  2. atomicshop/a_mains/dns_gateway_setting.py +11 -0
  3. atomicshop/basics/booleans.py +14 -5
  4. atomicshop/dns.py +104 -0
  5. atomicshop/file_io/docxs.py +8 -0
  6. atomicshop/file_io/tomls.py +133 -0
  7. atomicshop/filesystem.py +5 -4
  8. atomicshop/get_process_list.py +3 -3
  9. atomicshop/mitm/config_static.py +195 -0
  10. atomicshop/mitm/config_toml_editor.py +55 -0
  11. atomicshop/mitm/connection_thread_worker.py +54 -90
  12. atomicshop/mitm/import_config.py +147 -139
  13. atomicshop/mitm/initialize_engines.py +7 -2
  14. atomicshop/mitm/initialize_mitm_server.py +161 -107
  15. atomicshop/mitm/shared_functions.py +0 -1
  16. atomicshop/mitm/statistic_analyzer.py +13 -1
  17. atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py +54 -14
  18. atomicshop/script_as_string_processor.py +5 -1
  19. atomicshop/wrappers/cryptographyw.py +3 -3
  20. atomicshop/wrappers/psutilw/networks.py +25 -1
  21. atomicshop/wrappers/pywin32w/wmis/__init__.py +0 -0
  22. atomicshop/wrappers/pywin32w/wmis/helpers.py +127 -0
  23. atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py +167 -0
  24. atomicshop/wrappers/socketw/accepter.py +8 -8
  25. atomicshop/wrappers/socketw/base.py +13 -0
  26. atomicshop/wrappers/socketw/certificator.py +202 -149
  27. atomicshop/wrappers/socketw/creator.py +15 -35
  28. atomicshop/wrappers/socketw/dns_server.py +157 -103
  29. atomicshop/wrappers/socketw/exception_wrapper.py +8 -27
  30. atomicshop/wrappers/socketw/get_process.py +115 -95
  31. atomicshop/wrappers/socketw/sni.py +298 -164
  32. atomicshop/wrappers/socketw/socket_client.py +5 -12
  33. atomicshop/wrappers/socketw/socket_server_tester.py +1 -1
  34. atomicshop/wrappers/socketw/socket_wrapper.py +328 -72
  35. atomicshop/wrappers/socketw/statistics_csv.py +94 -16
  36. {atomicshop-2.15.12.dist-info → atomicshop-2.16.0.dist-info}/METADATA +1 -1
  37. {atomicshop-2.15.12.dist-info → atomicshop-2.16.0.dist-info}/RECORD +41 -36
  38. atomicshop/mitm/config_editor.py +0 -37
  39. /atomicshop/wrappers/pywin32w/{wmi_win32process.py → wmis/win32process.py} +0 -0
  40. {atomicshop-2.15.12.dist-info → atomicshop-2.16.0.dist-info}/LICENSE.txt +0 -0
  41. {atomicshop-2.15.12.dist-info → atomicshop-2.16.0.dist-info}/WHEEL +0 -0
  42. {atomicshop-2.15.12.dist-info → atomicshop-2.16.0.dist-info}/top_level.txt +0 -0
@@ -7,8 +7,12 @@ import socket
7
7
  from ...print_api import print_api
8
8
  from ..loggingw import loggingw
9
9
  from ..psutilw import networks
10
+ from ... import queues
11
+ from ...basics import booleans
10
12
 
13
+ # noinspection PyPackageRequirements
11
14
  import dnslib
15
+ # noinspection PyPackageRequirements
12
16
  from dnslib import DNSRecord, DNSHeader, RR, A
13
17
 
14
18
 
@@ -16,7 +20,8 @@ class DnsPortInUseError(Exception):
16
20
  pass
17
21
 
18
22
 
19
- OUTBOUND_DNS_PORT: int = 53
23
+ class DnsConfigurationValuesError(Exception):
24
+ pass
20
25
 
21
26
 
22
27
  class DnsServer:
@@ -25,33 +30,89 @@ class DnsServer:
25
30
  """
26
31
  logger = loggingw.get_logger_with_level("network." + __name__.rpartition('.')[2])
27
32
 
28
- def __init__(self, config):
33
+ def __init__(
34
+ self,
35
+ listening_interface: str,
36
+ listening_port: int,
37
+ log_directory_path: str,
38
+ forwarding_dns_service_ipv4: str = '8.8.8.8',
39
+ forwarding_dns_service_port: int = 53,
40
+ resolve_to_tcp_server_only_tcp_resolve_domains: bool = False,
41
+ resolve_to_tcp_server_all_domains: bool = False,
42
+ resolve_regular: bool = False,
43
+ offline_mode: bool = False,
44
+ tcp_target_server_ipv4: str = '127.0.0.1',
45
+ tcp_resolve_domain_list: list = None,
46
+ request_domain_queue: queues.NonBlockQueue = None,
47
+ buffer_size_receive: int = 8192,
48
+ response_ttl: int = 60,
49
+ dns_service_retries: int = 5,
50
+ cache_timeout_minutes: int = 60,
51
+ ):
52
+ """
53
+ Initialize the DNS Server object with all the necessary settings.
54
+
55
+ :param listening_interface: str: Interface that the DNS Server will listen on.
56
+ Example: '0.0.0.0'. For all interfaces.
57
+ :param listening_port: int: Port number that the DNS Server will listen on.
58
+ :param log_directory_path: str: Path to the directory where the logs will be saved.
59
+ :param forwarding_dns_service_ipv4: str: IPv4 address of the DNS Service that will be used for resolving.
60
+ Example: '8.8.8.8'. For Google DNS Service.
61
+ :param forwarding_dns_service_port: int: Port number of the DNS Service that will be used for resolving.
62
+ Default is 53.
63
+ :param resolve_to_tcp_server_only_tcp_resolve_domains: bool: If the DNS Server should route only the
64
+ domains from 'tcp_resolve_domain_list' to the TCP Server in 'tcp_target_server_ipv4'.
65
+ :param resolve_to_tcp_server_all_domains: bool: If the DNS Server should route all domains to the TCP Server.
66
+ :param resolve_regular: bool: If the DNS Server should resolve all the domains to the Live DNS Service.
67
+ :param offline_mode: bool: If the DNS Server should work in offline mode.
68
+ :param tcp_target_server_ipv4: str: IPv4 address of the TCP Server that the specified booleans will resolve
69
+ the domains to.
70
+ :param tcp_resolve_domain_list: list: List of domains that will be resolved to the TCP Server.
71
+ This means that all the requests will be resolved to the specified offline IPv4 address.
72
+ :param request_domain_queue: queues.NonBlockQueue: Queue to pass all the requested domains that hit the DNS
73
+ :param buffer_size_receive: int: Buffer size of the connection while receiving messages.
74
+ :param response_ttl: int, Time to live of the DNS Response that will be returned. Default is 60 seconds.
75
+ :param dns_service_retries: int, How many times the request will be sent to forwarded DNS Service on errors:
76
+ (socket connect / request send / response receive).
77
+ :param cache_timeout_minutes: int: Timeout in minutes to clear the DNS Cache.
78
+ server. Each domain will be pass in the queue as a string.
79
+ """
80
+
81
+ self.listening_interface: str = listening_interface
82
+ self.listening_port: int = listening_port
83
+ self.log_directory_path: str = log_directory_path
84
+ self.forwarding_dns_service_ipv4: str = forwarding_dns_service_ipv4
85
+ self.forwarding_dns_service_port: int = forwarding_dns_service_port
86
+ self.tcp_target_server_ipv4: str = tcp_target_server_ipv4
87
+ self.tcp_resolve_domain_list: list = tcp_resolve_domain_list
88
+ self.offline_mode: bool = offline_mode
89
+ self.resolve_to_tcp_server_only_tcp_resolve_domains: bool = resolve_to_tcp_server_only_tcp_resolve_domains
90
+ self.resolve_to_tcp_server_all_domains: bool = resolve_to_tcp_server_all_domains
91
+ self.resolve_regular: bool = resolve_regular
92
+ self.request_domain_queue: queues.NonBlockQueue = request_domain_queue
93
+ self.buffer_size_receive: int = buffer_size_receive
94
+ self.response_ttl: int = response_ttl
95
+ self.dns_service_retries: int = dns_service_retries
96
+ self.cache_timeout_minutes: int = cache_timeout_minutes
97
+
98
+ if not tcp_resolve_domain_list:
99
+ self.tcp_resolve_domain_list = list()
100
+ else:
101
+ self.tcp_resolve_domain_list = tcp_resolve_domain_list
102
+
29
103
  # Settings for static DNS Responses in offline mode.
30
- self.offline_route_ipv4 = '10.10.10.10'
31
- self.offline_route_ipv6 = 'fe80::3c09:df29:d52b:af39'
32
- self.offline_route_domain = 'domain.com'
33
- self.offline_srv_answer = \
104
+ self.offline_route_ipv4: str = '10.10.10.10'
105
+ self.offline_route_ipv6: str = 'fe80::3c09:df29:d52b:af39'
106
+ self.offline_route_domain: str = 'domain.com'
107
+ self.offline_srv_answer: str = \
34
108
  '. 86391 IN SOA domain.com. domain.com. 2022012500 1800 900 604800 86400'
109
+ # self.offline_https_answer: str = str()
35
110
 
36
- # Other settings.
37
- # Full domain list to pass to TCP Server module.
38
- self.domain_list: list = list()
39
-
40
- # Set Buffer size of the connection while receiving messages. The function uses this variable right away.
41
- self.buffer_size_receive: int = 8192
42
- # TTL variable that is going to be returned in DNS response.
43
- self.response_ttl: int = 60
44
- # How many times the DNS Service will retry on errors (socket connect / request send / response receive)
45
- self.dns_service_retries: int = 5
46
111
  # If forwarding to Live DNS Service fails. Currently, we didn't send anything, so it's 'False'.
47
112
  self.retried: bool = False
48
113
  # Defining cache dictionary for assigning DNS Questions to DNS Answers
49
114
  self.dns_questions_to_answers_cache: dict = dict()
50
115
 
51
- # Queue for all the requested domains that hit the dns server.
52
- # self.request_domain_queue: queue.Queue = queue.Queue()
53
- self.request_domain_queue = None
54
-
55
116
  # Filename to save all the known domains and their relative IPv4 addresses.
56
117
  self.known_domains_filename: str = 'dns_known_domains.txt'
57
118
  # Filename to save all the known IPv4 addresses and their relative domains.
@@ -59,18 +120,35 @@ class DnsServer:
59
120
  # Filename to save domains and their IPv4 addresses by time they hit the DNS server.
60
121
  self.known_dns_ipv4_by_time_filename: str = 'dns_ipv4_by_time.txt'
61
122
 
62
- # Configuration object with all the settings.
63
- self.config = config
64
-
65
123
  # Logger that logs all the DNS Requests and responses in DNS format. These entries will not present in
66
124
  # network log of TCP Server module.
67
125
  self.dns_full_logger = loggingw.create_logger(
68
126
  logger_name="dns",
69
- directory_path=self.config['log']['logs_path'],
127
+ directory_path=self.log_directory_path,
70
128
  add_timedfile=True,
71
129
  formatter_filehandler='DEFAULT'
72
130
  )
73
131
 
132
+ self.test_config()
133
+
134
+ def test_config(self):
135
+ try:
136
+ booleans.check_3_booleans_when_only_1_can_be_true(
137
+ (self.resolve_to_tcp_server_only_tcp_resolve_domains,
138
+ 'resolve_to_tcp_server_only_tcp_resolve_domains'),
139
+ (self.resolve_to_tcp_server_all_domains, 'resolve_to_tcp_server_all_domains'),
140
+ (self.resolve_regular, 'resolve_regular')
141
+ )
142
+ except ValueError as e:
143
+ raise DnsConfigurationValuesError(e)
144
+
145
+ port_in_use = networks.get_processes_using_port_list([self.listening_port])
146
+ if port_in_use:
147
+ error_messages: list = list()
148
+ for port, process_info in port_in_use.items():
149
+ error_messages.append(f"Port [{port}] is already in use by process: {process_info}")
150
+ raise DnsPortInUseError("\n".join(error_messages))
151
+
74
152
  def thread_worker_empty_dns_cache(self, function_sleep_time: int):
75
153
  """
76
154
  A thread worker function to empty the cache of DNS request and response lists.
@@ -90,11 +168,6 @@ class DnsServer:
90
168
  :return: None.
91
169
  """
92
170
 
93
- port_in_use = networks.get_processes_using_port_list([self.config['dns']['listening_port']])
94
- if port_in_use:
95
- for port, process_info in port_in_use.items():
96
- raise DnsPortInUseError(f"Port [{port}] is already in use by process: {process_info}")
97
-
98
171
  self.logger.info("DNS Server Module Started.")
99
172
 
100
173
  # Define objects for global usage
@@ -107,19 +180,19 @@ class DnsServer:
107
180
  known_a_records_ipv4_dict: dict = dict()
108
181
 
109
182
  # Check if 'route_to_tcp_server_only_engine_domains' was set to 'True' and output message accordingly.
110
- if self.config['dns']['route_to_tcp_server_only_engine_domains']:
183
+ if self.resolve_to_tcp_server_only_tcp_resolve_domains:
111
184
  message = "Routing only engine domains to Built-in TCP Server."
112
185
  print_api(message, logger=self.logger)
113
186
 
114
- message = f"Current engine domains: {self.domain_list}"
187
+ message = f"Current engine domains: {self.tcp_resolve_domain_list}"
115
188
  print_api(message, logger=self.logger, color='green')
116
189
 
117
- if self.config['dns']['route_to_tcp_server_all_domains']:
190
+ if self.resolve_to_tcp_server_all_domains:
118
191
  message = "Routing all domains to Built-in TCP Server."
119
192
  print_api(message, logger=self.logger, color='green')
120
193
 
121
- if self.config['dns']['regular_resolving']:
122
- message = f"Routing all domains to Live DNS Service: {self.config['dns']['forwarding_dns_service_ipv4']}"
194
+ if self.resolve_regular:
195
+ message = f"Routing all domains to Live DNS Service: {self.forwarding_dns_service_ipv4}"
123
196
  print_api(message, logger=self.logger, color='green')
124
197
 
125
198
  # The list that will hold all the threads that can be joined later
@@ -127,7 +200,7 @@ class DnsServer:
127
200
 
128
201
  # Starting a thread that will empty the DNS Cache lists
129
202
  thread_current = threading.Thread(target=self.thread_worker_empty_dns_cache,
130
- args=(self.config['dns']['cache_timeout_minutes'],))
203
+ args=(self.cache_timeout_minutes,))
131
204
  thread_current.daemon = True
132
205
  # Start the thread
133
206
  thread_current.start()
@@ -142,12 +215,13 @@ class DnsServer:
142
215
 
143
216
  # Binding / assigning the port to the server / this script, that is going to be used for
144
217
  # receiving connections.
145
- main_socket_object.bind((self.config['dns']['listening_interface'], self.config['dns']['listening_port']))
218
+ main_socket_object.bind((self.listening_interface, self.listening_port))
146
219
 
147
220
  while True:
148
221
  # Needed this logging line when DNS was separate process.
149
222
  # self.logger.info("Waiting to receive new requests...")
150
223
 
224
+ # noinspection PyBroadException
151
225
  try:
152
226
  client_data, client_address = main_socket_object.recvfrom(self.buffer_size_receive)
153
227
  client_data: bytes
@@ -171,6 +245,7 @@ class DnsServer:
171
245
  pass
172
246
  continue
173
247
 
248
+ # noinspection PyBroadException
174
249
  try:
175
250
  # This is the real point when the request received was logged, but since it takes too much place
176
251
  # on the screen, moved it to full request logging position.
@@ -180,11 +255,11 @@ class DnsServer:
180
255
 
181
256
  # Received DNS request that needs to be parsed to readable format
182
257
  dns_object: dnslib.dns.DNSRecord = DNSRecord.parse(client_data)
183
- # "qtype" returns as numeric identification, we need to convert it to Readable QType (DNS Record Type)
184
- # provided by the dnslib
258
+ # "qtype" returns as numeric identification, we need to convert it to
259
+ # Readable QType (DNS Record Type) provided by the dnslib
185
260
  # "dns_object.q" is the Question from the client that holds all the DNS question data,
186
- # like which domain was
187
- # questioned for resolving, the class (example: IN), DNS Record Type that was questioned and a header.
261
+ # like which domain was questioned for resolving,
262
+ # the class (example: IN), DNS Record Type that was questioned and a header.
188
263
  # "dns_object.q.qtype" returns only QType of the Question
189
264
  qtype_string: str = dnslib.QTYPE[dns_object.q.qtype]
190
265
  # "qclass" returns as numeric identification, we need to convert it
@@ -204,7 +279,8 @@ class DnsServer:
204
279
  self.dns_full_logger.info(f"QTYPE: {qtype_string}")
205
280
  self.dns_full_logger.info(f"Question Domain: {question_domain}")
206
281
 
207
- message = f"Received request from: {client_address}. Full Request: {dns_object.q}"
282
+ message = (f"Received DNS request: {question_domain} | {qclass_string} | {qtype_string} | "
283
+ f"From: {client_address}.")
208
284
  self.logger.info(message)
209
285
  self.dns_full_logger.info(message)
210
286
 
@@ -229,12 +305,12 @@ class DnsServer:
229
305
  else:
230
306
  # Check if the incoming Record is "A" record.
231
307
  if qtype_string == "A":
232
- # Check if 'route_to_tcp_server_only_engine_domains' is set to 'True' in 'config.ini'.
233
- # If so, we need to check if the incoming domain contain any of the 'engine_domains'.
234
- if self.config['dns']['route_to_tcp_server_only_engine_domains']:
308
+ # Check if 'resolve_to_tcp_server_only_tcp_resolve_domains' is set to 'True'.
309
+ # If so, we need to check if the incoming domain contain any of the domains in the list.
310
+ if self.resolve_to_tcp_server_only_tcp_resolve_domains:
235
311
  # If current query domain (+ subdomains) CONTAIN any of the domains from modules config
236
312
  # files and current request contains "A" (IPv4) record.
237
- if any(x in question_domain for x in self.domain_list):
313
+ if any(x in question_domain for x in self.tcp_resolve_domain_list):
238
314
  # If incoming domain contains any of the 'engine_domains' then domain will
239
315
  # be forwarded to our TCP Server.
240
316
  forward_to_tcp_server = True
@@ -243,12 +319,12 @@ class DnsServer:
243
319
 
244
320
  # If 'route_to_tcp_server_all_domains' was set to 'False' in 'config.ini' file then
245
321
  # we'll forward all 'A' records domains to the Built-in TCP Server.
246
- if self.config['dns']['route_to_tcp_server_all_domains']:
322
+ if self.resolve_to_tcp_server_all_domains:
247
323
  forward_to_tcp_server = True
248
324
 
249
325
  # If 'regular_resolving' was set to 'True' in 'config.ini' file then
250
326
  # we'll forward all 'A' records domains to the Live DNS Service.
251
- if self.config['dns']['regular_resolving']:
327
+ if self.resolve_regular:
252
328
  forward_to_tcp_server = False
253
329
 
254
330
  # If incoming record is not an "A" record, then it will not be forwarded to our TCP Server.
@@ -268,7 +344,7 @@ class DnsServer:
268
344
  # q=DNSQuestion(question_domain),
269
345
  q=dns_object.q,
270
346
  a=RR(question_domain,
271
- rdata=A(self.config['dns']['target_tcp_server_ipv4']),
347
+ rdata=A(self.tcp_target_server_ipv4),
272
348
  ttl=self.response_ttl)
273
349
  )
274
350
  # Encode the response that was built above to legit DNS Response
@@ -279,7 +355,7 @@ class DnsServer:
279
355
  # any of the domains from modules config files
280
356
  else:
281
357
  # If we're in offline mode
282
- if self.config['dns']['offline_mode']:
358
+ if self.offline_mode:
283
359
  # Make DNS response that will refer TCP traffic to our server
284
360
  # dns_question = DNSRecord.question(question_domain)
285
361
  dns_built_response = dns_object.reply()
@@ -290,8 +366,8 @@ class DnsServer:
290
366
  if qtype_string == "AAAA":
291
367
  dns_built_response.add_answer(
292
368
  *RR.fromZone(
293
- question_domain + " " + str(self.response_ttl) + " " + qtype_string + " " +
294
- self.offline_route_ipv6)
369
+ f'{question_domain} {str(self.response_ttl)} {qtype_string} '
370
+ f'{self.offline_route_ipv6}')
295
371
  )
296
372
 
297
373
  message = f"!!! Question / Answer is in offline mode returning " \
@@ -308,7 +384,7 @@ class DnsServer:
308
384
  # com. domain.com. 2022012500 1800 900 604800 86400
309
385
  # Basically SOA is the same, but can be with additional fields.
310
386
  # Since, it's offline and not online - we don't really care.
311
- elif qtype_string == "SRV" or qtype_string == "SOA":
387
+ elif qtype_string == "SRV" or qtype_string == "SOA" or qtype_string == "HTTPS":
312
388
  dns_built_response.add_answer(*RR.fromZone(self.offline_srv_answer))
313
389
 
314
390
  message = f"!!! Question / Answer is in offline mode returning: " \
@@ -317,8 +393,6 @@ class DnsServer:
317
393
  self.dns_full_logger.info(message)
318
394
  elif qtype_string == "ANY":
319
395
  dns_built_response.add_answer(
320
- # *RR.fromZone(question_domain + " " + str(response_ttl) + " " + qclass_string +
321
- # " CNAME " + dns_server_offline_route_domain)
322
396
  *RR.fromZone(question_domain + " " + str(self.response_ttl) + " CNAME " +
323
397
  self.offline_route_domain)
324
398
  )
@@ -330,8 +404,8 @@ class DnsServer:
330
404
  else:
331
405
  dns_built_response.add_answer(
332
406
  *RR.fromZone(
333
- question_domain + " " + str(self.response_ttl) + " " + qtype_string + " " +
334
- self.offline_route_ipv4)
407
+ question_domain + " " + str(self.response_ttl) + " " + qtype_string +
408
+ " " + self.offline_route_ipv4)
335
409
  )
336
410
 
337
411
  message = f"!!! Question / Answer is in offline mode returning " \
@@ -353,7 +427,8 @@ class DnsServer:
353
427
  # General exception in response creation.
354
428
  except Exception:
355
429
  message = \
356
- f"Unknown exception while creating response for QTYPE: {qtype_string}. Response: "
430
+ (f"Unknown exception while creating response for QTYPE: {qtype_string}. "
431
+ f"Response: ")
357
432
  print_api(message, logger=self.logger, logger_method='critical',
358
433
  traceback_string=True, oneline=True)
359
434
  print_api(f"{dns_built_response}", logger=self.logger, logger_method='critical',
@@ -381,8 +456,8 @@ class DnsServer:
381
456
  self.logger.info(f"Retry #: {counter}/{self.dns_service_retries}")
382
457
  self.dns_full_logger.info(
383
458
  f"Forwarding request. Creating UDP socket to: "
384
- f"{self.config['dns']['forwarding_dns_service_ipv4']}:"
385
- f"{OUTBOUND_DNS_PORT}")
459
+ f"{self.forwarding_dns_service_ipv4}:"
460
+ f"{self.forwarding_dns_service_port}")
386
461
  try:
387
462
  google_dns_ipv4_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
388
463
  google_dns_ipv4_socket.settimeout(5)
@@ -392,8 +467,8 @@ class DnsServer:
392
467
  self.dns_full_logger.info(message)
393
468
 
394
469
  google_dns_ipv4_socket.sendto(client_data, (
395
- self.config['dns']['forwarding_dns_service_ipv4'],
396
- OUTBOUND_DNS_PORT
470
+ self.forwarding_dns_service_ipv4,
471
+ self.forwarding_dns_service_port
397
472
  ))
398
473
  # The script needs to wait a second or receive can hang
399
474
  message = "Request sent to the forwarding DNS, Receiving the answer..."
@@ -417,7 +492,7 @@ class DnsServer:
417
492
  self.logger.info(
418
493
  f"Retried {self.dns_service_retries} times. "
419
494
  f"Couldn't forward DNS request to: "
420
- f"[{self.config['dns']['forwarding_dns_service_ipv4']}]. "
495
+ f"[{self.forwarding_dns_service_ipv4}]. "
421
496
  f"Continuing to next request.")
422
497
  self.dns_full_logger.info("==========")
423
498
 
@@ -433,7 +508,7 @@ class DnsServer:
433
508
  continue
434
509
 
435
510
  self.dns_full_logger.info(
436
- f"Answer received from: {self.config['dns']['forwarding_dns_service_ipv4']}")
511
+ f"Answer received from: {self.forwarding_dns_service_ipv4}")
437
512
 
438
513
  # Closing the socket to forwarding service
439
514
  google_dns_ipv4_socket.close()
@@ -442,20 +517,11 @@ class DnsServer:
442
517
  # Appending current DNS Request and DNS Answer to the Cache
443
518
  self.dns_questions_to_answers_cache.update({client_data: dns_response})
444
519
 
445
- # if dns_object.q.qtype == dnslib.QTYPE.AAAA:
446
-
447
- # dns_response = dns_object.reply()
448
- # dns_response.add_answer(*RR.fromZone(f"{question_domain} 60 {qtype_object} 8.8.8.8"))
449
-
450
- # dns_built_response = \
451
- # DNSRecord(
452
- # DNSHeader(id=dns_object.header.id, qr=1, aa=1, ra=1), q=DNSQuestion(question_domain),
453
- # a=RR.fromZone(question_domain + " 60 " + qtype_object + " " + dns_server_offline_ipv4))
454
-
455
- # If 'forward_to_tcp_server' it means that we built the response, and we don't need to reparse it, since
456
- # we already have all the data.
520
+ # If 'forward_to_tcp_server' it means that we built the response, and we don't need to reparse it,
521
+ # since we already have all the data.
457
522
  if forward_to_tcp_server:
458
523
  self.dns_full_logger.info(f"Response IP: {dns_built_response.short()}")
524
+ self.logger.info(f"Response {dns_built_response.short()}")
459
525
 
460
526
  message = f"Response Details: {dns_built_response.rr}"
461
527
  print_api(message, logger=self.dns_full_logger, logger_method='info', oneline=True)
@@ -477,7 +543,8 @@ class DnsServer:
477
543
  # Reinitializing the ipv4 addresses list.
478
544
  ipv4_addresses = list()
479
545
 
480
- if dns_response_parsed.a:
546
+ # If the DNS answer section isn't empty, and log the returned IPv4 addresses.
547
+ if dns_response_parsed.rr:
481
548
  for rr in dns_response_parsed.rr:
482
549
  if isinstance(rr.rdata, A):
483
550
  self.dns_full_logger.info(f"Response IP: {rr.rdata}")
@@ -500,7 +567,7 @@ class DnsServer:
500
567
  # for index, ip_address in enumerate(ipv4_addresses):
501
568
  # ipv4_addresses[index] = str(ip_address)
502
569
 
503
- # ==============================================================================================================
570
+ # ==================================================================================================
504
571
  # # Known domain dictionary of last 2 A records' management.
505
572
  #
506
573
  # # Sorting the addresses, so it will be easier to compare dictionaries in the list.
@@ -522,7 +589,7 @@ class DnsServer:
522
589
  #
523
590
  # dns.logger.info(f"Latest known list: {known_a_records_domains_list_last_entries}")
524
591
 
525
- # ==============================================================================================================
592
+ # ==================================================================================================
526
593
  # Known domain list management (A Records only)
527
594
 
528
595
  # If current request is in the cache,
@@ -568,20 +635,20 @@ class DnsServer:
568
635
 
569
636
  # Save this string object as log file.
570
637
  with open(
571
- self.config['log']['logs_path'] + os.sep + self.known_domains_filename, 'w'
638
+ self.log_directory_path + os.sep + self.known_domains_filename, 'w'
572
639
  ) as output_file:
573
640
  output_file.write(record_string_line)
574
641
 
575
642
  self.dns_full_logger.info(
576
643
  f"Saved new known domains file: "
577
- f"{self.config['log']['logs_path'] + os.sep + self.known_domains_filename}")
644
+ f"{self.log_directory_path}{os.sep}{self.known_domains_filename}")
578
645
 
579
646
  # Known domain list managements EOF
580
- # ==============================================================================================================
647
+ # ==================================================================================================
581
648
  # Known IPv4 address to domains list management (A Records only)
582
649
 
583
650
  # If DNS Server 'offline_mode' was set to 'False'.
584
- if not self.config['dns']['offline_mode']:
651
+ if not self.offline_mode:
585
652
  dump_ipv4_dictionary_to_file = False
586
653
  # If IPv4 address list is not empty, meaning this DNS request was A type.
587
654
  if ipv4_addresses:
@@ -594,9 +661,9 @@ class DnsServer:
594
661
  # If so, get the list of current domains for current ipv4 address.
595
662
  current_domains_list = known_a_records_ipv4_dict[current_ip_address]
596
663
 
597
- # If current question domain is not in the known domains that we had from previous DNS
598
- # requests for the same IPv4 address, then we'll add this domain to the known domains
599
- # list for this IPv4.
664
+ # If current question domain is not in the known domains that we had from
665
+ # previous DNS requests for the same IPv4 address, then we'll add this domain
666
+ # to the known domains list for this IPv4.
600
667
  # And update the dictionary of known IPv4 addresses and their domains.
601
668
  if question_domain not in current_domains_list:
602
669
  current_domains_list.append(question_domain)
@@ -627,16 +694,16 @@ class DnsServer:
627
694
 
628
695
  # Save this string object as log file.
629
696
  with open(
630
- self.config['log']['logs_path'] + os.sep + self.known_ipv4_filename, 'w'
697
+ self.log_directory_path + os.sep + self.known_ipv4_filename, 'w'
631
698
  ) as output_file:
632
699
  output_file.write(record_string_line)
633
700
 
634
701
  self.dns_full_logger.info(
635
702
  f"Saved new known IPv4 addresses file: "
636
- f"{self.config['log']['logs_path'] + os.sep + self.known_ipv4_filename}")
703
+ f"{self.log_directory_path}{os.sep}{self.known_ipv4_filename}")
637
704
 
638
705
  # Known IPv4 address to domains list management EOF
639
- # ==============================================================================================================
706
+ # ==================================================================================================
640
707
  # Writing IPs by time.
641
708
 
642
709
  # If IPv4 address list is not empty, meaning this DNS request was A type.
@@ -647,25 +714,12 @@ class DnsServer:
647
714
 
648
715
  # Save this string object as log file.
649
716
  with open(
650
- self.config['log']['logs_path'] + os.sep + self.known_dns_ipv4_by_time_filename, 'a'
717
+ self.log_directory_path + os.sep + self.known_dns_ipv4_by_time_filename, 'a'
651
718
  ) as output_file:
652
719
  output_file.write(record_string_line + '\n')
653
720
 
654
721
  # EOF Writing IPs by time.
655
- # ==============================================================================================================
656
- # SSH Remote / LOCALHOST script execution to identify process section
657
-
658
- # Starting a thread that will query IPs of the last DNS request.
659
- # thread_current = \
660
- # threading.Thread(
661
- # target=thread_worker_check_process_by_ip, args=(ipv4_addresses, client_address[0],))
662
- # # Append to list of threads, so they can be "joined" later
663
- # threads_list.append(thread_current)
664
- # # Start the thread
665
- # thread_current.start()
666
-
667
- # EOF SSH / LOCALHOST executing process command line harvesting.
668
- # ==================================================================================================================
722
+ # ==================================================================================================
669
723
 
670
724
  self.dns_full_logger.info("==========")
671
725
  except Exception:
@@ -24,13 +24,13 @@ def connection_exception_decorator(function_name):
24
24
  # After that second exception will be "pass"-ed. This is an exception inside an exception handling.
25
25
  # Looks like was introduced in Python 3 in PEP 3134.
26
26
  except ConnectionAbortedError:
27
- message = f"Socket Accept: {kwargs['dns_domain']}:{port}: " \
27
+ message = f"Socket Accept: {kwargs['domain_from_dns_server']}:{port}: " \
28
28
  f"* Established connection was aborted by software on the host..."
29
29
  wrapper_handle_connection_exceptions.message = message
30
- print_api(message, logger_method='error', traceback_string=True, oneline=True, **kwargs['print_kwargs'])
30
+ print_api(message, logger_method='error', traceback_string=True, **kwargs['print_kwargs'])
31
31
  pass
32
32
  except ConnectionResetError:
33
- message = f"Socket Accept: {kwargs['dns_domain']}:{port}: " \
33
+ message = f"Socket Accept: {kwargs['domain_from_dns_server']}:{port}: " \
34
34
  f"* An existing connection was forcibly closed by the remote host..."
35
35
  wrapper_handle_connection_exceptions.message = message
36
36
  print_api(message, logger_method='error', traceback_string=True, oneline=True, **kwargs['print_kwargs'])
@@ -45,7 +45,7 @@ def connection_exception_decorator(function_name):
45
45
  wrapper_handle_connection_exceptions.message = message
46
46
  try:
47
47
  message = \
48
- f"Socket Accept: {kwargs['dns_domain']}:{port}: {message}"
48
+ f"Socket Accept: {kwargs['domain_from_dns_server']}:{port}: {message}"
49
49
  wrapper_handle_connection_exceptions.message = message
50
50
  print_api(message, error_type=True, logger_method='error', **kwargs['print_kwargs'])
51
51
  except Exception:
@@ -59,7 +59,7 @@ def connection_exception_decorator(function_name):
59
59
  wrapper_handle_connection_exceptions.message = message
60
60
  try:
61
61
  message = \
62
- f"Socket Accept: {kwargs['dns_domain']}:{port}: {message}"
62
+ f"Socket Accept: {kwargs['domain_from_dns_server']}:{port}: {message}"
63
63
  wrapper_handle_connection_exceptions.message = message
64
64
  print_api(message, logger_method='error', **kwargs['print_kwargs'])
65
65
  except Exception:
@@ -80,14 +80,6 @@ def connection_exception_decorator(function_name):
80
80
  f"{base.get_source_destination(kwargs['socket_object'])}"
81
81
  wrapper_handle_connection_exceptions.message = message
82
82
  print_api(message, logger_method='error', traceback_string=True, oneline=True, **kwargs['print_kwargs'])
83
- # elif exception_object.reason == "SSLV3_ALERT_CERTIFICATE_UNKNOWN":
84
- # message = f"ssl.SSLError:{exception_object}"
85
- # message = f"Socket Accept: {domain_name}:{socket_object.getsockname()[1]}: {message}"
86
- # print_api(message, logger=self.logger, logger_method='error', traceback_string=True, oneline=True)
87
- # elif exception_object.reason == "NO_SHARED_CIPHER":
88
- # message = f"ssl.SSLError:{exception_object}"
89
- # message = f"Socket Accept: {domain_name}:{socket_object.getsockname()[1]}: {message}"
90
- # print_api(message, logger=self.logger, logger_method='error', traceback_string=True, oneline=True)
91
83
  else:
92
84
  # Not all requests have the server name passed through Client Hello.
93
85
  # If it is not passed an error of undefined variable will be raised.
@@ -97,35 +89,24 @@ def connection_exception_decorator(function_name):
97
89
  message = "SSLError on accept. Not documented..."
98
90
  wrapper_handle_connection_exceptions.message = message
99
91
  print_api(message, logger_method='error', **kwargs['print_kwargs'])
100
- # try:
101
- # message = f"Socket Accept: {domain_name}:{socket_object.getsockname()[1]}: {message}"
102
- # print_api(message, logger=self.logger, logger_method='error', traceback_string=True, oneline=True)
103
- # except Exception:
104
- # message = f"Socket Accept: port {socket_object.getsockname()[1]}: {message}"
105
- # print_api(message, logger=self.logger, logger_method='error', traceback_string=True, oneline=True)
106
- # pass
107
92
 
108
93
  message = f'ssl.SSLError:{exception_object}'
109
94
  wrapper_handle_connection_exceptions.message = message
110
95
  message = \
111
- f"Socket Accept: {kwargs['dns_domain']}:{port}: {message}"
96
+ f"Socket Accept: {kwargs['domain_from_dns_server']}:{port}: {message}"
112
97
  wrapper_handle_connection_exceptions.message = message
113
98
  print_api(message, logger_method='error', **kwargs['print_kwargs'])
114
99
  pass
115
100
  except FileNotFoundError:
116
101
  message = "'SSLSocket.accept()' crashed: 'FileNotFoundError'. Some problem with SSL during Handshake - " \
117
102
  "Could be certificate, client, or server."
118
- message = f"Socket Accept: {kwargs['dns_domain']}:{port}: {message}"
103
+ message = f"Socket Accept: {kwargs['domain_from_dns_server']}:{port}: {message}"
119
104
  wrapper_handle_connection_exceptions.message = message
120
105
  print_api(message, logger_method='error', traceback_string=True, oneline=True, **kwargs['print_kwargs'])
121
- # except Exception:
122
- # message = f"Socket Accept: port {socket_object.getsockname()[1]}: {message}"
123
- # print_api(message, logger=self.logger, logger_method='error', traceback_string=True, oneline=True)
124
- # pass
125
106
  pass
126
107
  except Exception:
127
108
  message = "Undocumented exception on accept."
128
- message = f"Socket Accept: {kwargs['dns_domain']}:{port}: {message}"
109
+ message = f"Socket Accept: {kwargs['domain_from_dns_server']}:{port}: {message}"
129
110
  wrapper_handle_connection_exceptions.message = message
130
111
  print_api(message, logger_method='error', traceback_string=True, oneline=True, **kwargs['print_kwargs'])
131
112
  pass