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
@@ -1,181 +1,315 @@
1
- import sys
2
1
  import ssl
2
+ from dataclasses import dataclass
3
3
 
4
4
  from . import certificator, creator
5
5
  from ...domains import get_domain_without_first_subdomain_if_no_subdomain_return_as_is
6
6
  from ...print_api import print_api
7
7
 
8
8
 
9
- def add_sni_callback_function_reference_to_ssl_context(
10
- ssl_context, config: dict, dns_domain: str = None,
11
- sni_function_name=None, use_default_sni_function: bool = False, use_sni_extended: bool = False,
12
- print_kwargs: dict = None):
9
+ @dataclass
10
+ class SNIReceivedParameters:
11
+ ssl_socket: ssl.SSLSocket
12
+ destination_name: str
13
+ ssl_context: ssl.SSLContext
14
+
15
+
16
+ class SNIDefaultCertificateCreationError(Exception):
17
+ pass
18
+
19
+
20
+ class SNISetup:
13
21
  """
14
- Add SNI callback function reference to SSLContext object. Inplace.
15
-
16
- :param ssl_context:
17
- :param config:
18
- :param dns_domain: domain that was received from DNS Server that will be used if no SNI was passed.
19
- :param sni_function_name: Reference to the function that will be called when SNI is present in the request.
20
- :param use_default_sni_function: If True, will use default SNI function.
21
- :param use_sni_extended: If True, will use extended SNI function.
22
- :param print_kwargs: dict, that contains all the arguments for 'print_api' function.
23
- :return:
22
+ Class to handle setting up SNI related features in socket and context.
24
23
  """
24
+ def __init__(
25
+ self,
26
+ ca_certificate_name: str,
27
+ ca_certificate_filepath: str,
28
+ default_server_certificate_usage: bool,
29
+ default_server_certificate_name: str,
30
+ default_server_certificate_directory: str,
31
+ default_certificate_domain_list: list,
32
+ sni_custom_callback_function: callable,
33
+ sni_use_default_callback_function: bool,
34
+ sni_use_default_callback_function_extended: bool,
35
+ sni_add_new_domains_to_default_server_certificate: bool,
36
+ sni_create_server_certificate_for_each_domain: bool,
37
+ sni_server_certificates_cache_directory: str,
38
+ sni_get_server_certificate_from_server_socket: bool,
39
+ sni_server_certificate_from_server_socket_download_directory: str,
40
+ custom_server_certificate_usage: bool,
41
+ custom_server_certificate_path: str,
42
+ custom_private_key_path: str,
43
+ forwarding_dns_service_ipv4_list___only_for_localhost: list,
44
+ tls: bool,
45
+ domain_from_dns_server: str = None,
46
+ skip_extension_id_list: list = None
47
+ ):
48
+ self.ca_certificate_name = ca_certificate_name
49
+ self.ca_certificate_filepath = ca_certificate_filepath
50
+ self.default_server_certificate_usage = default_server_certificate_usage
51
+ self.default_server_certificate_name = default_server_certificate_name
52
+ self.default_server_certificate_directory = default_server_certificate_directory
53
+ self.default_certificate_domain_list = default_certificate_domain_list
54
+ self.sni_custom_callback_function: callable = sni_custom_callback_function
55
+ self.sni_use_default_callback_function: bool = sni_use_default_callback_function
56
+ self.sni_use_default_callback_function_extended: bool = sni_use_default_callback_function_extended
57
+ self.sni_add_new_domains_to_default_server_certificate = sni_add_new_domains_to_default_server_certificate
58
+ self.sni_create_server_certificate_for_each_domain = sni_create_server_certificate_for_each_domain
59
+ self.sni_server_certificates_cache_directory = sni_server_certificates_cache_directory
60
+ self.sni_get_server_certificate_from_server_socket = sni_get_server_certificate_from_server_socket
61
+ self.sni_server_certificate_from_server_socket_download_directory = (
62
+ sni_server_certificate_from_server_socket_download_directory)
63
+ self.custom_server_certificate_usage = custom_server_certificate_usage
64
+ self.custom_server_certificate_path = custom_server_certificate_path
65
+ self.custom_private_key_path = custom_private_key_path
66
+ self.forwarding_dns_service_ipv4_list___only_for_localhost = (
67
+ forwarding_dns_service_ipv4_list___only_for_localhost)
68
+ self.domain_from_dns_server: str = domain_from_dns_server
69
+ self.skip_extension_id_list = skip_extension_id_list
70
+ self.tls = tls
71
+
72
+ self.certificator_instance = None
25
73
 
26
- if sni_function_name and (use_default_sni_function or use_sni_extended):
27
- raise ValueError("You can't use both custom and default SNI function at the same time.")
28
-
29
- if use_sni_extended and not use_default_sni_function:
30
- raise ValueError("You can't use extended SNI function without default SNI function.")
31
-
32
- # SNI - Server Name Indication: https://en.wikipedia.org/wiki/Server_Name_Indication
33
- # SNI is extension to TLS protocol to tell the Server what is destination domain that the client is trying to
34
- # connect. The server knowing the destination domain then can present to the client the appropriate certificate.
35
- # "sni_callback" method: https://docs.python.org/3/library/ssl.html#ssl.SSLContext.sni_callback
36
- # The method calls your custom function. If there is SNI present in the TLS request from the client, then the
37
- # function will be called. Automatically providing 3 parameters from the system: ssl.SSLSocket, The destination
38
- # server name, current ssl.SSLContext object.
39
- # If you check the custom function it has all these variables mandatory, since this is what system provides and
40
- # handled by the system, if SNI is existent.
41
- # The function is actually called at "accept()" method of the "ssl.SSLSocket"
42
- # This needs to be set only once on the listening socket
43
- if sni_function_name:
44
- ssl_context.sni_callback = sni_function_name
45
-
46
- if use_default_sni_function:
47
- ssl_context.set_servername_callback(
48
- setup_sni_callback(
49
- use_sni_extended=use_sni_extended, config=config, dns_domain=dns_domain, print_kwargs=print_kwargs)
74
+ def wrap_socket_with_ssl_context_server_sni_extended(
75
+ self,
76
+ socket_object,
77
+ print_kwargs: dict = None
78
+ ):
79
+
80
+ # Create SSL Socket to wrap the raw socket with.
81
+ ssl_context = creator.create_ssl_context_for_server()
82
+
83
+ self.certificator_instance = certificator.Certificator(
84
+ ca_certificate_name=self.ca_certificate_name,
85
+ ca_certificate_filepath=self.ca_certificate_filepath,
86
+ default_server_certificate_usage=self.default_server_certificate_usage,
87
+ default_server_certificate_name=self.default_server_certificate_name,
88
+ default_server_certificate_directory=self.default_server_certificate_directory,
89
+ default_certificate_domain_list=self.default_certificate_domain_list,
90
+ sni_server_certificates_cache_directory=self.sni_server_certificates_cache_directory,
91
+ sni_get_server_certificate_from_server_socket=self.sni_get_server_certificate_from_server_socket,
92
+ sni_server_certificate_from_server_socket_download_directory=(
93
+ self.sni_server_certificate_from_server_socket_download_directory),
94
+ custom_server_certificate_usage=self.custom_server_certificate_usage,
95
+ custom_server_certificate_path=self.custom_server_certificate_path,
96
+ custom_private_key_path=self.custom_private_key_path,
97
+ forwarding_dns_service_ipv4_list___only_for_localhost=(
98
+ self.forwarding_dns_service_ipv4_list___only_for_localhost),
99
+ skip_extension_id_list=self.skip_extension_id_list,
100
+ tls=self.tls
50
101
  )
51
102
 
103
+ # Add SNI callback function to the SSL context.
104
+ self.add_sni_callback_function_to_ssl_context(ssl_context=ssl_context, print_kwargs=print_kwargs)
105
+
106
+ server_certificate_file_path, server_private_key_file_path = \
107
+ self.certificator_instance.select_server_ssl_context_certificate(print_kwargs=print_kwargs)
108
+
109
+ # If the user chose 'sni_create_server_certificate_for_each_domain = 1' in the configuration file,
110
+ # it means that 'self.server_certificate_file_path' will be empty, which is OK, since we'll inject
111
+ # dynamically created certificate from certs folder through SNI.
112
+ if server_certificate_file_path:
113
+ creator.load_certificate_and_key_into_server_ssl_context(
114
+ ssl_context, server_certificate_file_path, server_private_key_file_path,
115
+ print_kwargs=print_kwargs)
52
116
 
53
- # Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) computer networking protocol.
54
- # Function to handle server's SSLContext's SNI callback function.
55
- # This is actually called first during "accept()" method of the "ssl.SSLSocket" then comes accept itself.
56
- # This happens in 'ssl.py' module in 'self._sslobj.do_handshake()' function.
57
- def setup_sni_callback(
58
- use_sni_extended: bool = False, config: dict = None, dns_domain: str = None, print_kwargs: dict = None):
117
+ ssl_socket, error_message = creator.wrap_socket_with_ssl_context_server_with_error_message(
118
+ socket_object=socket_object, ssl_context=ssl_context, domain_from_dns_server=self.domain_from_dns_server,
119
+ print_kwargs=print_kwargs)
120
+
121
+ return ssl_socket, error_message
122
+
123
+ def add_sni_callback_function_to_ssl_context(
124
+ self,
125
+ ssl_context,
126
+ print_kwargs: dict = None
127
+ ):
128
+ """
129
+ Add SNI callback function reference to SSLContext object. Inplace.
130
+
131
+ :param ssl_context: SSLContext object.
132
+ :param print_kwargs: dict, that contains all the arguments for 'print_api' function.
133
+ :return:
134
+ """
135
+
136
+ # SNI - Server Name Indication: https://en.wikipedia.org/wiki/Server_Name_Indication
137
+ # SNI is extension to TLS protocol to tell the Server what is destination domain that the client is trying to
138
+ # connect. The server knowing the destination domain then can present to the client the appropriate certificate.
139
+ # "sni_callback" method: https://docs.python.org/3/library/ssl.html#ssl.SSLContext.sni_callback
140
+ # The method calls your custom function. If there is SNI present in the TLS request from the client, then the
141
+ # function will be called. Automatically providing 3 parameters from the system: ssl.SSLSocket, The destination
142
+ # server name, current ssl.SSLContext object.
143
+ # If you check the custom function it has all these variables mandatory, since this is what system provides and
144
+ # handled by the system, if SNI is existent.
145
+ # The function is actually called at "accept()" method of the "ssl.SSLSocket"
146
+ # This needs to be set only once on the listening socket
147
+ if self.sni_custom_callback_function:
148
+ ssl_context.sni_callback = self.sni_custom_callback_function
149
+
150
+ if self.sni_use_default_callback_function:
151
+ sni_handler_instance = SNIHandler(
152
+ sni_use_default_callback_function_extended=self.sni_use_default_callback_function_extended,
153
+ sni_add_new_domains_to_default_server_certificate=self.sni_add_new_domains_to_default_server_certificate,
154
+ sni_create_server_certificate_for_each_domain=self.sni_create_server_certificate_for_each_domain,
155
+ certificator_instance=self.certificator_instance,
156
+ domain_from_dns_server=self.domain_from_dns_server,
157
+ default_certificate_domain_list=self.default_certificate_domain_list
158
+ )
159
+ ssl_context.set_servername_callback(
160
+ sni_handler_instance.setup_sni_callback(print_kwargs=print_kwargs))
161
+
162
+
163
+ class SNIHandler:
59
164
  """
60
- Setup SNI callback function.
61
- :param use_sni_extended: Use extended SNI function, besides the default one.
62
- :param config:
63
- :param dns_domain: domain that was received from DNS Server that will be used if no SNI was passed.
64
- :param print_kwargs: dict, that contains all the arguments for 'print_api' function.
65
- :return:
165
+ THe class is responsible for handling SNI callback execution.
66
166
  """
67
167
 
68
- def sni_handle(
69
- sni_ssl_socket: ssl.SSLSocket,
70
- sni_destination_name: str,
71
- sni_ssl_context: ssl.SSLContext):
72
-
73
- if use_sni_extended and not config:
74
- raise ValueError("You can't use extended SNI function without config.")
75
-
76
- sni_received_dict = {
77
- 'ssl_socket': sni_ssl_socket,
78
- 'destination_name': sni_destination_name,
79
- 'ssl_context': sni_ssl_context
80
- }
81
-
82
- # If 'sni_execute_extended' was set to True.
83
- if use_sni_extended:
84
- sni_handle_extended(sni_received_dict, config=config, dns_domain=dns_domain, print_kwargs=print_kwargs)
85
- # Just set the server_hostname in current socket.
86
- else:
87
- sni_received_dict['ssl_socket'].server_hostname = sni_destination_name
88
- return sni_handle
89
-
90
-
91
- def sni_handle_extended(sni_received_dict: dict, config: dict, dns_domain: str = None, print_kwargs: dict = None):
92
- # Set 'server_hostname' for the socket.
93
- set_socket_server_hostname(sni_received_dict=sni_received_dict, dns_domain=dns_domain, print_kwargs=print_kwargs)
94
-
95
- # If 'sni_default_server_certificates_addons' was set to 'True' in the 'config.ini'.
96
- # This section will add all the new domains that hit the server to default certificate SAN with wildcard.
97
- if config['certificates']['sni_default_server_certificate_addons']:
98
- sni_add_domain_to_default_server_certificate(sni_received_dict=sni_received_dict, config=config,
99
- print_kwargs=print_kwargs)
100
-
101
- # If SNI server certificate creation was set to 'True', we'll create certificate for each incoming domain if
102
- # non-existent in certificates cache folder.
103
- if config['certificates']['sni_create_server_certificate_for_each_domain']:
104
- certificator.create_use_sni_server_certificate_ca_signed(
105
- sni_received_dict=sni_received_dict, config=config, print_kwargs=print_kwargs)
106
-
107
-
108
- def set_socket_server_hostname(sni_received_dict: dict, dns_domain: str = None, print_kwargs: dict = None):
109
- service_name_from_sni = None
110
-
111
- # Try on general settings in the SNI function.
112
- try:
113
- # Check if SNI was passed.
114
- if sni_received_dict['destination_name']:
115
- service_name_from_sni = sni_received_dict['destination_name']
116
- # If no SNI was passed.
117
- else:
118
- # If DNS server is enabled we'll get the domain from dns server.
119
- if dns_domain:
120
- service_name_from_sni = dns_domain
121
- message = f"SNI Handler: No SNI was passed, using domain from DNS Server: {service_name_from_sni}"
122
- print_api(message, **print_kwargs)
123
- # If DNS server is disabled, the domain from dns server will be empty.
168
+ def __init__(
169
+ self,
170
+ sni_use_default_callback_function_extended: bool,
171
+ sni_add_new_domains_to_default_server_certificate: bool,
172
+ sni_create_server_certificate_for_each_domain: bool,
173
+ certificator_instance: certificator.Certificator,
174
+ domain_from_dns_server: str,
175
+ default_certificate_domain_list: list
176
+ ):
177
+ self.sni_use_default_callback_function_extended = sni_use_default_callback_function_extended
178
+ self.sni_add_new_domains_to_default_server_certificate = sni_add_new_domains_to_default_server_certificate
179
+ self.sni_create_server_certificate_for_each_domain = sni_create_server_certificate_for_each_domain
180
+ self.certificator_instance = certificator_instance
181
+ self.domain_from_dns_server: str = domain_from_dns_server
182
+ self.default_certificate_domain_list = default_certificate_domain_list
183
+
184
+ # noinspection PyTypeChecker
185
+ self.sni_received_parameters: SNIReceivedParameters = None
186
+
187
+ # Server Name Indication (SNI) is an extension to the Transport Layer Security (TLS) computer networking protocol.
188
+ # Function to handle server's SSLContext's SNI callback function.
189
+ # This is actually called first during "accept()" method of the "ssl.SSLSocket" then comes accept itself.
190
+ # This happens in 'ssl.py' module in 'self._sslobj.do_handshake()' function.
191
+ def setup_sni_callback(
192
+ self,
193
+ print_kwargs: dict = None
194
+ ):
195
+ """
196
+ Setup SNI callback function.
197
+ :param print_kwargs: dict, that contains all the arguments for 'print_api' function.
198
+ :return:
199
+ """
200
+
201
+ def sni_handle(
202
+ sni_ssl_socket: ssl.SSLSocket,
203
+ sni_destination_name: str,
204
+ sni_ssl_context: ssl.SSLContext):
205
+ # Set 'server_hostname' for the socket.
206
+ sni_ssl_socket.server_hostname = sni_destination_name
207
+
208
+ # If 'sni_execute_extended' was set to True.
209
+ if self.sni_use_default_callback_function_extended:
210
+ self.sni_received_parameters = SNIReceivedParameters(
211
+ ssl_socket=sni_ssl_socket,
212
+ destination_name=sni_destination_name,
213
+ ssl_context=sni_ssl_context
214
+ )
215
+
216
+ self.sni_handle_extended(print_kwargs=print_kwargs)
217
+
218
+ return sni_handle
219
+
220
+ def sni_handle_extended(
221
+ self,
222
+ print_kwargs: dict = None
223
+ ):
224
+ # Set 'server_hostname' for the socket.
225
+ self.set_socket_server_hostname(print_kwargs=print_kwargs)
226
+
227
+ # If 'sni_default_server_certificates_addons' was set to 'True' in the 'config.ini'.
228
+ # This section will add all the new domains that hit the server to default certificate SAN with wildcard.
229
+ if self.sni_add_new_domains_to_default_server_certificate:
230
+ self.sni_add_domain_to_default_server_certificate(print_kwargs=print_kwargs)
231
+
232
+ # If SNI server certificate creation was set to 'True', we'll create certificate for each incoming domain if
233
+ # non-existent in certificates cache folder.
234
+ if self.sni_create_server_certificate_for_each_domain:
235
+ self.certificator_instance.create_use_sni_server_certificate_ca_signed(
236
+ sni_received_parameters=self.sni_received_parameters, print_kwargs=print_kwargs)
237
+
238
+ def set_socket_server_hostname(
239
+ self,
240
+ print_kwargs: dict = None
241
+ ):
242
+ service_name_from_sni = None
243
+
244
+ # Try on general settings in the SNI function.
245
+ try:
246
+ # Check if SNI was passed.
247
+ if self.sni_received_parameters.destination_name:
248
+ service_name_from_sni = self.sni_received_parameters.destination_name
249
+ # If no SNI was passed.
250
+ else:
251
+ # If DNS server is enabled we'll get the domain from dns server.
252
+ if self.domain_from_dns_server:
253
+ service_name_from_sni = self.domain_from_dns_server
254
+ message = f"SNI Handler: No SNI was passed, using domain from DNS Server: {service_name_from_sni}"
255
+ print_api(message, **(print_kwargs or {}))
256
+ # If DNS server is disabled, the domain from dns server will be empty.
257
+ else:
258
+ message = f"SNI Handler: No SNI was passed, No domain passed from DNS Server. " \
259
+ f"Service name will be 'None'."
260
+ print_api(message, **(print_kwargs or {}))
261
+
262
+ # Setting "server_hostname" as a domain.
263
+ self.sni_received_parameters.ssl_socket.server_hostname = service_name_from_sni
264
+ message = \
265
+ f"SNI Handler: port {self.sni_received_parameters.ssl_socket.getsockname()[1]}: " \
266
+ f"Incoming connection for [{self.sni_received_parameters.ssl_socket.server_hostname}]"
267
+ print_api(message, **(print_kwargs or {}))
268
+ except Exception as exception_object:
269
+ message = f"SNI Handler: Undocumented exception general settings section: {exception_object}"
270
+ print_api(message, error_type=True, logger_method="error", traceback_string=True, oneline=True,
271
+ **(print_kwargs or {}))
272
+ pass
273
+
274
+ def sni_add_domain_to_default_server_certificate(
275
+ self,
276
+ print_kwargs: dict = None
277
+ ):
278
+ # Check if incoming domain is already in the parent domains of 'domains_all_times' list.
279
+ if not any(x in self.sni_received_parameters.ssl_socket.server_hostname for x in
280
+ self.default_certificate_domain_list):
281
+ message = f"SNI Handler: Current domain is not in known domains list. Adding."
282
+ print_api(message, **(print_kwargs or {}))
283
+ # In the past was using 'certauth' to extract tlds, but it works only in online mode, so rewrote
284
+ # the function to disable online fetching of TLD snapshot.
285
+ # Initialize 'certauth' object.
286
+ # certificate_object = CertificateAuthority(certificate_ca_name, certificate_ca_filepath)
287
+ # Extract parent domain from the current SNI domain.
288
+ # parent_domain = certificate_object.get_wildcard_domain(service_name_from_sni)
289
+
290
+ # Extract parent domain from the current SNI domain.
291
+ parent_domain = get_domain_without_first_subdomain_if_no_subdomain_return_as_is(
292
+ self.sni_received_parameters.ssl_socket.server_hostname)
293
+ # Add the parent domain to the known domains list.
294
+ self.default_certificate_domain_list.append(parent_domain)
295
+
296
+ default_server_certificate_path, subject_alternate_names = \
297
+ self.certificator_instance.create_overwrite_default_server_certificate_ca_signed()
298
+
299
+ if default_server_certificate_path:
300
+ message = f"SNI Handler: Default Server Certificate was created / overwritten: " \
301
+ f"{default_server_certificate_path}"
302
+ print_api(message, **(print_kwargs or {}))
303
+
304
+ message = f"SNI Handler: Server Certificate current 'Subject Alternative Names': " \
305
+ f"{subject_alternate_names}"
306
+ print_api(message, **(print_kwargs or {}))
307
+
308
+ # Since new default certificate was created we need to create new SSLContext and add the certificate.
309
+ # You need to build new context and exchange the context that being inherited from the main socket,
310
+ # or else the context will receive previous certificate each time.
311
+ self.sni_received_parameters.ssl_socket.context = \
312
+ creator.create_server_ssl_context___load_certificate_and_key(default_server_certificate_path, None)
124
313
  else:
125
- message = f"SNI Handler: No SNI was passed, No domain passed from DNS Server. " \
126
- f"Service name will be 'None'."
127
- print_api(message, **print_kwargs)
128
-
129
- # Setting "server_hostname" as a domain.
130
- sni_received_dict['ssl_socket'].server_hostname = service_name_from_sni
131
- message = \
132
- f"SNI Handler: port {sni_received_dict['ssl_socket'].getsockname()[1]}: " \
133
- f"Incoming connection for [{sni_received_dict['ssl_socket'].server_hostname}]"
134
- print_api(message, **print_kwargs)
135
- except Exception as exception_object:
136
- message = f"SNI Handler: Undocumented exception general settings section: {exception_object}"
137
- print_api(message, error_type=True, logger_method="error", traceback_string=True, oneline=True,
138
- **print_kwargs)
139
- pass
140
-
141
-
142
- def sni_add_domain_to_default_server_certificate(sni_received_dict: dict, config: dict, print_kwargs: dict = None):
143
- # Check if incoming domain is already in the parent domains of 'domains_all_times' list.
144
- if not any(x in sni_received_dict['ssl_socket'].server_hostname for x in
145
- config['certificates']['domains_all_times']):
146
- message = f"SNI Handler: Current domain is not in known domains list. Adding."
147
- print_api(message, **print_kwargs)
148
- # In the past was using 'certauth' to extract tlds, but it works only in online mode, so rewrote
149
- # the function to disable online fetching of TLD snapshot.
150
- # Initialize 'certauth' object.
151
- # certificate_object = CertificateAuthority(certificate_ca_name, certificate_ca_filepath)
152
- # Extract parent domain from the current SNI domain.
153
- # parent_domain = certificate_object.get_wildcard_domain(service_name_from_sni)
154
-
155
- # Extract parent domain from the current SNI domain.
156
- parent_domain = get_domain_without_first_subdomain_if_no_subdomain_return_as_is(
157
- sni_received_dict['ssl_socket'].server_hostname)
158
- # Add the parent domain to the known domains list.
159
- config['certificates']['domains_all_times'].append(parent_domain)
160
-
161
- default_server_certificate_path, subject_alternate_names = \
162
- certificator.create_overwrite_default_server_certificate_ca_signed(config=config)
163
-
164
- if default_server_certificate_path:
165
- message = f"SNI Handler: Default Server Certificate was created / overwritten: " \
166
- f"{default_server_certificate_path}"
167
- print_api(message, **print_kwargs)
168
-
169
- message = f"SNI Handler: Server Certificate current 'Subject Alternative Names': " \
170
- f"{subject_alternate_names}"
171
- print_api(message, **print_kwargs)
172
-
173
- # Since new default certificate was created we need to create new SSLContext and add the certificate.
174
- # You need to build new context and exchange the context that being inherited from the main socket,
175
- # or else the context will receive previous certificate each time.
176
- sni_received_dict['ssl_socket'].context = \
177
- creator.create_server_ssl_context___load_certificate_and_key(default_server_certificate_path, None)
178
- else:
179
- message = f"Couldn't create / overwrite Default Server Certificate: {default_server_certificate_path}"
180
- print_api(message, error_type=True, logger_method="critical", **print_kwargs)
181
- sys.exit()
314
+ message = f"Couldn't create / overwrite Default Server Certificate: {default_server_certificate_path}"
315
+ raise SNIDefaultCertificateCreationError(message)
@@ -1,6 +1,9 @@
1
1
  import socket
2
2
  import ssl
3
3
  import time
4
+ from typing import Literal, Union
5
+
6
+ from cryptography import x509
4
7
 
5
8
  from . import creator
6
9
  from .receiver import Receiver
@@ -10,7 +13,6 @@ from .. import cryptographyw
10
13
  from ..loggingw import loggingw
11
14
  from ...print_api import print_api
12
15
  from ...file_io import file_io
13
- from ... import filesystem
14
16
 
15
17
  import dns.resolver
16
18
 
@@ -323,9 +325,9 @@ class SocketClient:
323
325
  self,
324
326
  save_as_file: bool = False,
325
327
  cert_file_path: str = None,
326
- cert_output_type: str = 'der',
328
+ cert_output_type: Literal['der', 'cryptography'] = 'der',
327
329
  **kwargs
328
- ):
330
+ ) -> Union[x509.Certificate]:
329
331
  """
330
332
  This function will get the certificate from the server and return it.
331
333
 
@@ -339,15 +341,6 @@ class SocketClient:
339
341
  # If "save_as_file" is True, then "cert_file_path" must be provided, if not, raise an exception.
340
342
  if save_as_file and not cert_file_path:
341
343
  raise ValueError("If 'save_as_file' is True, then 'cert_file_path' must be provided.")
342
- # If 'save_as_file' is True and 'cert_file_path' is provided, then check if the file exists.
343
- # Since there is no point fetching the certificate from the socket if it already exists.
344
- elif save_as_file and cert_file_path:
345
- # If certificate from socket exists, then we don't need to get it from the socket and write to file.
346
- # and we will return None, since no certificate was fetched.
347
- if filesystem.is_file_exists(cert_file_path):
348
- return None
349
- else:
350
- print_api("Certificate from socket doesn't exist, fetching.", logger=self.logger)
351
344
 
352
345
  # Connect and get the connected socket.
353
346
  server_socket_for_certificate = self.service_connection()
@@ -37,7 +37,7 @@ def get_key_values_from_json(json_dict: dict, extract_keys: list):
37
37
  def execute_test(config_static):
38
38
  # Import config ini file and read it to dict.
39
39
  config_importer = ConfigParserWrapper(
40
- file_name=config_static.CONFIG_INI_TESTER_FILE_NAME, directory_path=config_static.WORKING_DIRECTORY)
40
+ file_name=config_static.CONFIG_INI_TESTER_FILE_NAME, directory_path=config_static.SCRIPT_DIRECTORY)
41
41
  config_importer.read_to_dict()
42
42
  # Convert keys.
43
43
  config_importer.convert_string_values(